From 8433c03ed05e4bf2a1a5033dd9e0f43ef93ad9e8 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Tue, 9 May 2006 23:22:15 +0000 Subject: [PATCH] Having managed to get WCM-DEV royally screwed up, I made a new branch, WCM-DEV2 and added back my changes. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2804 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- source/java/hibernate.cfg.xml | 23 + source/java/log4j.properties | 9 + .../java/org/alfresco/repo/avm/AVMNode.java | 243 +++++++++ .../org/alfresco/repo/avm/AVMNodeFactory.java | 57 ++ .../org/alfresco/repo/avm/AVMNodeType.java | 30 ++ .../org/alfresco/repo/avm/AVMService.java | 190 +++++++ .../org/alfresco/repo/avm/DirectoryNode.java | 83 +++ .../org/alfresco/repo/avm/FileContent.java | 118 +++++ .../alfresco/repo/avm/FileContentFactory.java | 36 ++ .../java/org/alfresco/repo/avm/FileNode.java | 38 ++ .../org/alfresco/repo/avm/FolderEntry.java | 68 +++ .../repo/avm/LayeredDirectoryNode.java | 407 ++++++++++++++ .../alfresco/repo/avm/LayeredFileNode.java | 119 +++++ source/java/org/alfresco/repo/avm/Lookup.java | 290 ++++++++++ .../alfresco/repo/avm/LookupComponent.java | 158 ++++++ .../alfresco/repo/avm/PlainDirectoryNode.java | 228 ++++++++ .../org/alfresco/repo/avm/PlainFileNode.java | 146 +++++ .../org/alfresco/repo/avm/Repository.java | 171 ++++++ .../alfresco/repo/avm/RepositoryFactory.java | 72 +++ .../alfresco/repo/avm/SuperRepository.java | 234 ++++++++ .../repo/avm/hibernate/AVMNode.hbm.xml | 98 ++++ .../repo/avm/hibernate/AVMNodeBean.java | 134 +++++ .../repo/avm/hibernate/AVMNodeBeanImpl.java | 275 ++++++++++ .../repo/avm/hibernate/Content.hbm.xml | 14 + .../repo/avm/hibernate/ContentBean.java | 61 +++ .../repo/avm/hibernate/ContentBeanImpl.java | 124 +++++ .../repo/avm/hibernate/DirectoryEntry.java | 108 ++++ .../repo/avm/hibernate/DirectoryNodeBean.java | 22 + .../avm/hibernate/DirectoryNodeBeanImpl.java | 53 ++ .../repo/avm/hibernate/FileNodeBean.java | 27 + .../repo/avm/hibernate/FileNodeBeanImpl.java | 54 ++ .../repo/avm/hibernate/HibernateHelper.java | 55 ++ .../repo/avm/hibernate/HibernateTxn.java | 93 ++++ .../avm/hibernate/HibernateTxnCallback.java | 33 ++ .../repo/avm/hibernate/Issuer.hbm.xml | 13 + .../alfresco/repo/avm/hibernate/Issuer.java | 122 +++++ .../hibernate/LayeredDirectoryNodeBean.java | 68 +++ .../LayeredDirectoryNodeBeanImpl.java | 173 ++++++ .../avm/hibernate/LayeredFileNodeBean.java | 37 ++ .../hibernate/LayeredFileNodeBeanImpl.java | 78 +++ .../avm/hibernate/PlainDirectoryNodeBean.java | 47 ++ .../hibernate/PlainDirectoryNodeBeanImpl.java | 102 ++++ .../repo/avm/hibernate/PlainFileNodeBean.java | 37 ++ .../avm/hibernate/PlainFileNodeBeanImpl.java | 78 +++ .../repo/avm/hibernate/Repository.hbm.xml | 30 ++ .../repo/avm/hibernate/RepositoryBean.java | 101 ++++ .../avm/hibernate/RepositoryBeanImpl.java | 204 +++++++ .../repo/avm/hibernate/TestPopulate.java | 211 ++++++++ .../repo/avm/impl/AVMServiceImpl.java | 421 +++++++++++++++ .../repo/avm/impl/RepositoryImpl.java | 291 ++++++++++ .../repo/avm/impl/SuperRepositoryImpl.java | 501 ++++++++++++++++++ 51 files changed, 6385 insertions(+) create mode 100644 source/java/hibernate.cfg.xml create mode 100644 source/java/log4j.properties create mode 100644 source/java/org/alfresco/repo/avm/AVMNode.java create mode 100644 source/java/org/alfresco/repo/avm/AVMNodeFactory.java create mode 100644 source/java/org/alfresco/repo/avm/AVMNodeType.java create mode 100644 source/java/org/alfresco/repo/avm/AVMService.java create mode 100644 source/java/org/alfresco/repo/avm/DirectoryNode.java create mode 100644 source/java/org/alfresco/repo/avm/FileContent.java create mode 100644 source/java/org/alfresco/repo/avm/FileContentFactory.java create mode 100644 source/java/org/alfresco/repo/avm/FileNode.java create mode 100644 source/java/org/alfresco/repo/avm/FolderEntry.java create mode 100644 source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java create mode 100644 source/java/org/alfresco/repo/avm/LayeredFileNode.java create mode 100644 source/java/org/alfresco/repo/avm/Lookup.java create mode 100644 source/java/org/alfresco/repo/avm/LookupComponent.java create mode 100644 source/java/org/alfresco/repo/avm/PlainDirectoryNode.java create mode 100644 source/java/org/alfresco/repo/avm/PlainFileNode.java create mode 100644 source/java/org/alfresco/repo/avm/Repository.java create mode 100644 source/java/org/alfresco/repo/avm/RepositoryFactory.java create mode 100644 source/java/org/alfresco/repo/avm/SuperRepository.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/AVMNode.hbm.xml create mode 100644 source/java/org/alfresco/repo/avm/hibernate/AVMNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/AVMNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/Content.hbm.xml create mode 100644 source/java/org/alfresco/repo/avm/hibernate/ContentBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/FileNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/FileNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/HibernateHelper.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/Issuer.hbm.xml create mode 100644 source/java/org/alfresco/repo/avm/hibernate/Issuer.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/Repository.hbm.xml create mode 100644 source/java/org/alfresco/repo/avm/hibernate/RepositoryBean.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/RepositoryBeanImpl.java create mode 100644 source/java/org/alfresco/repo/avm/hibernate/TestPopulate.java create mode 100644 source/java/org/alfresco/repo/avm/impl/AVMServiceImpl.java create mode 100644 source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java create mode 100644 source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java diff --git a/source/java/hibernate.cfg.xml b/source/java/hibernate.cfg.xml new file mode 100644 index 0000000000..564ec176cd --- /dev/null +++ b/source/java/hibernate.cfg.xml @@ -0,0 +1,23 @@ + + + + + root + + jdbc:mysql://127.0.0.1/avm + com.mysql.jdbc.Driver + thread + org.hibernate.dialect.MySQLInnoDBDialect + true + 2 + 5 + 20 + 900 + 50 + + + + + + diff --git a/source/java/log4j.properties b/source/java/log4j.properties new file mode 100644 index 0000000000..ba55e67c78 --- /dev/null +++ b/source/java/log4j.properties @@ -0,0 +1,9 @@ +### Set logging to console. +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %5p %c{1}:%m%n + +### Set log levels. +log4j.rootLogger=warn, stdout +log4j.logger.org.hibernate=warn diff --git a/source/java/org/alfresco/repo/avm/AVMNode.java b/source/java/org/alfresco/repo/avm/AVMNode.java new file mode 100644 index 0000000000..6f6dc9d9a3 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMNode.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.repo.avm.hibernate.AVMNodeBean; +import org.alfresco.repo.avm.hibernate.DirectoryNodeBean; + +/** + * Base class for all repository file system like objects. + * @author britt + */ +public abstract class AVMNode +{ + /** + * The AVMNodeBean that contains our data. + */ + private AVMNodeBean fData; + + /** + * Default constructor. + */ + protected AVMNode() + { + fData = null; + } + + /** + * Set the ancestor of this node. + * @param ancestor The ancestor to set. + */ + public void setAncestor(AVMNode ancestor) + { + fData.setAncestor(ancestor.getDataBean()); + } + + /** + * Get the ancestor of this node. + * @return The ancestor of this node. + */ + public AVMNode getAncestor() + { + return AVMNodeFactory.CreateFromBean(fData.getAncestor()); + } + + /** + * Set the merged from node. + * @param mergedFrom The merged from node. + */ + public void setMergedFrom(AVMNode mergedFrom) + { + fData.setMergedFrom(mergedFrom.getDataBean()); + } + + /** + * Get the node this was merged from. + * @return The node this was merged from. + */ + public AVMNode getMergedFrom() + { + return AVMNodeFactory.CreateFromBean(fData.getMergedFrom()); + } + + /** + * Should this be copied on modification. + */ + public boolean shouldBeCopied() + { + return !fData.getIsNew(); + } + + /** + * Set to need copying or not. + * @param copyable Whether this should be copied. + */ + public void setShouldBeCopied(boolean copyable) + { + fData.setIsNew(!copyable); + } + + /** + * Get the version number. + * @return The version number. + */ + public long getVersion() + { + return fData.getVersionID(); + } + + /** + * Set the version number. + * @param version The version number to set. + */ + public void setVersion(long version) + { + fData.setVersionID(version); + } + + /** + * Get the branch id of this node. + * @return The branch id. + */ + public long getBranchID() + { + return fData.getBranchID(); + } + + /** + * Set the branch id on this node. + * @param branchID The id to set. + */ + public void setBranchID(long branchID) + { + fData.setBranchID(branchID); + } + + /** + * Get the (possibly null) parent. + * @return The parent or null. + */ + public DirectoryNode getParent() + { + return (DirectoryNode)AVMNodeFactory.CreateFromBean(fData.getParent()); + } + + /** + * Set the parent of this node. + * @param parent The DirectoryNode to set. + */ + public void setParent(DirectoryNode parent) + { + fData.setParent((DirectoryNodeBean)parent.getDataBean()); + } + + /** + * Perform a COW if required. + * @param lPath The lookup path. + * @return A 'copied' version of this node. + */ + public AVMNode copyOnWrite(Lookup lPath) + { + AVMNode newMe = possiblyCopy(lPath); + String myName = lPath.getName(); + lPath.upCurrentNode(); + if (newMe == null) + { + return this; + } + Repository repos = getRepository(); + newMe.setVersion(repos.getLatestVersion() + 1); + DirectoryNode parent = null; + if (getParent() != null) + { + parent = (DirectoryNode)lPath.getCurrentNode(); + } + if (parent != null) + { + DirectoryNode newParent = + (DirectoryNode)parent.copyOnWrite(lPath); + newParent.putChild(myName, newMe); + newMe.setParent(newParent); + } + else // Null parent means root of repository. + { + newMe.setRepository(getRepository()); + repos.setNewRoot((DirectoryNode)newMe); + } + newMe.setShouldBeCopied(false); + repos.setNew(newMe); + return newMe; + } + + + /** + * Possibly copy ourselves. + * @param lPath The Lookup for this node. + * @return A copy of ourself or null if no copy was necessary. + */ + public abstract AVMNode possiblyCopy(Lookup lPath); + + /** + * Handle any after recursive copy processing. + * + * @param parent The DirectoryNode that is the parent of + * this copied node, after recursive copying. + */ + public abstract void handlePostCopy(DirectoryNode parent); + + /** + * Set the repository for a node. + * @param repo The Repository to set. + */ + public void setRepository(Repository repo) + { + fData.setRepository(repo.getDataBean()); + } + + /** + * Get the Repository we 'belong' to. + * @return The Repository. + */ + public Repository getRepository() + { + return RepositoryFactory.GetInstance().createFromBean(fData.getRepository()); + } + + /** + * Get the data bean in this node. + * @return The data bean. + */ + public AVMNodeBean getDataBean() + { + return fData; + } + + /** + * Set the data bean in this node. + * @param bean The data bean to set. + */ + public void setDataBean(AVMNodeBean bean) + { + fData = bean; + } + + /** + * Get the type of this node. + */ + public abstract AVMNodeType getType(); +} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeFactory.java b/source/java/org/alfresco/repo/avm/AVMNodeFactory.java new file mode 100644 index 0000000000..2c1179b3c5 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMNodeFactory.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.repo.avm.hibernate.AVMNodeBean; +import org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.LayeredFileNodeBean; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.PlainFileNodeBean; + +/** + * Responsible for instantiating AVMNode implementations. + * @author britt + */ +public class AVMNodeFactory +{ + /** + * Create a node from a data bean. + * @param bean The AVMNodeBean. + */ + public static AVMNode CreateFromBean(AVMNodeBean bean) + { + if (bean == null) + { + return null; + } + if (bean instanceof PlainFileNodeBean) + { + return new PlainFileNode((PlainFileNodeBean)bean); + } + if (bean instanceof PlainDirectoryNodeBean) + { + return new PlainDirectoryNode((PlainDirectoryNodeBean)bean); + } + if (bean instanceof LayeredDirectoryNodeBean) + { + return new LayeredDirectoryNode((LayeredDirectoryNodeBean)bean); + } + assert bean instanceof LayeredFileNodeBean : "Unknown AVMNodeBean suptype."; + return new LayeredFileNode((LayeredFileNodeBean)bean); + } +} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeType.java b/source/java/org/alfresco/repo/avm/AVMNodeType.java new file mode 100644 index 0000000000..3b9df3163b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMNodeType.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +/** + * This defines the different types of FolderEntrys. + * @author britt + */ +public enum AVMNodeType +{ + PLAIN_FILE, + LAYERED_FILE, + PLAIN_DIRECTORY, + LAYERED_DIRECTORY +} diff --git a/source/java/org/alfresco/repo/avm/AVMService.java b/source/java/org/alfresco/repo/avm/AVMService.java new file mode 100644 index 0000000000..680fabc669 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMService.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +/** + * This is the service interface for the [Alfresco|Addled|Advanced|Apotheosed] Versioning + * Model. It specifies methods that are close in functionality to the underlying + * implementation, and is intended, for now, as an internal interface to build a different + * implementation of NodeService and others. + * @author britt + */ +public interface AVMService +{ + /** + * Get an InputStream for a file node. + * @param version The version id to look in. + * @param path The simple absolute path to the file node. + * @return An InputStream for the designated file. + */ + public InputStream getFileInputStream(int version, String path); + + /** + * Get an output stream to a file node. + * @param path The simple absolute path to the file node. + */ + public OutputStream getFileOutputStream(String path); + + /** + * Get a listing of a Folder by name. + * @param version The version id to look in. + * @param path The simple absolute path to the file node. + * @return A List of FolderEntrys. + */ + public List getDirectoryListing(int version, String path); + + /** + * Create a new File. + * @param parent The simple absolute path to the parent. + * @param name The name to give the file. + */ + public void createFile(String path, String name); + + /** + * Create a new Folder. + * @param parent The simple absolute path to the parent. + * @param name The name to give the folder. + */ + public void createDirectory(String path, String name); + + /** + * Create a new layered file. + * @param srcPath The simple absolute path that the new file will shadow. + * @param parent The simple absolute path to the parent. + * @param name The name to give the new file. + */ + public void createLayeredFile(String srcPath, String parent, String name); + + /** + * Create a new layered folder. + * @param srcPath The simple absolute path that the new folder will shadow. + * @param parent The simple absolute path to the parent. + * @param name The name to give the new folder. + */ + public void createLayeredDirectory(String srcPath, String parent, String name); + + /** + * Retarget a layered folder. + * @param path Path to the layered directory. + * @param target The new target to aim at. + */ + public void retargetLayeredFolder(String path, String target); + + /** + * Create a new Repository. All Repositories are top level in a hierarchical + * sense. + * @param name The name to give the virtual repository. + */ + public void createRepository(String name); + + /** + * Create a branch from a given version and path. + * @param version The version number from which to make the branch. + * @param srcPath The path to the node to branch from. + * @param dstPath The path to the directory to contain the + * new branch. + * @param name The name to give the new branch. + */ + public void createBranch(int version, String srcPath, String dstPath, String name); + + /** + * Remove a child from its parent. + * @param parent The simple absolute path to the parent directory. + * @param name The name of the child to remove. + */ + public void removeNode(String parent, String name); + + /** + * Rename a node. + * @param srcParent The simple absolute path to the parent folder. + * @param srcName The name of the node in the src Folder. + * @param dstParent The simple absolute path to the destination folder. + * @param dstName The name that the node will have in the destination folder. + */ + public void rename(String srcParent, String srcName, String dstParent, String dstName); + + /** + * Slide a directory from one place in a layer to another uncovering what was + * underneath it. + * @param srcParent The simple absolute path to the parent folder. + * @param srcName The name of the node in the src Folder. + * @param dstParent The simple absolute path to the destination folder. + * @param dstName The name that the node will have in the destination folder. + */ + public void slide(String srcParent, String srcName, String dstParent, String dstName); + + /** + * Get the latest version id of the repository. + * @param repName The name of the repository. + * @return The latest version id of the repository. + */ + public long getLatestVersionID(String repName); + + /** + * Snapshot the given repositories. When this is called everything that has been added, + * deleted, or modified since the last time this function was called, is marked + * as needing to be copied, so that further modifications will trigger copy on write + * semantics. + * @param repositories The names of the repositories to snapshot. + */ + public void createSnapshot(List repositories); + + /** + * Get the set of version IDs in a Repository + * @param name The name of the Repository. + * @return A Set of version IDs + */ + public Set getRepositoryVersions(String name); + + /** + * Lookup a node by version ids and path. Note that an AVMNode is essentially + * informational only. There is very little you can do to an AVMNode in the absence + * of path information. + * @param version The version id to look under. + * @param path The simple absolute path to the parent directory. + * @return An AVMNode. + */ + public AVMNode lookup(int version, String path); + + /** + * Get the indirection path for a layered file or directory. + * @param version The version number to get. + * @param path The path to the node of interest. + * @return The indirection path. + */ + public String getIndirectionPath(int version, String path); + + /** + * Destroy a repository. This is a complete wipe of a Repository. + * @param name The name of the Repository. + */ + public void destroyRepository(String name); + + /** + * Purge a version from a repository. Deletes everything that lives in + * the given version only. + * @param version The version to purge. + * @param name The name of the Repository from which to purge it. + */ + public void purgeVersion(int version, String name); +} diff --git a/source/java/org/alfresco/repo/avm/DirectoryNode.java b/source/java/org/alfresco/repo/avm/DirectoryNode.java new file mode 100644 index 0000000000..dc753b7ae5 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/DirectoryNode.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.util.Map; + +import org.alfresco.repo.avm.hibernate.DirectoryEntry; + +/** + * + * @author britt + */ +public abstract class DirectoryNode extends AVMNode +{ + /** + * Does this directory directly contain the specified node. + * @param node The node to check. + * @return Whether it does. + */ + public abstract boolean directlyContains(AVMNode node); + + /** + * Put child into this directory directly. No copy on write. + * @param name The name to give it. + * @param node The child. + */ + public abstract void putChild(String name, AVMNode node); + + /** + * Lookup a child node. + * @param lPath The Lookup so far. + * @param name The name of the child to lookup. + * @param version The version to look under. + */ + public abstract AVMNode lookupChild(Lookup lPath, String name, int version); + + /** + * Add a child node. Fails if child already exists. + * Copy is possible. + * @param name The name to give the child. + * @param child The child to add. + * @param The lookup path. + */ + public abstract boolean addChild(String name, AVMNode child, + Lookup lPath); + + /** + * Remove a child node. Fails if child does not exist. + * Copy is possible. + * @param name The name of the child to remove. + * @param lPath The lookup path. + */ + public abstract boolean removeChild(String name, Lookup lPath); + + /** + * Remove a child directly. No copy is possible. + * @param name The name of the child to remove. + */ + public abstract void rawRemoveChild(String name); + + /** + * Get a directory listing. + * @param lPath The lookup context. + * @param version The version to look under. + * @return A Map of names to DirectoryEntries. + */ + public abstract Map getListing(Lookup lPath, int version); +} diff --git a/source/java/org/alfresco/repo/avm/FileContent.java b/source/java/org/alfresco/repo/avm/FileContent.java new file mode 100644 index 0000000000..7f7e5a5c9b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/FileContent.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.avm.hibernate.ContentBean; +import org.alfresco.repo.avm.hibernate.ContentBeanImpl; + +/** + * Content that is readable and writeable. + * @author britt + */ +public class FileContent +{ + /** + * The data containing bean. + */ + private ContentBean fData; + + /** + * Make one from a bean. + * @param data The Bean with the data. + */ + public FileContent(ContentBean data) + { + fData = data; + } + + /** + * Make a brand new one. + * @param superRepo The SuperRepository. + */ + public FileContent(SuperRepository superRepo) + { + fData = new ContentBeanImpl(superRepo.issueContentID()); + } + + /** + * Copy constructor, sort of. + * @param other The content to copy from. + * @param superRepo The SuperRepository. + */ + public FileContent(FileContent other, SuperRepository superRepo) + { + fData = new ContentBeanImpl(superRepo.issueContentID()); + // TODO Something. + } + + /** + * Get the number of files that refer to this content. + * @return The reference count. + */ + public int getRefCount() + { + return fData.getRefCount(); + } + + /** + * Set the reference count. + * @param count The count to set. + */ + public void setRefCount(int count) + { + fData.setRefCount(count); + } + + /** + * Get an input stream from the content. + * @param superRepo The SuperRepository. + * @return An InputStream. + */ + public InputStream getInputStream(SuperRepository superRepo) + { + // TODO Something. + return null; + } + + /** + * Get an output stream to the content. + * @param superRepo The SuperRepository. + * @return an OutputStream. + */ + public OutputStream getOutputStream(SuperRepository superRepo) + { + // TODO Something. + return null; + } + + /** + * Get the underlying data bean. Don't abuse the privilege. + * @return The data bean. + */ + public ContentBean getDataBean() + { + return fData; + } +} diff --git a/source/java/org/alfresco/repo/avm/FileContentFactory.java b/source/java/org/alfresco/repo/avm/FileContentFactory.java new file mode 100644 index 0000000000..a2a52b5133 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/FileContentFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.repo.avm.hibernate.ContentBean; + +/** + * Static method for making FileContent instances from beans. + * @author britt + */ +public class FileContentFactory +{ + /** + * Make A FileContent object from a ContentBean. + * @param bean The bean with the data. + */ + public static FileContent CreateFileContentFromBean(ContentBean bean) + { + return new FileContent(bean); + } +} diff --git a/source/java/org/alfresco/repo/avm/FileNode.java b/source/java/org/alfresco/repo/avm/FileNode.java new file mode 100644 index 0000000000..8bb82f8d35 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/FileNode.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +/** + * Interface for file objects. + * @author britt + */ +public abstract class FileNode extends AVMNode +{ + /** + * Get the content object associated with this node, for reading. + * @param version The version to get in. + * @return A FileContent object. + */ + public abstract FileContent getContentForRead(int version); + + /** + * Get the content object for writing. This will do COW + * as needed. + */ + public abstract FileContent getContentForWrite(Repository repo); +} diff --git a/source/java/org/alfresco/repo/avm/FolderEntry.java b/source/java/org/alfresco/repo/avm/FolderEntry.java new file mode 100644 index 0000000000..adcf05a81f --- /dev/null +++ b/source/java/org/alfresco/repo/avm/FolderEntry.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +/** + * A FolderEntry is a simple value class containing type + * information and name for an entry in a folder list. + * @author britt + */ +public class FolderEntry +{ + /** + * The name of the entry. + */ + private String fName; + + /** + * The type of the entry. + */ + private AVMNodeType fType; + + /** + * @return the name + */ + public String getName() + { + return fName; + } + + /** + * @param name the name to set + */ + public void getName(String name) + { + fName = name; + } + + /** + * @return the type + */ + public AVMNodeType getType() + { + return fType; + } + + /** + * @param type the type to set + */ + public void setType(AVMNodeType type) + { + fType = type; + } +} diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java new file mode 100644 index 0000000000..fc6b5b448e --- /dev/null +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.TreeMap; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.avm.hibernate.DirectoryEntry; +import org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBeanImpl; + +/** + * Interface for a layered directory node. Stub. + * @author britt + */ +public class LayeredDirectoryNode extends DirectoryNode +{ + /** + * The underlying bean data. + */ + private LayeredDirectoryNodeBean fData; + + /** + * Make one up from Bean data. + * @param data The bean with the persistent data. + */ + public LayeredDirectoryNode(LayeredDirectoryNodeBean data) + { + fData = data; + setDataBean(data); + } + + /** + * Make a new one from a specified indirection path. + * @param indirection The indirection path to set. + * @param repository The repository that owns this node. + */ + public LayeredDirectoryNode(String indirection, Repository repos) + { + fData = new LayeredDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repos.getDataBean(), + -1, + indirection); + setDataBean(fData); + repos.getSuperRepository().getSession().save(fData); + } + + /** + * Kind of copy constructor, sort of. + * @param other The LayeredDirectoryNode we are copied from. + * @param repos The Repository object we use. + */ + public LayeredDirectoryNode(LayeredDirectoryNode other, + Repository repos) + { + fData = new LayeredDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repos.getDataBean(), + -1, + other.getUnderlying()); + fData.setAdded(((LayeredDirectoryNodeBean)other.getDataBean()).getAdded()); + fData.setDeleted(((LayeredDirectoryNodeBean)other.getDataBean()).getDeleted()); + fData.setPrimaryIndirection(((LayeredDirectoryNodeBean)other.getDataBean()).getPrimaryIndirection()); + repos.getSuperRepository().getSession().save(fData); + } + + /** + * Construct one from a PlainDirectoryNode. + * @param other The PlainDirectoryNode. + * @param repos The Repository we should belong to. + * @param lPath The Lookup object. + */ + public LayeredDirectoryNode(PlainDirectoryNode other, + Repository repos, + Lookup lPath) + { + fData = new LayeredDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repos.getDataBean(), + -1, + null); + // TODO Is this right? + fData.setAdded(other.getListing(lPath, -1)); + fData.setPrimaryIndirection(false); + repos.getSuperRepository().getSession().save(fData); + } + + public LayeredDirectoryNode(DirectoryNode dir, + Repository repo, + Lookup srcLookup, + String name) + { +/* + fAdded = new HashMap(); + fDeleted = new HashSet(); + fProxied = srcLookup.getIndirectionPath() + "/" + name; + fIsPrimaryIndirection = true; +*/ + } + + /** + * Does this node have a primary indirection. + * @returns Whether this is a primary indirection. + */ + public boolean hasPrimaryIndirection() + { + return fData.getPrimaryIndirection(); + } + + /** + * Set whether this has a primary indirection. + * @param has Whether this has a primary indirection. + */ + public void setPrimaryIndirection(boolean has) + { + fData.setPrimaryIndirection(has); + } + + /** + * Get the raw underlying indirection. Only meaningful + * for a node that hasPrimaryIndirection(). + */ + public String getUnderlying() + { + return fData.getIndirection(); + } + + /** + * Get the underlying indirection in the context of a Lookup. + * @param lPath The lookup path. + */ + public String getUnderlying(Lookup lPath) + { + if (fData.getPrimaryIndirection()) + { + return fData.getIndirection(); + } + return lPath.getCurrentIndirection(); + } + + /** + * Get the layer id for this node. + * @return The layer id. + */ + public long getLayerID() + { + return fData.getLayerID(); + } + + /** + * Set the layer id for this node. + * @param layerID The id to set. + */ + public void setLayerID(long id) + { + fData.setLayerID(id); + } + + /** + * Handle post copy on write details. + * @param parent + */ + public void handlePostCopy(DirectoryNode parent) + { + if (parent instanceof LayeredDirectoryNode) + { + LayeredDirectoryNode dir = (LayeredDirectoryNode)parent; + setLayerID(dir.getLayerID()); + // TODO Is this right? + setRepository(parent.getRepository()); + } + } + + /** + * Copy on write logic. + * @param lPath + * @return The copy or null. + */ + public AVMNode possiblyCopy(Lookup lPath) + { + if (!shouldBeCopied()) + { + return null; + } + // Otherwise we do an actual copy. + LayeredDirectoryNode newMe = null; + long newBranchID = lPath.getHighestBranch(); + if (!lPath.isInThisLayer()) + { + if (hasPrimaryIndirection()) + { + newMe = new LayeredDirectoryNode(lPath.getIndirectionPath(), + getRepository()); + } + else + { + newMe = new LayeredDirectoryNode((String)null, + getRepository()); + newMe.setPrimaryIndirection(false); + } + } + else + { + newMe = new LayeredDirectoryNode(this, + getRepository()); + + newMe.setLayerID(getLayerID()); + } + newMe.setAncestor(this); + newMe.setBranchID(newBranchID); + return newMe; + } + + /** + * Insert a child node without COW. + * @param name The name to give the child. + */ + public void putChild(String name, AVMNode node) + { + DirectoryEntry entry = new DirectoryEntry(node.getType(), node.getDataBean()); + fData.getAdded().put(name, entry); + fData.getDeleted().remove(name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.DirectoryNode#addChild(java.lang.String, org.alfresco.repo.avm.AVMNode, org.alfresco.repo.avm.Lookup) + */ + public boolean addChild(String name, AVMNode child, Lookup lPath) + { + if (fData.getAdded().containsKey(name)) + { + return false; + } + if (!fData.getDeleted().contains(name)) + { + try + { + Lookup lookup = getRepository().getSuperRepository().lookupDirectory(-1, getUnderlying(lPath)); + DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); + if (dir.lookupChild(lookup, name, -1) != null) + { + return false; + } + } + catch (AlfrescoRuntimeException re) + { + // Do nothing. + } + } + DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath); + toModify.putChild(name, child); + child.setParent(toModify); + child.setRepository(toModify.getRepository()); + return true; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.DirectoryNode#directlyContains(org.alfresco.repo.avm.AVMNode) + */ + public boolean directlyContains(AVMNode node) + { + return fData.getAdded().containsValue(node.getDataBean()); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.DirectoryNode#getListing(org.alfresco.repo.avm.Lookup, int) + */ + public Map getListing(Lookup lPath, int version) + { + Map baseListing = null; + try + { + Lookup lookup = getRepository().getSuperRepository().lookupDirectory(version, getUnderlying(lPath)); + DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); + baseListing = dir.getListing(lookup, version); + } + catch (AlfrescoRuntimeException re) + { + baseListing = new HashMap(); + } + Map listing = new TreeMap(); + for (String name : baseListing.keySet()) + { + if (fData.getDeleted().contains(name)) + { + continue; + } + listing.put(name, baseListing.get(name)); + } + for (String name : fData.getAdded().keySet()) + { + listing.put(name, fData.getAdded().get(name)); + } + return listing; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.DirectoryNode#lookupChild(org.alfresco.repo.avm.Lookup, java.lang.String, int) + */ + public AVMNode lookupChild(Lookup lPath, String name, int version) + { + // TODO revisit the order in this. + if (fData.getAdded().containsKey(name)) + { + return AVMNodeFactory.CreateFromBean(fData.getAdded().get(name).getChild()); + } + AVMNode child = null; + try + { + Lookup lookup = getRepository().getSuperRepository().lookupDirectory(version, getUnderlying(lPath)); + DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); + child = dir.lookupChild(lookup, name, version); + } + catch (AlfrescoRuntimeException re) + { + return null; + } + if (child ==null) + { + return null; + } + if (fData.getDeleted().contains(name)) + { + return null; + } + return child; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.DirectoryNode#rawRemoveChild(java.lang.String) + */ + public void rawRemoveChild(String name) + { + fData.getAdded().remove(name); + fData.getDeleted().add(name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.DirectoryNode#removeChild(java.lang.String, org.alfresco.repo.avm.Lookup) + */ + public boolean removeChild(String name, Lookup lPath) + { + if (fData.getDeleted().contains(name)) + { + return false; + } + if (!fData.getAdded().containsKey(name)) + { + try + { + Lookup lookup = getRepository().getSuperRepository().lookupDirectory(-1, getUnderlying(lPath)); + DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); + if (dir.lookupChild(lookup, name, -1) == null) + { + return false; + } + } + catch (AlfrescoRuntimeException re) + { + return false; + } + } + LayeredDirectoryNode toModify = + (LayeredDirectoryNode)copyOnWrite(lPath); + toModify.rawRemoveChild(name); + return true; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMNode#getType() + */ + public AVMNodeType getType() + { + return AVMNodeType.LAYERED_DIRECTORY; + } +} diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNode.java b/source/java/org/alfresco/repo/avm/LayeredFileNode.java new file mode 100644 index 0000000000..7ff85a540a --- /dev/null +++ b/source/java/org/alfresco/repo/avm/LayeredFileNode.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.avm.hibernate.LayeredFileNodeBean; + +/** + * A LayeredFileNode behaves like a copy on write symlink. + * @author britt + */ +public class LayeredFileNode extends FileNode +{ + /** + * The data bean. + */ + private LayeredFileNodeBean fData; + + /** + * Construct one from its data bean. + */ + public LayeredFileNode(LayeredFileNodeBean data) + { + fData = data; + setDataBean(fData); + } + + /** + * Basically a copy constructor. + * @param other The file to make a copy of. + * @param repo The repository that contains us. + */ + public LayeredFileNode(LayeredFileNode other, Repository repo) + { + // TODO Something. + } + + public LayeredFileNode(FileNode file, + Repository repos, + Lookup srcLookup, + String name) + { + // TODO Something. + } + + + /** + * Set the repository after a copy. + * @param parent The parent after copying. + */ + public void handlePostCopy(DirectoryNode parent) + { + if (parent != null) + { + setRepository(parent.getRepository()); + } + } + + /** + * Copy on write logic. + * @param lPath The path by which this was found. + */ + public AVMNode possiblyCopy(Lookup lPath) + { + // LayeredFileNodes are always copied. + PlainFileNode newMe = new PlainFileNode(getRepository()); + newMe.setAncestor(this); + return newMe; + } + + /** + * Get the type of this node. + * @return The type. + */ + public AVMNodeType getType() + { + return AVMNodeType.LAYERED_FILE; + } + + /** + * Get the content of the specified version. + * @return A FileContent object. + */ + public FileContent getContentForRead(int version) + { + Lookup lookup = getRepository().getSuperRepository().lookup(version, fData.getIndirection()); + AVMNode node = lookup.getCurrentNode(); + if (!(node instanceof FileNode)) + { + throw new AlfrescoRuntimeException("Missing Link."); + } + FileNode file = (FileNode)node; + return file.getContentForRead(version); + } + + /** + * Get File Content for writing. Should never be called. + */ + public FileContent getContentForWrite(Repository repo) + { + assert false : "Never happens"; + return null; + } +} diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java new file mode 100644 index 0000000000..006d082823 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/Lookup.java @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.util.ArrayList; +import java.util.List; + +/** + * This holds all the information necessary to perform operations + * on AVMNodes. + * @author britt + */ +public class Lookup +{ + /** + * The Repository. + */ + @SuppressWarnings("unused") + private Repository fRepository; + + /** + * The name of the Repository. + */ + @SuppressWarnings("unused") + private String fRepName; + + /** + * The components that make up this path. + */ + private List fComponents; + + /** + * Whether, at this point, a layered node has been hit. + * Used while building a Lookup. + */ + private boolean fLayeredYet; + + /** + * The first LayeredDirectoryNode in the path. + */ + private LayeredDirectoryNode fTopLayer; + + /** + * The path index of the top LayeredDirectoryNode in the path. + */ + private int fTopLayerIndex; + + /** + * The highest branch id seen in the lookup. + */ + private long fHighestBranchID; + + /** + * The lowest layered directory node's index seen so far. + */ + private int fLowestLayerIndex; + + /** + * The current component being looked at by this lookup. + */ + private int fPosition; + + /** + * Create a new instance. + */ + public Lookup(Repository repository, String repName) + { + fRepository = repository; + fRepName = repName; + fComponents = new ArrayList(); + fLayeredYet = false; + fTopLayer = null; + fHighestBranchID = 0; + fPosition = -1; + fTopLayerIndex = -1; + fLowestLayerIndex = -1; + } + + /** + * Add a new node to the lookup. + * @param node The node to add. + * @param name The name of the node in the path. + */ + public void add(AVMNode node, String name) + { + LookupComponent comp = new LookupComponent(); + comp.setName(name); + comp.setNode(node); + // Bump up the highest branch id seen if necessary. + if (node.getBranchID() > fHighestBranchID) + { + fHighestBranchID = node.getBranchID(); + } + // Set the highest branch id seen by this component in the lookup. + comp.setHighestBranch(fHighestBranchID); + // Record various things if this is layered. + if (node instanceof LayeredDirectoryNode) + { + LayeredDirectoryNode oNode = (LayeredDirectoryNode)node; + // Record the indirection path that should be used. + if (oNode.hasPrimaryIndirection()) + { + comp.setIndirection(oNode.getUnderlying()); + } + else + { + comp.setIndirection(fComponents.get(fPosition).getIndirection() + "/" + name); + } + fLayeredYet = true; + // Record the first layer seen. + if (fTopLayer == null) + { + fTopLayer = oNode; + fTopLayerIndex = fPosition + 1; + } + fLowestLayerIndex = fPosition + 1; + } + comp.setLowestLayerIndex(fLowestLayerIndex); + comp.setLayered(fLayeredYet); + fComponents.add(comp); + fPosition++; + } + + /** + * Get the current node we're looking at. + * @return The current node. + */ + public AVMNode getCurrentNode() + { + return fComponents.get(fPosition).getNode(); + } + + /** + * Set the current node to one higher in the lookup. + */ + public void upCurrentNode() + { + fPosition--; + } + + /** + * Is the current path layered. + * @return Whether the current position in the path is layered. + */ + public boolean isLayered() + { + assert fPosition >= 0; + return fComponents.get(fPosition).isLayered(); + } + + /** + * Determine if a node is directly in this layer. + * @return Whether this node is directly in this layer. + */ + public boolean isInThisLayer() + { + if (!isLayered()) + { + return false; + } + int pos = fPosition; + // Special case of the top layer. + if (fComponents.get(pos).getNode() == fTopLayer) + { + return true; + } + while (pos > 1) + { + DirectoryNode dir = (DirectoryNode)fComponents.get(pos - 1).getNode(); + if (!dir.directlyContains(fComponents.get(pos).getNode())) + { + return false; + } + if (dir == fTopLayer) + { + return true; + } + pos--; + } + return false; + } + + /** + * Get the highest branch traversed in this lookup at the current position. + * @return The highest branch traversed. + */ + public long getHighestBranch() + { + return fComponents.get(fPosition).getHighestBranch(); + } + + /** + * Get the name of the current component. + * @return The name. + */ + public String getName() + { + return fComponents.get(fPosition).getName(); + } + + /** + * Get the number of nodes. + * @return The number of nodes. + */ + public int size() + { + return fComponents.size(); + } + + /** + * Get the current position within the lookup. + * @return The current position. + */ + public int getPosition() + { + return fPosition; + } + + /** + * Calculate the indirection path at this node. + * @return The indirection path all the way down to the current node. + */ + public String getIndirectionPath() + { + int lowestLayerIndex = fComponents.get(fPosition).getLowestLayerIndex(); + // The path is the underlying path of the lowest layer that is directly contained + // by the top layer that is a primary indirection node. + for (int pos = lowestLayerIndex; pos >= fTopLayerIndex; pos--) + { + AVMNode node = fComponents.get(pos).getNode(); + if (!(node instanceof LayeredDirectoryNode)) + { + continue; + } + LayeredDirectoryNode oNode = + (LayeredDirectoryNode)node; + if (oNode.getLayerID() == fTopLayer.getLayerID()) + { + if (oNode.hasPrimaryIndirection()) + { + StringBuilder builder = new StringBuilder(); + builder.append(oNode.getUnderlying()); + for (int i = pos + 1; i <= fPosition; i++) + { + builder.append("/"); + builder.append(fComponents.get(i).getName()); + } + return builder.toString(); + } + } + } + // TODO This is gross. There has to be a neater way to do this. + assert false : "Not reached."; + return "bogus"; + } + + /** + * Get the computed indirection for the current node. + * @return The indirection. + */ + public String getCurrentIndirection() + { + return fComponents.get(fPosition).getIndirection(); + } + + /** + * Get the topmost Layered directory node. Topmost in the + * path lookup sense. + * @return The topmost layered directory node. + */ + public LayeredDirectoryNode getTopLayer() + { + return fTopLayer; + } +} diff --git a/source/java/org/alfresco/repo/avm/LookupComponent.java b/source/java/org/alfresco/repo/avm/LookupComponent.java new file mode 100644 index 0000000000..8cff08efeb --- /dev/null +++ b/source/java/org/alfresco/repo/avm/LookupComponent.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +/** + * Represents a path component in a lookup. + * @author britt + */ +public class LookupComponent +{ + /** + * The name of this component. + */ + private String fName; + + /** + * The node of this component. + */ + private AVMNode fNode; + + /** + * The highest branch seen by this component. + */ + private long fHighestBranch; + + /** + * The indirection path (if any) for this node. + */ + private String fIndirection; + + /** + * The lowest layer index. + */ + private int fLowestLayerIndex; + + /** + * Whether this node is in a layer. + */ + private boolean fLayered; + + /** + * @return the highestBranch + */ + public long getHighestBranch() + { + return fHighestBranch; + } + + /** + * Create a new empty lookup component. + */ + public LookupComponent() + { + } + + /** + * @param highestBranch the highestBranch to set + */ + public void setHighestBranch(long highestBranch) + { + fHighestBranch = highestBranch; + } + + /** + * @return the indirection + */ + public String getIndirection() + { + return fIndirection; + } + + /** + * @param indirection the indirection to set + */ + public void setIndirection(String indirection) + { + fIndirection = indirection; + } + + /** + * @return the layered + */ + public boolean isLayered() + { + return fLayered; + } + + /** + * @param layered the layered to set + */ + public void setLayered(boolean layered) + { + fLayered = layered; + } + + /** + * @return the lowestLayerIndex + */ + public int getLowestLayerIndex() + { + return fLowestLayerIndex; + } + + /** + * @param lowestLayerIndex the lowestLayerIndex to set + */ + public void setLowestLayerIndex(int lowestLayerIndex) + { + fLowestLayerIndex = lowestLayerIndex; + } + + /** + * @return the name + */ + public String getName() + { + return fName; + } + + /** + * @param name the name to set + */ + public void setName(String name) + { + fName = name; + } + + /** + * @return the node + */ + public AVMNode getNode() + { + return fNode; + } + + /** + * @param node the node to set + */ + public void setNode(AVMNode node) + { + fNode = node; + } +} diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java new file mode 100644 index 0000000000..e0fdc28cc7 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.alfresco.repo.avm.hibernate.DirectoryEntry; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBeanImpl; + +/** + * @author britt + * + */ +public class PlainDirectoryNode extends DirectoryNode +{ + /** + * The Bean data. + */ + private PlainDirectoryNodeBean fData; + + /** + * Make up a new directory with nothing in it. + * @param repo + */ + public PlainDirectoryNode(Repository repo) + { + fData = new PlainDirectoryNodeBeanImpl(repo.getSuperRepository().issueID(), + repo.getLatestVersion(), + 0L, + null, + null, + null, + repo.getDataBean(), + false); + repo.getSuperRepository().getSession().save(fData); + } + + /** + * Make one up from its bean data. + * @param data The bean data. + */ + public PlainDirectoryNode(PlainDirectoryNodeBean data) + { + fData = data; + setDataBean(data); + } + + /** + * Copy like constructor. + * @param other The other directory. + * @param repos The Repository Object that will own us. + */ + public PlainDirectoryNode(PlainDirectoryNode other, + Repository repos) + { + fData = new PlainDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repos.getDataBean(), + false); + setDataBean(fData); + fData.setChildren(new HashMap(((PlainDirectoryNodeBean)other.getDataBean()).getChildren())); + } + + /** + * Add a child to this directory, possibly doing a copy. + * @param name The name of the child. + * @param child The child node. + * @param lPath The lookup path to this directory. + * @return Success or failure. + */ + public boolean addChild(String name, AVMNode child, Lookup lPath) + { + if (fData.getChildren().containsKey(name)) + { + return false; + } + DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath); + toModify.putChild(name, child); + child.setParent(toModify); + child.setRepository(toModify.getRepository()); + return true; + } + + /** + * Does this directory directly contain the given node. + * @param node The node to check. + * @return Whether it was found. + */ + public boolean directlyContains(AVMNode node) + { + return fData.getChildren().containsValue(node.getDataBean()); + } + + + /** + * Get a directory listing. + * @param lPath The lookup path. + * @param version Which version. + * @return The listing. + */ + public Map getListing(Lookup lPath, int version) + { + return new TreeMap(fData.getChildren()); + } + + /** + * Lookup a child by name. + * @param lPath The lookup path so far. + * @param name The name to lookup. + * @param version The version to look under. + * @return The child or null. + */ + public AVMNode lookupChild(Lookup lPath, String name, int version) + { + DirectoryEntry child = fData.getChildren().get(name); + if (child == null) + { + return null; + } + return AVMNodeFactory.CreateFromBean(child.getChild()); + } + + /** + * Remove a child, no copying. + * @param name The name of the child to remove. + */ + public void rawRemoveChild(String name) + { + fData.getChildren().remove(name); + } + + /** + * Remove a child. Possibly copy. + * @param name The name of the child to remove. + * @param lPath The lookup path. + * @return Success or failure. + */ + public boolean removeChild(String name, Lookup lPath) + { + if (!fData.getChildren().containsKey(name)) + { + return false; + } + DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath); + toModify.rawRemoveChild(name); + return true; + } + + /** + * Put a new child node into this directory. No copy. + * @param name The namke of the child. + * @param node The node to add. + */ + public void putChild(String name, AVMNode node) + { + fData.getChildren().put(name, new DirectoryEntry(node.getType(), node.getDataBean())); + } + + /** + * Set repository after copy on write. + * @param parent The parent after copy on write. + */ + public void handlePostCopy(DirectoryNode parent) + { + if (parent != null) + { + setRepository(parent.getRepository()); + } + } + + /** + * Copy on write logic. + * @param lPath The lookup path. + * @return + */ + public AVMNode possiblyCopy(Lookup lPath) + { + if (!shouldBeCopied()) + { + return null; + } + // Otherwise do an actual copy. + DirectoryNode newMe = null; + long newBranchID = lPath.getHighestBranch(); + if (lPath.isLayered()) + { + newMe = new LayeredDirectoryNode(this, getRepository(), lPath); + } + else + { + newMe = new PlainDirectoryNode(this, getRepository()); + } + newMe.setAncestor(this); + newMe.setBranchID(newBranchID); + return newMe; + } + + /** + * Get the type of this node. + * @return The type of this node. + */ + public AVMNodeType getType() + { + return AVMNodeType.PLAIN_DIRECTORY; + } +} diff --git a/source/java/org/alfresco/repo/avm/PlainFileNode.java b/source/java/org/alfresco/repo/avm/PlainFileNode.java new file mode 100644 index 0000000000..a3c83c76d5 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/PlainFileNode.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.repo.avm.hibernate.ContentBean; +import org.alfresco.repo.avm.hibernate.ContentBeanImpl; +import org.alfresco.repo.avm.hibernate.PlainFileNodeBean; +import org.alfresco.repo.avm.hibernate.PlainFileNodeBeanImpl; + +/** + * @author britt + * + */ +public class PlainFileNode extends FileNode +{ + /** + * The data bean. + */ + private PlainFileNodeBean fData; + + /** + * Construct one from its data bean. + * @param data The data bean. + */ + public PlainFileNode(PlainFileNodeBean data) + { + fData = data; + setDataBean(data); + } + + /** + * Make one from just a repository. + * @param repos A Repository. + */ + public PlainFileNode(Repository repos) + { + ContentBean content = new ContentBeanImpl(repos.getSuperRepository().issueContentID()); + fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repos.getDataBean(), + content); + content.setRefCount(1); + // Transitive persistence should take care of content. + repos.getSuperRepository().getSession().save(fData); + setDataBean(fData); + } + + /** + * Copy on write constructor. + * @param other The node we are being copied from. + * @param repos The Repository. + */ + public PlainFileNode(PlainFileNode other, + Repository repos) + { + fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repos.getDataBean(), + other.fData.getContent()); + repos.getSuperRepository().getSession().save(fData); + fData.getContent().setRefCount(fData.getContent().getRefCount() + 1); + setDataBean(fData); + } + + /** + * Handle setting repository after a COW. + * @param parent The possibly new parent directory. + */ + public void handlePostCopy(DirectoryNode parent) + { + if (parent != null) + { + setRepository(parent.getRepository()); + } + } + + /** + * Copy on write logic. + * @param lPath The lookup path. + */ + public AVMNode possiblyCopy(Lookup lPath) + { + if (!shouldBeCopied()) + { + return null; + } + PlainFileNode newMe = new PlainFileNode(this, getRepository()); + newMe.setAncestor(this); + newMe.setBranchID(lPath.getHighestBranch()); + return newMe; + } + + /** + * Get the type of this node. + * @return The type. + */ + public AVMNodeType getType() + { + return AVMNodeType.PLAIN_FILE; + } + + /** + * Get content for reading. + */ + public FileContent getContentForRead(int version) + { + return FileContentFactory.CreateFileContentFromBean(fData.getContent()); + } + + /** + * Get content for writing. + * @param repo The Repository. + */ + public FileContent getContentForWrite(Repository repo) + { + if (fData.getContent().getRefCount() > 1) + { + fData.setContent(new ContentBeanImpl(repo.getSuperRepository().issueContentID())); + // Need to copy the underlying file data. + } + return FileContentFactory.CreateFileContentFromBean(fData.getContent()); + } +} diff --git a/source/java/org/alfresco/repo/avm/Repository.java b/source/java/org/alfresco/repo/avm/Repository.java new file mode 100644 index 0000000000..7dc1ea28b8 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/Repository.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +import org.alfresco.repo.avm.hibernate.RepositoryBean; + + +/** + * This is the interface between low level repository objects + * and the high level implementation of the repository. + * @author britt + */ +public interface Repository +{ + /** + * Inform this Repository that a Node is new and should + * therefore not be copied. + * @param node The node that is reporting itself. + */ + public void setNew(AVMNode node); + + /** + * Get the latest version id. + * @return The latest version. + */ + public long getLatestVersion(); + + /** + * Inform this Repository that the root node is new. + * @param root The new root directory node. + */ + public void setNewRoot(DirectoryNode root); + + /** + * Make a snapshot. Equivalent of subversion end of commit. A new + * version number is issued. + */ + public void createSnapshot(); + + /** + * Create a new directory. + * @param path The path to the directory for creation. + * @param name The name for the new directory. + */ + public void createDirectory(String path, String name); + + /** + * Create a layered directory over srcPath at dstPath/name. + * @param srcPath Fully qualified path. + * @param dstPath Repository path to target directory. + * @param name What the new layered directory should be called. + */ + public void createLayeredDirectory(String srcPath, String dstPath, String name); + + /** + * Create a new empty file. + * @param path The path to the directory for creation. + * @param name The name for the new file. + */ + public void createFile(String path, String name); + + /** + * Create a layered file over srcPath at dstPath/name + * @param srcPath Fully qualified path. + * @param dstPath Repository path. + * @param name The name the new layered file should have. + */ + public void createLayeredFile(String srcPath, String dstPath, String name); + + /** + * Get an input stream from an existing file. + * TODO Figure out nio way of doing things. + * @param version The version id to look under. + * @param path The path to the file. + * @return An InputStream. + */ + public InputStream getInputStream(int version, String path); + + /** + * Get a directory listing. + * @param version The version to look under. + * @param path The path to the directory. + * @return A List of FolderEntries. + */ + public List getListing(int version, String path); + + /** + * Get an OutputStream to an existing file. This may trigger a copy. + * @param path The path to the file. + */ + public OutputStream getOutputStream(String path); + + /** + * Remove a node from a directory. + * @param path The path to the directory. + * @param name The name of the node to remove. + */ + public void removeNode(String path, String name); + + /** + * This moves a node from one place in a layer to another place in + * the same layer without leaving a deleted entry in the source directory. + * @param srcPath The path containing the src node. + * @param srcName The name of the src node. + * @param dstPath The destination container. + * @param dstName The name of the destination node. + */ + public void slide(String srcPath, String srcName, String dstPath, String dstName); + + /** + * Get the version ids that this Repository has. + * @return A Set of Version IDs. + */ + public Set getVersions(); + + /** + * Get the data bean. + * @return The data bean. + */ + public RepositoryBean getDataBean(); + + /** + * Get the super repository. + * @return The SuperRepository. + */ + public SuperRepository getSuperRepository(); + + /** + * Get a lookup object for a path. + * @param version The version to look under. + * @param path The Repository path. + * @return The Lookup. + */ + public Lookup lookup(int version, String path); + + /** + * Get a lookup object for a path. Directory only. + * @param version The version to look under. + * @param path The Repository path. + * @return The Lookup. + */ + public Lookup lookupDirectory(int version, String path); + + /** + * Get the indirection path of a layered node. + * @param version The version id. + * @param path The Repository path. + * @return The indirection. + */ + public String getIndirectionPath(int version, String path); +} diff --git a/source/java/org/alfresco/repo/avm/RepositoryFactory.java b/source/java/org/alfresco/repo/avm/RepositoryFactory.java new file mode 100644 index 0000000000..4aeb7553c0 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/RepositoryFactory.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.repo.avm.hibernate.RepositoryBean; +import org.alfresco.repo.avm.impl.RepositoryImpl; + +/** + * @author britt + * + */ +public class RepositoryFactory +{ + /** + * The single instance of this. So far. + */ + private static RepositoryFactory fgFactory; + + /** + * The super repository. + */ + private SuperRepository fSuper; + + public RepositoryFactory() + { + fSuper = null; + fgFactory = this; + } + + /** + * Create a Repository instance from a bean. + * @param bean The RepositoryBean. + * @return A Repository instance. + */ + public Repository createFromBean(RepositoryBean bean) + { + return new RepositoryImpl(fSuper, bean); + } + + /** + * Set the super repository. + * @param superRepo + */ + public void setSuperRepository(SuperRepository superRepo) + { + fSuper = superRepo; + } + + /** + * Get the single instance. + * @return The instance. + */ + public static RepositoryFactory GetInstance() + { + return fgFactory; + } +} diff --git a/source/java/org/alfresco/repo/avm/SuperRepository.java b/source/java/org/alfresco/repo/avm/SuperRepository.java new file mode 100644 index 0000000000..9027a65543 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/SuperRepository.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +import org.hibernate.Session; + +/** + * A SuperRepository is responsible for the high level implemenation of all + * operations on Repositories. It is responsible for issuing Node ids, branch ids, + * and layer ids. Repositories themselves are responsible for issuing version ids. + * Paths in super repositories are of the form "repositoryname:/a/b/c/d + * @author britt + */ +public interface SuperRepository +{ + // Modify operations. + + /** + * Create a new file. + * @param path The path to create the file in. + * @param name The name to give the new file. + */ + public void createFile(String path, String name); + + /** + * Create a new Directory. + * @param path The path to create the directory in. + * @param name The name to give the new directory. + */ + public void createDirectory(String path, String name); + + /** + * Create a new LayeredDirectory. + * @param srcPath The source path that the LayeredDirectory refers to. + * @param dstPath The path to create the new LayeredDirectory in. + * @param name The name to give the new LayeredDirectory. + */ + public void createLayeredDirectory(String srcPath, String dstPath, String name); + + /** + * Create a new LayeredFile. + * @param srcPath The source path that the LayeredFile refers to. + * @param dstPath The path to create the new LayeredFile in. + * @param name The name to give the new LayeredFile. + */ + public void createLayeredFile(String srcPath, String dstPath, String name); + + /** + * Create a new Repository. + * @param name The name to give the repository. + */ + public void createRepository(String name); + + /** + * Create a branch. + * @param version The version to look under. + * @param srcPath The path to the source node for the branch. + * @param dstPath The directory to put the branch in. + * @param name The name for the new branch. + */ + public void createBranch(int version, String srcPath, String dstPath, String name); + + // Modify operations. + + /** + * Get an OutputStream to a file. + * @param path The path to the file. + * @return An OutputStream. + */ + public OutputStream getOutputStream(String path); + + /** + * Rename a node. + * @param srcPath The source path. + * @param srcName The name of the node to rename. + * @param dstPath The destination directory for the rename. + * @param dstName The name to give the renamed node. + */ + public void rename(String srcPath, String srcName, String dstPath, String dstName); + + /** + * Slide a directory in a layer to another location in the same + * layer uncovering what was originally shadowed. + * @param srcPath The source path. + * @param srcName The name of the directory to slide. + * @param dstPath The destination directory for the slide. + * @param dstName The name of the directory after sliding. + */ + public void slide(String srcPath, String srcName, String dstPath, String dstName); + + /** + * Create a snapshot of the given repositories. + * @param repositories A List of Repository names. + */ + public void createSnapshot(List repositories); + + // Different flavors of deletions. + + /** + * Delete a node. + * @param path The path to the containing directory. + * @param name The name of the node to remove. + */ + public void remove(String path, String name); + + /** + * Purge a repository. + * @param name + */ + public void destroyRepository(String name); + + /** + * Purge a version in a repository. + * @param name The name of the repository. + * @param version The id of the version to purge. + */ + public void purgeVersion(String name, int version); + + // Read operations. + + /** + * Get an InputStream from a File. + * @param version The version to look under. + * @param path The path to the file. + * @return An InputStream. + */ + public InputStream getInputStream(int version, String path); + + /** + * Get the listing for a directory. + * @param version The version to get a listing of. + * @param path The path to the directory. + * @return A List of FolderEntries. + */ + public List getListing(int version, String path); + + /** + * Get a listing of all repository names. + * @return A List of repository names. + */ + public List getRepositoryNames(); + + /** + * Get a Set of version IDs for a given Repository. + * @param name The name of the repository. + * @return A Set of IDs. + */ + public Set getRepositoryVersions(String name); + + /** + * Issue a unique identifier for a new node. + * @return A new identifier. + */ + public long issueID(); + + /** + * Issue an ID for content. + * @return A new content ID. + */ + public long issueContentID(); + + /** + * Get the current Hibernate Session. + * @return The Hibernate Session object. + */ + public Session getSession(); + + /** + * Return an OutputStream for the content object of the given id. This + * creates the directory path if needed. + * @param path The path to the file. + * @return An OutputStream. + */ + public OutputStream createContentOutputStream(String path); + + /** + * Gets an input stream from the content with the given id. + * @param version The version id. + * @param path The path to the file. + * @return An InputStream. + */ + public InputStream getContentInputStream(int version, String path); + + /** + * Get the latest version id for a given repository. + * @param name The name of the repository. + * @return The latest version id for the given repository. + */ + public long getLatestVersionID(String name); + + /** + * Get the indirection path for a layered node. + * @param version The version to look under. + * @param path The path to the node. + * @return The indirection path. + */ + public String getIndirectionPath(int version, String path); + + /** + * Get a lookup object for a path. + * @param version The version to look under. + * @param path The full path. + * @return The Lookup. + */ + public Lookup lookup(int version, String path); + + /** + * Get a lookup object for a path. Directory only. + * @param version The version to look under. + * @param path The full path. + * @return The Lookup. + */ + public Lookup lookupDirectory(int version, String path); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVMNode.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/AVMNode.hbm.xml new file mode 100644 index 0000000000..1a943c71a3 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/AVMNode.hbm.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVMNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/AVMNodeBean.java new file mode 100644 index 0000000000..330080b585 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/AVMNodeBean.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + + +/** + * The base Node class for the new versioning model, at least for now. + * @author britt + */ +public interface AVMNodeBean +{ + /** + * Set the object id of this node. + * @param id The Object ID. + */ + public void setId(long id); + + /** + * Get the object id of this node. + * @return The Object ID of this node. + */ + public long getId(); + + /** + * Set the version id. + * @param id The version id of the node. + */ + public void setVersionID(long id); + + /** + * Get the version id of this node. + * @return The version id. + */ + public long getVersionID(); + + /** + * Set the parent of this node. This is only a canonical parent, + * the one that this node had at the time of its creation. + * @param parent The id of the parent node. + */ + public void setParent(DirectoryNodeBean parent); + + /** + * Get the parent of this node. + * @return The parent of this node. + */ + public DirectoryNodeBean getParent(); + + /** + * Set the node that is this node's direct ancestor. + * @param ancestor The id of the ancestor node. + */ + public void setAncestor(AVMNodeBean ancestor); + + /** + * Get the direct ancestor of this node. + * @return The id of the direct ancestor of this node. + */ + public AVMNodeBean getAncestor(); + + /** + * Set the node that this node was merged from. + * @param mergedFrom The id of the node from which this was merged. + */ + public void setMergedFrom(AVMNodeBean mergedFrom); + + /** + * Get the node that this was merged from. + * @return The id of the node this was merged from. + */ + public AVMNodeBean getMergedFrom(); + + /** + * Set the branch id. + * @param branchID The branch id to set. + */ + public void setBranchID(long branchID); + + /** + * Get the branch id of this node. + * @return The branch id of this node. + */ + public long getBranchID(); + + /** + * Set the Repository that owns this node. + * @param repository The repository that owns this node. + */ + public void setRepository(RepositoryBean repository); + + /** + * Get the Repository that owns this node. + * @return The Repository. + */ + public RepositoryBean getRepository(); + + /** + * Set is new. + * @param isNew + */ + public void setIsNew(boolean isNew); + + /** + * Get is new. + * @return Whether this node is new. + */ + public boolean getIsNew(); + + /** + * Set the version (for concurrency management.) + * @param vers The version. + */ + public void setVers(long vers); + + /** + * Get the version (for concurrency management.) + * @return The version. + */ + public long getVers(); +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVMNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/AVMNodeBeanImpl.java new file mode 100644 index 0000000000..82445f3db4 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/AVMNodeBeanImpl.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + + +/** + * Base interface for versioned and layered node implementation data objects. + * @author britt + */ +public class AVMNodeBeanImpl implements AVMNodeBean +{ + /** + * The Object ID (and Primary Key) + */ + private long fID; + + /** + * The Version ID + */ + private long fVersionID; + + /** + * The Branch ID + */ + private long fBranchID; + + /** + * The ancestor of this. + */ + private AVMNodeBean fAncestor; + + /** + * The node that was merged into this. + */ + private AVMNodeBean fMergedFrom; + + /** + * The id of the parent of this. + */ + private DirectoryNodeBean fParent; + + /** + * The Repository that owns this. + */ + private RepositoryBean fRepository; + + /** + * Whether this node is new (and should therefore not be COWed). + */ + private boolean fIsNew; + + /** + * The version number (for concurrency control). + */ + private long fVers; + + /** + * Anonymous constructor. + */ + public AVMNodeBeanImpl() + { + } + + /** + * Rich constructor. + * @param id The ID to set. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent. + * @param repository The repository. + */ + public AVMNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository) + { + fID = id; + fVersionID = versionID; + fBranchID = branchID; + fAncestor = ancestor; + fMergedFrom = mergedFrom; + fParent = parent; + fRepository = repository; + fIsNew = true; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (!(obj instanceof AVMNodeBean)) + { + return false; + } + return fID == ((AVMNodeBean)obj).getId(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + return (int)fID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#setId(int) + */ + public void setId(long id) + { + fID = id; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#getId() + */ + public long getId() + { + return fID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#setVersionID(int) + */ + public void setVersionID(long id) + { + fVersionID = id; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#getVersionID() + */ + public long getVersionID() + { + return fVersionID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#setParent(int) + */ + public void setParent(DirectoryNodeBean parent) + { + fParent = parent; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#getParent() + */ + public DirectoryNodeBean getParent() + { + return fParent; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#setAncestor(int) + */ + public void setAncestor(AVMNodeBean ancestor) + { + fAncestor = ancestor; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#getAncestor() + */ + public AVMNodeBean getAncestor() + { + return fAncestor; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#setMergedFrom(int) + */ + public void setMergedFrom(AVMNodeBean mergedFrom) + { + fMergedFrom = mergedFrom; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#getMergedFrom() + */ + public AVMNodeBean getMergedFrom() + { + return fMergedFrom; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#setBranchID(int) + */ + public void setBranchID(long branchID) + { + fBranchID = branchID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNode#getBranchID() + */ + public long getBranchID() + { + return fBranchID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNodeBean#getRepository() + */ + public RepositoryBean getRepository() + { + return fRepository; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.AVMNodeBean#setRepository(org.alfresco.proto.avm.RepositoryBean) + */ + public void setRepository(RepositoryBean repository) + { + fRepository = repository; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.AVMNodeBean#getIsNew() + */ + public boolean getIsNew() + { + return fIsNew; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.AVMNodeBean#setIsNew(boolean) + */ + public void setIsNew(boolean isNew) + { + fIsNew = isNew; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.AVMNodeBean#getVers() + */ + public long getVers() + { + return fVers; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.AVMNodeBean#setVers(java.lang.int) + */ + public void setVers(long vers) + { + fVers = vers; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/Content.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/Content.hbm.xml new file mode 100644 index 0000000000..9e0b69f80b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/Content.hbm.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/avm/hibernate/ContentBean.java b/source/java/org/alfresco/repo/avm/hibernate/ContentBean.java new file mode 100644 index 0000000000..551fa2a274 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/ContentBean.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +/** + * This exists to share content across different versions. + * @author britt + */ +public interface ContentBean +{ + /** + * Set the object id. + * @param id The object id. + */ + public void setId(long id); + + /** + * Get the object id. + * @return The object id. + */ + public long getId(); + + /** + * Set the reference count on this. + * @param refCount The reference count to set. + */ + public void setRefCount(int refCount); + + /** + * Get the reference count on this. + * @return The reference count. + */ + public int getRefCount(); + + /** + * Set the version (for concurrency control). + * @param vers The version. + */ + public void setVers(long vers); + + /** + * Get the version (for concurrency control). + * @return The version. + */ + public long getVers(); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java new file mode 100644 index 0000000000..426109fe2f --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + + +/** + * @author britt + * + */ +public class ContentBeanImpl implements ContentBean +{ + /** + * The object id. + */ + private long fID; + + /** + * The reference count of this id. + */ + private int fRefCount; + + /** + * The version (for concurrency control). + */ + private long fVers; + + /** + * Basic constructor with an id. + */ + public ContentBeanImpl(long id) + { + fID = id; + fRefCount = 0; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Content#setId(int) + */ + public void setId(long id) + { + fID = id; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Content#getID() + */ + public long getId() + { + return fID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Content#setRefCount(int) + */ + public void setRefCount(int refCount) + { + fRefCount = refCount; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Content#getRefCount() + */ + public int getRefCount() + { + return fRefCount; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (!(obj instanceof ContentBean)) + { + return false; + } + return fID == ((ContentBean)obj).getId(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + return (int)fID; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.ContentBean#getVers() + */ + public long getVers() + { + return fVers; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.ContentBean#setVers(java.lang.int) + */ + public void setVers(long vers) + { + fVers = vers; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java b/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java new file mode 100644 index 0000000000..a3365a559b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +import org.alfresco.repo.avm.AVMNodeType; + +/** + * This holds Directory Entries in directories. + * @author britt + */ +public class DirectoryEntry +{ + /** + * The type of entry a node is. + */ + private AVMNodeType fType; + + /** + * This is the actual child Node. + */ + private AVMNodeBean fChild; + + /** + * Anonymous constructor. + */ + public DirectoryEntry() + { + } + + /** + * Make one from scratch. + * @param type The type. + * @param child The child node. + */ + public DirectoryEntry(AVMNodeType type, AVMNodeBean child) + { + fType = type; + fChild = child; + } + + /** + * Set the entry type. + * @param type The type to set. + */ + public void setEntryType(AVMNodeType type) + { + fType = type; + } + + /** + * Get the entry type. + * @return The type. + */ + public AVMNodeType getEntryType() + { + return fType; + } + + /** + * Set the child. + * @param child The child to set. + */ + public void setChild(AVMNodeBean child) + { + fChild = child; + } + + /** + * Get the child. + * @return The child. + */ + public AVMNodeBean getChild() + { + return fChild; + } + + /** + * Set the type by name. + * @param name The name of the type. + */ + public void setType(String name) + { + fType = Enum.valueOf(AVMNodeType.class, name); + } + + /** + * Get the type name. + */ + public String getType() + { + return fType.name(); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBean.java new file mode 100644 index 0000000000..09402cb6e4 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBean.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + + +public interface DirectoryNodeBean extends AVMNodeBean +{ +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBeanImpl.java new file mode 100644 index 0000000000..129e971c8e --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/DirectoryNodeBeanImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + + +/** + * Base for all for all directory data types. + * @author britt + */ +public class DirectoryNodeBeanImpl extends AVMNodeBeanImpl implements DirectoryNodeBean +{ + /** + * Anonymous constructor. + */ + public DirectoryNodeBeanImpl() + { + super(); + } + + /** + * Rich constructor. + * @param id The id to assign it. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent. + */ + public DirectoryNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository) + { + super(id, versionID, branchID, ancestor, mergedFrom, parent, repository); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/FileNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/FileNodeBean.java new file mode 100644 index 0000000000..076203a7c2 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/FileNodeBean.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + + +/** + * Doesn't do much. + * @author britt + */ +public interface FileNodeBean extends AVMNodeBean +{ +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/FileNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/FileNodeBeanImpl.java new file mode 100644 index 0000000000..cf32eb2457 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/FileNodeBeanImpl.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + + +/** + * Doesn't do much. + * @author britt + */ +public class FileNodeBeanImpl extends AVMNodeBeanImpl implements FileNodeBean +{ + /** + * Anonymous constructor. + */ + public FileNodeBeanImpl() + { + super(); + } + + /** + * Rich constructor. + * @param id The ID to set. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent. + */ + public FileNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository) + { + super(id, versionID, branchID, ancestor, mergedFrom, parent, repository); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateHelper.java b/source/java/org/alfresco/repo/avm/hibernate/HibernateHelper.java new file mode 100644 index 0000000000..654b544e6b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/HibernateHelper.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; + +/** + * @author britt + */ +public class HibernateHelper +{ + private static Configuration fgCfg = null; + private static SessionFactory fgFactory = null; + + static + { + try + { + fgCfg = new Configuration(); + fgCfg.configure(); + fgFactory = fgCfg.buildSessionFactory(); + } + catch (Throwable t) + { + t.printStackTrace(System.err); + System.exit(1); + } + } + + public static SessionFactory GetSessionFactory() + { + return fgFactory; + } + + public static Configuration GetConfiguration() + { + return fgCfg; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java b/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java new file mode 100644 index 0000000000..a52507e3c1 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java @@ -0,0 +1,93 @@ +package org.alfresco.repo.avm.hibernate; + +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +/** + * Helper for DAOs. + * @author britt + */ +public class HibernateTxn +{ + /** + * The SessionFactory. + */ + private SessionFactory fSessionFactory; + + /** + * Make one up. + * @param sessionFactory The SessionFactory. + */ + public HibernateTxn(SessionFactory sessionFactory) + { + fSessionFactory = sessionFactory; + } + + /** + * Perform a set of operations under a single Hibernate transaction. + * @param callback The worker. + * @return Whether the operation finished with a commit. + */ + public boolean perform(HibernateTxnCallback callback) + { + Session sess = null; + Transaction txn = null; + try + { + sess = fSessionFactory.openSession(); + txn = sess.beginTransaction(); + callback.perform(sess); + txn.commit(); + return true; + } + catch (Throwable t) + { + t.printStackTrace(System.err); + if (txn != null) + { + try + { + txn.rollback(); + } + catch (HibernateException he) + { + // Do nothing. + } + } + return false; + } + finally + { + if (sess != null) + { + try + { + sess.close(); + } + catch (HibernateException he) + { + // Do nothing. + } + } + } + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java b/source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java new file mode 100644 index 0000000000..8c6c978188 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +import org.hibernate.Session; + +/** + * Worker object for Hibernate Transactions. + * @author britt + */ +public interface HibernateTxnCallback +{ + /** + * Do our work. + * @param sess The Hibernate session. + */ + public void perform(Session sess); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/Issuer.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/Issuer.hbm.xml new file mode 100644 index 0000000000..4d7728a978 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/Issuer.hbm.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/avm/hibernate/Issuer.java b/source/java/org/alfresco/repo/avm/hibernate/Issuer.java new file mode 100644 index 0000000000..206ffdbcfe --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/Issuer.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +/** + * This is a helper class that knows how to issue identifiers. + * @author britt + */ +public class Issuer +{ + /** + * The name of this issuer. Used as the primary key in it's + * mapping. + */ + private String fName; + + /** + * The next number to issue. + */ + private long fNext; + + /** + * The version (for concurrency control). + */ + private long fVers; + + /** + * Anonymous constructor. + */ + public Issuer() + { + } + + /** + * Rich constructor. + * @param name The name of this issuer. + * @param next The next number to issue. + */ + public Issuer(String name, long next) + { + fName = name; + fNext = next; + } + + // Bean methods. + + /** + * Set the name of this issuer. + * @param name The name to set. + */ + public void setName(String name) + { + fName = name; + } + + /** + * Get the name of this issuer. + * @return The name of this issuer. + */ + public String getName() + { + return fName; + } + + /** + * Set the next number. + * @param next The next number. + */ + public void setNext(long next) + { + fNext = next; + } + + /** + * Get the next number. + * @return The next number. + */ + public long getNext() + { + return fNext; + } + + /** + * Issue the next number. + * @return A serial number. + */ + public long issue() + { + return fNext++; + } + + /** + * @return the vers + */ + public long getVers() + { + return fVers; + } + + /** + * @param vers the vers to set + */ + public void setVers(long vers) + { + fVers = vers; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBean.java new file mode 100644 index 0000000000..1a1c1f5512 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBean.java @@ -0,0 +1,68 @@ +package org.alfresco.repo.avm.hibernate; + +import java.util.Map; +import java.util.Set; + + +public interface LayeredDirectoryNodeBean extends DirectoryNodeBean +{ + /** + * Set the layer id. + * @param id The id to set. + */ + public void setLayerID(long id); + + /** + * Get the layer id. + * @return The layer id. + */ + public long getLayerID(); + + /** + * Set the indirection. + * @param indirection The indirection to set. + */ + public void setIndirection(String indirection); + + /** + * Get the indirection. + * @return The indirection. + */ + public String getIndirection(); + + /** + * Set the added map. + * @param added The added children. + */ + public void setAdded(Map added); + + /** + * Get the added map. + * @return The map of added children. + */ + public Map getAdded(); + + /** + * Set the Set of deleted names. + * @param deleted The deleted names. + */ + public void setDeleted(Set deleted); + + /** + * Get the Set of deleted names. + * @return The Set of deleted names. + */ + public Set getDeleted(); + + /** + * Set the primary indirection-ness of this. + * @param primary Whether this is a primary indirection node. + */ + public void setPrimaryIndirection(boolean primary); + + /** + * Get the primary indirection-ness of this. + * @return Whether this is a primary indirection node. + */ + public boolean getPrimaryIndirection(); +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBeanImpl.java new file mode 100644 index 0000000000..2f20297b60 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/LayeredDirectoryNodeBeanImpl.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + + +/** + * Layered directories are semitransparent links to other directories. + * They maintain a delta of what has been changed relative to what they + * link to. + * @author britt + */ +public class LayeredDirectoryNodeBeanImpl extends DirectoryNodeBeanImpl implements LayeredDirectoryNodeBean +{ + /** + * The Layer ID. + */ + private long fLayerID; + + /** + * The link to the underlying directory. + */ + private String fIndirection; + + /** + * The Map of nodes added in this layer. + */ + private Map fAdded; + + /** + * The Set of names that have been deleted. + */ + private Set fDeleted; + + /** + * Whether this is a primary indirection node. + */ + private boolean fPrimaryIndirection; + + /** + * Anonymous constructor. + */ + public LayeredDirectoryNodeBeanImpl() + { + super(); + } + + /** + * Rich constructor. + * @param id The id to assign. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent node. + * @param layerID The layer id of this node. + * @param indirection The indirection pointer of this. + */ + public LayeredDirectoryNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository, + long layerID, + String indirection) + { + super(id, versionID, branchID, ancestor, mergedFrom, parent, repository); + fLayerID = layerID; + fIndirection = indirection; + fAdded = new HashMap(); + fDeleted = new HashSet(); + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#setLayerID(int) + */ + public void setLayerID(long id) + { + fLayerID = id; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#getLayerID() + */ + public long getLayerID() + { + return fLayerID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#setIndirection(java.lang.String) + */ + public void setIndirection(String indirection) + { + fIndirection = indirection; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#getIndirection() + */ + public String getIndirection() + { + return fIndirection; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#setAdded(java.util.Map) + */ + public void setAdded(Map added) + { + fAdded = added; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#getAdded() + */ + public Map getAdded() + { + return fAdded; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#setDeleted(java.util.Set) + */ + public void setDeleted(Set deleted) + { + fDeleted = deleted; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.LayeredDirectoryNode#getDeleted() + */ + public Set getDeleted() + { + return fDeleted; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBean#getPrimaryIndirection() + */ + public boolean getPrimaryIndirection() + { + return fPrimaryIndirection; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.LayeredDirectoryNodeBean#setPrimaryIndirection(boolean) + */ + public void setPrimaryIndirection(boolean primary) + { + fPrimaryIndirection = primary; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBean.java new file mode 100644 index 0000000000..f6789016b5 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBean.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +/** + * Very much like a copy on write symlink. + * @author britt + */ +public interface LayeredFileNodeBean extends FileNodeBean +{ + /** + * Set the indirection for this node. + * @param indirection The indirection to set. + */ + public void setIndirection(String indirection); + + /** + * Get the indirection for this node. + * @return The indirection. + */ + public String getIndirection(); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBeanImpl.java new file mode 100644 index 0000000000..a033e69eb9 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/LayeredFileNodeBeanImpl.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + + +/** + * @author britt + */ +public class LayeredFileNodeBeanImpl extends FileNodeBeanImpl implements + LayeredFileNodeBean +{ + /** + * The indirection. + */ + private String fIndirection; + + /** + * Anonymous constructor. + */ + public LayeredFileNodeBeanImpl() + { + super(); + } + + /** + * Rich constructor. + * @param id The ID to set. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent. + * @param indirection The indirection pointer. + */ + public LayeredFileNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository, + String indirection) + { + super(id, versionID, branchID, ancestor, mergedFrom, parent, repository); + fIndirection = indirection; + } + + /** + * @see org.alfresco.repo.avm.hibernate.LayeredFileNodeBean#setIndirection(java.lang.String) + */ + public void setIndirection(String indirection) + { + fIndirection = indirection; + } + + /** + * @see org.alfresco.repo.avm.hibernate.LayeredFileNodeBean#getIndirection() + */ + public String getIndirection() + { + return fIndirection; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBean.java new file mode 100644 index 0000000000..2369a7d7f6 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBean.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + +import java.util.Map; + + +public interface PlainDirectoryNodeBean extends DirectoryNodeBean +{ + /** + * Set the child map. + * @param children The Map to set. + */ + public void setChildren(Map children); + + /** + * Get the child map. + * @return The map of child names to IDs. + */ + public Map getChildren(); + + /** + * Set whether this node is a root directory. + * @param isRoot + */ + public void setIsRoot(boolean isRoot); + + /** + * Get whether this node is a root directory. + * @return Whether it is. + */ + public boolean getIsRoot(); +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBeanImpl.java new file mode 100644 index 0000000000..aa302146be --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/PlainDirectoryNodeBeanImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + +import java.util.HashMap; +import java.util.Map; + + +/** + * A plain directory node is just a map of names to AVMNodes. + * @author britt + */ +public class PlainDirectoryNodeBeanImpl extends DirectoryNodeBeanImpl implements PlainDirectoryNodeBean +{ + /** + * The child map. + */ + private Map fChildren; + + /** + * Whether this is a root node. + */ + private boolean fIsRoot; + + /** + * Anonymous constructor. + */ + public PlainDirectoryNodeBeanImpl() + { + super(); + } + + /** + * Rich constructor. + * @param id The id to assign it. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent. + * @param isRoot Whether this is a root node. + */ + public PlainDirectoryNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository, + boolean isRoot) + { + super(id, versionID, branchID, ancestor, mergedFrom, parent, repository); + fChildren = new HashMap(); + fIsRoot = isRoot; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.PlainDirectoryNode#setChildren(java.util.Map) + */ + public void setChildren(Map children) + { + fChildren = children; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.PlainDirectoryNode#getChildren() + */ + public Map getChildren() + { + return fChildren; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean#getIsRoot() + */ + public boolean getIsRoot() + { + return fIsRoot; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean#setIsRoot(boolean) + */ + public void setIsRoot(boolean isRoot) + { + fIsRoot = isRoot; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBean.java b/source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBean.java new file mode 100644 index 0000000000..05e13ec90e --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBean.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + + +/** + * A Plain File Node. Contains a possibly shared Content object. + * @author britt + */ +public interface PlainFileNodeBean extends FileNodeBean +{ + /** + * Set the Content object for this. + */ + public void setContent(ContentBean content); + + /** + * Get the Content object for this. + * @return The Content object. + */ + public ContentBean getContent(); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBeanImpl.java new file mode 100644 index 0000000000..2837cbbffb --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/PlainFileNodeBeanImpl.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + + +/** + * @author britt + * + */ +public class PlainFileNodeBeanImpl extends FileNodeBeanImpl implements PlainFileNodeBean +{ + /** + * The Content object. + */ + private ContentBean fContent; + + /** + * Anonymous constructor. + */ + public PlainFileNodeBeanImpl() + { + super(); + } + + /** + * Rich constructor. + * @param id The ID to set. + * @param versionID The version id. + * @param branchID The branch id. + * @param ancestor The ancestor. + * @param mergedFrom The node that merged into us. + * @param parent The parent. + * @param content The content object. + */ + public PlainFileNodeBeanImpl(long id, + long versionID, + long branchID, + AVMNodeBean ancestor, + AVMNodeBean mergedFrom, + DirectoryNodeBean parent, + RepositoryBean repository, + ContentBean content) + { + super(id, versionID, branchID, ancestor, mergedFrom, parent, repository); + fContent = content; + } + + /** + * @see org.alfresco.repo.avm.hibernate.PlainFileNodeBean#setContent(org.alfresco.repo.avm.hibernate.ContentBean) + */ + public void setContent(ContentBean content) + { + fContent = content; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.PlainFileNode#getContent() + */ + public ContentBean getContent() + { + return fContent; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/Repository.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/Repository.hbm.xml new file mode 100644 index 0000000000..f7477d2fda --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/Repository.hbm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/avm/hibernate/RepositoryBean.java b/source/java/org/alfresco/repo/avm/hibernate/RepositoryBean.java new file mode 100644 index 0000000000..e6dd0445ad --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/RepositoryBean.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +import java.util.Map; +import java.util.Set; + +/** + * This is responsible for keeping track of the root + * directories for different versions. + * @author britt + */ +public interface RepositoryBean +{ + /** + * Set the name of this Repository. + * @param name The name of the respository. + */ + public void setName(String name); + + /** + * Get the name of this Repository. + * @return The name. + */ + public String getName(); + + /** + * Set the current root. + * @param root The root to set. + */ + public void setRoot(DirectoryNodeBean root); + + /** + * Get the current root. + * @return The current root. + */ + public DirectoryNodeBean getRoot(); + + /** + * Set the roots map. + * @param roots The Map of version ids to roots. + */ + public void setRoots(Map roots); + + /** + * Get the roots map. + * @return The roots map. + */ + public Map getRoots(); + + /** + * Set the next version id. + * @param nextVersionID The value to set. + */ + public void setNextVersionID(long nextVersionID); + + /** + * Get the next version id. + * @return The next version id. + */ + public long getNextVersionID(); + + /** + * Set the new nodes. + * @param newNodes The new nodes Set to set. + */ + public void setNewNodes(Set newNodes); + + /** + * Get the new nodes. + * @return The new nodes associated with this Repository. + */ + public Set getNewNodes(); + + /** + * Set the version (for concurrency control). + * @param vers The version to set. + */ + public void setVers(long vers); + + /** + * Get the version (for concurrency control). + * @return The version. + */ + public long getVers(); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/RepositoryBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/RepositoryBeanImpl.java new file mode 100644 index 0000000000..df19d37549 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/RepositoryBeanImpl.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.hibernate; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * @author britt + * + */ +public class RepositoryBeanImpl implements RepositoryBean +{ + /** + * The name of this repository. + */ + private String fName; + + /** + * The current root directory. + */ + private DirectoryNodeBean fRoot; + + /** + * The root directories for all versions. + */ + private Map fRoots; + + /** + * The next version id. + */ + private long fNextVersionID; + + /** + * The nodes that are new since the last end operation. + */ + private Set fNewNodes; + + /** + * The version (for concurrency control). + */ + private long fVers; + + /** + * Anonymous constructor. + */ + public RepositoryBeanImpl() + { + } + + /** + * Rich constructor + * @param name The name of the Repository. + * @param root The current root node. + */ + public RepositoryBeanImpl(String name, + DirectoryNodeBean root) + { + fName = name; + fNextVersionID = 0; + fRoot = root; + fRoots = new HashMap(); + fNewNodes = new HashSet(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RepositoryBean#getName() + */ + public String getName() + { + return fName; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RepositoryBean#setName(java.lang.String) + */ + public void setName(String name) + { + fName = name; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Repository#setRoot(org.alfresco.proto.avm.DirectoryNode) + */ + public void setRoot(DirectoryNodeBean root) + { + fRoot = root; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Repository#getRoot() + */ + public DirectoryNodeBean getRoot() + { + return fRoot; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Repository#setRoots(java.util.Map) + */ + public void setRoots(Map roots) + { + fRoots = roots; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Repository#getRoots() + */ + public Map getRoots() + { + return fRoots; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Repository#setNextVersionID(int) + */ + public void setNextVersionID(long nextVersionID) + { + fNextVersionID = nextVersionID; + } + + /* (non-Javadoc) + * @see org.alfresco.proto.avm.Repository#getNextVersionID() + */ + public long getNextVersionID() + { + return fNextVersionID; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (!(obj instanceof RepositoryBean)) + { + return false; + } + return fName.equals(((RepositoryBean)obj).getName()); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + return fName.hashCode(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RepositoryBean#getNewNodes() + */ + public Set getNewNodes() + { + return fNewNodes; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RepositoryBean#setNewNodes(java.util.Set) + */ + public void setNewNodes(Set newNodes) + { + fNewNodes = newNodes; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RepositoryBean#getVers() + */ + public long getVers() + { + return fVers; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RepositoryBean#setVers(java.lang.int) + */ + public void setVers(long vers) + { + fVers = vers; + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/TestPopulate.java b/source/java/org/alfresco/repo/avm/hibernate/TestPopulate.java new file mode 100644 index 0000000000..0d5a1d20fb --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/TestPopulate.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.avm.hibernate; + +import org.alfresco.repo.avm.AVMNodeType; +import org.alfresco.repo.avm.hibernate.ContentBean; +import org.alfresco.repo.avm.hibernate.ContentBeanImpl; +import org.alfresco.repo.avm.hibernate.HibernateHelper; +import org.alfresco.repo.avm.hibernate.HibernateTxn; +import org.alfresco.repo.avm.hibernate.HibernateTxnCallback; +import org.alfresco.repo.avm.hibernate.Issuer; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBeanImpl; +import org.alfresco.repo.avm.hibernate.PlainFileNodeBean; +import org.alfresco.repo.avm.hibernate.PlainFileNodeBeanImpl; +import org.alfresco.repo.avm.hibernate.RepositoryBean; +import org.alfresco.repo.avm.hibernate.RepositoryBeanImpl; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; +import org.hibernate.tool.hbm2ddl.SchemaExport; + +import junit.framework.TestCase; + +public class TestPopulate extends TestCase +{ + /** + * The SessionFactory. + */ + private SessionFactory fSessionFactory; + + public TestPopulate(String name) + { + super(name); + } + + protected void setUp() throws Exception + { + fSessionFactory = HibernateHelper.GetSessionFactory(); + Configuration cfg = HibernateHelper.GetConfiguration(); + SchemaExport se = new SchemaExport(cfg); + se.drop(false, true); + se.create(false, true); + } + + protected void tearDown() throws Exception + { + } + + /** + * Add some data to persistent store. + */ + public void testPopulate() + { + try + { + HibernateTxn hTxn = new HibernateTxn(fSessionFactory); + boolean result = hTxn.perform( + new HibernateTxnCallback() + { + public void perform(Session session) + { + // Set up issuers. + Issuer nodeIssuer = new Issuer("node", 0); + Issuer contentIssuer = new Issuer("content", 0); + Issuer repositoryIssuer = new Issuer("repository", 0); + // Make the initial root directory. + PlainDirectoryNodeBean root = + new PlainDirectoryNodeBeanImpl(nodeIssuer.issue(), + 0, + 0, + null, + null, + null, + null, + true); + // Make a new repository. + RepositoryBean rep = + new RepositoryBeanImpl("main", root); + root.setRepository(rep); + session.save(rep); + rep.getRoots().put(rep.getNextVersionID(), root); + rep.setNextVersionID(rep.getNextVersionID() + 1); + session.save(nodeIssuer); + session.save(contentIssuer); + session.save(repositoryIssuer); + root.setIsNew(false); + } + }); + assertTrue(result); + System.out.println("--------------------------------------------"); + result = hTxn.perform( + new HibernateTxnCallback() + { + public void perform(Session session) + { + // Now read some things back, and modify some stuff. + Issuer nodeIssuer = (Issuer)session.get(Issuer.class, "node"); + Issuer contentIssuer = (Issuer)session.get(Issuer.class, "content"); + RepositoryBean rep = (RepositoryBean)session.get(RepositoryBeanImpl.class, 0L); + long version = rep.getNextVersionID(); + rep.setNextVersionID(version + 1); + assertTrue(rep != null); + PlainDirectoryNodeBean root = (PlainDirectoryNodeBean)rep.getRoot(); + PlainDirectoryNodeBean newRoot = new PlainDirectoryNodeBeanImpl(nodeIssuer.issue(), + version, + 0L, + root, + null, + null, + rep, + true); + ContentBean content = new ContentBeanImpl(contentIssuer.issue()); + PlainFileNodeBean file = new PlainFileNodeBeanImpl(nodeIssuer.issue(), + version, + 0L, + null, + null, + newRoot, + rep, + content); + content.setRefCount(content.getRefCount() + 1); + newRoot.getChildren().put("foo", new DirectoryEntry(AVMNodeType.PLAIN_FILE, file)); + session.save(content); + session.save(newRoot); + content = new ContentBeanImpl(contentIssuer.issue()); + content.setRefCount(content.getRefCount() + 1); + file.setIsNew(false); + file = new PlainFileNodeBeanImpl(nodeIssuer.issue(), + version, + 0L, + null, + null, + newRoot, + rep, + content); + session.save(content); + file.setIsNew(false); + newRoot.getChildren().put("bar", new DirectoryEntry(AVMNodeType.PLAIN_FILE, file)); + rep.setRoot(newRoot); + rep.getRoots().put(version, newRoot); + newRoot.setIsNew(false); + } + }); + assertTrue(result); + System.out.println("-----------------------------------------------"); + result = hTxn.perform( + new HibernateTxnCallback() + { + public void perform(Session session) + { + Query query = session.createQuery("from RepositoryBeanImpl r where r.name = :name"); + query.setString("name", "main"); + RepositoryBean rep = (RepositoryBean)query.uniqueResult(); + PlainDirectoryNodeBean root = (PlainDirectoryNodeBean)rep.getRoot(); + assertEquals(2, root.getChildren().size()); + for (String name : root.getChildren().keySet()) + { + System.out.println(name); + } + for (DirectoryEntry entry : root.getChildren().values()) + { + assertEquals(AVMNodeType.PLAIN_FILE, entry.getEntryType()); + } + } + }); + assertTrue(result); + System.out.println("----------------------------------------------"); + // Just check cascading deletes for the children of a directory. + result = hTxn.perform( + new HibernateTxnCallback() + { + public void perform(Session session) + { + RepositoryBean rep = (RepositoryBean)session.get(RepositoryBeanImpl.class, 0L); + PlainDirectoryNodeBean root = (PlainDirectoryNodeBean)rep.getRoot(); + PlainDirectoryNodeBean prev = (PlainDirectoryNodeBean)root.getAncestor(); + rep.setRoot(prev); + rep.getRoots().remove(1); + for (String name : root.getChildren().keySet()) + { + AVMNodeBean child = root.getChildren().get(name).getChild(); + child.setParent(null); + } + session.delete(root); + } + }); + assertTrue(result); + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } +} diff --git a/source/java/org/alfresco/repo/avm/impl/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/impl/AVMServiceImpl.java new file mode 100644 index 0000000000..eae37355ea --- /dev/null +++ b/source/java/org/alfresco/repo/avm/impl/AVMServiceImpl.java @@ -0,0 +1,421 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.impl; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.AVMService; +import org.alfresco.repo.avm.FolderEntry; +import org.alfresco.repo.avm.Lookup; +import org.alfresco.repo.avm.SuperRepository; +import org.alfresco.repo.avm.hibernate.HibernateHelper; +import org.alfresco.repo.avm.hibernate.HibernateTxn; +import org.alfresco.repo.avm.hibernate.HibernateTxnCallback; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +/** + * Implements the AVMService. Stub. + * @author britt + */ +public class AVMServiceImpl implements AVMService +{ + /** + * The Hibernate SessionFactory. + */ + private SessionFactory fSessionFactory; + + /** + * The HibernateTxn. + */ + private HibernateTxn fTransaction; + + /** + * The SuperRepository for each service thread. + */ + private ThreadLocal fSuperRepository; + + /** + * Basic constructor for the service. + */ + public AVMServiceImpl() + { + fSessionFactory = HibernateHelper.GetSessionFactory(); + fTransaction = new HibernateTxn(fSessionFactory); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#getFileInputStream(int, java.lang.String) + */ + public InputStream getFileInputStream(final int version, final String path) + { + class HTxnCallback implements HibernateTxnCallback + { + public InputStream in = null; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + in = fSuperRepository.get().getInputStream(version, path); + } + }; + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.in; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#getFileOutputStream(java.lang.String) + */ + public OutputStream getFileOutputStream(final String path) + { + class HTxnCallback implements HibernateTxnCallback + { + public OutputStream out = null; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + out = fSuperRepository.get().getOutputStream(path); + } + }; + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.out; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#getFolderListing(int, java.lang.String) + */ + public List getDirectoryListing(final int version, final String path) + { + class HTxnCallback implements HibernateTxnCallback + { + public List listing; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + listing = fSuperRepository.get().getListing(version, path); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.listing; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createFile(java.lang.String, java.lang.String) + */ + public void createFile(final String path, final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createFile(path, name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createFolder(java.lang.String, java.lang.String) + */ + public void createDirectory(final String path, final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createDirectory(path, name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createLayeredFile(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredFile(final String srcPath, final String parent, final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createLayeredFile(srcPath, parent, name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createLayeredFolder(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredDirectory(final String srcPath, final String parent, final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createLayeredDirectory(srcPath, parent, name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createRepository(java.lang.String) + */ + public void createRepository(final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createRepository(name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createBranch(int, java.lang.String, java.lang.String, java.lang.String) + */ + public void createBranch(final int version, final String srcPath, final String dstPath, + final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createBranch(version, srcPath, dstPath, name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#removeNode(java.lang.String, java.lang.String) + */ + public void removeNode(final String parent, final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().remove(parent, name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#rename(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void rename(final String srcParent, final String srcName, final String dstParent, + final String dstName) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().rename(srcParent, srcName, dstParent, dstName); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#slide(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void slide(final String srcParent, final String srcName, final String dstParent, + final String dstName) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().slide(srcParent, srcName, dstParent, dstName); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#getLatestVersionID(java.lang.String) + */ + public long getLatestVersionID(final String repName) + { + class HTxnCallback implements HibernateTxnCallback + { + public long latestVersionID; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + latestVersionID = fSuperRepository.get().getLatestVersionID(repName); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.latestVersionID; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#createSnapshot(java.util.List) + */ + public void createSnapshot(final List repositories) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().createSnapshot(repositories); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#lookup(int, java.lang.String) + */ + public AVMNode lookup(final int version, final String path) + { + class HTxnCallback implements HibernateTxnCallback + { + public Lookup lookup; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + lookup = fSuperRepository.get().lookup(version, path); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.lookup.getCurrentNode(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#destroyRepository(java.lang.String) + */ + public void destroyRepository(final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().destroyRepository(name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#purgeVersion(int, java.lang.String) + */ + public void purgeVersion(final int version, final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + fSuperRepository.get().purgeVersion(name, version); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#getIndirectionPath(java.lang.String) + */ + public String getIndirectionPath(final int version, final String path) + { + class HTxnCallback implements HibernateTxnCallback + { + public String indirectionPath; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + indirectionPath = fSuperRepository.get().getIndirectionPath(version, path); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.indirectionPath; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#getRepositoryVersions(java.lang.String) + */ + public Set getRepositoryVersions(final String name) + { + class HTxnCallback implements HibernateTxnCallback + { + public Set versions; + + public void perform(Session session) + { + fSuperRepository.set(new SuperRepositoryImpl(session)); + versions = fSuperRepository.get().getRepositoryVersions(name); + } + } + HTxnCallback doit = new HTxnCallback(); + fTransaction.perform(doit); + return doit.versions; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.AVMService#retargetLayeredFolder(java.lang.String, java.lang.String) + */ + public void retargetLayeredFolder(String path, String target) + { + // TODO Auto-generated method stub + + } +} diff --git a/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java b/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java new file mode 100644 index 0000000000..bab700cc66 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.impl; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.DirectoryNode; +import org.alfresco.repo.avm.FolderEntry; +import org.alfresco.repo.avm.LayeredDirectoryNode; +import org.alfresco.repo.avm.Lookup; +import org.alfresco.repo.avm.PlainDirectoryNode; +import org.alfresco.repo.avm.Repository; +import org.alfresco.repo.avm.SuperRepository; +import org.alfresco.repo.avm.hibernate.AVMNodeBean; +import org.alfresco.repo.avm.hibernate.DirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean; +import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBeanImpl; +import org.alfresco.repo.avm.hibernate.RepositoryBean; +import org.alfresco.repo.avm.hibernate.RepositoryBeanImpl; + +/** + * @author britt + * + */ +public class RepositoryImpl implements Repository +{ + /** + * The data bean. + */ + private RepositoryBean fData; + + /** + * The super repository. + */ + private SuperRepository fSuper; + + /** + * Make a brand new repository. + * @param superRepo The SuperRepository. + * @param name The name of the Repository. + */ + public RepositoryImpl(SuperRepository superRepo, String name) + { + fSuper = superRepo; + fData = new RepositoryBeanImpl(name, null); + fSuper.getSession().save(fData); + PlainDirectoryNodeBean rootBean = + new PlainDirectoryNodeBeanImpl(fSuper.issueID(), + fData.getNextVersionID(), + 0L, + null, + null, + null, + fData, + true // is root + ); + fSuper.getSession().save(rootBean); + fData.setRoot(rootBean); + fData.getRoots().put(fData.getNextVersionID(), rootBean); + fData.setNextVersionID(fData.getNextVersionID() + 1); + } + + /** + * Make one from a data bean. + * @param data The data. + */ + public RepositoryImpl(SuperRepository superRepo, RepositoryBean data) + { + fData = data; + fSuper = superRepo; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#setNew(org.alfresco.repo.avm.AVMNode) + */ + public void setNew(AVMNode node) + { + fData.getNewNodes().add(node.getDataBean()); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getLatestVersion() + */ + public long getLatestVersion() + { + return fData.getNextVersionID(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#setNewRoot(org.alfresco.repo.avm.DirectoryNode) + */ + public void setNewRoot(DirectoryNode root) + { + fData.setRoot((DirectoryNodeBean)root.getDataBean()); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#createSnapshot() + */ + public void createSnapshot() + { + // Walk through the new nodes and mark them not new. + for (AVMNodeBean newBean : fData.getNewNodes()) + { + newBean.setIsNew(false); + } + // Clear out the new nodes. + fData.getNewNodes().clear(); + // Add the current root to the root history. + fData.getRoots().put(fData.getNextVersionID(), fData.getRoot()); + // Increment the version id. + fData.setNextVersionID(fData.getNextVersionID() + 1); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#createDirectory(java.lang.String, java.lang.String) + */ + public void createDirectory(String path, String name) + { + Lookup lPath = lookupDirectory(-1, path); + DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); + if (dir.lookupChild(lPath, name, -1) != null) + { + throw new AlfrescoRuntimeException("Child exists: " + name); + } + DirectoryNode newDir = null; + if (lPath.isLayered()) // Creating a directory in a layered context creates + // a LayeredDirectoryNode that gets its indirection from + // its parent. + { + newDir = new LayeredDirectoryNode((String)null, this); + ((LayeredDirectoryNode)newDir).setPrimaryIndirection(false); + } + else + { + newDir = new PlainDirectoryNode(this); + } + // TODO Untangle when you are going to set a new version id. + newDir.setVersion(fData.getNextVersionID()); + this.setNew(newDir); + dir.addChild(name, newDir, lPath); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#createLayeredDirectory(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredDirectory(String srcPath, String dstPath, + String name) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#createFile(java.lang.String, java.lang.String) + */ + public void createFile(String path, String name) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#createLayeredFile(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredFile(String srcPath, String dstPath, String name) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getInputStream(int, java.lang.String) + */ + public InputStream getInputStream(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getListing(int, java.lang.String) + */ + public List getListing(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getOutputStream(java.lang.String) + */ + public OutputStream getOutputStream(String path) + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#removeNode(java.lang.String, java.lang.String) + */ + public void removeNode(String path, String name) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#slide(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void slide(String srcPath, String srcName, String dstPath, + String dstName) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getVersions() + */ + public Set getVersions() + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getDataBean() + */ + public RepositoryBean getDataBean() + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getSuperRepository() + */ + public SuperRepository getSuperRepository() + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#lookup(int, java.lang.String) + */ + public Lookup lookup(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#lookupDirectory(int, java.lang.String) + */ + public Lookup lookupDirectory(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.Repository#getIndirectionPath(int, java.lang.String) + */ + public String getIndirectionPath(int version, String path) + { + // TODO Auto-generated method stub + return null; + } +} diff --git a/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java b/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java new file mode 100644 index 0000000000..b9b502ec28 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java @@ -0,0 +1,501 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm.impl; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.DirectoryNode; +import org.alfresco.repo.avm.FileNode; +import org.alfresco.repo.avm.FolderEntry; +import org.alfresco.repo.avm.LayeredDirectoryNode; +import org.alfresco.repo.avm.LayeredFileNode; +import org.alfresco.repo.avm.Lookup; +import org.alfresco.repo.avm.PlainDirectoryNode; +import org.alfresco.repo.avm.PlainFileNode; +import org.alfresco.repo.avm.Repository; +import org.alfresco.repo.avm.SuperRepository; +import org.alfresco.repo.avm.hibernate.Issuer; +import org.alfresco.repo.avm.hibernate.RepositoryBean; +import org.hibernate.Query; +import org.hibernate.Session; + +/** + * Implementation of a SuperRepository. This is a per thread + * class. + * @author britt + */ +public class SuperRepositoryImpl implements SuperRepository +{ + /** + * The Hibernate Session associated with the current operation. + */ + private Session fSession; + + /** + * The node id issuer. + */ + private Issuer fNodeIssuer; + + /** + * The content id issuer; + */ + private Issuer fContentIssuer; + + /** + * The branch id issuer. + */ + private Issuer fBranchIssuer; + + /** + * The layer id issuer. + */ + private Issuer fLayerIssuer; + + /** + * Make a new one, initialized with the session. + * @param session The session for this operation. + */ + public SuperRepositoryImpl(Session session) + { + fSession = session; + fNodeIssuer = (Issuer)fSession.get(Issuer.class, "node"); + fContentIssuer = (Issuer)fSession.get(Issuer.class, "content"); + fBranchIssuer = (Issuer)fSession.get(Issuer.class, "branch"); + fLayerIssuer = (Issuer)fSession.get(Issuer.class, "layer"); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createFile(java.lang.String, java.lang.String) + */ + public void createFile(String path, String name) + { + String[] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + rep.createFile(pathParts[1], name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createDirectory(java.lang.String, java.lang.String) + */ + public void createDirectory(String path, String name) + { + String[] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + rep.createDirectory(pathParts[1], name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createLayeredDirectory(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredDirectory(String srcPath, String dstPath, + String name) + { + String[] pathParts = SplitPath(dstPath); + Repository rep = getRepositoryByName(pathParts[0]); + rep.createLayeredDirectory(srcPath, pathParts[1], name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createLayerdFile(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredFile(String srcPath, String dstPath, String name) + { + String[] pathParts = SplitPath(dstPath); + Repository rep = getRepositoryByName(pathParts[0]); + rep.createLayeredFile(srcPath, pathParts[1], name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createRepository(java.lang.String) + */ + public void createRepository(String name) + { + // Newing up the object causes it to be written to the db. + @SuppressWarnings("unused") + Repository rep = new RepositoryImpl(this, name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createBranch(int, java.lang.String, java.lang.String, java.lang.String) + */ + public void createBranch(int version, String srcPath, String dstPath, String name) + { + // Lookup the src node. + String [] pathParts = SplitPath(srcPath); + Repository srcRepo = getRepositoryByName(pathParts[0]); + Lookup sPath = srcRepo.lookup(version, pathParts[1]); + // Lookup the destination direcctory. + pathParts = SplitPath(dstPath); + Repository dstRepo = getRepositoryByName(pathParts[0]); + Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1]); + DirectoryNode dirNode = (DirectoryNode)dPath.getCurrentNode(); + AVMNode srcNode = sPath.getCurrentNode(); + AVMNode dstNode = null; + if (srcNode instanceof PlainDirectoryNode) + { + dstNode = new PlainDirectoryNode((PlainDirectoryNode)srcNode, dstRepo); + } + else if (srcNode instanceof LayeredDirectoryNode) + { + dstNode = + new LayeredDirectoryNode((LayeredDirectoryNode)srcNode, dstRepo); + } + else if (srcNode instanceof LayeredFileNode) + { + dstNode = new LayeredFileNode((LayeredFileNode)srcNode, dstRepo); + } + else // This is a plain file. + { + dstNode = new PlainFileNode((PlainFileNode)srcNode, dstRepo); + } + dstNode.setVersion(dstRepo.getLatestVersion() + 1); + dstRepo.setNew(dstNode); + dstNode.setAncestor(srcNode); + dstNode.setBranchID(fBranchIssuer.issue()); + dirNode.addChild(name, dstNode, dPath); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getOutputStream(java.lang.String) + */ + public OutputStream getOutputStream(String path) + { + String [] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + return rep.getOutputStream(pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#rename(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void rename(String srcPath, String srcName, String dstPath, + String dstName) + { + String [] pathParts = SplitPath(srcPath); + Repository srcRepo = getRepositoryByName(pathParts[0]); + Lookup sPath = srcRepo.lookupDirectory(-1, pathParts[1]); + DirectoryNode srcDir = (DirectoryNode)sPath.getCurrentNode(); + AVMNode srcNode = srcDir.lookupChild(sPath, srcName, -1); + if (srcNode == null) + { + throw new AlfrescoRuntimeException("Not found: " + srcName); + } + pathParts = SplitPath(dstPath); + Repository dstRepo = getRepositoryByName(pathParts[0]); + Lookup dPath = dstRepo.lookupDirectory(-1, dstPath); + DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode(); + AVMNode dstNode = dstDir.lookupChild(dPath, dstName, -1); + if (dstNode != null) + { + throw new AlfrescoRuntimeException("Node exists: " + dstName); + } + // We've passed the check, so we can go ahead and do the rename. + if (srcNode instanceof PlainDirectoryNode) + { + // If the source is layered then the renamed thing needs to be layered also. + if (sPath.isLayered()) + { + // If this is a rename happening in the same layer we make a new + // OverlayedDirectoryNode that is not a primary indirection layer. + // Otherwise we do make the new OverlayedDirectoryNode a primary + // Indirection layer. This complexity begs the question of whether + // we should allow renames from within one layer to within another + // layer. Allowing it makes the logic absurdly complex. + if (dPath.isLayered() && dPath.getTopLayer() == sPath.getTopLayer()) + { + dstNode = new LayeredDirectoryNode((PlainDirectoryNode)srcNode, dstRepo, sPath); + } + else + { + dstNode = new LayeredDirectoryNode((DirectoryNode)srcNode, dstRepo, sPath, srcName); + } + } + else + { + dstNode = new PlainDirectoryNode((PlainDirectoryNode)srcNode, dstRepo); + } + } + else if (srcNode instanceof LayeredDirectoryNode) + { + if (!sPath.isLayered() || (sPath.isInThisLayer() && + srcDir instanceof LayeredDirectoryNode && + ((LayeredDirectoryNode)srcDir).directlyContains(srcNode))) + { + // Use the simple 'copy' constructor. + dstNode = + new LayeredDirectoryNode((LayeredDirectoryNode)srcNode, dstRepo); + ((LayeredDirectoryNode)dstNode).setLayerID(((LayeredDirectoryNode)srcNode).getLayerID()); + } + else + { + // The thing we are renaming does not belong to sPath's layer and therefore + // we need to compute the indirection path for this layer after the rename. + dstNode = + new LayeredDirectoryNode((DirectoryNode)srcNode, dstRepo, sPath, srcName); + ((LayeredDirectoryNode)dstNode).setLayerID(fLayerIssuer.issue()); + } + } + else if (srcNode instanceof LayeredFileNode) + { + if (!sPath.isLayered() || (sPath.isInThisLayer() && + srcDir instanceof LayeredDirectoryNode && + ((LayeredDirectoryNode)srcDir).directlyContains(srcNode))) + { + // Use the simple 'copy' constructor. + dstNode = + new LayeredFileNode((LayeredFileNode)srcNode, dstRepo); + } + else + { + // Calculate the indirection path, because srcNode was not in this layer. + dstNode = + new LayeredFileNode((FileNode)srcNode, dstRepo, sPath, srcName); + } + } + else // This is a plain file node. + { + dstNode = new PlainFileNode((PlainFileNode)srcNode, dstRepo); + } + dstNode.setVersion(dstRepo.getLatestVersion() + 1); + dstRepo.setNew(dstNode); + dstDir.addChild(dstName, dstNode, dPath); + dstNode.setAncestor(srcNode); + pathParts = SplitPath(srcPath); + sPath = srcRepo.lookup(-1, pathParts[1]); + srcDir = (DirectoryNode)sPath.getCurrentNode(); + srcDir.removeChild(srcName, sPath); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#slide(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void slide(String srcPath, String srcName, String dstPath, + String dstName) + { + String[] srcPathParts = SplitPath(srcPath); + String[] dstPathParts = SplitPath(dstPath); + if (!srcPathParts[0].equals(dstPathParts[0])) + { + throw new AlfrescoRuntimeException("Argument must be in same Repository: " + srcPathParts[0] + "!=" + + dstPathParts[0]); + } + Repository repo = getRepositoryByName(srcPathParts[0]); + repo.slide(srcPathParts[1], srcName, dstPathParts[1], dstName); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createSnapshot(java.util.List) + */ + public void createSnapshot(List repositories) + { + for (String repName : repositories) + { + Repository repo = getRepositoryByName(repName); + repo.createSnapshot(); + } + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#remove(java.lang.String, java.lang.String) + */ + public void remove(String path, String name) + { + String [] pathParts = SplitPath(path); + Repository repo = getRepositoryByName(pathParts[0]); + repo.removeNode(pathParts[1], name); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#purgeRepository(java.lang.String) + */ + public void purgeRepository(String name) + { + // TODO Leave until later. Need to set up GC thread to handle this. + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#purgeVersion(java.lang.String, int) + */ + public void purgeVersion(String name, int version) + { + // TODO Leave until later. Need to set up GC thread to handle this. + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getInputStream(java.lang.String) + */ + public InputStream getInputStream(int version, String path) + { + String [] pathParts = SplitPath(path); + Repository repo = getRepositoryByName(pathParts[0]); + return repo.getInputStream(version, pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getListing(java.lang.String) + */ + public List getListing(int version, String path) + { + String [] pathParts = SplitPath(path); + Repository repo = getRepositoryByName(pathParts[0]); + return repo.getListing(version, pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getRepositoryNames() + */ + @SuppressWarnings("unchecked") + public List getRepositoryNames() + { + Query query = fSession.createQuery("select r.name from RepositoryBeanImpl r"); + return (List)query.list(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getRepositoryVersions(java.lang.String) + */ + public Set getRepositoryVersions(String name) + { + Repository rep = getRepositoryByName(name); + return rep.getVersions(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#issueID() + */ + public long issueID() + { + return fNodeIssuer.issue(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#issueContentID() + */ + public long issueContentID() + { + return fContentIssuer.issue(); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getSession() + */ + public Session getSession() + { + return fSession; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#createContentOutputStream(int) + */ + public OutputStream createContentOutputStream(String path) + { + String [] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + return rep.getOutputStream(pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getContentInputStream(int) + */ + public InputStream getContentInputStream(int version, String path) + { + String[] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + return rep.getInputStream(version, pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#destroyRepository(java.lang.String) + */ + public void destroyRepository(String name) + { + // TODO Auto-generated method stub + // Leave this until we have GC in place. + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getIndirectionPath(int, java.lang.String) + */ + public String getIndirectionPath(int version, String path) + { + String [] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + return rep.getIndirectionPath(version, pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#getLatestVersionID(java.lang.String) + */ + public long getLatestVersionID(String name) + { + Repository rep = getRepositoryByName(name); + return rep.getLatestVersion(); + } + + /** + * Get a repository by name. + * @param name The name of the repository. + * @return The Repository. + */ + private Repository getRepositoryByName(String name) + { + Query query = fSession.createQuery("from repositories r where r.name = :name"); + query.setString("name", name); + return new RepositoryImpl(this, (RepositoryBean)query.uniqueResult()); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#lookup(int, java.lang.String) + */ + public Lookup lookup(int version, String path) + { + String [] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + return rep.lookup(version, pathParts[1]); + } + + /* (non-Javadoc) + * @see org.alfresco.repo.avm.SuperRepository#lookupDirectory(int, java.lang.String) + */ + public Lookup lookupDirectory(int version, String path) + { + String[] pathParts = SplitPath(path); + Repository rep = getRepositoryByName(pathParts[0]); + return rep.lookupDirectory(version, pathParts[1]); + } + + /** + * Utility to split a path, foo:/bar/baz into its repository and path parts. + * @param path The fully qualified path. + * @return The repository name and the repository path. + */ + private String[] SplitPath(String path) + { + String [] pathParts = path.split(":"); + if (pathParts.length != 2) + { + throw new AlfrescoRuntimeException("Invalid path: " + path); + } + return pathParts; + } +}