diff --git a/config/alfresco/avm-console-context.xml b/config/alfresco/avm-console-context.xml index 0a43242607..4626c441ec 100644 --- a/config/alfresco/avm-console-context.xml +++ b/config/alfresco/avm-console-context.xml @@ -68,7 +68,7 @@ 60 - + @@ -92,6 +92,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -104,7 +188,7 @@ - + @@ -130,8 +214,8 @@ 50 - - + + @@ -149,8 +233,8 @@ ${avm.initialize} - - + + diff --git a/config/alfresco/avm-test-context.xml b/config/alfresco/avm-test-context.xml index c002253f84..37a4c21b9b 100644 --- a/config/alfresco/avm-test-context.xml +++ b/config/alfresco/avm-test-context.xml @@ -63,6 +63,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -130,8 +214,8 @@ 50 - - + + @@ -143,8 +227,8 @@ ${avm.initialize} - - + + - \ No newline at end of file + diff --git a/source/java/org/alfresco/repo/avm/AVMContext.java b/source/java/org/alfresco/repo/avm/AVMContext.java new file mode 100644 index 0000000000..e00e66ceb2 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMContext.java @@ -0,0 +1,139 @@ +/** + * + */ +package org.alfresco.repo.avm; + +/** + * This is the (shudder) global context for AVM. It a rendezvous + * point for access to needed global instances. + * @author britt + */ +public class AVMContext +{ + /** + * The single instance of an AVMContext. + */ + public static AVMContext fgInstance; + + public AVMContext() + { + fgInstance = this; + } + + /** + * The IssuerDAO. + */ + public IssuerDAO fIssuerDAO; + + /** + * The AVMNodeDAO. + */ + public AVMNodeDAO fAVMNodeDAO; + + /** + * The Repository DAO. + */ + public RepositoryDAO fRepositoryDAO; + + /** + * The VersionRootDAO. + */ + public VersionRootDAO fVersionRootDAO; + + /** + * The FileContentDAO. + */ + public FileContentDAO fFileContentDAO; + + /** + * The ChildEntryDAO. + */ + public ChildEntryDAO fChildEntryDAO; + + /** + * The HistoryLinkDAO. + */ + public HistoryLinkDAO fHistoryLinkDAO; + + /** + * The MergeLinkDAO. + */ + public MergeLinkDAO fMergeLinkDAO; + + /** + * The DeletedChildDAO. + */ + public DeletedChildDAO fDeletedChildDAO; + + /** + * @param nodeDAO the fAVMNodeDAO to set + */ + public void setNodeDAO(AVMNodeDAO nodeDAO) + { + fAVMNodeDAO = nodeDAO; + } + + /** + * @param childEntryDAO the fChildEntryDAO to set + */ + public void setChildEntryDAO(ChildEntryDAO childEntryDAO) + { + fChildEntryDAO = childEntryDAO; + } + + /** + * @param deletedChildDAO the fDeletedChildDAO to set + */ + public void setDeletedChildDAO(DeletedChildDAO deletedChildDAO) + { + fDeletedChildDAO = deletedChildDAO; + } + + /** + * @param fileContentDAO the fFileContentDAO to set + */ + public void setFileContentDAO(FileContentDAO fileContentDAO) + { + fFileContentDAO = fileContentDAO; + } + + /** + * @param historyLinkDAO the fHistoryLinkDAO to set + */ + public void setHistoryLinkDAO(HistoryLinkDAO historyLinkDAO) + { + fHistoryLinkDAO = historyLinkDAO; + } + + /** + * @param mergeLinkDAO the fMergeLinkDAO to set + */ + public void setMergeLinkDAO(MergeLinkDAO mergeLinkDAO) + { + fMergeLinkDAO = mergeLinkDAO; + } + + /** + * @param repositoryDAO the fRepositoryDAO to set + */ + public void setRepositoryDAO(RepositoryDAO repositoryDAO) + { + fRepositoryDAO = repositoryDAO; + } + + /** + * @param versionRootDAO the fVersionRootDAO to set + */ + public void setVersionRootDAO(VersionRootDAO versionRootDAO) + { + fVersionRootDAO = versionRootDAO; + } + + /** + * @param issuerDAO the fIssuerDAO to set + */ + public void setIssuerDAO(IssuerDAO issuerDAO) + { + fIssuerDAO = issuerDAO; + } +} diff --git a/source/java/org/alfresco/repo/avm/AVMCrawlTest.java b/source/java/org/alfresco/repo/avm/AVMCrawlTest.java index 9a7ef0525b..1d3916b56e 100644 --- a/source/java/org/alfresco/repo/avm/AVMCrawlTest.java +++ b/source/java/org/alfresco/repo/avm/AVMCrawlTest.java @@ -35,8 +35,8 @@ public class AVMCrawlTest extends AVMServiceTestBase */ public void testCrawl() { - int n = 8; // Number of Threads. - int m = 16; // How many multiples of content to start with. + int n = 2; // Number of Threads. + int m = 4; // How many multiples of content to start with. long runTime = 1200000; // Ten minutes fService.purgeRepository("main"); fReaper.setInactiveBaseSleep(60000); diff --git a/source/java/org/alfresco/repo/avm/AVMNode.java b/source/java/org/alfresco/repo/avm/AVMNode.java index 1844745996..630038ea53 100644 --- a/source/java/org/alfresco/repo/avm/AVMNode.java +++ b/source/java/org/alfresco/repo/avm/AVMNode.java @@ -20,7 +20,7 @@ package org.alfresco.repo.avm; * The Interface for versionable objects. * @author britt */ -interface AVMNode +public interface AVMNode { /** * Set the ancestor of this node. diff --git a/source/java/org/alfresco/repo/avm/AVMNodeDAO.java b/source/java/org/alfresco/repo/avm/AVMNodeDAO.java new file mode 100644 index 0000000000..b84338c9d1 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMNodeDAO.java @@ -0,0 +1,105 @@ +/* + * 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.Iterator; +import java.util.List; + +/** + * DAO for AVMNodes interface. + * @author britt + */ +public interface AVMNodeDAO +{ + /** + * Save the given node, having never been saved before. + */ + public void save(AVMNode node); + + /** + * Make all the nodes owned by a repository no longer + * point to that repository. + * @param rep The Repository. + */ + public void dereferenceNodesInRepository(Repository rep); + + /** + * Delete a single node. + * @param node The node to delete. + */ + public void delete(AVMNode node); + + /** + * Get by ID. + * @param id The id to get. + */ + public AVMNode getByID(long id); + + /** + * Get the root of a particular version. + * @param rep The repository we're querying. + * @param version The version. + * @return The VersionRoot or null. + */ + public DirectoryNode getRepositoryRoot(Repository rep, int version); + + /** + * Get those nodes which are new in the given repository. + * @param repo The repository. + * @return A List of AVMNodes. + */ + public List getNewInRepo(Repository repo); + + /** + * Update a node that has been dirtied. + * @param node The node. + */ + public void update(AVMNode node); + + /** + * Get the ancestor of a node. + * @param node The node whose ancestor is desired. + * @return The ancestor or null. + */ + public AVMNode getAncestor(AVMNode node); + + /** + * Get the node the given node was merged from. + * @param node The node whose merged from is desired. + * @return The merged from node or null. + */ + public AVMNode getMergedFrom(AVMNode node); + + /** + * Get up to batchSize orphans. + * @param batchSize Get no more than this number. + * @return A List of orphaned AVMNodes. + */ + public List getOrphans(int batchSize); + + /** + * Get all nodes that have the given repository as their owning repository. + * @param rep The Repository. + * @return An Iterator over the matching nodes. + */ + public Iterator getByRepository(Repository rep); + + /** + * Inappropriate hack to get Hibernate to play nice. + */ + public void flush(); +} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java index 60ca61180b..630f141fe7 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java @@ -26,7 +26,7 @@ import org.hibernate.Session; * Base class for all repository file system like objects. * @author britt */ -abstract class AVMNodeImpl implements AVMNode, Serializable +public abstract class AVMNodeImpl implements AVMNode, Serializable { /** * The Object ID. @@ -105,7 +105,7 @@ abstract class AVMNodeImpl implements AVMNode, Serializable HistoryLinkImpl link = new HistoryLinkImpl(); link.setAncestor(ancestor); link.setDescendent(this); - SuperRepository.GetInstance().getSession().save(link); + AVMContext.fgInstance.fHistoryLinkDAO.save(link); } /** @@ -114,10 +114,7 @@ abstract class AVMNodeImpl implements AVMNode, Serializable */ public AVMNode getAncestor() { - Session sess = SuperRepository.GetInstance().getSession(); - Query query = sess.createQuery("select hl.ancestor from HistoryLinkImpl hl where hl.descendent = :desc"); - query.setEntity("desc", this); - return (AVMNode)query.uniqueResult(); + return AVMContext.fgInstance.fAVMNodeDAO.getAncestor(this); } /** @@ -133,7 +130,7 @@ abstract class AVMNodeImpl implements AVMNode, Serializable MergeLinkImpl link = new MergeLinkImpl(); link.setMfrom(mergedFrom); link.setMto(this); - SuperRepository.GetInstance().getSession().save(link); + AVMContext.fgInstance.fMergeLinkDAO.save(link); } /** @@ -142,10 +139,7 @@ abstract class AVMNodeImpl implements AVMNode, Serializable */ public AVMNode getMergedFrom() { - Session sess = SuperRepository.GetInstance().getSession(); - Query query = sess.createQuery("select ml.mfrom from MergeLinkImpl ml where ml.mto = :to"); - query.setEntity("to", this); - return (AVMNode)query.uniqueResult(); + return AVMContext.fgInstance.fAVMNodeDAO.getMergedFrom(this); } /** diff --git a/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java b/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java index 1d68a18149..37841097e9 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java @@ -26,7 +26,7 @@ import org.hibernate.proxy.HibernateProxy; * The CGLIB villains dither unintelligibly. * @author britt */ -class AVMNodeUnwrapper +public class AVMNodeUnwrapper { public static AVMNode Unwrap(AVMNode node) { diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index 624ae0f9d0..e979265e5a 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -28,10 +28,6 @@ import java.util.List; import java.util.SortedMap; import org.alfresco.repo.avm.SuperRepository; -import org.alfresco.repo.avm.hibernate.HibernateTxn; -import org.alfresco.repo.avm.hibernate.HibernateTxnCallback; -import org.hibernate.Query; -import org.hibernate.Session; /** * Implements the AVMService. Stub. @@ -40,9 +36,9 @@ import org.hibernate.Session; public class AVMServiceImpl implements AVMService { /** - * The HibernateTxn. + * The RetryingTransaction. */ - private HibernateTxn fTransaction; + private RetryingTransaction fTransaction; /** * The SuperRepository for each service thread. @@ -90,18 +86,16 @@ public class AVMServiceImpl implements AVMService try { fTransaction.perform( - new HibernateTxnCallback() + new RetryingTransactionCallback() { - public void perform(Session sess) + public void perform() { - Query query = sess.createQuery("select max(an.id) from AVMNodeImpl an"); - Long val = (Long)query.uniqueResult(); + IssuerDAO dao = AVMContext.fgInstance.fIssuerDAO; + Long val = dao.getNodeIssuerValue(); fNodeIssuer = new Issuer(val == null ? 0L : val + 1L); - query = sess.createQuery("select max(fc.id) from FileContentImpl fc"); - val = (Long)query.uniqueResult(); + val = dao.getContentIssuerValue(); fContentIssuer = new Issuer(val == null ? 0L : val + 1L); - query = sess.createQuery("select max(an.layerID) from AVMNodeImpl an"); - val = (Long)query.uniqueResult(); + val = dao.getLayerIssuerValue(); fLayerIssuer = new Issuer(val == null ? 0L : val + 1L); } }, false); @@ -122,10 +116,10 @@ public class AVMServiceImpl implements AVMService } /** - * Set the Hibernate Transaction wrapper. + * Set the Retrying Transaction wrapper. * @param txn */ - public void setHibernateTxn(HibernateTxn txn) + public void setRetryingTransaction(RetryingTransaction txn) { fTransaction = txn; } @@ -161,17 +155,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null path."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public InputStream in = null; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); in = fSuperRepository.getInputStream(version, path); } }; - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.in; } @@ -187,23 +180,22 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public InputStream in = null; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); in = fSuperRepository.getInputStream(desc); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.in; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#getFileOutputStream(java.lang.String) + /** + * Get an output stream to a file. Triggers versioning. */ public OutputStream getFileOutputStream(final String path) { @@ -211,17 +203,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null path."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public OutputStream out = null; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); out = fSuperRepository.getOutputStream(path); } }; - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); return doit.out; } @@ -239,23 +230,25 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public RandomAccessFile file; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); file = fSuperRepository.getRandomAccess(version, path, access); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); return doit.file; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#getFolderListing(int, java.lang.String) + + /** + * Get a directory listing. + * @param version The version id to lookup. + * @param path The path to lookup. */ public SortedMap getDirectoryListing(final int version, final String path) { @@ -263,17 +256,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null path."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public SortedMap listing; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); listing = fSuperRepository.getListing(version, path); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.listing; } @@ -289,23 +281,25 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null descriptor."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public SortedMap listing; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); listing = fSuperRepository.getListing(dir); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.listing; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createFile(java.lang.String, java.lang.String) + /** + * Create a new file. The file must not exist. + * @param path The path to the containing directory. + * @param name The name of the file. + * @return An output stream to the file. */ public OutputStream createFile(final String path, final String name) { @@ -313,17 +307,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public OutputStream out; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); out = fSuperRepository.createFile(path, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); return doit.out; } @@ -361,15 +354,14 @@ public class AVMServiceImpl implements AVMService { throw new AVMException("I/O Error."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.createFile(path, name, temp); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); try { fTransaction.perform(doit, true); @@ -380,8 +372,10 @@ public class AVMServiceImpl implements AVMService } } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createFolder(java.lang.String, java.lang.String) + /** + * Create a directory. The directory must not exist. + * @param path The path to the containing directory. + * @param name The name of the new directory. */ public void createDirectory(final String path, final String name) { @@ -389,20 +383,22 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.createDirectory(path, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createLayeredFile(java.lang.String, java.lang.String, java.lang.String) + /** + * Create a new layered file. It must not exist. + * @param srcPath The src path. Ie the target for the layering. + * @param parent The path to the parent directory. + * @param name The name to give the new file. */ public void createLayeredFile(final String srcPath, final String parent, final String name) { @@ -410,20 +406,22 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.createLayeredFile(srcPath, parent, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createLayeredFolder(java.lang.String, java.lang.String, java.lang.String) + /** + * Create a new layered directory. It must not exist. + * @param srcPath The src path. Ie the target for layering. + * @param parent The path to the parent directory. + * @param name The name for the new directory. */ public void createLayeredDirectory(final String srcPath, final String parent, final String name) { @@ -431,20 +429,20 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.createLayeredDirectory(srcPath, parent, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createRepository(java.lang.String) + /** + * Create a repository with the given name. It must not exist. + * @param name The name to give the repository. */ public void createRepository(final String name) { @@ -452,20 +450,23 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Name is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.createRepository(name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createBranch(int, java.lang.String, java.lang.String, java.lang.String) + /** + * Create a branch. + * @param version The version to branch from. + * @param srcPath The path to the thing to branch from. + * @param dstPath The path to the destination containing directory. + * @param name The name of the new branch. */ public void createBranch(final int version, final String srcPath, final String dstPath, final String name) @@ -474,20 +475,22 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.createBranch(version, srcPath, dstPath, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#removeNode(java.lang.String, java.lang.String) + /** + * Remove a node. Beware, the node can be a directory and + * this acts recursively. + * @param parent The path to the parent. + * @param name The name of the node to remove. */ public void removeNode(final String parent, final String name) { @@ -495,20 +498,23 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.remove(parent, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#rename(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + /** + * Rename a node. + * @param srcParent The path to the source parent. + * @param srcName The name of the source node. + * @param dstParent The path to the destination parent. + * @param dstName The name to give the renamed node. */ public void rename(final String srcParent, final String srcName, final String dstParent, final String dstName) @@ -517,15 +523,14 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.rename(srcParent, srcName, dstParent, dstName); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } @@ -540,20 +545,21 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.uncover(dirPath, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#getLatestVersionID(java.lang.String) + /** + * Get the Latest Version ID for a repository. + * @param repName The name of the repository. + * @return The Latest Version ID. */ public int getLatestVersionID(final String repName) { @@ -561,23 +567,24 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public int latestVersionID; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); latestVersionID = fSuperRepository.getLatestVersionID(repName); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.latestVersionID; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createSnapshot(java.util.List) + /** + * Create snapshots of a group of repositories. + * @param repositories A List of repository name. + * @return A List of the new version ids. */ public List createSnapshot(final List repositories) { @@ -585,23 +592,24 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Repositories is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public List versionIDs; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); versionIDs = fSuperRepository.createSnapshot(repositories); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); return doit.versionIDs; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#createSnapshot(java.lang.String) + /** + * Snapshot a repository. + * @param repository The name of the repository. + * @return The id of the new version. */ public int createSnapshot(final String repository) { @@ -609,23 +617,25 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Repository is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public int versionID; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); versionID = fSuperRepository.createSnapshot(repository); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); return doit.versionID; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#lookup(int, java.lang.String) + /** + * Look up information about a node. + * @param version The version to look up. + * @param path The path to look up. + * @return A Descriptor. */ public AVMNodeDescriptor lookup(final int version, final String path) { @@ -633,18 +643,17 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Path is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public AVMNodeDescriptor descriptor; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); Lookup lookup = fSuperRepository.lookup(version, path); descriptor = lookup.getCurrentNode().getDescriptor(lookup); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.descriptor; } @@ -661,23 +670,24 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public AVMNodeDescriptor child; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); child = fSuperRepository.lookup(dir, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.child; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#destroyRepository(java.lang.String) + /** + * Purge a repository. Permanently delete everything that + * is only referenced in that repository. + * @param name The name of the repository to purge. */ public void purgeRepository(final String name) { @@ -685,20 +695,21 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Name is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.purgeRepository(name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#purgeVersion(int, java.lang.String) + /** + * Purge a particular version from a repository. + * @param version The id of the version to purge. + * @param name The name of the repository. */ public void purgeVersion(final int version, final String name) { @@ -706,20 +717,22 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Name is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.purgeVersion(name, version); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#getIndirectionPath(java.lang.String) + /** + * Get the indirection path of a layered node. + * @param version The version to lookup. + * @param path The path to lookup. + * @return The indirection path (target) of the layered node. */ public String getIndirectionPath(final int version, final String path) { @@ -727,23 +740,24 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Path is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public String indirectionPath; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); indirectionPath = fSuperRepository.getIndirectionPath(version, path); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.indirectionPath; } - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMService#getRepositoryVersions(java.lang.String) + /** + * Get the extant version ids for a repository. + * @param name The name of the repository. + * @return A List of VersionDescriptors. */ public List getRepositoryVersions(final String name) { @@ -751,17 +765,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Name is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public List versions; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); versions = fSuperRepository.getRepositoryVersions(name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.versions; } @@ -780,23 +793,23 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public List versions; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); versions = fSuperRepository.getRepositoryVersions(name, from, to); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.versions; } /** * Change what a layered directory points to. + * @param path The path to the layered directory. */ public void retargetLayeredDirectory(final String path, final String target) { @@ -804,15 +817,14 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Illegal null argument."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.retargetLayeredDirectory(path, target); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } @@ -826,15 +838,14 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Path is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.makePrimary(path); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } @@ -844,17 +855,16 @@ public class AVMServiceImpl implements AVMService */ public List getRepositories() { - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public List reps; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); reps = fSuperRepository.getRepositories(); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.reps; } @@ -866,17 +876,16 @@ public class AVMServiceImpl implements AVMService */ public RepositoryDescriptor getRepository(final String name) { - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public RepositoryDescriptor desc; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); desc = fSuperRepository.getRepository(name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.desc; } @@ -893,17 +902,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Name is null."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public AVMNodeDescriptor root; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); root = fSuperRepository.getRepositoryRoot(version, name); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.root; } @@ -920,17 +928,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null descriptor."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public List history; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); history = fSuperRepository.getHistory(desc, count); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.history; } @@ -947,15 +954,14 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null path."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); fSuperRepository.setOpacity(path, opacity); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } @@ -976,17 +982,16 @@ public class AVMServiceImpl implements AVMService { throw new AVMBadArgumentException("Null node descriptor."); } - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { public AVMNodeDescriptor ancestor; - public void perform(Session session) + public void perform() { - fSuperRepository.setSession(session); ancestor = fSuperRepository.getCommonAncestor(left, right); } } - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, false); return doit.ancestor; } diff --git a/source/java/org/alfresco/repo/avm/ChildEntryDAO.java b/source/java/org/alfresco/repo/avm/ChildEntryDAO.java new file mode 100644 index 0000000000..6420cfd514 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/ChildEntryDAO.java @@ -0,0 +1,74 @@ +/* + * 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.List; + +/** + * DAO for ChildEntries. + * @author britt + */ +public interface ChildEntryDAO +{ + /** + * Save an unsaved ChildEntry. + * @param entry The entry to save. + */ + public void save(ChildEntry entry); + + /** + * Get an entry by name and parent. + * @param name The name of the child to find. + * @param parent The parent to look in. + * @return The ChildEntry or null if not foun. + */ + public ChildEntry getByNameParent(String name, DirectoryNode parent); + + /** + * Get all the children of a given parent. + * @param parent The parent. + * @return A List of ChildEntries. + */ + public List getByParent(DirectoryNode parent); + + /** + * Get the entry for a given child in a given parent. + * @param parent The parent. + * @param child The child. + * @return The ChildEntry or null. + */ + public ChildEntry getByParentChild(DirectoryNode parent, AVMNode child); + + /** + * Update a dirty ChildEntry. + * @param child The dirty entry. + */ + public void update(ChildEntry child); + + /** + * Delete one. + * @param child The one to delete. + */ + public void delete(ChildEntry child); + + /** + * Delete all children of the given parent. + * @param parent The parent. + */ + public void deleteByParent(AVMNode parent); +} diff --git a/source/java/org/alfresco/repo/avm/DeletedChildDAO.java b/source/java/org/alfresco/repo/avm/DeletedChildDAO.java new file mode 100644 index 0000000000..635aa83cc6 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/DeletedChildDAO.java @@ -0,0 +1,60 @@ +/* + * 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.List; + +/** + * DAO for DeletedChildren. + * @author britt + */ +public interface DeletedChildDAO +{ + /** + * Save an unsaved DeletedChild. + * @param child The DeletedChild to be saved. + */ + public void save(DeletedChild child); + + /** + * Delete one. + * @param child The one to delete. + */ + public void delete(DeletedChild child); + + /** + * Delete all belonging to the given parent. + * @param parent The parent. + */ + public void deleteByParent(AVMNode parent); + + /** + * Get by name and parent. + * @param name The name of the deleted entry. + * @param parent The parent. + * @return A DeletedChild or null if not found. + */ + public DeletedChild getByNameParent(String name, LayeredDirectoryNode parent); + + /** + * Get all the deleted children of a given parent. + * @param parent The parent. + * @return A List of DeletedChildren. + */ + public List getByParent(LayeredDirectoryNode parent); +} diff --git a/source/java/org/alfresco/repo/avm/DirectoryNode.java b/source/java/org/alfresco/repo/avm/DirectoryNode.java index 388c890685..178392bb89 100644 --- a/source/java/org/alfresco/repo/avm/DirectoryNode.java +++ b/source/java/org/alfresco/repo/avm/DirectoryNode.java @@ -24,7 +24,7 @@ import java.util.SortedMap; * The interface for Directory Nodes. * @author britt */ -interface DirectoryNode extends AVMNode +public interface DirectoryNode extends AVMNode { /** * Does this directory directly contain the specified node. diff --git a/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java index c6bdb426fd..dd92258ae2 100644 --- a/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java @@ -19,9 +19,6 @@ package org.alfresco.repo.avm; import java.util.List; -import org.hibernate.Query; -import org.hibernate.Session; - /** * Base class for Directories. * @author britt @@ -52,14 +49,9 @@ abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode * @param write Whether the child should be looked up for writing. * @return The ChildEntry or null if not found. */ - @SuppressWarnings("unchecked") protected ChildEntry getChild(String name, boolean write) { - // TODO This may be very Dangerous! - Session sess = SuperRepository.GetInstance().getSession(); - ChildEntry entry = (ChildEntry)sess.get(ChildEntryImpl.class, new ChildEntryImpl(name, this, null)); - // (write && getIsNew()) ? LockMode.UPGRADE : LockMode.READ); - return entry; + return AVMContext.fgInstance.fChildEntryDAO.getByNameParent(name, this); } /** @@ -68,16 +60,9 @@ abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode * exposed through the interface. * @return A List of ChildEntries. */ - @SuppressWarnings("unchecked") public List getChildren() { - Session sess = SuperRepository.GetInstance().getSession(); - Query query = sess.getNamedQuery("ChildEntry.ByParent"); - query.setEntity("parent", this); - query.setCacheable(true); - query.setCacheRegion("ChildEntry.ByParent"); - List found = (List)query.list(); - return found; + return AVMContext.fgInstance.fChildEntryDAO.getByParent(this); } /** @@ -85,20 +70,8 @@ abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode * @param child The child node to look for. * @return The ChildEntry or null if not found. */ - @SuppressWarnings("unchecked") protected ChildEntry getChild(AVMNode child) { - Session sess = SuperRepository.GetInstance().getSession(); - Query query = sess.getNamedQuery("ChildEntry.ByParentChild"); - query.setEntity("parent", this); - query.setEntity("child", child); - query.setCacheable(true); - query.setCacheRegion("ChildEntry.ByParentChild"); - List found = (List)query.list(); - if (found.size() == 0) - { - return null; - } - return found.get(0); + return AVMContext.fgInstance.fChildEntryDAO.getByParentChild(this, child); } } diff --git a/source/java/org/alfresco/repo/avm/FileContent.java b/source/java/org/alfresco/repo/avm/FileContent.java index e4b9b357fd..4a5cc20195 100644 --- a/source/java/org/alfresco/repo/avm/FileContent.java +++ b/source/java/org/alfresco/repo/avm/FileContent.java @@ -24,7 +24,7 @@ import java.io.RandomAccessFile; * Interface for file content. FileContent can be shared between files. * @author britt */ -interface FileContent +public interface FileContent { /** * Get the number of files that refer to this content. diff --git a/source/java/org/alfresco/repo/avm/FileContentDAO.java b/source/java/org/alfresco/repo/avm/FileContentDAO.java new file mode 100644 index 0000000000..5a707848f6 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/FileContentDAO.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; + +/** + * DAO for FileContent objects. + * @author britt + */ +public interface FileContentDAO +{ + /** + * Save one. + * @param content To be saved. + */ + public void save(FileContent content); + + /** + * Delete one. + * @param content To be deleted. + */ + public void delete(FileContent content); +} diff --git a/source/java/org/alfresco/repo/avm/FileContentImpl.java b/source/java/org/alfresco/repo/avm/FileContentImpl.java index ea6423c88c..9c5153c908 100644 --- a/source/java/org/alfresco/repo/avm/FileContentImpl.java +++ b/source/java/org/alfresco/repo/avm/FileContentImpl.java @@ -89,7 +89,7 @@ class FileContentImpl implements FileContent, Serializable { throw new AVMException("File data error.", ie); } - SuperRepository.GetInstance().getSession().save(this); + AVMContext.fgInstance.fFileContentDAO.save(this); } /** @@ -119,7 +119,7 @@ class FileContentImpl implements FileContent, Serializable { throw new AVMException("I/O Error.", ie); } - SuperRepository.GetInstance().getSession().save(this); + AVMContext.fgInstance.fFileContentDAO.save(this); } /** @@ -150,7 +150,7 @@ class FileContentImpl implements FileContent, Serializable { throw new AVMException("I/O failure in Copy on Write.", ie); } - SuperRepository.GetInstance().getSession().save(this); + AVMContext.fgInstance.fFileContentDAO.save(this); } /** diff --git a/source/java/org/alfresco/repo/avm/HistoryLink.java b/source/java/org/alfresco/repo/avm/HistoryLink.java index fe22acdccf..eeb7953b5c 100644 --- a/source/java/org/alfresco/repo/avm/HistoryLink.java +++ b/source/java/org/alfresco/repo/avm/HistoryLink.java @@ -21,7 +21,7 @@ package org.alfresco.repo.avm; * Interface for the ancestor-descendent relationship. * @author britt */ -interface HistoryLink +public interface HistoryLink { /** * Set the ancestor part of this. diff --git a/source/java/org/alfresco/repo/avm/HistoryLinkDAO.java b/source/java/org/alfresco/repo/avm/HistoryLinkDAO.java new file mode 100644 index 0000000000..895de21759 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/HistoryLinkDAO.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; + +import java.util.List; + +/** + * DAO for history links. + * @author britt + */ +public interface HistoryLinkDAO +{ + /** + * Save and unsaved HistoryLink. + * @param link + */ + public void save(HistoryLink link); + + /** + * Get the history link with the given descendent. + * @param descendent The descendent. + * @return The HistoryLink or null if not found. + */ + public HistoryLink getByDescendent(AVMNode descendent); + + /** + * Get all the descendents of a node. + * @param ancestor The ancestor node. + * @return A List of AVMNode descendents. + */ + public List getByAncestor(AVMNode ancestor); + + /** + * Delete a HistoryLink + * @param link The link to delete. + */ + public void delete(HistoryLink link); +} diff --git a/source/java/org/alfresco/repo/avm/IssuerDAO.java b/source/java/org/alfresco/repo/avm/IssuerDAO.java new file mode 100644 index 0000000000..3fd8ff965c --- /dev/null +++ b/source/java/org/alfresco/repo/avm/IssuerDAO.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * DAO for Issuers. + * @author britt + */ +public interface IssuerDAO +{ + /** + * Get the node Issuer value. + */ + public Long getNodeIssuerValue(); + + /** + * Get the content Issuer value. + */ + public Long getContentIssuerValue(); + + /** + * Get the layer Issuer value. + */ + public Long getLayerIssuerValue(); +} diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java index ff8789b441..8176562d09 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java @@ -6,7 +6,7 @@ import java.util.List; * Interface for Layered Directories. * @author britt */ -interface LayeredDirectoryNode extends DirectoryNode, Layered +public interface LayeredDirectoryNode extends DirectoryNode, Layered { /** * Does this node have a primary indirection. diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java index 6364beca4a..269849dadd 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java @@ -17,16 +17,12 @@ package org.alfresco.repo.avm; -import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; -import org.hibernate.Query; -import org.hibernate.Session; - /** * A layered directory node. A layered directory node points at * an underlying directory, which may or may not exist. The visible @@ -78,7 +74,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec fIndirection = indirection; fPrimaryIndirection = true; fOpacity = false; - repos.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -91,24 +87,23 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec Repository repos) { super(repos.getSuperRepository().issueID(), repos); - Session sess = repos.getSuperRepository().getSession(); fIndirection = other.getUnderlying(); fPrimaryIndirection = other.getPrimaryIndirection(); fLayerID = -1; fOpacity = false; - sess.save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); for (ChildEntry child : other.getChildren()) { ChildEntryImpl newChild = new ChildEntryImpl(child.getName(), this, child.getChild()); - repos.getSuperRepository().getSession().save(newChild); + AVMContext.fgInstance.fChildEntryDAO.save(newChild); } for (DeletedChild dc : other.getDeleted()) { DeletedChild newDel = new DeletedChildImpl(dc.getName(), this); - sess.save(newDel); + AVMContext.fgInstance.fDeletedChildDAO.save(newDel); } } @@ -130,8 +125,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec fPrimaryIndirection = false; fLayerID = -1; fOpacity = false; - Session sess = repos.getSuperRepository().getSession(); - sess.save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); if (copyContents) { for (ChildEntry child : other.getChildren()) @@ -139,7 +133,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec ChildEntryImpl newChild = new ChildEntryImpl(child.getName(), this, child.getChild()); - sess.save(newChild); + AVMContext.fgInstance.fChildEntryDAO.save(newChild); } } } @@ -162,7 +156,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec fPrimaryIndirection = true; fLayerID = -1; fOpacity = false; - repo.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -266,22 +260,21 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec */ public void putChild(String name, AVMNode node) { - Session sess = SuperRepository.GetInstance().getSession(); -// sess.lock(this, LockMode.UPGRADE); - ChildEntry entry = new ChildEntryImpl(name, this, node); - ChildEntry existing = (ChildEntry)sess.get(ChildEntryImpl.class, (Serializable)entry); + ChildEntry existing = getChild(name, true); if (existing != null) { existing.setChild(node); + AVMContext.fgInstance.fChildEntryDAO.update(existing); } else { - sess.save(entry); + ChildEntry entry = new ChildEntryImpl(name, this, node); + AVMContext.fgInstance.fChildEntryDAO.save(entry); } - DeletedChild dc = getDeleted("name"); + DeletedChild dc = getDeleted(name); if (dc != null) { - sess.delete(dc); + AVMContext.fgInstance.fDeletedChildDAO.delete(dc); } } @@ -499,11 +492,11 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec ChildEntry entry = getChild(name, true); if (entry != null) { - SuperRepository.GetInstance().getSession().delete(entry); + AVMContext.fgInstance.fChildEntryDAO.delete(entry); } DeletedChild dc = new DeletedChildImpl(name, this); - SuperRepository.GetInstance().getSession().save(dc); + AVMContext.fgInstance.fDeletedChildDAO.save(dc); } /** @@ -564,7 +557,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec DeletedChild dc = getDeleted(name); if (dc != null) { - SuperRepository.GetInstance().getSession().delete(dc); + AVMContext.fgInstance.fDeletedChildDAO.delete(dc); } } @@ -687,31 +680,16 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec @SuppressWarnings("unchecked") private DeletedChild getDeleted(String name) { - Query query = SuperRepository.GetInstance().getSession().getNamedQuery("DeletedChild.ByNameParent"); - query.setString("name", name); - query.setEntity("parent", this); - query.setCacheable(true); - query.setCacheRegion("DeletedChild.ByNameParent"); - List dc = (List)query.list(); - if (dc.size() == 0) - { - return null; - } - return dc.get(0); + return AVMContext.fgInstance.fDeletedChildDAO.getByNameParent(name, this); } /** * Get all the deleted entries in this directory. * @return A List of DeletedEntry objects. */ - @SuppressWarnings("unchecked") public List getDeleted() { - Query query = SuperRepository.GetInstance().getSession().getNamedQuery("DeletedChild.ByParent"); - query.setEntity("parent", this); - query.setCacheable(true); - query.setCacheRegion("DeletedChild.ByParent"); - return (List)query.list(); + return AVMContext.fgInstance.fDeletedChildDAO.getByParent(this); } /** diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java index 8e67de1a71..99536d28a7 100644 --- a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java @@ -47,7 +47,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode { super(repo.getSuperRepository().issueID(), repo); fIndirection = other.getIndirection(); - repo.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -59,7 +59,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode { super(repo.getSuperRepository().issueID(), repo); fIndirection = indirection; - repo.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java index e9625abae6..3572965530 100644 --- a/source/java/org/alfresco/repo/avm/Lookup.java +++ b/source/java/org/alfresco/repo/avm/Lookup.java @@ -185,7 +185,8 @@ class Lookup { // Inform the repository of a new root. fRepository.setNewRoot((DirectoryNode)node); - SuperRepository.GetInstance().getSession().flush(); + AVMContext.fgInstance.fRepositoryDAO.update(fRepository); + // TODO More Hibernate weirdness to figure out: SuperRepository.GetInstance().getSession().flush(); return; } // Not the root. Check if we are the top layer and insert this into it's parent. @@ -194,7 +195,7 @@ class Lookup fTopLayer = (LayeredDirectoryNode)node; } ((DirectoryNode)fComponents.get(fPosition - 1).getNode()).putChild(name, node); - SuperRepository.GetInstance().getSession().flush(); + // TODO More Hibernate hijinx: SuperRepository.GetInstance().getSession().flush(); } } diff --git a/source/java/org/alfresco/repo/avm/MergeLink.java b/source/java/org/alfresco/repo/avm/MergeLink.java index 1be0b9c153..7be48ddb5b 100644 --- a/source/java/org/alfresco/repo/avm/MergeLink.java +++ b/source/java/org/alfresco/repo/avm/MergeLink.java @@ -21,7 +21,7 @@ package org.alfresco.repo.avm; * This is the interface for the merged from - to relationship. * @author britt */ -interface MergeLink +public interface MergeLink { /** * Set the from part. diff --git a/source/java/org/alfresco/repo/avm/MergeLinkDAO.java b/source/java/org/alfresco/repo/avm/MergeLinkDAO.java new file mode 100644 index 0000000000..fb27f61572 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/MergeLinkDAO.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; + +import java.util.List; + +/** + * DAO for MergeLinks. + * @author britt + */ +public interface MergeLinkDAO +{ + /** + * Save an unsaved MergeLink. + * @param link The link to save. + */ + public void save(MergeLink link); + + /** + * Get a link from the merged to node. + * @param to The node merged to. + * @return An AVMNode or null if not found. + */ + public MergeLink getByTo(AVMNode to); + + /** + * Get all the link that the given node was merged to. + * @param from The node that was merged from + * @return A List of MergeLinks. + */ + public List getByFrom(AVMNode from); + + /** + * Delete a link. + * @param link The link to delete. + */ + public void delete(MergeLink link); +} diff --git a/source/java/org/alfresco/repo/avm/OrphanReaper.java b/source/java/org/alfresco/repo/avm/OrphanReaper.java index 8c920120fb..ecda2c409d 100644 --- a/source/java/org/alfresco/repo/avm/OrphanReaper.java +++ b/source/java/org/alfresco/repo/avm/OrphanReaper.java @@ -19,11 +19,6 @@ package org.alfresco.repo.avm; import java.util.List; -import org.alfresco.repo.avm.hibernate.HibernateTxn; -import org.alfresco.repo.avm.hibernate.HibernateTxnCallback; -import org.hibernate.Query; -import org.hibernate.Session; - /** * This is the background thread for reaping no longer referenced nodes * in the AVM repository. These orphans arise from purge operations. @@ -34,7 +29,7 @@ public class OrphanReaper implements Runnable /** * The HibernateTxn instance. */ - private HibernateTxn fTransaction; + private RetryingTransaction fTransaction; /** * Inactive base sleep interval. @@ -112,7 +107,7 @@ public class OrphanReaper implements Runnable * Set the Hibernate Transaction Wrapper. * @param transaction */ - public void setHibernateTxn(HibernateTxn transaction) + public void setRetryingTransaction(RetryingTransaction transaction) { fTransaction = transaction; } @@ -184,17 +179,13 @@ public class OrphanReaper implements Runnable /** * Do a batch of cleanup work. */ - @SuppressWarnings("unchecked") public void doBatch() { - class HTxnCallback implements HibernateTxnCallback + class TxnCallback implements RetryingTransactionCallback { - public void perform(Session session) + public void perform() { - SuperRepository.GetInstance().setSession(session); - Query query = session.getNamedQuery("FindOrphans"); - query.setMaxResults(fBatchSize); - List nodes = (List)query.list(); + List nodes = AVMContext.fgInstance.fAVMNodeDAO.getOrphans(fBatchSize); if (nodes.size() == 0) { fActive = false; @@ -204,28 +195,22 @@ public class OrphanReaper implements Runnable for (AVMNode node : nodes) { // Save away the ancestor and merged from fields from this node. - query = session.createQuery("from HistoryLinkImpl hl where hl.descendent = :desc"); - query.setEntity("desc", node); - HistoryLink hlink = (HistoryLink)query.uniqueResult(); + HistoryLink hlink = AVMContext.fgInstance.fHistoryLinkDAO.getByDescendent(node); AVMNode ancestor = null; if (hlink != null) { ancestor = hlink.getAncestor(); - session.delete(hlink); + AVMContext.fgInstance.fHistoryLinkDAO.delete(hlink); } - query = session.createQuery("from MergeLinkImpl ml where ml.mto = :to"); - query.setEntity("to", node); - MergeLink mlink = (MergeLink)query.uniqueResult(); + MergeLink mlink = AVMContext.fgInstance.fMergeLinkDAO.getByTo(node); AVMNode mergedFrom = null; if (mlink != null) { mergedFrom = mlink.getMfrom(); - session.delete(mlink); + AVMContext.fgInstance.fMergeLinkDAO.delete(mlink); } // Get all the nodes that have this node as ancestor. - query = session.getNamedQuery("HistoryLink.ByAncestor"); - query.setEntity("node", node); - List links = (List)query.list(); + List links = AVMContext.fgInstance.fHistoryLinkDAO.getByAncestor(node); for (HistoryLink link : links) { AVMNode desc = link.getDescendent(); @@ -234,56 +219,51 @@ public class OrphanReaper implements Runnable { desc.setMergedFrom(mergedFrom); } - session.delete(link); + AVMContext.fgInstance.fHistoryLinkDAO.delete(link); } // Get all the nodes that have this node as mergedFrom - query = session.getNamedQuery("MergeLink.ByFrom"); - query.setEntity("merged", node); - List mlinks = (List)query.list(); + List mlinks = AVMContext.fgInstance.fMergeLinkDAO.getByFrom(node); for (MergeLink link : mlinks) { link.getMto().setMergedFrom(ancestor); - session.delete(link); + AVMContext.fgInstance.fMergeLinkDAO.delete(link); } - session.flush(); - node = AVMNodeUnwrapper.Unwrap(node); + // TODO What to do about such Hibernate wackiness: session.flush(); + // TODO More of the same: node = AVMNodeUnwrapper.Unwrap(node); // Extra work for directories. - if (node instanceof DirectoryNode) + if (node.getType() == AVMNodeType.PLAIN_DIRECTORY || + node.getType() == AVMNodeType.LAYERED_DIRECTORY) { // First get rid of all child entries for the node. - Query delete = session.getNamedQuery("ChildEntry.DeleteByParent"); - delete.setEntity("parent", node); - delete.executeUpdate(); - if (node instanceof LayeredDirectoryNode) + AVMContext.fgInstance.fChildEntryDAO.deleteByParent(node); + if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) { // More special work for layered directories. - delete = session.getNamedQuery("DeletedChild.DeleteByParent"); - delete.setEntity("parent", node); - delete.executeUpdate(); + AVMContext.fgInstance.fDeletedChildDAO.deleteByParent(node); } - session.delete(node); + AVMContext.fgInstance.fAVMNodeDAO.delete(node); } else if (node instanceof PlainFileNode) { - session.delete(node); + AVMContext.fgInstance.fAVMNodeDAO.delete(node); // FileContent should be purged if nobody else references it. FileContent content = ((PlainFileNode)node).getContent(); if (content.getRefCount() == 1) { content.delete(); - session.delete(content); + AVMContext.fgInstance.fFileContentDAO.delete(content); } } else { - session.delete(node); + AVMContext.fgInstance.fAVMNodeDAO.delete(node); } } } } try { - HTxnCallback doit = new HTxnCallback(); + TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } catch (Exception e) diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java index 48bad4e5d2..a7b6363f1c 100644 --- a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java @@ -17,14 +17,11 @@ package org.alfresco.repo.avm; -import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; -import org.hibernate.Session; - /** * A plain directory. No monkey tricks except for possiblyCopy. * @author britt @@ -40,7 +37,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory public PlainDirectoryNodeImpl(Repository repo) { super(repo.getSuperRepository().issueID(), repo); - repo.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -60,16 +57,15 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory Repository repos) { super(repos.getSuperRepository().issueID(), repos); - Session sess = repos.getSuperRepository().getSession(); - sess.save(this); - sess.flush(); + AVMContext.fgInstance.fAVMNodeDAO.save(this); + // TODO Something about this. sess.flush(); for (ChildEntry child : other.getChildren()) { ChildEntry newChild = new ChildEntryImpl(child.getName(), this, child.getChild()); - sess.save(newChild); - sess.flush(); + AVMContext.fgInstance.fChildEntryDAO.save(newChild); + // TODO Something about this: sess.flush(); } } @@ -172,7 +168,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory ChildEntry entry = getChild(name, true); if (entry != null) { - SuperRepository.GetInstance().getSession().delete(entry); + AVMContext.fgInstance.fChildEntryDAO.delete(entry); } } @@ -183,18 +179,16 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory */ public void putChild(String name, AVMNode node) { - Session sess = SuperRepository.GetInstance().getSession(); -// sess.lock(this, LockMode.UPGRADE); - ChildEntry entry = new ChildEntryImpl(name, this, node); - ChildEntry existing = (ChildEntry)sess.get(ChildEntryImpl.class, (Serializable)entry); + ChildEntry existing = AVMContext.fgInstance.fChildEntryDAO.getByNameParent(name, this); if (existing != null) { existing.setChild(node); - sess.flush(); // TODO Should we or shouldn't we? + AVMContext.fgInstance.fChildEntryDAO.update(existing); } else { - sess.save(entry); + ChildEntry entry = new ChildEntryImpl(name, this, node); + AVMContext.fgInstance.fChildEntryDAO.save(entry); } } diff --git a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java index effcb87367..b2faf0f9cc 100644 --- a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java @@ -49,7 +49,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode { super(repos.getSuperRepository().issueID(), repos); fContent = new FileContentImpl(SuperRepository.GetInstance().issueContentID()); - repos.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -61,7 +61,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode { super(repos.getSuperRepository().issueID(), repos); fContent = new FileContentImpl(SuperRepository.GetInstance().issueContentID(), content); - repos.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -75,7 +75,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode super(repos.getSuperRepository().issueID(), repos); fContent = other.getContent(); fContent.setRefCount(fContent.getRefCount() + 1); - repos.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** @@ -90,7 +90,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode super(repos.getSuperRepository().issueID(), repos); fContent = content; fContent.setRefCount(fContent.getRefCount() + 1); - repos.getSuperRepository().getSession().save(this); + AVMContext.fgInstance.fAVMNodeDAO.save(this); } /** diff --git a/source/java/org/alfresco/repo/avm/Repository.java b/source/java/org/alfresco/repo/avm/Repository.java index ebebf65f9c..fe8811a71f 100644 --- a/source/java/org/alfresco/repo/avm/Repository.java +++ b/source/java/org/alfresco/repo/avm/Repository.java @@ -29,7 +29,7 @@ import java.util.SortedMap; * and layering operations. * @author britt */ -interface Repository +public interface Repository { /** * This returns the next version in this repository that will be snapshotted. diff --git a/source/java/org/alfresco/repo/avm/RepositoryDAO.java b/source/java/org/alfresco/repo/avm/RepositoryDAO.java new file mode 100644 index 0000000000..5391c2cc0c --- /dev/null +++ b/source/java/org/alfresco/repo/avm/RepositoryDAO.java @@ -0,0 +1,58 @@ +/* + * 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.List; + +/** + * DAO for Repositories. + * @author britt + */ +public interface RepositoryDAO +{ + /** + * Save a repository, never before saved. + * @param rep The repository + */ + public void save(Repository rep); + + /** + * Delete the given Repository. + * @param rep The Repository. + */ + public void delete(Repository rep); + + /** + * Get all repositories. + * @return A List of all the Repositories. + */ + public List getAll(); + + /** + * Get a repository by name. + * @param name The name of the repository. + * @return The repository or null if not found. + */ + public Repository getByName(String name); + + /** + * Update the given Repository record. + * @param rep The dirty Repository. + */ + public void update(Repository rep); +} diff --git a/source/java/org/alfresco/repo/avm/RepositoryImpl.java b/source/java/org/alfresco/repo/avm/RepositoryImpl.java index a4839655a6..a75e9e5cf1 100644 --- a/source/java/org/alfresco/repo/avm/RepositoryImpl.java +++ b/source/java/org/alfresco/repo/avm/RepositoryImpl.java @@ -37,7 +37,7 @@ import org.hibernate.Query; * operation. * @author britt */ -class RepositoryImpl implements Repository, Serializable +public class RepositoryImpl implements Repository, Serializable { static final long serialVersionUID = -1485972568675732904L; @@ -98,20 +98,20 @@ class RepositoryImpl implements Repository, Serializable fRoot = null; fCreator = "britt"; fCreateDate = System.currentTimeMillis(); - fSuper.getSession().save(this); + AVMContext.fgInstance.fRepositoryDAO.save(this); // Make up the initial version record and save. long time = System.currentTimeMillis(); fRoot = new PlainDirectoryNodeImpl(this); fRoot.setIsNew(false); fRoot.setIsRoot(true); - fSuper.getSession().save(fRoot); + AVMContext.fgInstance.fAVMNodeDAO.save(fRoot); VersionRoot versionRoot = new VersionRootImpl(this, fRoot, fNextVersionID, time, "britt"); fNextVersionID++; - fSuper.getSession().save(versionRoot); + AVMContext.fgInstance.fVersionRootDAO.save(versionRoot); } /** @@ -137,20 +137,21 @@ class RepositoryImpl implements Repository, Serializable throw new AVMExistsException("Already snapshotted."); } // Clear out the new nodes. - Query query = - fSuper.getSession().getNamedQuery("AVMNode.ByNewInRepo"); - query.setEntity("repo", this); - for (AVMNode newNode : (List)query.list()) + AVMNodeDAO anDAO = AVMContext.fgInstance.fAVMNodeDAO; + for (AVMNode newNode : anDAO.getNewInRepo(this)) { newNode.setIsNew(false); +// anDAO.update(newNode); } + // TODO: This is a grotesque hack to deal with hibernate. + anDAO.flush(); // Make up a new version record. VersionRoot versionRoot = new VersionRootImpl(this, fRoot, fNextVersionID, System.currentTimeMillis(), "britt"); - fSuper.getSession().save(versionRoot); + AVMContext.fgInstance.fVersionRootDAO.save(versionRoot); // Increment the version id. fNextVersionID++; return fNextVersionID - 1; @@ -438,9 +439,7 @@ class RepositoryImpl implements Repository, Serializable @SuppressWarnings("unchecked") public List getVersions() { - Query query = fSuper.getSession().createQuery("from VersionRootImpl v where v.repository = :rep order by v.versionID"); - query.setEntity("rep", this); - List versions = (List)query.list(); + List versions = AVMContext.fgInstance.fVersionRootDAO.getAllInRepository(this); List descs = new ArrayList(); for (VersionRoot vr : versions) { @@ -464,32 +463,7 @@ class RepositoryImpl implements Repository, Serializable @SuppressWarnings("unchecked") public List getVersions(Date from, Date to) { - Query query; - if (from == null) - { - query = - fSuper.getSession().createQuery("from VersionRootImpl vr where vr.createDate <= :to " + - "order by vr.versionID"); - query.setLong("to", to.getTime()); - } - else if (to == null) - { - query = - fSuper.getSession().createQuery("from VersionRootImpl vr " + - "where vr.createDate >= :from " + - "order by vr.versionID"); - query.setLong("from", from.getTime()); - } - else - { - query = - fSuper.getSession().createQuery("from VersionRootImpl vr "+ - "where vr.createDate between :from and :to " + - "order by vr.versionID"); - query.setLong("from", from.getTime()); - query.setLong("to", to.getTime()); - } - List versions = (List)query.list(); + List versions = AVMContext.fgInstance.fVersionRootDAO.getByDates(this, from, to); List descs = new ArrayList(); for (VersionRoot vr : versions) { @@ -537,17 +511,13 @@ class RepositoryImpl implements Repository, Serializable // Versions less than 0 mean get current. if (version < 0) { - dir = (DirectoryNode)AVMNodeUnwrapper.Unwrap(fRoot); + dir = fRoot; // TODO How to factor out this kind of Hibernate goofiness. + // (DirectoryNode)AVMNodeUnwrapper.Unwrap(fRoot); } else { - Query query = - fSuper.getSession().getNamedQuery("VersionRoot.GetVersionRoot"); - query.setEntity("rep", this); - query.setInteger("version", version); - dir = (DirectoryNode)AVMNodeUnwrapper.Unwrap((AVMNode)query.uniqueResult()); + dir = AVMContext.fgInstance.fAVMNodeDAO.getRepositoryRoot(this, version); } -// fSuper.getSession().lock(dir, LockMode.READ); // Add an entry for the root. result.add(dir, "", write); dir = (DirectoryNode)result.getCurrentNode(); @@ -599,15 +569,7 @@ class RepositoryImpl implements Repository, Serializable } else { - Query query = - fSuper.getSession().getNamedQuery("VersionRoot.GetVersionRoot"); - query.setEntity("rep", this); - query.setInteger("version", version); - root = (AVMNode)query.uniqueResult(); - if (root == null) - { - throw new AVMException("Invalid version: " + version); - } + root = AVMContext.fgInstance.fAVMNodeDAO.getRepositoryRoot(this, version); } return root.getDescriptor("main:", "", null); } @@ -800,28 +762,22 @@ class RepositoryImpl implements Repository, Serializable { throw new AVMBadArgumentException("Cannot purge initial version"); } - Query query = fSuper.getSession().getNamedQuery("VersionRoot.VersionByID"); - query.setEntity("rep", this); - query.setInteger("version", version); - VersionRoot vRoot = (VersionRoot)query.uniqueResult(); - AVMNode root = vRoot.getRoot(); - if (root == null) + VersionRoot vRoot = AVMContext.fgInstance.fVersionRootDAO.getByVersionID(this, version); + if (vRoot == null) { throw new AVMNotFoundException("Version not found."); } + AVMNode root = vRoot.getRoot(); root.setIsRoot(false); - fSuper.getSession().delete(vRoot); + AVMContext.fgInstance.fAVMNodeDAO.update(root); + AVMContext.fgInstance.fVersionRootDAO.delete(vRoot); if (root.equals(fRoot)) { // We have to set a new current root. - fSuper.getSession().flush(); - query = fSuper.getSession().createQuery("select max(vr.versionID) from VersionRootImpl vr"); - int latest = (Integer)query.uniqueResult(); - query = fSuper.getSession().getNamedQuery("VersionRoot.VersionByID"); - query.setEntity("rep", this); - query.setInteger("version", latest); - vRoot = (VersionRoot)query.uniqueResult(); + // TODO More hibernate goofiness to compensate for: fSuper.getSession().flush(); + vRoot = AVMContext.fgInstance.fVersionRootDAO.getMaxVersion(this); fRoot = vRoot.getRoot(); + AVMContext.fgInstance.fRepositoryDAO.update(this); } } diff --git a/source/java/org/alfresco/repo/avm/RetryingTransaction.java b/source/java/org/alfresco/repo/avm/RetryingTransaction.java new file mode 100644 index 0000000000..24c6c9bd7b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/RetryingTransaction.java @@ -0,0 +1,15 @@ +package org.alfresco.repo.avm; + + +public interface RetryingTransaction +{ + + /** + * Perform a set of operations under a single transaction. + * Keep trying if the operation fails because of a concurrency issue. + * @param callback The worker. + * @param write Whether this is a write operation. + */ + public void perform(RetryingTransactionCallback callback, boolean write); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java b/source/java/org/alfresco/repo/avm/RetryingTransactionCallback.java similarity index 72% rename from source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java rename to source/java/org/alfresco/repo/avm/RetryingTransactionCallback.java index 8c6c978188..ca780860c3 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/HibernateTxnCallback.java +++ b/source/java/org/alfresco/repo/avm/RetryingTransactionCallback.java @@ -15,19 +15,16 @@ * License. */ -package org.alfresco.repo.avm.hibernate; - -import org.hibernate.Session; +package org.alfresco.repo.avm; /** - * Worker object for Hibernate Transactions. + * Worker object for AVM Retrying Transactions. * @author britt */ -public interface HibernateTxnCallback +public interface RetryingTransactionCallback { /** * Do our work. - * @param sess The Hibernate session. */ - public void perform(Session sess); + public void perform(); } diff --git a/source/java/org/alfresco/repo/avm/SuperRepository.java b/source/java/org/alfresco/repo/avm/SuperRepository.java index aee0193c31..08313c3a0b 100644 --- a/source/java/org/alfresco/repo/avm/SuperRepository.java +++ b/source/java/org/alfresco/repo/avm/SuperRepository.java @@ -27,10 +27,6 @@ import java.util.Iterator; import java.util.List; import java.util.SortedMap; -import org.hibernate.LockMode; -import org.hibernate.Query; -import org.hibernate.Session; - /** * This or Repository are * the implementors of the operations specified by AVMService. @@ -43,11 +39,6 @@ class SuperRepository */ private static SuperRepository fgInstance; - /** - * The Hibernate Session associated with the current operation. - */ - private ThreadLocal fSession; - /** * The current lookup count. */ @@ -89,21 +80,10 @@ class SuperRepository fNodeIssuer = nodeIssuer; fContentIssuer = contentIssuer; fLayerIssuer = layerIssuer; - fSession = new ThreadLocal(); fLookupCount = new ThreadLocal(); fgInstance = this; } - /** - * Set the (thread local) Hibernate session. - * @param session The Session to set. - */ - public void setSession(Session session) - { - fSession.set(session); - fLookupCount.set(0); - } - /** * Create a file. * @param path The path to the containing directory. @@ -485,25 +465,24 @@ class SuperRepository // fSession.get().lock(rep, LockMode.UPGRADE); AVMNode root = rep.getRoot(); root.setIsRoot(false); - Query query = fSession.get().createQuery("from VersionRootImpl vr where vr.repository = :rep"); - query.setEntity("rep", rep); - List vRoots = (List)query.list(); +// AVMContext.fgInstance.fAVMNodeDAO.update(root); + VersionRootDAO vrDAO = AVMContext.fgInstance.fVersionRootDAO; + List vRoots = vrDAO.getAllInRepository(rep); for (VersionRoot vr : vRoots) { AVMNode node = vr.getRoot(); node.setIsRoot(false); - fSession.get().delete(vr); +// AVMContext.fgInstance.fAVMNodeDAO.update(node); + vrDAO.delete(vr); } - query = fSession.get().createQuery("from AVMNodeImpl an where an.repository = :rep"); - query.setEntity("rep", rep); - Iterator iter = (Iterator)query.iterate(); + Iterator iter = AVMContext.fgInstance.fAVMNodeDAO.getByRepository(rep); while (iter.hasNext()) { AVMNode node = iter.next(); node.setRepository(null); + AVMContext.fgInstance.fAVMNodeDAO.update(node); } - fSession.get().flush(); - fSession.get().delete(rep); + AVMContext.fgInstance.fRepositoryDAO.delete(rep); } /** @@ -541,7 +520,7 @@ class SuperRepository public InputStream getInputStream(AVMNodeDescriptor desc) { fLookupCount.set(1); - AVMNode node = (AVMNode)fSession.get().get(AVMNodeImpl.class, desc.getId()); + AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Not found."); @@ -578,7 +557,7 @@ class SuperRepository public SortedMap getListing(AVMNodeDescriptor dir) { fLookupCount.set(1); - AVMNode node = (AVMNode)fSession.get().get(AVMNodeImpl.class, dir.getId()); + AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(dir.getId()); if (node.getType() != AVMNodeType.LAYERED_DIRECTORY && node.getType() != AVMNodeType.PLAIN_DIRECTORY) { @@ -595,8 +574,7 @@ class SuperRepository @SuppressWarnings("unchecked") public List getRepositories() { - Query query = fSession.get().createQuery("from RepositoryImpl r"); - List l = (List)query.list(); + List l = AVMContext.fgInstance.fRepositoryDAO.getAll(); List result = new ArrayList(); for (Repository rep : l) { @@ -670,15 +648,6 @@ class SuperRepository return fLayerIssuer.issue(); } - /** - * Get the (thread local) Hibernate session. - * @return The Session. - */ - public Session getSession() - { - return fSession.get(); - } - /** * Get the indirection path for a layered node. * @param version The version to look under. @@ -714,17 +683,11 @@ class SuperRepository */ private Repository getRepositoryByName(String name, boolean write) { - Repository rep = (Repository)fSession.get().get(RepositoryImpl.class, - name); /* LockMode.READ , - write ? LockMode.UPGRADE : LockMode.READ); */ + Repository rep = AVMContext.fgInstance.fRepositoryDAO.getByName(name); if (rep == null) { throw new AVMNotFoundException("Repository not found: " + name); } -// if (write && !rep.getRoot().getIsNew()) -// { -// fSession.get().lock(rep, LockMode.UPGRADE); -// } return rep; } @@ -744,7 +707,8 @@ class SuperRepository // fSession.get().lock(rep, LockMode.READ); return rep.getRoot(version); } - + + // TODO Fix this awful mess regarding cycle detection. /** * Lookup a node. * @param version The version to look under. @@ -753,15 +717,27 @@ class SuperRepository */ public Lookup lookup(int version, String path) { - fLookupCount.set(fLookupCount.get() + 1); - if (fLookupCount.get() > 10) + Integer count = fLookupCount.get(); + if (count == null) + { + fLookupCount.set(1); + } + else + { + fLookupCount.set(count + 1); + } + if (fLookupCount.get() > 50) { throw new AVMCycleException("Cycle in lookup."); } String [] pathParts = SplitPath(path); Repository rep = getRepositoryByName(pathParts[0], false); -// fSession.get().lock(rep, LockMode.READ); - return rep.lookup(version, pathParts[1], false); + Lookup result = rep.lookup(version, pathParts[1], false); + if (count == null) + { + fLookupCount.set(null); + } + return result; } /** @@ -773,7 +749,7 @@ class SuperRepository public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name) { fLookupCount.set(0); - AVMNode node = (AVMNode)fSession.get().get(AVMNodeImpl.class, dir.getId()); + AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(dir.getId()); if (node == null) { throw new AVMNotFoundException("Not found: " + dir.getId()); @@ -865,7 +841,7 @@ class SuperRepository */ public List getHistory(AVMNodeDescriptor desc, int count) { - AVMNode node = (AVMNode)fSession.get().get(AVMNodeImpl.class, desc.getId()); + AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Not found."); @@ -926,8 +902,8 @@ class SuperRepository public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, AVMNodeDescriptor right) { - AVMNode lNode = (AVMNode)fSession.get().get(AVMNodeImpl.class, left.getId()); - AVMNode rNode = (AVMNode)fSession.get().get(AVMNodeImpl.class, right.getId()); + AVMNode lNode = AVMContext.fgInstance.fAVMNodeDAO.getByID(left.getId()); + AVMNode rNode = AVMContext.fgInstance.fAVMNodeDAO.getByID(right.getId()); if (lNode == null || rNode == null) { throw new AVMNotFoundException("Node not found."); diff --git a/source/java/org/alfresco/repo/avm/VersionRootDAO.java b/source/java/org/alfresco/repo/avm/VersionRootDAO.java new file mode 100644 index 0000000000..602a80d903 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/VersionRootDAO.java @@ -0,0 +1,71 @@ +/* + * 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.Date; +import java.util.List; + +/** + * DAO for VersionRoot objects. + * @author britt + */ +public interface VersionRootDAO +{ + /** + * Save an unsaved VersionRoot. + * @param vr The VersionRoot to save. + */ + public void save(VersionRoot vr); + + /** + * Delete a VersionRoot. + * @param vr The VersionRoot to delete. + */ + public void delete(VersionRoot vr); + + /** + * Get all the version roots in a given repository. + * @param rep The repository. + * @return A List of VersionRoots. In id order. + */ + public List getAllInRepository(Repository rep); + + /** + * Get the VersionRoot corresponding to the given id. + * @param rep The repository + * @param id The version id. + * @return The VersionRoot or null if not found. + */ + public VersionRoot getByVersionID(Repository rep, int id); + + /** + * Get the version of a repository by dates. + * @param rep The repository. + * @param from The starting date. May be null but not with to null also. + * @param to The ending date. May be null but not with from null also. + * @return A List of VersionRoots. + */ + public List getByDates(Repository rep, Date from, Date to); + + /** + * Get the highest numbered version in a repository. + * @param rep The repository. + * @return The highest numbered version. + */ + public VersionRoot getMaxVersion(Repository rep); +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVMNodeDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/AVMNodeDAOHibernate.java new file mode 100644 index 0000000000..5eedd01af8 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/AVMNodeDAOHibernate.java @@ -0,0 +1,194 @@ +/* + * 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.Iterator; +import java.util.List; + +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.AVMNodeDAO; +import org.alfresco.repo.avm.AVMNodeImpl; +import org.alfresco.repo.avm.AVMNodeUnwrapper; +import org.alfresco.repo.avm.DirectoryNode; +import org.alfresco.repo.avm.Repository; +import org.hibernate.Query; +import org.hibernate.Session; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * @author britt + * + */ +public class AVMNodeDAOHibernate extends HibernateDaoSupport implements + AVMNodeDAO +{ + /** + * Do nothing constructor. + */ + public AVMNodeDAOHibernate() + { + super(); + } + + /** + * Save the given node, having never been saved before. + */ + public void save(AVMNode node) + { + getSession().save(node); + } + + /** + * Get all the nodes owned by a Repository and make + * them no longer point at that Repository. + * @param rep The Repository. + */ + @SuppressWarnings("unchecked") + public void dereferenceNodesInRepository(Repository rep) + { + Session sess = getSession(); + Query query = sess.createQuery("from AVMNodeImpl an where an.repository = :rep"); + query.setEntity("rep", rep); + Iterator iter = (Iterator)query.iterate(); + while (iter.hasNext()) + { + AVMNode node = iter.next(); + node.setRepository(null); + } + sess.flush(); + } + + /** + * Delete a single node. + * @param node The node to delete. + */ + public void delete(AVMNode node) + { + getSession().delete(node); + } + + /** + * Get by ID. + * @param id The id to get. + */ + public AVMNode getByID(long id) + { + return AVMNodeUnwrapper.Unwrap((AVMNode)getSession().get(AVMNodeImpl.class, id)); + } + + /** + * Get those nodes which are new in the given repository. + * @param repo The repository. + * @return A List of AVMNodes. + */ + @SuppressWarnings("unchecked") + public List getNewInRepo(Repository repo) + { + Query query = + getSession().getNamedQuery("AVMNode.ByNewInRepo"); + query.setEntity("repo", repo); + return (List)query.list(); + } + + /** + * Update a node that has been dirtied. + * @param node The node. + */ + public void update(AVMNode node) + { + getSession().flush(); + } + + /** + * Get the root of a particular version. + * @param rep The repository we're querying. + * @param version The version. + * @return The VersionRoot or null. + */ + public DirectoryNode getRepositoryRoot(Repository rep, int version) + { + Query query = + getSession().getNamedQuery("VersionRoot.GetVersionRoot"); + query.setEntity("rep", rep); + query.setInteger("version", version); + AVMNode root = (AVMNode)query.uniqueResult(); + if (root == null) + { + return null; + } + return (DirectoryNode)AVMNodeUnwrapper.Unwrap(root); + } + + /** + * Get the ancestor of a node. + * @param node The node whose ancestor is desired. + * @return The ancestor or null. + */ + public AVMNode getAncestor(AVMNode node) + { + Query query = getSession().createQuery("select hl.ancestor from HistoryLinkImpl hl where hl.descendent = :desc"); + query.setEntity("desc", node); + return (AVMNode)query.uniqueResult(); + } + + /** + * Get the node the given node was merged from. + * @param node The node whose merged from is desired. + * @return The merged from node or null. + */ + public AVMNode getMergedFrom(AVMNode node) + { + Query query = getSession().createQuery("select ml.mfrom from MergeLinkImpl ml where ml.mto = :to"); + query.setEntity("to", node); + return (AVMNode)query.uniqueResult(); + } + + /** + * Get up to batchSize orphans. + * @param batchSize Get no more than this number. + * @return A List of orphaned AVMNodes. + */ + @SuppressWarnings("unchecked") + public List getOrphans(int batchSize) + { + Query query = getSession().getNamedQuery("FindOrphans"); + query.setMaxResults(batchSize); + return (List)query.list(); + } + + /** + * Get all nodes that have the given repository as their owning repository. + * @param rep The Repository. + * @return An Iterator over the matching nodes. + */ + @SuppressWarnings("unchecked") + public Iterator getByRepository(Repository rep) + { + Query query = getSession().createQuery("from AVMNodeImpl an where an.repository = :rep"); + query.setEntity("rep", rep); + return (Iterator)query.iterate(); + } + + /** + * Inappropriate hack to get Hibernate to play nice. + */ + public void flush() + { + getSession().flush(); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java new file mode 100644 index 0000000000..18840c4ce0 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java @@ -0,0 +1,126 @@ +/* + * 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.io.Serializable; +import java.util.List; + +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.ChildEntry; +import org.alfresco.repo.avm.ChildEntryDAO; +import org.alfresco.repo.avm.ChildEntryImpl; +import org.alfresco.repo.avm.DirectoryNode; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * The Hibernate version of the ChildEntry DAO. + * @author britt + */ +public class ChildEntryDAOHibernate extends HibernateDaoSupport implements + ChildEntryDAO +{ + /** + * Do nothing constructor. + */ + public ChildEntryDAOHibernate() + { + super(); + } + + /** + * Save an unsaved ChildEntry. + * @param entry The entry to save. + */ + public void save(ChildEntry entry) + { + getSession().save(entry); + } + + /** + * Get an entry by name and parent. + * @param name The name of the child to find. + * @param parent The parent to look in. + * @return The ChildEntry or null if not foun. + */ + public ChildEntry getByNameParent(String name, DirectoryNode parent) + { + ChildEntry query = new ChildEntryImpl(name, parent, null); + return (ChildEntry)getSession().get(ChildEntryImpl.class, (Serializable)query); + } + + /** + * Get all the children of a given parent. + * @param parent The parent. + * @return A List of ChildEntries. + */ + @SuppressWarnings("unchecked") + public List getByParent(DirectoryNode parent) + { + Query query = getSession().getNamedQuery("ChildEntry.ByParent"); + query.setEntity("parent", parent); + query.setCacheable(true); + query.setCacheRegion("ChildEntry.ByParent"); + return (List)query.list(); + } + + /** + * Get the entry for a given child in a given parent. + * @param parent The parent. + * @param child The child. + * @return The ChildEntry or null. + */ + public ChildEntry getByParentChild(DirectoryNode parent, AVMNode child) + { + Query query = getSession().getNamedQuery("ChildEntry.ByParentChild"); + query.setEntity("parent", parent); + query.setEntity("child", child); + query.setCacheable(true); + query.setCacheRegion("ChildEntry.ByParentChild"); + return (ChildEntry)query.uniqueResult(); + } + + /** + * Update a dirty ChildEntry. + * @param child The dirty entry. + */ + public void update(ChildEntry child) + { + // NO OP in Hibernate. + } + + /** + * Delete one. + * @param child The one to delete. + */ + public void delete(ChildEntry child) + { + getSession().delete(child); + } + + /** + * Delete all children of the given parent. + * @param parent The parent. + */ + public void deleteByParent(AVMNode parent) + { + Query delete = getSession().getNamedQuery("ChildEntry.DeleteByParent"); + delete.setEntity("parent", parent); + delete.executeUpdate(); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/DeletedChildDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/DeletedChildDAOHibernate.java new file mode 100644 index 0000000000..ed811f78da --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/DeletedChildDAOHibernate.java @@ -0,0 +1,103 @@ +/* + * 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.List; + +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.DeletedChild; +import org.alfresco.repo.avm.DeletedChildDAO; +import org.alfresco.repo.avm.LayeredDirectoryNode; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * Hibernate implementation of DAO for DeletedChildren. + * @author britt + */ +public class DeletedChildDAOHibernate extends HibernateDaoSupport implements + DeletedChildDAO +{ + /** + * Do nothing constructor. + */ + public DeletedChildDAOHibernate() + { + super(); + } + + /** + * Save an unsaved DeletedChild. + * @param child The DeletedChild to be saved. + */ + public void save(DeletedChild child) + { + getSession().save(child); + } + + /** + * Delete one. + * @param child The one to delete. + */ + public void delete(DeletedChild child) + { + getSession().delete(child); + } + + /** + * Delete all belonging to the given parent. + * @param parent The parent. + */ + public void deleteByParent(AVMNode parent) + { + Query delete = getSession().getNamedQuery("DeletedChild.DeleteByParent"); + delete.setEntity("parent", parent); + delete.executeUpdate(); + } + + /** + * Get by name and parent. + * @param name The name of the deleted entry. + * @param parent The parent. + * @return A DeletedChild or null if not found. + */ + public DeletedChild getByNameParent(String name, LayeredDirectoryNode parent) + { + Query query = getSession().getNamedQuery("DeletedChild.ByNameParent"); + query.setString("name", name); + query.setEntity("parent", parent); + query.setCacheable(true); + query.setCacheRegion("DeletedChild.ByNameParent"); + return (DeletedChild)query.uniqueResult(); + } + + /** + * Get all the deleted children of a given parent. + * @param parent The parent. + * @return A List of DeletedChildren. + */ + @SuppressWarnings("unchecked") + public List getByParent(LayeredDirectoryNode parent) + { + Query query = getSession().getNamedQuery("DeletedChild.ByParent"); + query.setEntity("parent", parent); + query.setCacheable(true); + query.setCacheRegion("DeletedChild.ByParent"); + return (List)query.list(); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/FileContentDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/FileContentDAOHibernate.java new file mode 100644 index 0000000000..0c07376ce3 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/FileContentDAOHibernate.java @@ -0,0 +1,56 @@ +/* + * 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.FileContent; +import org.alfresco.repo.avm.FileContentDAO; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * @author britt + * + */ +public class FileContentDAOHibernate extends HibernateDaoSupport implements + FileContentDAO +{ + /** + * Do nothing constructor. + */ + public FileContentDAOHibernate() + { + super(); + } + + /** + * Save one. + * @param content The one to save. + */ + public void save(FileContent content) + { + getSession().save(content); + } + + /** + * Delete one. + * @param content To be deleted. + */ + public void delete(FileContent content) + { + getSession().delete(content); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateCallbackWrapper.java b/source/java/org/alfresco/repo/avm/hibernate/HibernateCallbackWrapper.java index fa169daed9..d4b03e2b47 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/HibernateCallbackWrapper.java +++ b/source/java/org/alfresco/repo/avm/hibernate/HibernateCallbackWrapper.java @@ -5,6 +5,7 @@ package org.alfresco.repo.avm.hibernate; import java.sql.SQLException; +import org.alfresco.repo.avm.RetryingTransactionCallback; import org.hibernate.HibernateException; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; @@ -18,13 +19,13 @@ public class HibernateCallbackWrapper implements HibernateCallback /** * The HibernateTxnCallback to execute. */ - private HibernateTxnCallback fCallback; + private RetryingTransactionCallback fCallback; /** * Make one up. * @param callback */ - public HibernateCallbackWrapper(HibernateTxnCallback callback) + public HibernateCallbackWrapper(RetryingTransactionCallback callback) { fCallback = callback; } @@ -36,7 +37,7 @@ public class HibernateCallbackWrapper implements HibernateCallback public Object doInHibernate(Session session) throws HibernateException, SQLException { - fCallback.perform(session); + fCallback.perform(); return null; } } diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java b/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java index fd1d74f762..ae23afcc65 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java +++ b/source/java/org/alfresco/repo/avm/hibernate/HibernateTxn.java @@ -21,6 +21,8 @@ import java.util.Random; import org.alfresco.repo.avm.AVMException; import org.alfresco.repo.avm.AVMNotFoundException; +import org.alfresco.repo.avm.RetryingTransactionCallback; +import org.alfresco.repo.avm.RetryingTransaction; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.DeadlockLoserDataAccessException; import org.springframework.dao.OptimisticLockingFailureException; @@ -34,7 +36,7 @@ import org.springframework.transaction.TransactionStatus; * Helper for DAOs. * @author britt */ -public class HibernateTxn extends HibernateTemplate +public class HibernateTxn extends HibernateTemplate implements RetryingTransaction { /** * The transaction manager. @@ -65,13 +67,10 @@ public class HibernateTxn extends HibernateTemplate fRandom = new Random(); } - /** - * Perform a set of operations under a single transaction. - * Keep trying if the operation fails because of a concurrency issue. - * @param callback The worker. - * @param write Whether this is a write operation. + /* (non-Javadoc) + * @see org.alfresco.repo.avm.hibernate.RetryingTransaction#perform(org.alfresco.repo.avm.hibernate.HibernateTxnCallback, boolean) */ - public void perform(HibernateTxnCallback callback, boolean write) + public void perform(RetryingTransactionCallback callback, boolean write) { while (true) { diff --git a/source/java/org/alfresco/repo/avm/hibernate/HistoryLinkDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/HistoryLinkDAOHibernate.java new file mode 100644 index 0000000000..6c1575c7fe --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/HistoryLinkDAOHibernate.java @@ -0,0 +1,85 @@ +/* + * 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.List; + +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.HistoryLink; +import org.alfresco.repo.avm.HistoryLinkDAO; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * The Hibernate implementation of the DAO for HistoryLinks. + * @author britt + */ +public class HistoryLinkDAOHibernate extends HibernateDaoSupport implements + HistoryLinkDAO +{ + /** + * Do nothing constructor. + */ + public HistoryLinkDAOHibernate() + { + super(); + } + + /** + * Save an unsaved HistoryLink. + * @param link + */ + public void save(HistoryLink link) + { + getSession().save(link); + } + + /** + * Get the history link with the given descendent. + * @param descendent The descendent. + * @return The HistoryLink or null if not found. + */ + public HistoryLink getByDescendent(AVMNode descendent) + { + Query query = getSession().createQuery("from HistoryLinkImpl hl where hl.descendent = :desc"); + query.setEntity("desc", descendent); + return (HistoryLink)query.uniqueResult(); + } + + /** + * Get all the descendents of a node. + * @param ancestor The ancestor node. + * @return A List of AVMNode descendents. + */ + @SuppressWarnings("unchecked") + public List getByAncestor(AVMNode ancestor) + { + Query query = getSession().getNamedQuery("HistoryLink.ByAncestor"); + query.setEntity("node", ancestor); + return (List)query.list(); + } + + /** + * Delete a HistoryLink + * @param link The link to delete. + */ + public void delete(HistoryLink link) + { + getSession().delete(link); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/IssuerDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/IssuerDAOHibernate.java new file mode 100644 index 0000000000..055225863c --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/IssuerDAOHibernate.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; + + +import org.alfresco.repo.avm.IssuerDAO; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * DAO for Issuers. Hibernate version. + * @author britt + */ +public class IssuerDAOHibernate extends HibernateDaoSupport implements + IssuerDAO +{ + /** + * Do nothing constructor. + */ + public IssuerDAOHibernate() + { + super(); + } + + public Long getContentIssuerValue() + { + return (Long)getSession().createQuery("select max(fc.id) from FileContentImpl fc").uniqueResult(); + } + + public Long getLayerIssuerValue() + { + return (Long)getSession().createQuery("select max(an.layerID) from AVMNodeImpl an").uniqueResult(); + } + + public Long getNodeIssuerValue() + { + return (Long)getSession().createQuery("select max(an.id) from AVMNodeImpl an").uniqueResult(); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/MergeLinkDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/MergeLinkDAOHibernate.java new file mode 100644 index 0000000000..6efcf32c2b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/MergeLinkDAOHibernate.java @@ -0,0 +1,85 @@ +/* + * 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.List; + +import org.alfresco.repo.avm.AVMNode; +import org.alfresco.repo.avm.MergeLink; +import org.alfresco.repo.avm.MergeLinkDAO; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * The Hibernate implementation of the DAO for a MergeLink + * @author britt + */ +public class MergeLinkDAOHibernate extends HibernateDaoSupport implements + MergeLinkDAO +{ + /** + * Do nothing constructor. + */ + public MergeLinkDAOHibernate() + { + super(); + } + + /** + * Save an unsaved MergeLink. + * @param link The link to save. + */ + public void save(MergeLink link) + { + getSession().save(link); + } + + /** + * Get a link from the merged to node. + * @param to The node merged to. + * @return An AVMNode or null if not found. + */ + public MergeLink getByTo(AVMNode to) + { + Query query = getSession().createQuery("from MergeLinkImpl ml where ml.mto = :to"); + query.setEntity("to", to); + return (MergeLink)query.uniqueResult(); + } + + /** + * Get all the link that the given node was merged to. + * @param from The node that was merged from + * @return A List of MergeLinks. + */ + @SuppressWarnings("unchecked") + public List getByFrom(AVMNode from) + { + Query query = getSession().getNamedQuery("MergeLink.ByFrom"); + query.setEntity("merged", from); + return (List)query.list(); + } + + /** + * Delete a link. + * @param link The link to delete. + */ + public void delete(MergeLink link) + { + getSession().delete(link); + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/RepositoryDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/RepositoryDAOHibernate.java new file mode 100644 index 0000000000..b87b554384 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/RepositoryDAOHibernate.java @@ -0,0 +1,90 @@ +/* + * 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.List; + +import org.alfresco.repo.avm.Repository; +import org.alfresco.repo.avm.RepositoryDAO; +import org.alfresco.repo.avm.RepositoryImpl; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * The Hibernate version for RepositoryDAO + * @author britt + */ +public class RepositoryDAOHibernate extends HibernateDaoSupport implements + RepositoryDAO +{ + /** + * Do nothing constructor. + */ + public RepositoryDAOHibernate() + { + super(); + } + + /** + * Save a repository, never before saved. + * @param rep The repository + */ + public void save(Repository rep) + { + getSession().save(rep); + } + + /** + * Delete the given Repository. + * @param rep The Repository. + */ + public void delete(Repository rep) + { + getSession().delete(rep); + } + + /** + * Get all repositories. + * @return A List of all the Repositories. + */ + @SuppressWarnings("unchecked") + public List getAll() + { + Query query = getSession().createQuery("from RepositoryImpl r"); + return (List)query.list(); + } + + /** + * Get a repository by name. + * @param name The name of the repository. + * @return The repository or null if not found. + */ + public Repository getByName(String name) + { + return (Repository)getSession().get(RepositoryImpl.class, name); + } + + /** + * Update the given Repository record. + * @param rep The dirty Repository. + */ + public void update(Repository rep) + { + // No op in Hibernate. + } +} diff --git a/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java new file mode 100644 index 0000000000..0255f5621b --- /dev/null +++ b/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java @@ -0,0 +1,147 @@ +/* + * 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.Date; +import java.util.List; + +import org.alfresco.repo.avm.Repository; +import org.alfresco.repo.avm.VersionRoot; +import org.alfresco.repo.avm.VersionRootDAO; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * This is the Hibernate version of the DAO for version roots. + * @author britt + */ +public class VersionRootDAOHibernate extends HibernateDaoSupport implements + VersionRootDAO +{ + /** + * Do nothing constructor. + */ + public VersionRootDAOHibernate() + { + super(); + } + + /** + * Save an unsaved VersionRoot. + * @param vr The VersionRoot to save. + */ + public void save(VersionRoot vr) + { + getSession().save(vr); + } + + /** + * Delete a VersionRoot. + * @param vr The VersionRoot to delete. + */ + public void delete(VersionRoot vr) + { + getSession().delete(vr); + getSession().flush(); + } + + /** + * Get all the version roots in a given repository. + * @param rep The repository. + * @return A List of VersionRoots. In id order. + */ + @SuppressWarnings("unchecked") + public List getAllInRepository(Repository rep) + { + Query query = getSession().createQuery("from VersionRootImpl v where v.repository = :rep order by v.versionID"); + query.setEntity("rep", rep); + return (List)query.list(); + } + + /** + * Get the version of a repository by dates. + * @param rep The repository. + * @param from The starting date. May be null but not with to null also. + * @param to The ending date. May be null but not with from null also. + * @return A List of VersionRoots. + */ + @SuppressWarnings("unchecked") + public List getByDates(Repository rep, Date from, Date to) + { + Query query; + if (from == null) + { + query = + getSession().createQuery("from VersionRootImpl vr where vr.createDate <= :to " + + "and vr.repository = :rep " + + "order by vr.versionID"); + query.setLong("to", to.getTime()); + query.setEntity("rep", rep); + } + else if (to == null) + { + query = + getSession().createQuery("from VersionRootImpl vr " + + "where vr.createDate >= :from " + + "and vr.repository = :rep " + + "order by vr.versionID"); + query.setLong("from", from.getTime()); + query.setEntity("rep", rep); + } + else + { + query = + getSession().createQuery("from VersionRootImpl vr "+ + "where vr.createDate between :from and :to " + + "and vr.repository = :rep " + + "order by vr.versionID"); + query.setLong("from", from.getTime()); + query.setLong("to", to.getTime()); + query.setEntity("rep", rep); + } + query.setEntity("rep", rep); + return (List)query.list(); + } + + /** + * Get the VersionRoot corresponding to the given id. + * @param rep The repository + * @param id The version id. + * @return The VersionRoot or null if not found. + */ + public VersionRoot getByVersionID(Repository rep, int id) + { + Query query = getSession().getNamedQuery("VersionRoot.VersionByID"); + query.setEntity("rep", rep); + query.setInteger("version", id); + return (VersionRoot)query.uniqueResult(); + } + + /** + * Get the highest numbered version in a repository. + * @param rep The repository. + * @return The highest numbered version. + */ + public VersionRoot getMaxVersion(Repository rep) + { + Query query = getSession().createQuery("from VersionRootImpl vr " + + "where vr.versionID = " + + "(select max(v.versionID) from VersionRootImpl v)"); + return (VersionRoot)query.uniqueResult(); + } +}