diff --git a/config/alfresco/content-services-context.xml b/config/alfresco/content-services-context.xml index 18a564d227..64aa5817a6 100644 --- a/config/alfresco/content-services-context.xml +++ b/config/alfresco/content-services-context.xml @@ -119,48 +119,6 @@ - - - - - - - - - - - - - - - - default - - - - - - - - - - - - defaultStoreSelector - - - - - - - - - diff --git a/source/java/org/alfresco/repo/content/ContentTestSuite.java b/source/java/org/alfresco/repo/content/ContentTestSuite.java index 5367cd1a41..6ba356afbb 100644 --- a/source/java/org/alfresco/repo/content/ContentTestSuite.java +++ b/source/java/org/alfresco/repo/content/ContentTestSuite.java @@ -24,12 +24,16 @@ */ package org.alfresco.repo.content; +import junit.framework.Test; +import junit.framework.TestSuite; + import org.alfresco.repo.content.cleanup.ContentStoreCleanerTest; import org.alfresco.repo.content.encoding.CharsetFinderTest; import org.alfresco.repo.content.filestore.FileContentStoreTest; import org.alfresco.repo.content.filestore.NoRandomAccessFileContentStoreTest; import org.alfresco.repo.content.filestore.ReadOnlyFileContentStoreTest; import org.alfresco.repo.content.metadata.HtmlMetadataExtracterTest; +import org.alfresco.repo.content.metadata.MailMetadataExtracterTest; import org.alfresco.repo.content.metadata.MappingMetadataExtracterTest; import org.alfresco.repo.content.metadata.OfficeMetadataExtracterTest; import org.alfresco.repo.content.metadata.OpenDocumentMetadataExtracterTest; @@ -37,13 +41,12 @@ import org.alfresco.repo.content.metadata.OpenOfficeMetadataExtracterTest; import org.alfresco.repo.content.metadata.PdfBoxMetadataExtracterTest; import org.alfresco.repo.content.replication.ContentStoreReplicatorTest; import org.alfresco.repo.content.replication.ReplicatingContentStoreTest; -import org.alfresco.repo.content.routing.StoreSelectorAspectContentStoreTest; import org.alfresco.repo.content.transform.BinaryPassThroughContentTransformerTest; import org.alfresco.repo.content.transform.ComplexContentTransformerTest; import org.alfresco.repo.content.transform.ContentTransformerRegistryTest; import org.alfresco.repo.content.transform.HtmlParserContentTransformerTest; -import org.alfresco.repo.content.transform.OpenOfficeContentTransformerTest; import org.alfresco.repo.content.transform.MailContentTransformerTest; +import org.alfresco.repo.content.transform.OpenOfficeContentTransformerTest; import org.alfresco.repo.content.transform.PdfBoxContentTransformerTest; import org.alfresco.repo.content.transform.PoiHssfContentTransformerTest; import org.alfresco.repo.content.transform.RuntimeExecutableContentTransformerTest; @@ -51,12 +54,6 @@ import org.alfresco.repo.content.transform.StringExtractingContentTransformerTes import org.alfresco.repo.content.transform.TextMiningContentTransformerTest; import org.alfresco.repo.content.transform.TextToPdfContentTransformerTest; -// TODO: This class is currently missing -// import org.alfresco.repo.content.transform.TextToPdfContentTransformerTest; - -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Suite for content-related tests. * @@ -64,6 +61,7 @@ import junit.framework.TestSuite; */ public class ContentTestSuite extends TestSuite { + @SuppressWarnings("unchecked") public static Test suite() { TestSuite suite = new TestSuite(); @@ -75,6 +73,7 @@ public class ContentTestSuite extends TestSuite suite.addTestSuite(ReadOnlyFileContentStoreTest.class); suite.addTestSuite(MappingMetadataExtracterTest.class); suite.addTestSuite(HtmlMetadataExtracterTest.class); + suite.addTestSuite(MailMetadataExtracterTest.class); suite.addTestSuite(OfficeMetadataExtracterTest.class); suite.addTestSuite(OpenDocumentMetadataExtracterTest.class); suite.addTestSuite(OpenOfficeMetadataExtracterTest.class); @@ -97,7 +96,17 @@ public class ContentTestSuite extends TestSuite suite.addTestSuite(MimetypeMapTest.class); suite.addTestSuite(RoutingContentServiceTest.class); suite.addTestSuite(RoutingContentStoreTest.class); - suite.addTestSuite(StoreSelectorAspectContentStoreTest.class); + + try + { + Class clazz = Class.forName("org.alfresco.repo.content.routing.StoreSelectorAspectContentStoreTest"); + suite.addTestSuite(clazz); + } + catch (Throwable e) + { + // Ignore + } + return suite; } diff --git a/source/java/org/alfresco/repo/content/routing/StoreSelectorAspectContentStore.java b/source/java/org/alfresco/repo/content/routing/StoreSelectorAspectContentStore.java deleted file mode 100644 index f502cca249..0000000000 --- a/source/java/org/alfresco/repo/content/routing/StoreSelectorAspectContentStore.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2005-2009 Alfresco Software Limited. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing" - */ -package org.alfresco.repo.content.routing; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; -import org.alfresco.repo.content.AbstractRoutingContentStore; -import org.alfresco.repo.content.ContentContext; -import org.alfresco.repo.content.ContentStore; -import org.alfresco.repo.content.NodeContentContext; -import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint; -import org.alfresco.repo.node.NodeServicePolicies; -import org.alfresco.repo.policy.JavaBehaviour; -import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.TransactionListenerAdapter; -import org.alfresco.repo.transaction.TransactionalResourceHelper; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; -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; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.EqualsHelper; -import org.alfresco.util.PropertyCheck; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; - -/** - * Implementation of a {@link AbstractRoutingContentStore routing content store} that diverts - * and moves content based on the cm:storeSelector aspect. - * - * @author Derek Hulley - * @since 3.2 - */ -public class StoreSelectorAspectContentStore - extends AbstractRoutingContentStore - implements InitializingBean, - NodeServicePolicies.OnUpdatePropertiesPolicy, - NodeServicePolicies.OnAddAspectPolicy -{ - private static final String ERR_INVALID_DEFAULT_STORE = "content.routing.err.invalid_default_store"; - private static final String KEY_CONTENT_MOVE_DETAILS = "StoreSelectorAspectContentStore.ContentMoveDetails"; - - private static Log logger = LogFactory.getLog(StoreSelectorAspectContentStore.class); - - private ContentMoveTransactionListener transactionListener; - private NodeService nodeService; - private PolicyComponent policyComponent; - private DictionaryService dictionaryService; - private Map storesByName; - private List stores; - private String defaultStoreName; - - public StoreSelectorAspectContentStore() - { - } - - /** - * @param nodeService the service to access the properties - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param policyComponent register to receive updates to the cm:storeSelector aspect - */ - public void setPolicyComponent(PolicyComponent policyComponent) - { - this.policyComponent = policyComponent; - } - - /** - * @param dictionaryService used to check for content property types - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * @param storesByName a map of content stores keyed by a common name - */ - public void setStoresByName(Map storesByName) - { - this.storesByName = storesByName; - this.stores = new ArrayList(storesByName.values()); - } - - /** - * @return Returns the stores keyed by store name - */ - public Map getStoresByName() - { - return storesByName; - } - - /** - * Set the name of the store to select if the content being created is not associated - * with any specific value in the cm:storeSelector or if the aspect is not - * present. - * - * @param defaultStoreName the name of one of the stores - * - * @see #setStoresByName(Map) - */ - public void setDefaultStoreName(String defaultStoreName) - { - this.defaultStoreName = defaultStoreName; - } - - /** - * Checks that the required properties are present - */ - public void afterPropertiesSet() throws Exception - { - PropertyCheck.mandatory(this, "nodeService", nodeService); - PropertyCheck.mandatory(this, "storesByName", storesByName); - PropertyCheck.mandatory(this, "defaultStoreName", defaultStoreName); - // Check that the default store name is valid - if (storesByName.get(defaultStoreName) == null) - { - AlfrescoRuntimeException.create(ERR_INVALID_DEFAULT_STORE, defaultStoreName, storesByName.keySet()); - } - // Register to receive change updates relevant to the aspect - // Register to receive property change updates - policyComponent.bindClassBehaviour( - QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), - ContentModel.ASPECT_STORE_SELECTOR, - new JavaBehaviour(this, "onAddAspect")); - policyComponent.bindClassBehaviour( - QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), - ContentModel.ASPECT_STORE_SELECTOR, - new JavaBehaviour(this, "onUpdateProperties")); - - // Construct the transaction listener that will be bound in - transactionListener = new ContentMoveTransactionListener(); - } - - @Override - protected List getAllStores() - { - return stores; - } - - @Override - protected ContentStore selectWriteStore(ContentContext ctx) - { - ContentStore store; - String storeNameProp; - if (!(ctx instanceof NodeContentContext)) - { - storeNameProp = ""; - store = storesByName.get(defaultStoreName); - } - else - { - NodeRef nodeRef = ((NodeContentContext) ctx).getNodeRef(); // Never null - storeNameProp = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_STORE_NAME); - if (storeNameProp == null) - { - storeNameProp = ""; - store = storesByName.get(defaultStoreName); - } - else - { - store = storesByName.get(storeNameProp); - if (store == null) - { - // There was no store with that name - storeNameProp = ""; - store = storesByName.get(defaultStoreName); - } - } - } - // Done - if (logger.isDebugEnabled()) - { - logger.debug( - "ContentStore selected: \n" + - " Node context: " + ctx + "\n" + - " Store name: " + storeNameProp + "\n" + - " Store Selected: " + store); - } - return store; - } - - /** - * Helper method to select a store, taking into account null and invalid values. - */ - private ContentStore selectStore(String storeName) - { - if (storeName == null || !storesByName.containsKey(storeName)) - { - storeName = defaultStoreName; - } - return storesByName.get(storeName); - } - - /** - * Class to carry info into the post-transaction phase - */ - private static class ContentMoveDetail - { - private final ContentStore oldStore; - private final ContentStore newStore; - private final String contentUrl; - private ContentMoveDetail(ContentStore oldStore, ContentStore newStore, String contentUrl) - { - this.oldStore = oldStore; - this.newStore = newStore; - this.contentUrl = contentUrl; - } - } - /** - * Ensures that the content is copied between stores only if the transaction is successful. - * - * @author Derek Hulley - * @since 3.2 - */ - private class ContentMoveTransactionListener extends TransactionListenerAdapter - { - @Override - public void afterCommit() - { - List contentMoveDetails = TransactionalResourceHelper.getList(KEY_CONTENT_MOVE_DETAILS); - for (ContentMoveDetail contentMoveDetail : contentMoveDetails) - { - moveContent(contentMoveDetail.oldStore, contentMoveDetail.newStore, contentMoveDetail.contentUrl); - } - } - } - - /** - * Move content from the old store to the new store - */ - private void scheduleContentMove(ContentStore oldStore, ContentStore newStore, String contentUrl) - { - // Add the details of the copy to the transaction - List contentMoveDetails = TransactionalResourceHelper.getList(KEY_CONTENT_MOVE_DETAILS); - ContentMoveDetail detail = new ContentMoveDetail(oldStore, newStore, contentUrl); - contentMoveDetails.add(detail); - // Bind the listener to the transaction - AlfrescoTransactionSupport.bindListener(transactionListener); - } - - private void moveContent(ContentStore oldStore, ContentStore newStore, String contentUrl) - { - ContentReader reader = oldStore.getReader(contentUrl); - if (!reader.exists()) - { - // Nothing to copy - return; - } - ContentContext ctx = new ContentContext(null, contentUrl); - ContentWriter writer = newStore.getWriter(ctx); - // Copy it - writer.putContent(reader); - // Remove the old content - oldStore.delete(contentUrl); - // Done - if (logger.isDebugEnabled()) - { - logger.debug( - "Store selector moved content: \n" + - " Old store: " + oldStore + "\n" + - " New Store: " + newStore + "\n" + - " Content: " + contentUrl); - } - } - - /** - * Ensures that all content is moved to the correct store. - *

- * Spoofs a call to {@link #onUpdateProperties(NodeRef, Map, Map)}. - */ - public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName) - { - Map after = nodeService.getProperties(nodeRef); - // Pass the call through. It is only interested in a single property. - onUpdateProperties( - nodeRef, - Collections.emptyMap(), - after); - } - - /** - * Keeps the content in the correct store based on changes to the cm:storeName property - */ - public void onUpdateProperties( - NodeRef nodeRef, - Map before, - Map after) - { - String storeNameBefore = (String) before.get(ContentModel.PROP_STORE_NAME); - String storeNameAfter = (String) after.get(ContentModel.PROP_STORE_NAME); - if (EqualsHelper.nullSafeEquals(storeNameBefore, storeNameAfter)) - { - // We're not interested in the change - return; - } - // Find out which store to move the content to - ContentStore oldStore = selectStore(storeNameBefore); - ContentStore newStore = selectStore(storeNameAfter); - // Don't do anything if the store did not change - if (oldStore == newStore) - { - return; - } - // Find all content properties and move the content - List contentUrls = new ArrayList(1); - for (QName propertyQName : after.keySet()) - { - PropertyDefinition propDef = dictionaryService.getProperty(propertyQName); - if (propDef == null) - { - // Ignore - continue; - } - if (!propDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)) - { - // It is not content - continue; - } - // The property value - Serializable propertyValue = after.get(propertyQName); - if (propertyValue == null) - { - // Ignore missing values - } - // Get the content URLs, being sensitive to collections - if (propDef.isMultiValued()) - { - Collection contentValues = - DefaultTypeConverter.INSTANCE.getCollection(ContentData.class, propertyValue); - if (contentValues.size() == 0) - { - // No content - continue; - } - for (ContentData contentValue : contentValues) - { - String contentUrl = contentValue.getContentUrl(); - if (contentUrl != null) - { - contentUrls.add(contentUrl); - } - } - } - else - { - ContentData contentValue = DefaultTypeConverter.INSTANCE.convert(ContentData.class, propertyValue); - String contentUrl = contentValue.getContentUrl(); - if (contentUrl != null) - { - contentUrls.add(contentUrl); - } - } - } - // Move content from the old store to the new store - for (String contentUrl : contentUrls) - { - scheduleContentMove(oldStore, newStore, contentUrl); - } - } - - /** - * A constraint that acts as a list of values, where the values are the store names - * injected into the {@link StoreSelectorAspectContentStore}. - *

- * If the store is not active or is incorrectly configured, then this constraint - * will contain a single value of 'Default'. Any attempt to set another value will - * lead to constraint failures. - * - * @author Derek Hulley - * @since 3.2 - */ - public static class StoreSelectorConstraint extends ListOfValuesConstraint - { - private StoreSelectorAspectContentStore store; - /** - * Required default constructor - */ - public StoreSelectorConstraint() - { - } - - public void setStore(StoreSelectorAspectContentStore store) - { - this.store = store; - } - - @Override - public void initialize() - { - checkPropertyNotNull("store", store); - List allowedValues = new ArrayList(store.getStoresByName().keySet()); - super.setAllowedValues(allowedValues); - // Now initialize as we have set the LOV - super.initialize(); - } - } -} diff --git a/source/java/org/alfresco/repo/content/routing/StoreSelectorAspectContentStoreTest.java b/source/java/org/alfresco/repo/content/routing/StoreSelectorAspectContentStoreTest.java deleted file mode 100644 index 360f14bce8..0000000000 --- a/source/java/org/alfresco/repo/content/routing/StoreSelectorAspectContentStoreTest.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2005-2009 Alfresco Software Limited. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing" - */ -package org.alfresco.repo.content.routing; - -import java.util.HashMap; -import java.util.Map; - -import junit.framework.TestCase; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.content.ContentServiceImpl; -import org.alfresco.repo.content.ContentStore; -import org.alfresco.repo.content.filestore.FileContentStore; -import org.alfresco.repo.content.routing.StoreSelectorAspectContentStore.StoreSelectorConstraint; -import org.alfresco.repo.node.integrity.IntegrityException; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.ApplicationContextHelper; -import org.alfresco.util.TempFileProvider; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * Tests {@link StoreSelectorAspectContentStore} - * - * @author Derek Hulley - * @since 3.2 - */ -public class StoreSelectorAspectContentStoreTest extends TestCase -{ - private static final String STORE_ONE = "Store1"; - private static final String STORE_TWO = "Store2"; - private static final String STORE_THREE = "Store3"; - - private static ConfigurableApplicationContext ctx = - (ConfigurableApplicationContext) ApplicationContextHelper.getApplicationContext(); - - private TransactionService transactionService; - private NodeService nodeService; - private FileFolderService fileFolderService; - - private Map storesByName; - private FileContentStore fileStore1; - private FileContentStore fileStore2; - private FileContentStore fileStore3; - private StoreSelectorAspectContentStore store; - private NodeRef contentNodeRef; - - @Override - public void setUp() throws Exception - { - super.setUp(); - - ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); - transactionService = serviceRegistry.getTransactionService(); - nodeService = serviceRegistry.getNodeService(); - fileFolderService = serviceRegistry.getFileFolderService(); - - AuthenticationUtil.pushAuthentication(); - AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); - - fileStore1 = new FileContentStore( - ctx, - TempFileProvider.getSystemTempDir() + "/fileStore1"); - fileStore2 = new FileContentStore( - ctx, - TempFileProvider.getSystemTempDir() + "/fileStore2"); - fileStore3 = new FileContentStore( - ctx, - TempFileProvider.getSystemTempDir() + "/fileStore3"); - - storesByName = new HashMap(7); - storesByName.put(STORE_ONE, fileStore1); - storesByName.put(STORE_TWO, fileStore2); - storesByName.put(STORE_THREE, fileStore3); - - store = (StoreSelectorAspectContentStore) ctx.getBean("storeSelectorContentStore"); - store.setStoresByName(storesByName); - store.setDefaultStoreName(STORE_ONE); - store.afterPropertiesSet(); - - // Force the constraint to re-initialize - StoreSelectorConstraint storeConstraint = (StoreSelectorConstraint) ctx.getBean("storeSelectorContentStore.constraint"); - storeConstraint.initialize(); - - // Change the content service's default store - ContentServiceImpl contentService = (ContentServiceImpl) ctx.getBean("contentService"); - contentService.setStore(store); - - // Create a content node - RetryingTransactionCallback makeNodeCallback = new RetryingTransactionCallback() - { - public NodeRef execute() throws Throwable - { - StoreRef storeRef = nodeService.createStore( - StoreRef.PROTOCOL_TEST, - getName() + "_" + System.currentTimeMillis()); - NodeRef rootNodeRef = nodeService.getRootNode(storeRef); - // Create a folder - NodeRef folderNodeRef = nodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - ContentModel.ASSOC_CHILDREN, - ContentModel.TYPE_FOLDER).getChildRef(); - // Add some content - return fileFolderService.create( - folderNodeRef, - getName() + ".txt", - ContentModel.TYPE_CONTENT).getNodeRef(); - } - }; - contentNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(makeNodeCallback); - } - - @Override - public void tearDown() throws Exception - { - AuthenticationUtil.popAuthentication(); - } - - /** - * Writes to the file - * @return Returns the new content URL - */ - private String writeToFile() - { - RetryingTransactionCallback writeContentCallback = new RetryingTransactionCallback() - { - public String execute() throws Throwable - { - ContentWriter writer = fileFolderService.getWriter(contentNodeRef); - writer.putContent("Some test content"); - return writer.getContentUrl(); - } - }; - return transactionService.getRetryingTransactionHelper().doInTransaction(writeContentCallback); - } - - /** - * Set the name of the store that must hold the content - * @param storeName the name of the store - */ - private void setStoreNameProperty(String storeName) - { - // The nodeService is transactional - nodeService.setProperty(contentNodeRef, ContentModel.PROP_STORE_NAME, storeName); - } - - /** - * Ensure that a null cm:storeName property is acceptable. - */ - public void testNullStoreNameProperty() throws Exception - { - try - { - setStoreNameProperty(null); - } - catch (Throwable e) - { - throw new Exception("Failed to set store name property to null", e); - } - } - - /** - * Ensure that an invalid cm:storeName property is kicked out. - */ - public void testInvalidStoreNameProperty() throws Exception - { - RetryingTransactionCallback setInvalidStoreNameCallback = new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - setStoreNameProperty("bogus"); - return null; - } - }; - try - { - transactionService.getRetryingTransactionHelper().doInTransaction(setInvalidStoreNameCallback, false, true); - setStoreNameProperty("bogus"); - fail("Expected integrity error for bogus store name"); - } - catch (IntegrityException e) - { - // Expected - } - } - - /** - * Check that the default store is used if the property is not set - */ - public void testWriteWithoutAspect() throws Exception - { - String contentUrl = writeToFile(); - // The content should be in the default store - assertTrue("Default store does not have content", fileStore1.exists(contentUrl)); - assertFalse("Mapped store should not have content", fileStore2.exists(contentUrl)); - assertFalse("Mapped store should not have content", fileStore3.exists(contentUrl)); - } - - public void testSimpleWritesWithAspect() throws Exception - { - for (Map.Entry entry : storesByName.entrySet()) - { - String storeName = entry.getKey(); - ContentStore store = entry.getValue(); - setStoreNameProperty(storeName); - String contentUrl = writeToFile(); - assertTrue("Content not in store " + storeName, store.exists(contentUrl)); - } - } - - public void testPropertyChange() throws Exception - { - setStoreNameProperty(STORE_ONE); - String contentUrl = writeToFile(); - assertTrue("Store1 should have content", storesByName.get(STORE_ONE).exists(contentUrl)); - assertFalse("Store2 should NOT have content", storesByName.get(STORE_TWO).exists(contentUrl)); - // Change the property - setStoreNameProperty(STORE_TWO); - // It should have moved - assertFalse("Store1 should NOT have content", storesByName.get(STORE_ONE).exists(contentUrl)); - assertTrue("Store2 should have content", storesByName.get(STORE_TWO).exists(contentUrl)); - } - - /** - * Ensure that the store move does not occur if an invalid cm:storeName property us used. - */ - public void testPropertyChangeWithIntegrityError() throws Exception - { -// setStoreNameProperty(STORE_ONE); - String contentUrl = writeToFile(); - assertTrue("Store1 should have content", storesByName.get(STORE_ONE).exists(contentUrl)); - assertFalse("Store2 should NOT have content", storesByName.get(STORE_TWO).exists(contentUrl)); - // Change the property - setStoreNameProperty(STORE_TWO); - // It should have moved - assertFalse("Store1 should NOT have content", storesByName.get(STORE_ONE).exists(contentUrl)); - assertTrue("Store2 should have content", storesByName.get(STORE_TWO).exists(contentUrl)); - RetryingTransactionCallback setInvalidStoreNameCallback = new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - setStoreNameProperty("bogus"); - return null; - } - }; - try - { - transactionService.getRetryingTransactionHelper().doInTransaction(setInvalidStoreNameCallback, false, true); - fail("Expected integrity error for bogus store name"); - } - catch (IntegrityException e) - { - // Expected - } - assertTrue("Store2 should have content", storesByName.get(STORE_TWO).exists(contentUrl)); - } -}