From d67b9265897ba66e96f21dea7fe5c4a40670780f Mon Sep 17 00:00:00 2001 From: Britt Park Date: Tue, 22 Aug 2006 01:22:01 +0000 Subject: [PATCH] Marking of AVM Nodes with Aspects works (according to some minimal tests). Schema has been updated, DAO written, garbage collection updated to clean out aspects. Also some seemingly unnecessary changes in visibility declarations to deal with strange intermittent Spring wiring failures in one of my tests. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3560 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/avm-services-context.xml | 9 ++ .../org/alfresco/repo/avm/AVMAspectName.java | 51 +++++++++ .../alfresco/repo/avm/AVMAspectNameDAO.java | 69 +++++++++++ .../repo/avm/AVMAspectNameDAOHibernate.java | 107 ++++++++++++++++++ .../alfresco/repo/avm/AVMAspectNameImpl.java | 105 +++++++++++++++++ .../org/alfresco/repo/avm/AVMContext.java | 30 +++++ .../org/alfresco/repo/avm/AVMRepository.java | 61 +++++++++- .../org/alfresco/repo/avm/AVMService.java | 33 ++++++ .../org/alfresco/repo/avm/AVMServiceImpl.java | 105 ++++++++++++++++- .../org/alfresco/repo/avm/AVMServiceTest.java | 27 +++++ .../java/org/alfresco/repo/avm/AVMStore.java | 31 +++++ .../org/alfresco/repo/avm/AVMStoreImpl.java | 75 ++++++++++++ .../HibernateRetryingTransactionHelper.java | 4 +- source/java/org/alfresco/repo/avm/Issuer.java | 6 +- .../org/alfresco/repo/avm/OrphanReaper.java | 10 +- .../alfresco/repo/avm/hibernate/AVM.hbm.xml | 10 +- 16 files changed, 716 insertions(+), 17 deletions(-) create mode 100644 source/java/org/alfresco/repo/avm/AVMAspectName.java create mode 100644 source/java/org/alfresco/repo/avm/AVMAspectNameDAO.java create mode 100644 source/java/org/alfresco/repo/avm/AVMAspectNameDAOHibernate.java create mode 100644 source/java/org/alfresco/repo/avm/AVMAspectNameImpl.java diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml index 51016b68b8..21383739b9 100644 --- a/config/alfresco/avm-services-context.xml +++ b/config/alfresco/avm-services-context.xml @@ -96,6 +96,12 @@ + + + + + + @@ -130,6 +136,9 @@ + + + diff --git a/source/java/org/alfresco/repo/avm/AVMAspectName.java b/source/java/org/alfresco/repo/avm/AVMAspectName.java new file mode 100644 index 0000000000..6a94b24387 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMAspectName.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +import org.alfresco.service.namespace.QName; + +/** + * Interface to Aspect names on AVM nodes. + * @author britt + */ +interface AVMAspectName +{ + /** + * Set the node that has the Aspect. + * @param node The node. + */ + public void setNode(AVMNode node); + + /** + * Get the node that has this Aspect name. + * @return The AVM Node. + */ + public AVMNode getNode(); + + /** + * Set the name of the Aspect. + * @param name The QName of the Aspect. + */ + public void setName(QName name); + + /** + * Get the name of this Aspect. + * @return The QName of this aspect. + */ + public QName getName(); +} diff --git a/source/java/org/alfresco/repo/avm/AVMAspectNameDAO.java b/source/java/org/alfresco/repo/avm/AVMAspectNameDAO.java new file mode 100644 index 0000000000..d201f62037 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMAspectNameDAO.java @@ -0,0 +1,69 @@ +/* + * 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; + +import org.alfresco.service.namespace.QName; + +/** + * DAO for AVMAspectNames. + * @author britt + */ +interface AVMAspectNameDAO +{ + /** + * Persist an aspect name. + * @param aspectName The item to persist. + */ + public void save(AVMAspectName aspectName); + + /** + * Delete an Aspect Name. + * @param aspectName The item to delete. + */ + public void delete(AVMAspectName aspectName); + + /** + * Delete a single aspect name from a node. + * @param node The node. + * @param aspectName The aspect name. + */ + public void delete(AVMNode node, QName aspectName); + + /** + * Delete all Aspect Names on a given node. + * @param node The given node. + */ + public void delete(AVMNode node); + + /** + * Get all Aspect Names for a given node. + * @param node The AVM Node. + * @return A List of AVMAspectNames. + */ + public List get(AVMNode node); + + /** + * Does the given node have the given asset. + * @param node The AVM node. + * @param name The QName of the Aspect. + * @return Whether the aspect is there. + */ + public boolean exists(AVMNode node, QName name); +} diff --git a/source/java/org/alfresco/repo/avm/AVMAspectNameDAOHibernate.java b/source/java/org/alfresco/repo/avm/AVMAspectNameDAOHibernate.java new file mode 100644 index 0000000000..1a4e590703 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMAspectNameDAOHibernate.java @@ -0,0 +1,107 @@ +/* + * 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; + +import org.alfresco.service.namespace.QName; +import org.hibernate.Query; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * Hibernate implementation of AVMAspectNameDAO. + * @author britt + */ +public class AVMAspectNameDAOHibernate extends HibernateDaoSupport + implements AVMAspectNameDAO +{ + /** + * Persist an aspect name. + * @param aspectName The item to persist. + */ + public void save(AVMAspectName aspectName) + { + getSession().save(aspectName); + } + + /** + * Delete an Aspect Name. + * @param aspectName The item to delete. + */ + public void delete(AVMAspectName aspectName) + { + getSession().delete(aspectName); + } + + /** + * Delete a single aspect name from a node. + * @param node The node. + * @param aspectName The aspect name. + */ + public void delete(AVMNode node, QName aspectName) + { + Query delete = + getSession().createQuery( + "delete from AVMAspectNameImpl aa where aa.node = :node and aa.name = :name"); + delete.setEntity("node", node); + delete.setParameter("name", aspectName); + delete.executeUpdate(); + } + + /** + * Delete all Aspect Names on a given node. + * @param node The given node. + */ + public void delete(AVMNode node) + { + Query delete = + getSession().createQuery("delete from AVMAspectNameImpl aa where aa.node = :node"); + delete.setEntity("node", node); + delete.executeUpdate(); + } + + /** + * Get all Aspect Names for a given node. + * @param node The AVM Node. + * @return A List of AVMAspectNames. + */ + @SuppressWarnings("unchecked") + public List get(AVMNode node) + { + Query query = + getSession().createQuery("from AVMAspectNameImpl aa where aa.node = :node"); + query.setEntity("node", node); + return (List)query.list(); + } + + /** + * Does the given node have the given asset. + * @param node The AVM node. + * @param name The QName of the Aspect. + * @return Whether the aspect is there. + */ + public boolean exists(AVMNode node, QName name) + { + Query query = + getSession().createQuery( + "from AVMAspectNameImpl aa where aa.node = :node and aa.name = :name"); + query.setEntity("node", node); + query.setParameter("name", name); + return query.uniqueResult() != null; + } +} diff --git a/source/java/org/alfresco/repo/avm/AVMAspectNameImpl.java b/source/java/org/alfresco/repo/avm/AVMAspectNameImpl.java new file mode 100644 index 0000000000..9e206a8bd1 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMAspectNameImpl.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.io.Serializable; + +import org.alfresco.service.namespace.QName; + +/** + * Simple bean that implements AVMAspectName. + * @author britt + */ +class AVMAspectNameImpl implements AVMAspectName, Serializable +{ + private static final long serialVersionUID = -6282415309583571934L; + + /** + * The Node that has the named aspect. + */ + private AVMNode fNode; + + /** + * The name of the Aspect. + */ + private QName fName; + + /** + * Default constructor. + */ + public AVMAspectNameImpl() + { + } + + /** + * Set the node that has the Aspect. + * @param node The node. + */ + public void setNode(AVMNode node) + { + fNode = node; + } + + /** + * Get the node that has this Aspect name. + * @return The AVM Node. + */ + public AVMNode getNode() + { + return fNode; + } + + /** + * Set the name of the Aspect. + * @param name The QName of the Aspect. + */ + public void setName(QName name) + { + fName = name; + } + + /** + * Get the name of this Aspect. + * @return The QName of this aspect. + */ + public QName getName() + { + return fName; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (!(obj instanceof AVMAspectName)) + { + return false; + } + AVMAspectName o = (AVMAspectName)obj; + return fNode.equals(o.getNode()) && fName.equals(o.getName()); + } + + @Override + public int hashCode() + { + return fNode.hashCode() + fName.hashCode(); + } +} diff --git a/source/java/org/alfresco/repo/avm/AVMContext.java b/source/java/org/alfresco/repo/avm/AVMContext.java index 1af884aa50..f1307bdfb1 100644 --- a/source/java/org/alfresco/repo/avm/AVMContext.java +++ b/source/java/org/alfresco/repo/avm/AVMContext.java @@ -4,6 +4,7 @@ package org.alfresco.repo.avm; import org.alfresco.repo.content.ContentStore; +import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.MimetypeService; import org.springframework.context.ApplicationContext; @@ -81,6 +82,11 @@ public class AVMContext implements ApplicationContextAware */ public AVMStorePropertyDAO fAVMStorePropertyDAO; + /** + * The AVMAspectNameDAO + */ + public AVMAspectNameDAO fAVMAspectNameDAO; + /** * The ContentService. */ @@ -101,6 +107,11 @@ public class AVMContext implements ApplicationContextAware */ private ContentStore fContentStore; + /** + * The DictionaryService + */ + private DictionaryService fDictionaryService; + /** * The application context. */ @@ -193,6 +204,11 @@ public class AVMContext implements ApplicationContextAware fAVMStorePropertyDAO = avmStorePropertyDAO; } + public void setAvmAspectNameDAO(AVMAspectNameDAO avmAspectNameDAO) + { + fAVMAspectNameDAO = avmAspectNameDAO; + } + /** * Get the Content Service. * @return The ContentService object. @@ -244,4 +260,18 @@ public class AVMContext implements ApplicationContextAware } return fContentStore; } + + /** + * Get the DictionaryService. + * @return The dictionary service. + */ + public DictionaryService getDictionaryService() + { + if (fDictionaryService == null) + { + // TODO Should this be DictionaryService or dictionaryService. + fDictionaryService = (DictionaryService)fAppContext.getBean("dictionaryService"); + } + return fDictionaryService; + } } diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index 3f1cd2597d..bb6bcb4820 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -37,7 +37,7 @@ import org.alfresco.service.namespace.QName; * the implementors of the operations specified by AVMService. * @author britt */ -class AVMRepository +public class AVMRepository { /** * The single instance of AVMRepository. @@ -67,7 +67,7 @@ class AVMRepository /** * Create a new one. */ - AVMRepository() + public AVMRepository() { fLookupCount = new ThreadLocal(); fgInstance = this; @@ -100,7 +100,7 @@ class AVMRepository fLayerIssuer = layerIssuer; } - void init() + public void init() { File storageDir = new File(fStorage); storageDir.mkdirs(); @@ -1134,4 +1134,59 @@ class AVMRepository { return fgInstance; } + + /** + * Add an aspect to an AVM Node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void addAspect(String path, QName aspectName) + { + fLookupCount.set(1); + String [] pathParts = SplitPath(path); + AVMStore store = getAVMStoreByName(pathParts[0]); + store.addAspect(pathParts[1], aspectName); + } + + /** + * Get all the aspects on an AVM node. + * @param version The version to look under. + * @param path The path to the node. + * @return A List of the QNames of the Aspects. + */ + public List getAspects(int version, String path) + { + fLookupCount.set(1); + String [] pathParts = SplitPath(path); + AVMStore store = getAVMStoreByName(pathParts[0]); + return store.getAspects(version, pathParts[1]); + } + + /** + * Remove an aspect and all associated properties from a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void removeAspect(String path, QName aspectName) + { + fLookupCount.set(1); + String [] pathParts = SplitPath(path); + AVMStore store = getAVMStoreByName(pathParts[0]); + store.removeAspect(pathParts[1], aspectName); + } + + /** + * Does a node have a particular aspect. + * @param version The version to look under. + * @param path The path to the node. + * @param aspectName The name of the aspect. + * @return Whether the node has the aspect. + */ + public boolean hasAspect(int version, String path, QName aspectName) + { + fLookupCount.set(1); + String [] pathParts = SplitPath(path); + AVMStore store = getAVMStoreByName(pathParts[0]); + return store.hasAspect(version, pathParts[1], aspectName); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMService.java b/source/java/org/alfresco/repo/avm/AVMService.java index 3a894f1e4c..c6bcf1ab0a 100644 --- a/source/java/org/alfresco/repo/avm/AVMService.java +++ b/source/java/org/alfresco/repo/avm/AVMService.java @@ -575,4 +575,37 @@ public interface AVMService * to a file. */ public void setContentData(String path, ContentData data); + + /** + * Add an aspect to an AVM node. + * @param path The path to the node. + * @param aspectName The QName of the aspect. + * @throws AVMNotFoundException If path does not exist. + * @throws AVMExistsException If the aspect already exists. + */ + public void addAspect(String path, QName aspectName); + + /** + * Get all the aspects on an AVM node. + * @param version The version to look under. + * @param path The path to the node. + * @return A List of the QNames of the aspects. + */ + public List getAspects(int version, String path); + + /** + * Remove an aspect and its properties from a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void removeAspect(String path, QName aspectName); + + /** + * Does a node have a particular aspect. + * @param version The version to look under. + * @param path The path to the node. + * @param aspectName The aspect name to check. + * @return Whether the given node has the given aspect. + */ + public boolean hasAspect(int version, String path, QName aspectName); } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index b78de31a01..928e3d7eb2 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -39,7 +39,7 @@ import org.apache.log4j.Logger; * Implements the AVMService. Stub. * @author britt */ -class AVMServiceImpl implements AVMService +public class AVMServiceImpl implements AVMService { private static Logger fgLogger = Logger.getLogger(AVMServiceImpl.class); @@ -66,7 +66,7 @@ class AVMServiceImpl implements AVMService /** * Basic constructor for the service. */ - AVMServiceImpl() + public AVMServiceImpl() { } @@ -83,7 +83,7 @@ class AVMServiceImpl implements AVMService * Final initialization of the service. Must be called only on a * fully initialized instance. */ - void init() + public void init() { if (fInitialize) { @@ -1399,4 +1399,103 @@ class AVMServiceImpl implements AVMService TxnCallback doit = new TxnCallback(); fTransaction.perform(doit, true); } + + /** + * Add an aspect to an AVM node. + * @param path The path to the node. + * @param aspectName The QName of the aspect. + * @throws AVMNotFoundException If path does not exist. + * @throws AVMExistsException If the aspect already exists. + */ + public void addAspect(final String path, final QName aspectName) + { + if (path == null || aspectName == null) + { + throw new AVMBadArgumentException("Illegal Null Argument."); + } + class TxnCallback implements RetryingTransactionCallback + { + public void perform() + { + fAVMRepository.addAspect(path, aspectName); + } + } + TxnCallback doit = new TxnCallback(); + fTransaction.perform(doit, true); + } + + /** + * Get all the aspects on an AVM node. + * @param version The version to look under. + * @param path The path to the node. + * @return A List of the QNames of the aspects. + */ + public List getAspects(final int version, final String path) + { + if (path == null) + { + throw new AVMBadArgumentException("Null path."); + } + class TxnCallback implements RetryingTransactionCallback + { + public List aspects; + + public void perform() + { + aspects = fAVMRepository.getAspects(version, path); + } + } + TxnCallback doit = new TxnCallback(); + fTransaction.perform(doit, false); + return doit.aspects; + } + + /** + * Remove an aspect and its properties from a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void removeAspect(final String path, final QName aspectName) + { + if (path == null || aspectName == null) + { + throw new AVMBadArgumentException("Null path."); + } + class TxnCallback implements RetryingTransactionCallback + { + public void perform() + { + fAVMRepository.removeAspect(path, aspectName); + } + } + TxnCallback doit = new TxnCallback(); + fTransaction.perform(doit, true); + } + + /** + * Does a node have a particular aspect. + * @param version The version to look under. + * @param path The path to the node. + * @param aspectName The aspect name to check. + * @return Whether the given node has the given aspect. + */ + public boolean hasAspect(final int version, final String path, final QName aspectName) + { + if (path == null || aspectName == null) + { + throw new AVMBadArgumentException("Illegal Null Argument."); + } + class TxnCallback implements RetryingTransactionCallback + { + public boolean has; + + public void perform() + { + has = fAVMRepository.hasAspect(version, path, aspectName); + } + } + TxnCallback doit = new TxnCallback(); + fTransaction.perform(doit, false); + return doit.has; + } } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index 256b88b897..0d8b9b2076 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.alfresco.model.ContentModel; import org.alfresco.repo.avm.util.BulkLoader; import org.alfresco.repo.domain.PropertyValue; import org.alfresco.service.namespace.QName; @@ -2196,4 +2197,30 @@ public class AVMServiceTest extends AVMServiceTestBase fail(); } } + + /** + * Test Aspect Name storage. + */ + public void testAspectNames() + { + try + { + setupBasicTree(); + fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_TITLED); + fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE); + fService.createSnapshot("main"); + List names = fService.getAspects(-1, "main:/a/b/c/foo"); + assertEquals(2, names.size()); + assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); + assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUTHOR)); + fService.removeAspect("main:/a/b/c/foo", ContentModel.ASPECT_TITLED); + fService.createSnapshot("main"); + assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } } diff --git a/source/java/org/alfresco/repo/avm/AVMStore.java b/source/java/org/alfresco/repo/avm/AVMStore.java index 748cad54f0..67c34e7b59 100644 --- a/source/java/org/alfresco/repo/avm/AVMStore.java +++ b/source/java/org/alfresco/repo/avm/AVMStore.java @@ -366,4 +366,35 @@ interface AVMStore * @param data The ContentData to set. */ public void setContentData(String path, ContentData data); + + /** + * Add an aspect to a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void addAspect(String path, QName aspectName); + + /** + * Get all aspects on a given node. + * @param version The version to look under. + * @param path The path to the node. + * @return A List of the QNames of the aspects. + */ + public List getAspects(int version, String path); + + /** + * Remove an aspect and all its properties from a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void removeAspect(String path, QName aspectName); + + /** + * Does a given node have a given aspect. + * @param version The version to look under. + * @param path The path to the node. + * @param aspectName The name of the aspect. + * @return Whether the node has the aspect. + */ + public boolean hasAspect(int version, String path, QName aspectName); } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java index 5a6f698875..3998d75648 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java @@ -31,7 +31,9 @@ import java.util.TreeMap; import org.alfresco.model.ContentModel; import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; @@ -1031,4 +1033,77 @@ class AVMStoreImpl implements AVMStore, Serializable } ((FileNode)node).setContentData(data); } + + /** + * Add an aspect to a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void addAspect(String path, QName aspectName) + { + Lookup lPath = lookup(-1, path, true); + AVMNode node = lPath.getCurrentNode(); + if (AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName)) + { + throw new AVMExistsException("Aspect exists."); + } + AVMAspectName newName = + new AVMAspectNameImpl(); + newName.setNode(node); + newName.setName(aspectName); + AVMContext.fgInstance.fAVMAspectNameDAO.save(newName); + } + + /** + * Get all aspects on a given node. + * @param version The version to look under. + * @param path The path to the node. + * @return A List of the QNames of the aspects. + */ + public List getAspects(int version, String path) + { + Lookup lPath = lookup(version, path, false); + AVMNode node = lPath.getCurrentNode(); + List names = + AVMContext.fgInstance.fAVMAspectNameDAO.get(node); + ArrayList result = new ArrayList(); + for (AVMAspectName name : names) + { + result.add(name.getName()); + } + return result; + } + + /** + * Remove an aspect and all its properties from a node. + * @param path The path to the node. + * @param aspectName The name of the aspect. + */ + public void removeAspect(String path, QName aspectName) + { + Lookup lPath = lookup(-1, path, true); + AVMNode node = lPath.getCurrentNode(); + AVMContext.fgInstance.fAVMAspectNameDAO.delete(node, aspectName); + AspectDefinition def = AVMContext.fgInstance.getDictionaryService().getAspect(aspectName); + Map properties = + def.getProperties(); + for (QName name : properties.keySet()) + { + AVMContext.fgInstance.fAVMNodePropertyDAO.delete(node, name); + } + } + + /** + * Does a given node have a given aspect. + * @param version The version to look under. + * @param path The path to the node. + * @param aspectName The name of the aspect. + * @return Whether the node has the aspect. + */ + public boolean hasAspect(int version, String path, QName aspectName) + { + Lookup lPath = lookup(version, path, false); + AVMNode node = lPath.getCurrentNode(); + return AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName); + } } diff --git a/source/java/org/alfresco/repo/avm/HibernateRetryingTransactionHelper.java b/source/java/org/alfresco/repo/avm/HibernateRetryingTransactionHelper.java index fd1c60db9a..ff09b139ba 100644 --- a/source/java/org/alfresco/repo/avm/HibernateRetryingTransactionHelper.java +++ b/source/java/org/alfresco/repo/avm/HibernateRetryingTransactionHelper.java @@ -32,7 +32,7 @@ import org.springframework.transaction.TransactionStatus; * Helper for DAOs. * @author britt */ -class HibernateRetryingTransactionHelper extends HibernateTemplate implements RetryingTransactionHelper +public class HibernateRetryingTransactionHelper extends HibernateTemplate implements RetryingTransactionHelper { private static Logger fgLogger = Logger.getLogger(HibernateRetryingTransactionHelper.class); @@ -60,7 +60,7 @@ class HibernateRetryingTransactionHelper extends HibernateTemplate implements Re * Make one up. * @param sessionFactory The SessionFactory. */ - HibernateRetryingTransactionHelper() + public HibernateRetryingTransactionHelper() { fRandom = new Random(); } diff --git a/source/java/org/alfresco/repo/avm/Issuer.java b/source/java/org/alfresco/repo/avm/Issuer.java index d207e2a744..289bb32d25 100644 --- a/source/java/org/alfresco/repo/avm/Issuer.java +++ b/source/java/org/alfresco/repo/avm/Issuer.java @@ -21,7 +21,7 @@ package org.alfresco.repo.avm; * This is a helper class that knows how to issue identifiers. * @author britt */ -class Issuer +public class Issuer { /** * The next number to issue. @@ -41,7 +41,7 @@ class Issuer /** * Default constructor. */ - Issuer() + public Issuer() { } @@ -66,7 +66,7 @@ class Issuer /** * After the database is up, get our value. */ - void init() + public void init() { class TxnCallback implements RetryingTransactionCallback { diff --git a/source/java/org/alfresco/repo/avm/OrphanReaper.java b/source/java/org/alfresco/repo/avm/OrphanReaper.java index f727c62ec8..e3ddde73dc 100644 --- a/source/java/org/alfresco/repo/avm/OrphanReaper.java +++ b/source/java/org/alfresco/repo/avm/OrphanReaper.java @@ -28,7 +28,7 @@ import org.apache.commons.logging.LogFactory; * in the AVM repository. These orphans arise from purge operations. * @author britt */ -class OrphanReaper implements Runnable +public class OrphanReaper implements Runnable { private Log fgLogger = LogFactory.getLog(OrphanReaper.class); /** @@ -80,7 +80,7 @@ class OrphanReaper implements Runnable /** * Create one with default parameters. */ - OrphanReaper() + public OrphanReaper() { fInactiveBaseSleep = 30000; fActiveBaseSleep = 1000; @@ -140,7 +140,7 @@ class OrphanReaper implements Runnable /** * Start things up after configuration is complete. */ - void init() + public void init() { fThread = new Thread(this); fThread.start(); @@ -150,7 +150,7 @@ class OrphanReaper implements Runnable * Shutdown the reaper. This needs to be called when * the application shuts down. */ - void shutDown() + public void shutDown() { synchronized (this) { @@ -282,6 +282,8 @@ class OrphanReaper implements Runnable } // Get rid of all properties belonging to this node. AVMContext.fgInstance.fAVMNodePropertyDAO.deleteAll(node); + // Get rid of all aspects belonging to this node. + AVMContext.fgInstance.fAVMAspectNameDAO.delete(node); // Extra work for directories. if (node.getType() == AVMNodeType.PLAIN_DIRECTORY || node.getType() == AVMNodeType.LAYERED_DIRECTORY) diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml index a6a87e914e..f2fda110b8 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml +++ b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml @@ -102,7 +102,6 @@ - @@ -199,7 +198,14 @@ - + + + + + + + +