diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index c46ce19805..3e78b23f49 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -642,8 +642,11 @@
${lucene.indexer.mergerMergeBlockingFactor}
-
- ${lucene.indexer.mergerMinMergeDocs}
+
+ ${lucene.indexer.mergerMaxBufferedDocs}
+
+
+ ${lucene.indexer.mergerRamBufferSizeMb}
@@ -652,8 +655,11 @@
${lucene.indexer.writerMergeFactor}
-
- ${lucene.indexer.writerMinMergeDocs}
+
+ ${lucene.indexer.writerMaxBufferedDocs}
+
+
+ ${lucene.indexer.writerRamBufferSizeMb}
@@ -668,6 +674,15 @@
${lucene.indexer.maxDocsForInMemoryMerge}
+
+ ${lucene.indexer.maxRamInMbForInMemoryMerge}
+
+
+ ${lucene.indexer.maxDocsForInMemoryIndex}
+
+
+ ${lucene.indexer.maxRamInMbForInMemoryIndex}
+
${lucene.indexer.termIndexInterval}
diff --git a/config/alfresco/extension/index-recovery-context.xml.sample b/config/alfresco/extension/index-recovery-context.xml.sample
index 76de980518..1a9088af32 100644
--- a/config/alfresco/extension/index-recovery-context.xml.sample
+++ b/config/alfresco/extension/index-recovery-context.xml.sample
@@ -15,6 +15,9 @@
+
+ ${alfresco.cluster.name}
+
diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties
index 9c73533789..2d514a57b0 100644
--- a/config/alfresco/messages/patch-service.properties
+++ b/config/alfresco/messages/patch-service.properties
@@ -286,3 +286,6 @@ patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for node
patch.personUsagePatch.description=Add person 'cm:sizeCurrent' property (if missing).
patch.personUsagePatch.result1=Added 'cm:sizeCurrent' property to {0} people that were missing this property.
patch.personUsagePatch.result2=No people were missing the 'cm:sizeCurrent' property.
+
+patch.redeployNominatedInvitationProcessWithPropsForShare.description=Redeploy nominated invitation workflow
+patch.redeployNominatedInvitationProcessWithPropsForShare.result=Nominated invitation workflow redeployed
\ No newline at end of file
diff --git a/config/alfresco/messages/system-messages.properties b/config/alfresco/messages/system-messages.properties
index a62e694849..6431e00ac9 100644
--- a/config/alfresco/messages/system-messages.properties
+++ b/config/alfresco/messages/system-messages.properties
@@ -24,6 +24,7 @@ system.openoffice.err.connection_remade=The OpenOffice connection was re-establi
system.locks.err.failed_to_acquire_lock=Failed to get lock ''{0}'' using token ''{1}''.
system.locks.err.lock_resource_missing=Failed to manipulate lock ''{0}'' using token ''{1}''. The lock resource no longer exists.
system.locks.err.lock_update_count=Failed to update lock ''{0}'' using token ''{1}''. {2} locks were updated when {3} should have been.
+system.locks.err.failed_to_release_lock=Failed to release lock ''{0}'' using token ''{1}''. The lock has expired and been taken by another process.
system.locks.err.excl_lock_exists=Failed to get lock ''{0}'' using token ''{1}''. An exclusive lock exists: {2}
# Multi-Tenant
diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index de266089f5..7d5fa8ce94 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -1992,4 +1992,21 @@
+
+
+ patch.redeployNominatedInvitationProcessWithPropsForShare
+ patch.redeployNominatedInvitationProcessWithPropsForShare.description
+ 0
+ 4000
+ 4001
+
+
+
+ jbpm
+ alfresco/workflow/invitation-nominated_processdefinition.xml
+ text/xml
+
+
+
+
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index 10c7552b82..bba14e857b 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -176,14 +176,16 @@ lucene.indexer.maxTypeCacheSize=10000
lucene.indexer.mergerMaxMergeDocs=1000000
lucene.indexer.mergerMergeFactor=5
lucene.indexer.mergerMergeBlockingFactor=1
-lucene.indexer.mergerMinMergeDocs=1000
+lucene.indexer.mergerMaxBufferedDocs=-1
+lucene.indexer.mergerRamBufferSizeMb=16
#
# Properties for delta indexes (not this does not affect the final index segment which will be optimised)
# Max merge docs only applies to the index building process not the resulting index which will be optimised.
#
lucene.indexer.writerMaxMergeDocs=1000000
lucene.indexer.writerMergeFactor=5
-lucene.indexer.writerMinMergeDocs=1000
+lucene.indexer.writerMaxBufferedDocs=-1
+lucene.indexer.writerRamBufferSizeMb=16
#
# Target number of indexes and deltas in the overall index and what index size to merge in memory
#
@@ -191,6 +193,9 @@ lucene.indexer.mergerTargetIndexCount=5
lucene.indexer.mergerTargetOverlayCount=5
lucene.indexer.mergerTargetOverlaysBlockingFactor=1
lucene.indexer.maxDocsForInMemoryMerge=10000
+lucene.indexer.maxRamInMbForInMemoryMerge=16
+lucene.indexer.maxDocsForInMemoryIndex=10000
+lucene.indexer.maxRamInMbForInMemoryIndex=16
#
# Other lucene properties
#
diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties
index 1918f9ad55..7be41d462d 100644
--- a/config/alfresco/version.properties
+++ b/config/alfresco/version.properties
@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number
-version.schema=4000
+version.schema=4001
diff --git a/config/alfresco/workflow/invitation-nominated-workflow-model.xml b/config/alfresco/workflow/invitation-nominated-workflow-model.xml
index 2f873422ac..99e1b7a75c 100644
--- a/config/alfresco/workflow/invitation-nominated-workflow-model.xml
+++ b/config/alfresco/workflow/invitation-nominated-workflow-model.xml
@@ -32,6 +32,51 @@
d:text
+
+ d:text
+
+
+
+ bpm:assignee
+ inwf:nominatedInvitationStats
+
+
+
+
+ bpm:workflowTask
+
+ inwf:nominatedInvitationStats
+
+
+
+
+ bpm:workflowTask
+
+ inwf:nominatedInvitationStats
+
+
+
+
+ bpm:workflowTask
+
+ inwf:nominatedInvitationStats
+
+
+
+
+
+
+
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
d:text
@@ -47,35 +92,8 @@
d:text
-
- d:text
-
-
- d:text
-
-
- d:text
-
-
- d:text
-
-
-
- bpm:assignee
-
-
-
-
- bpm:workflowTask
-
-
-
- bpm:workflowTask
-
-
-
- bpm:workflowTask
-
-
-
+
+
+
+
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java b/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java
index b7a3d36056..be436e7776 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java
@@ -1,2951 +1,3101 @@
-/*
- * 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.avm;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.alfresco.model.ContentModel;
-import org.alfresco.repo.avm.util.RemoteBulkLoader;
-import org.alfresco.repo.domain.PropertyValue;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
-import org.alfresco.service.cmr.avm.AVMNotFoundException;
-import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
-import org.alfresco.service.cmr.avm.VersionDescriptor;
-import org.alfresco.service.cmr.avmsync.AVMDifference;
-import org.alfresco.service.cmr.avmsync.AVMSyncException;
-import org.alfresco.service.cmr.avmsync.AVMSyncService;
-import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
-import org.alfresco.service.cmr.remote.AVMRemote;
-import org.alfresco.service.cmr.security.AuthenticationService;
-import org.alfresco.service.namespace.QName;
-import org.alfresco.util.ApplicationContextHelper;
-import org.alfresco.util.NameMatcher;
-import org.springframework.extensions.surf.util.Pair;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.context.ApplicationContext;
-
-/**
- * Local unit tests of AVM (AVMSyncService & AVMService)
- */
-public class AVMServiceLocalTest extends TestCase
-{
- private static Log logger = LogFactory.getLog(AVMServiceLocalTest.class);
-
- /**
- * The AVMRemote - can be local (AVMRemoteLocal) or remote (AVMRemote)
- */
- protected static AVMRemote fService;
-
- /**
- * The AVMSyncService - can be local (AVMSyncService) or remote (AVMSyncServiceRemote)
- */
- protected static AVMSyncService fSyncService;
-
- /**
- * The application context.
- */
- protected static ApplicationContext fContext;
-
- protected static NameMatcher excluder;
-
-
- protected void setUp() throws Exception
- {
- if (fContext == null)
- {
- // local (embedded) test setup
- fContext = ApplicationContextHelper.getApplicationContext();
- fService = (AVMRemote)fContext.getBean("avmRemote");
- fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");
- excluder = (NameMatcher) fContext.getBean("globalPathExcluder");
-
- AuthenticationService authService = (AuthenticationService)fContext.getBean("AuthenticationService");
- authService.authenticate(AuthenticationUtil.getAdminUserName(), "admin".toCharArray());
- }
-
- if (fService.getStore("main") == null)
- {
- fService.createStore("main");
- }
- if (fService.getStore("layer") == null)
- {
- fService.createStore("layer");
- }
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- fService.purgeStore("main");
- fService.purgeStore("layer");
- }
-
- public void testSetup() throws Exception
- {
- setUp();
- }
-
- public void testGetAPath() throws Exception
- {
- try
- {
- fService.createStore("test2932");
- fService.createDirectory("test2932:/", "a");
- fService.createFile("test2932:/a", "foo.txt").close();
- AVMNodeDescriptor found = fService.lookup(-1, "test2932:/a/foo.txt");
- Pair path = fService.getAPath(found);
- assertEquals(path.getSecond(), "test2932:/a/foo.txt");
- explorePaths("test2932:/");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw e;
- }
- finally
- {
- fService.purgeStore("test2932");
- }
- }
-
- /**
- * Do a simple hello world test.
- */
- public void testSimple() throws Throwable
- {
- try
- {
- List stores = fService.getStores();
-
- for (AVMStoreDescriptor store : stores)
- {
- if (logger.isDebugEnabled()) { logger.debug(store); }
- }
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- protected void explorePaths(String path) throws Exception
- {
- Map listing = fService.getDirectoryListing(-1, path);
- for (Map.Entry entry : listing.entrySet())
- {
- Pair childPath = fService.getAPath(entry.getValue());
- if (logger.isDebugEnabled()) { logger.debug(childPath); }
- if (entry.getValue().isDirectory())
- {
- explorePaths(entry.getValue().getPath());
- }
- }
- }
-
- /**
- * Test reading and writing.
- */
- public void testReadWrite() throws Throwable
- {
- try
- {
- // Create a test store.
- fService.createStore("test2933");
- // Create a directory.
- fService.createDirectory("test2933:/", "a");
- // Write out a file.
- OutputStream out =
- fService.createFile("test2933:/a", "foo.txt");
- byte [] buff = "This is a plain old text file.\n".getBytes();
- out.write(buff);
- buff = "It contains text.\n".getBytes();
- out.write(buff);
- out.close();
- // Read back that file.
- InputStream in =
- fService.getFileInputStream(-1, "test2933:/a/foo.txt");
- buff = new byte[1024];
- assertEquals(49, in.read(buff));
- if (logger.isDebugEnabled()) { logger.debug(new String(buff)); }
- assertEquals(-1, in.read(buff));
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("test2933");
- }
- }
-
- /**
- * Another test of reading.
- */
- public void testRead() throws Throwable
- {
- try
- {
- fService.createStore("froo");
- // Create a file.
- byte [] buff = new byte[64];
- for (int i = 0; i < 64; i++)
- {
- buff[i] = (byte)i;
- }
- OutputStream out =
- fService.createFile("froo:/", "foo.dat");
- out.write(buff, 32, 32);
- out.close();
- // Read it back in.
- InputStream in =
- fService.getFileInputStream(-1, "froo:/foo.dat");
- buff = new byte[1024];
- assertEquals(32, in.read(buff));
- in.close();
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("froo");
- }
- }
-
- /**
- * Test a call that should return null;
- */
- public void testErrorState() throws Throwable
- {
- try
- {
- assertNull(fService.lookup(-1, "main:/fizz/fazz"));
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
-
- /**
- * Test update to branch
- */
- public void testSimpleUpdateBR() throws Throwable
- {
- try
- {
- // Create a store.
- fService.createStore("froo");
- // Create a directory.
- fService.createDirectory("froo:/", "a");
- // Create a file.
- fService.createFile("froo:/a", "foo").close();
- // Create another store.
- fService.createStore("broo");
- // Create a branch.
- fService.createBranch(-1, "froo:/a", "broo:/", "a");
- List diffs = fSyncService.compare(-1, "froo:/a", -1, "broo:/a", null);
- assertEquals(0, diffs.size());
- fService.createFile("froo:/a", "bar").close();
- diffs = fSyncService.compare(-1, "froo:/a", -1, "broo:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[froo:/a/bar[-1] > broo:/a/bar[-1]]", diffs.toString());
- // Update.
- fSyncService.update(diffs, null, false, false, false, false, "flippy", "Stuff");
- diffs = fSyncService.compare(-1, "froo:/a", -1, "broo:/a", null);
- assertEquals(0, diffs.size());
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw e;
- }
- finally
- {
- fService.purgeStore("broo");
- fService.purgeStore("froo");
- }
- }
-
- //
- // Test updates to layered directories
- //
-
- public void testSimpleUpdateLD1() throws Throwable
- {
- try
- {
- List diffs = fSyncService.compare(-1, "main:/", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- diffs = fSyncService.compare(-1, "layer:/", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- // create file f-a in main root dir
- fService.createFile("main:/", "f-a").close();
-
- diffs = fSyncService.compare(-1, "layer:/", -1, "main:/", null);
- assertEquals("[layer:/f-a[-1] < main:/f-a[-1]]", diffs.toString());
- assertEquals(1, diffs.size());
-
- fService.createLayeredDirectory("main:/", "layer:/", "layer");
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- // create file f-b in main root dir
- fService.createFile("main:/", "f-b").close();
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- // edit file f-b in layer
- fService.getFileOutputStream("layer:/layer/f-b").close();
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals("[layer:/layer/f-b[-1] > main:/f-b[-1]]", diffs.toString());
- assertEquals(1, diffs.size());
-
- // update main from layer
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- throw t;
- }
- }
-
- public void testSimpleUpdateLD2() throws Throwable
- {
- try
- {
- // create directories base/d-a and file f-aa in main
- fService.createDirectory("main:/", "base");
- fService.createDirectory("main:/base", "d-a");
- fService.createFile("main:/base/d-a", "f-aa").close();
-
- List diffs = fSyncService.compare(-1, "layer" + ":/", -1, "main:/", null);
- assertEquals("[layer:/base[-1] < main:/base[-1]]", diffs.toString());
- assertEquals(1, diffs.size());
-
- fService.createLayeredDirectory("main:/base", "layer:/", "layer-to-base");
-
- diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals(0, diffs.size());
-
- // edit file f-aa in main
- fService.getFileOutputStream("main:/base/d-a/f-aa").close();
-
- diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals(0, diffs.size());
-
- // edit file f-aa in layer
- fService.getFileOutputStream("layer:/layer-to-base/d-a/f-aa").close();
-
- diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals("[layer:/layer-to-base/d-a/f-aa[-1] > main:/base/d-a/f-aa[-1]]", diffs.toString());
- assertEquals(1, diffs.size());
-
- // update main from layer
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals(0, diffs.size());
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- throw t;
- }
- }
-
- public void testSimpleUpdateLD3() throws Throwable
- {
- try
- {
- fService.createDirectory("main:/", "base");
-
- fService.createLayeredDirectory("main:/base", "layer:/", "layer-to-base");
-
- List diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals(0, diffs.size());
-
- // create directory d-a and file f-aa in layer
- fService.createDirectory("layer:/layer-to-base", "d-a");
- fService.createFile("layer:/layer-to-base/d-a", "f-aa").close();
-
- diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals("[layer:/layer-to-base/d-a[-1] > "+"main:/base/d-a[-1]]", diffs.toString());
- assertEquals(1, diffs.size());
-
- // update main from layer
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
- assertEquals(0, diffs.size());
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- throw t;
- }
- }
-
- public void testSimpleUpdateLD4() throws Exception
- {
- try
- {
- fService.createLayeredDirectory("main:/", "layer:/", "layer");
-
- // create directory b and file foo in layer
- fService.createDirectory("layer:/layer", "b");
- fService.createFile("layer:/layer/b", "foo").close();
-
- List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fService.createSnapshot("layer", null, null);
-
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- fService.createSnapshot("main", null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- fService.createStore("layer2");
- fService.createLayeredDirectory("layer:/layer", "layer2:/", "layer");
-
- // create directory c and file foo in layer2
- fService.createDirectory("layer2:/layer/", "c");
- fService.createFile("layer2:/layer/c", "foo").close();
-
- fService.createSnapshot("layer2", null, null);
-
- diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer2:/layer/c[-1] > layer:/layer/c[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer2:/layer", "layer:/layer");
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/c[-1] > main:/c[-1]]", diffs.toString());
-
- recursiveList("main");
- recursiveList("layer");
- recursiveList("layer2");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("layer2");
- }
- }
-
- public void testSimpleUpdateLD5() throws Exception
- {
- try
- {
- logger.debug("created 2 stores: main, layer");
-
- fService.createLayeredDirectory("main:/", "layer:/", "layer");
-
- logger.debug("created layered dir: layer:/layer -> main:/");
-
- fService.createDirectory("layer:/layer", "b");
-
- logger.debug("created dir in layer: layer:/layer/b");
-
- List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- logger.debug("updated & flattened: created directory: main:/b");
-
- fService.createFile("layer:/layer/b", "foo").close();
- fService.createFile("layer:/layer/b", "bar").close();
-
- logger.debug("created 2 files in layer: layer:/layer/b/foo and layer:/layer/b/bar");
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(2, diffs.size());
- assertEquals("[layer:/layer/b/bar[-1] > main:/b/bar[-1], layer:/layer/b/foo[-1] > main:/b/foo[-1]]", diffs.toString());
-
- // submit only first diff
- List selected = new ArrayList(1);
- selected.add(diffs.get(1));
-
- assertEquals("[layer:/layer/b/foo[-1] > main:/b/foo[-1]]", selected.toString());
-
- fSyncService.update(selected, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/b/bar[-1] > main:/b/bar[-1]]", diffs.toString());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- logger.debug("updated & flattened: created file: main:/b/foo");
-
- fService.removeNode("layer:/layer", "b");
- fService.createSnapshot("layer", null, null);
-
- logger.debug("removed dir in layer & snapshot: layer:/layer/b");
-
- // ETWOTWO-1266
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- logger.debug("updated & flattened: deleted dir: main:/b");
-
- recursiveList("main");
- recursiveList("layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- public void testDeleteLD1() throws Exception
- {
- try
- {
- logger.debug("created 2 stores: main, layer");
-
- fService.createDirectory("main:/", "a");
-
- OutputStream o = fService.createFile("main:/a", "foo");
- PrintStream out = new PrintStream(o);
- out.println("I am main:/a/foo");
- out.close();
-
- logger.debug("created file in main: main:/a/foo");
-
- fService.createLayeredDirectory("main:/a", "layer:/", "a");
-
- logger.debug("created layered dir: layer:/a -> main:/a");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
- out.println("I am layer:/a/foo");
- out.close();
-
- logger.debug("update file in layer: layer:/a/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/a/foo[-1] > main:/a/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/a", "main:/a");
-
- logger.debug("updated & flattened: updated file: main:/a/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- fService.removeNode("main:/", "a");
- fService.createSnapshot("main", null, null);
-
- logger.debug("remove directory in main & snapshot: main:/a");
-
- assertNotNull(fService.lookup(-1, "layer:/a"));
- assertNull(fService.lookup(-1, "layer:/a/foo"));
-
- try
- {
- fService.getFileInputStream(-1, "layer:/a/foo");
- fail();
- }
- catch (AVMNotFoundException nfe)
- {
- // expected
- }
-
- try
- {
- fService.getFileOutputStream("layer:/a/foo");
- fail();
- }
- catch (AVMNotFoundException nfe)
- {
- // expected
- }
-
- recursiveList("main");
- recursiveList("layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- public void testDeleteLD2() throws Exception
- {
- try
- {
- logger.debug("created 2 stores: main, layer");
-
- fService.createDirectory("main:/", "a");
-
- OutputStream o = fService.createFile("main:/a", "foo");
- PrintStream out = new PrintStream(o);
- out.println("I am main:/a/foo");
- out.close();
-
- logger.debug("created file in main: main:/a/foo");
-
- fService.createLayeredDirectory("main:/a", "layer:/", "a");
-
- logger.debug("created layered dir: layer:/a -> main:/a");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
- out.println("I am layer:/a/foo");
- out.close();
-
- logger.debug("update file in layer: layer:/a/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- fService.removeNode("main:/", "a");
-
- logger.debug("remove directory in main: main:/a");
-
- fService.createSnapshot("main", null, null);
-
- logger.debug("snapshot: main:/a");
-
- assertNull(fService.lookup(-1, "main:/a"));
- assertNull(fService.lookup(-1, "main:/a/foo"));
-
- try
- {
- fService.getFileInputStream(-1, "main:/a/foo");
- fail();
- }
- catch (AVMNotFoundException nfe)
- {
- // expected
- }
-
- assertNotNull(fService.lookup(-1, "layer:/a"));
- assertNotNull(fService.lookup(-1, "layer:/a/foo"));
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
- out.println("I am layer:/a/foo V2");
- out.close();
-
- List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/a[-1] > main:/a[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(0, diffs.size());
-
- logger.debug("updated: updated dir & file: main:/a/foo");
-
- fSyncService.flatten("layer:/a", "main:/a");
-
- logger.debug("flattened: layer:/a -> main:/a");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo V2", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo V2", line);
-
- recursiveList("main");
- recursiveList("layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- /**
- * Test bulk update (using layered directory).
- */
- public void testBulkUpdateLD() throws Exception
- {
- try
- {
- RemoteBulkLoader loader = new RemoteBulkLoader();
- loader.setAvmRemoteService(fService);
-
- fService.createLayeredDirectory("main:/", "layer:/", "layer");
- loader.recursiveLoad("config/alfresco/bootstrap", "layer:/layer");
- List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/bootstrap[-1] > main:/bootstrap[-1]]", diffs.toString());
- fService.createSnapshot("layer", null, null);
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
- fSyncService.flatten("layer:/layer", "main:/");
- recursiveList("layer");
- recursiveList("main");
- fService.createStore("layer2");
- fService.createLayeredDirectory("layer:/layer", "layer2:/", "layer");
- loader.recursiveLoad("config/alfresco/bootstrap", "layer2:/layer/bootstrap");
- fService.createSnapshot("layer2", null, null);
- diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer2:/layer/bootstrap/bootstrap[-1] > layer:/layer/bootstrap/bootstrap[-1]]", diffs.toString());
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
- assertEquals(0, diffs.size());
- fSyncService.flatten("layer2:/layer", "layer:/layer");
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/layer/bootstrap/bootstrap[-1] > main:/bootstrap/bootstrap[-1]]", diffs.toString());
- recursiveList("layer2");
- recursiveList("layer");
- recursiveList("main");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("layer2");
- }
- }
-
- /**
- * Test the flatten operation, with a little bit of compare and update.
- */
- public void testFlatten() throws Exception
- {
- try
- {
- setupBasicTree();
- fService.createLayeredDirectory("main:/a", "main:/", "layer");
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- // Change some stuff.
- fService.createFile("main:/layer/b", "fig").close();
- fService.getFileOutputStream("main:/layer/b/c/foo").close();
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- // Do a compare.
- List diffs = fSyncService.compare(-1, "main:/layer", -1, "main:/a", null);
- assertEquals(2, diffs.size());
- assertEquals("[main:/layer/b/c/foo[-1] > main:/a/b/c/foo[-1], main:/layer/b/fig[-1] > main:/a/b/fig[-1]]", diffs.toString());
- // Update.
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- recursiveList("main");
- // Flatten.
- fSyncService.flatten("main:/layer", "main:/a");
- recursiveList("main");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- /**
- * Test partial flatten.
- */
- public void testPartialFlatten() throws Exception
- {
- try
- {
- setupBasicTree();
- fService.createLayeredDirectory("main:/a", "layer:/", "a");
- fService.getFileOutputStream("layer:/a/b/c/foo").close();
- fService.createFile("layer:/a/b", "bing").close();
- List diffs = new ArrayList();
- diffs.add(new AVMDifference(-1, "layer:/a/b/c/foo", -1, "main:/a/b/c/foo", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fSyncService.flatten("layer:/a", "main:/a");
- AVMNodeDescriptor b = fService.lookup(-1, "layer:/a/b");
- assertTrue(b.isLayeredDirectory());
- AVMNodeDescriptor c = fService.lookup(-1, "layer:/a/b/c");
- assertTrue(c.isPlainDirectory());
- diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[layer:/a/b/bing[-1] > main:/a/b/bing[-1]]", diffs.toString());
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- /**
- * Test AVMSyncService resetLayer.
- */
- public void testResetLayer() throws Exception
- {
- try
- {
- setupBasicTree();
- fService.createLayeredDirectory("main:/a", "main:/", "layer");
- fService.createFile("main:/layer", "figs").close();
- assertFalse(recursiveContents("main:/a", -1, true).equals(recursiveContents("main:/layer", -1, true)));
- recursiveList("main");
- fSyncService.resetLayer("main:/layer");
- assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true));
- recursiveList("main");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- /**
- * Test AVMSyncService update.
- */
- public void testUpdate() throws Exception
- {
- try
- {
- setupBasicTree();
- // Try branch to branch update.
- fService.createBranch(-1, "main:/a", "main:/", "abranch");
- fService.createFile("main:/abranch", "monkey").close();
- fService.createFile("main:/abranch", "#foo").close();
- fService.createFile("main:/abranch", "figs.tmp").close();
- fService.getFileOutputStream("main:/abranch/b/c/foo").close();
- recursiveList("main");
- List cmp = fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder);
- assertEquals(2, cmp.size());
- assertEquals("[main:/abranch/b/c/foo[-1] > main:/a/b/c/foo[-1], main:/abranch/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
- List diffs = new ArrayList();
- diffs.add(new AVMDifference(-1, "main:/abranch/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
- diffs.add(new AVMDifference(-1, "main:/abranch/b/c/foo", -1, "main:/a/b/c/foo", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- assertEquals(fService.lookup(-1, "main:/abranch/monkey").getId(), fService.lookup(-1, "main:/a/monkey").getId());
- assertEquals(fService.lookup(-1, "main:/abranch/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/c/foo").getId());
- // Try updating a deletion.
- fService.removeNode("main:/abranch", "monkey");
- recursiveList("main");
- cmp = fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder);
- assertEquals(1, cmp.size());
- assertEquals("[main:/abranch/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/abranch/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- assertEquals(0, fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder).size());
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- assertEquals(fService.lookup(-1, "main:/abranch/monkey", true).getId(), fService.lookup(-1, "main:/a/monkey", true).getId());
- // Try one that should fail.
- fService.createFile("main:/abranch", "monkey").close();
- cmp = fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder);
- assertEquals(1, cmp.size());
- assertEquals("[main:/abranch/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/abranch/monkey", AVMDifference.NEWER));
- try
- {
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fail();
- }
- catch (AVMSyncException se)
- {
- // Do nothing.
- }
- // Get synced again by doing an override older.
- recursiveList("main");
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/abranch/monkey", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, true, null, null);
- assertEquals(0, fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder).size());
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- assertEquals(fService.lookup(-1, "main:/a/monkey", true).getId(), fService.lookup(-1, "main:/abranch/monkey", true).getId());
- // Cleanup for layered tests.
- fService.purgeStore("main");
- fService.createStore("main");
- setupBasicTree();
- fService.createLayeredDirectory("main:/a", "main:/", "layer");
- fService.createFile("main:/layer", "monkey").close();
- fService.getFileOutputStream("main:/layer/b/c/foo").close();
- cmp = fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder);
- assertEquals(2, cmp.size());
- assertEquals("[main:/layer/b/c/foo[-1] > main:/a/b/c/foo[-1], main:/layer/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
- recursiveList("main");
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/layer/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
- diffs.add(new AVMDifference(-1, "main:/layer/b/c/foo", -1, "main:/a/b/c/foo", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- assertEquals(0, fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder).size());
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- assertEquals(fService.lookup(-1, "main:/layer/monkey").getId(), fService.lookup(-1, "main:/a/monkey").getId());
- assertEquals(fService.lookup(-1, "main:/layer/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/c/foo").getId());
- // Try updating a deletion.
- fService.removeNode("main:/layer", "monkey");
- recursiveList("main");
- cmp = fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder);
- assertEquals(1, cmp.size());
- assertEquals("[main:/layer/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/layer/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- assertEquals(0, fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder).size());
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- assertEquals(fService.lookup(-1, "main:/layer/monkey", true).getId(), fService.lookup(-1, "main:/a/monkey", true).getId());
- // Try one that should fail.
- fService.createFile("main:/layer", "monkey").close();
- cmp = fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder);
- assertEquals(1, cmp.size());
- assertEquals("[main:/layer/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/layer/monkey", AVMDifference.NEWER));
- try
- {
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fail();
- }
- catch (AVMSyncException se)
- {
- // Do nothing.
- }
- // Get synced again by doing an override older.
- recursiveList("main");
- diffs.clear();
- diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/layer/monkey", AVMDifference.NEWER));
- fSyncService.update(diffs, null, false, false, false, true, null, null);
- assertEquals(0, fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder).size());
- fService.createSnapshot("main", null, null);
- recursiveList("main");
- assertEquals(fService.lookup(-1, "main:/a/monkey", true).getId(), fService.lookup(-1, "main:/layer/monkey", true).getId());
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- /**
- * Test that an update forces a snapshot on the source.
- */
- public void testUpdateSnapshot() throws Exception
- {
- try
- {
- setupBasicTree();
- fService.createStore("branch");
- fService.createBranch(-1, "main:/", "branch:/", "branch");
- // Modify some things in the branch.
- fService.createFile("branch:/branch/a/b", "fing").close();
- fService.getFileOutputStream("branch:/branch/a/b/c/foo").close();
- fService.removeNode("branch:/branch/a/b/c", "bar");
- List diffs = fSyncService.compare(-1, "branch:/branch", -1, "main:/", null);
- assertEquals(3, diffs.size());
- assertEquals("[branch:/branch/a/b/c/bar[-1] > main:/a/b/c/bar[-1], branch:/branch/a/b/c/foo[-1] > main:/a/b/c/foo[-1], branch:/branch/a/b/fing[-1] > main:/a/b/fing[-1]]", diffs.toString());
- // Now update.
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- diffs = fSyncService.compare(-1, "branch:/branch", -1, "main:/", null);
- assertEquals(0, diffs.size());
- fService.getFileOutputStream("branch:/branch/a/b/fing").close();
- assertTrue(fService.lookup(-1, "branch:/branch/a/b/fing").getId() != fService.lookup(-1, "main:/a/b/fing").getId());
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("branch");
- }
- }
-
- /**
- * Test a noodle update.
- */
- public void testNoodleUpdate() throws Exception
- {
- try
- {
- setupBasicTree();
- fService.createStore("staging");
- List diffs = fSyncService.compare(-1, "main:/", -1, "staging:/", null);
- assertEquals(2, diffs.size());
- assertEquals("[main:/a[-1] > staging:/a[-1], main:/d[-1] > staging:/d[-1]]", diffs.toString());
- List noodle = new ArrayList();
- noodle.add(new AVMDifference(-1, "main:/a/b/c/foo", -1, "staging:/a/b/c/foo", AVMDifference.NEWER));
- noodle.add(new AVMDifference(-1, "main:/d", -1, "staging:/d", AVMDifference.NEWER));
- fSyncService.update(noodle, null, false, false, false, false, null, null);
- diffs = fSyncService.compare(-1, "main:/", -1, "staging:/", null);
- assertEquals(1, diffs.size());
- assertEquals("[main:/a/b/c/bar[-1] > staging:/a/b/c/bar[-1]]", diffs.toString());
- assertEquals("main:/a/b/c/bar", diffs.get(0).getSourcePath());
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("staging");
- }
- }
-
-
- public void testRename6() throws Exception
- {
- try
- {
- setupBasicTree();
- fService.createLayeredDirectory("main:/a", "layer:/", "a");
- fService.rename("layer:/a/b", "c", "layer:/a/b", "z");
- recursiveContents("layer:/");
- List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(2, diffs.size());
- assertEquals("[layer:/a/b/c[-1] > main:/a/b/c[-1], layer:/a/b/z[-1] > main:/a/b/z[-1]]", diffs.toString());
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- recursiveContents("layer:/");
- recursiveContents("main:/");
- fSyncService.flatten("layer:/a", "main:/a");
- recursiveContents("layer:/");
- recursiveContents("main:/");
- fService.createFile("layer:/a/b/z", "fudge").close();
- fService.rename("layer:/a/b", "z", "layer:/a/b", "y");
- recursiveContents("layer:/");
- diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(2, diffs.size());
- assertEquals("[layer:/a/b/y[-1] > main:/a/b/y[-1], layer:/a/b/z[-1] > main:/a/b/z[-1]]", diffs.toString());
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- recursiveContents("layer:/");
- recursiveContents("main:/");
- fSyncService.flatten("layer:/a", "main:/a");
- recursiveContents("layer:/");
- recursiveContents("main:/");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw e;
- }
- }
-
- /**
- * Test file properties update ...
- */
- public void testUpdateFileTitleAndDescription() throws Exception
- {
- try
- {
- fService.createLayeredDirectory("main:/", "layer:/", "layer");
- fService.createDirectory("layer:/layer", "b");
- fService.createFile("layer:/layer/b", "foo").close();
-
- List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fService.createSnapshot("layer", null, null);
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- assertEquals(0, fService.getNodeProperties(-1, "main:/b/foo").size());
- assertEquals(0, fService.getNodeProperties(-1, "layer:/layer/b/foo").size());
-
- Map properties = new HashMap();
- properties.put(ContentModel.PROP_TITLE, new PropertyValue(DataTypeDefinition.TEXT, "foo title"));
- properties.put(ContentModel.PROP_DESCRIPTION, new PropertyValue(DataTypeDefinition.TEXT, "foo descrip"));
- fService.setNodeProperties("layer:/layer/b/foo", properties);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals("[layer:/layer/b/foo[-1] > main:/b/foo[-1]]", diffs.toString());
-
- fService.createSnapshot("layer", null, null);
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- assertEquals(2, fService.getNodeProperties(-1, "main:/b/foo").size());
-
- assertEquals("foo title", fService.getNodeProperty(-1, "main:/b/foo", ContentModel.PROP_TITLE).getStringValue());
- assertEquals("foo descrip", fService.getNodeProperty(-1, "main:/b/foo", ContentModel.PROP_DESCRIPTION).getStringValue());
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- /**
- * Test directory properties update ...
- */
- public void testUpdateDirectoryTitleAndDescription() throws Exception
- {
- try
- {
- fService.createLayeredDirectory("main:/", "layer:/", "layer");
- fService.createDirectory("layer:/layer", "b");
- fService.createFile("layer:/layer/b", "foo").close();
-
- List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fService.createSnapshot("layer", null, null);
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- assertEquals(0, fService.getNodeProperties(-1, "main:/b").size());
- assertEquals(0, fService.getNodeProperties(-1, "layer:/layer/b").size());
-
- Map properties = new HashMap();
- properties.put(ContentModel.PROP_TITLE, new PropertyValue(DataTypeDefinition.TEXT, "b title"));
- properties.put(ContentModel.PROP_DESCRIPTION, new PropertyValue(DataTypeDefinition.TEXT, "b descrip"));
- fService.setNodeProperties("layer:/layer/b", properties);
-
- assertEquals(0, fService.getNodeProperties(-1, "main:/b").size());
- assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fService.createSnapshot("layer", null, null);
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
-
- assertEquals(2, fService.getNodeProperties(-1, "main:/b").size());
- assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- assertEquals(2, fService.getNodeProperties(-1, "main:/b").size());
- assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
-
- assertEquals("b title", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_TITLE).getStringValue());
- assertEquals("b descrip", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_DESCRIPTION).getStringValue());
-
- fService.setNodeProperty("layer:/layer/b", ContentModel.PROP_TITLE, new PropertyValue(DataTypeDefinition.TEXT, "b title2"));
- fService.setNodeProperty("layer:/layer/b", ContentModel.PROP_DESCRIPTION, new PropertyValue(DataTypeDefinition.TEXT, "b descrip2"));
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
-
- fService.createSnapshot("layer", null, null);
- fSyncService.update(diffs, null, false, false, false, false, null, null);
- fService.createSnapshot("main", null, null);
-
- diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
- assertEquals(0, diffs.size());
-
- fSyncService.flatten("layer:/layer", "main:/");
-
- assertEquals(2, fService.getNodeProperties(-1, "main:/b").size());
- assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
-
- assertEquals("b title2", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_TITLE).getStringValue());
- assertEquals("b descrip2", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_DESCRIPTION).getStringValue());
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- public void testSimpleUpdateLF1() throws Exception
- {
- try
- {
- List snapshots = fService.getStoreVersions("main");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- snapshots = fService.getStoreVersions("layer");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- fService.createDirectory("main:/", "a");
- fService.createDirectory("layer:/", "a");
-
- logger.debug("created 2 plain dirs: main:/a, layer:/a");
-
- fService.createFile("main:/a", "foo");
-
- assertEquals(1, fService.lookup(-1, "main:/a/foo").getVersionID());
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("main:/a/foo"));
- out.println("I am main:/a/foo");
- out.close();
-
- AVMNodeDescriptor node = fService.lookup(-1, "main:/a/foo");
- assertEquals(1, node.getVersionID());
- List history = fService.getHistory(node, -1);
- assertEquals(0, history.size());
-
- fService.createSnapshot("main", null, null);
-
- snapshots = fService.getStoreVersions("main");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- snapshots = fService.getStoreVersions("layer");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- assertEquals(1, fService.lookup(-1, "main:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(1, "main:/a/foo").getVersionID());
-
- logger.debug("created plain file: main:/a/foo");
-
- fService.createLayeredFile("main:/a/foo", "layer:/a", "foo");
-
- assertEquals(1, fService.lookup(-1, "layer:/a/foo").getVersionID());
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- node = fService.lookup(-1, "layer:/a/foo");
- assertEquals(1, node.getVersionID());
-
- history = fService.getHistory(node, -1);
- assertEquals(0, history.size());
-
- fService.createSnapshot("layer", null, null);
-
- snapshots = fService.getStoreVersions("main");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- snapshots = fService.getStoreVersions("layer");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- assertEquals(1, fService.lookup(-1, "layer:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(1, "layer:/a/foo").getVersionID());
-
- List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(0, diffs.size());
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- logger.debug("created layered file: layer:/a/foo -> main:/a/foo");
-
- out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
- out.println("I am layer:/a/foo");
- out.close();
-
- logger.debug("modified file: layer:/a/foo");
-
- assertEquals(2, fService.lookup(-1, "layer:/a/foo").getVersionID());
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am main:/a/foo", line);
-
- diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
- assertEquals(1, diffs.size());
-
- // TODO - review behaviour
- assertEquals("[layer:/a/foo[-1] > main:/a/foo[-1]]", diffs.toString());
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
-
- // update will implicitly snapshot (src and dst)
- snapshots = fService.getStoreVersions("main");
- assertEquals(3, snapshots.size());
- assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
-
- snapshots = fService.getStoreVersions("layer");
- assertEquals(3, snapshots.size());
- assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
-
- node = fService.lookup(-1, "layer:/a/foo");
- assertEquals(2, node.getVersionID());
- history = fService.getHistory(node, -1);
-
- assertEquals(1, history.size());
- assertEquals(1, history.get(0).getVersionID());
-
- assertEquals(1, fService.lookup(1, "layer:/a/foo").getVersionID());
- assertEquals(2, fService.lookup(2, "layer:/a/foo").getVersionID());
-
- logger.debug("submitted/updated file: layer:/a/foo -> main:/a/foo");
-
- fSyncService.flatten("layer:/a", "main:/a");
-
- logger.debug("flatten dir: layer:/a -> main:/a");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am layer:/a/foo", line);
-
- snapshots = fService.getStoreVersions("main");
- assertEquals(3, snapshots.size());
- assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
-
- snapshots = fService.getStoreVersions("layer");
- assertEquals(3, snapshots.size());
- assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
-
- recursiveList("main");
- recursiveList("layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- }
-
- public void testSimpleUpdateLF2() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
- fService.createStore("mainB--layer");
-
- List snapshots = fService.getStoreVersions("mainA");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- snapshots = fService.getStoreVersions("mainB");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- snapshots = fService.getStoreVersions("mainB--layer");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- logger.debug("created 3 stores: mainA, mainB, mainB-layer");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainB:/", "a");
-
- logger.debug("created 2 plain dirs: mainA:/a, mainB:/a");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
-
- // note: unlike WCM, edit staging directly (ie. don't bother with mainA--layer for now)
- fService.createFile("mainA:/a", "foo");
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertNull(fService.lookup(-1, "mainB:/a/foo"));
- assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
- out.println("I am mainA:/a/foo");
- out.close();
-
- logger.debug("created plain file: mainA:/a/foo");
-
- fService.createSnapshot("mainA", null, null);
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertNull(fService.lookup(-1, "mainB:/a/foo"));
- assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
-
- snapshots = fService.getStoreVersions("mainA");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- logger.debug("created snapshot: mainA");
-
- // note: WCM does not expose layered file (between web project staging sandboxes)
- fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
-
- // modify file in user's sandbox
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/foo"));
- out.println("I am mainB--layer:/a/foo");
- out.close();
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
- assertEquals(2, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
-
- logger.debug("modified file: mainB--layer:/a/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
-
- // TODO - review behaviour
- assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
-
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertEquals(2, fService.lookup(-1, "mainB:/a/foo").getVersionID());
- assertEquals(2, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
-
- snapshots = fService.getStoreVersions("mainB--layer");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- snapshots = fService.getStoreVersions("mainB");
- assertEquals(3, snapshots.size());
- assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
-
- logger.debug("submit/update file: mainB--layer:/a/foo -> mainB:/a/foo");
-
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("flatten dir: mainB--layer:/a/foo -> mainB:/a/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testSimpleUpdateLF3() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
- fService.createStore("mainB--layer");
-
- List snapshots = fService.getStoreVersions("mainA");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- snapshots = fService.getStoreVersions("mainB");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- snapshots = fService.getStoreVersions("mainB--layer");
- assertEquals(1, snapshots.size());
- assertEquals(0, snapshots.get(0).getVersionID());
-
- logger.debug("created 3 stores: mainA, mainB, mainB-layer");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainB:/", "a");
-
- logger.debug("created 2 plain dirs: mainA:/a, mainB:/a");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
-
- // note: unlike WCM, edit staging directly (ie. don't bother with mainA--layer for now)
- fService.createFile("mainA:/a", "foo");
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertNull(fService.lookup(-1, "mainB:/a/foo"));
- assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
- out.println("I am mainA:/a/foo");
- out.close();
-
- logger.debug("created plain file: mainA:/a/foo");
-
- fService.createSnapshot("mainA", null, null);
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertNull(fService.lookup(-1, "mainB:/a/foo"));
- assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
-
- snapshots = fService.getStoreVersions("mainA");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- logger.debug("created snapshot: mainA");
-
- // note: WCM does not expose layered file (between web project staging sandboxes)
- fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
-
- AVMNodeDescriptor foo = fService.lookup(-1, "mainB--layer:/a/foo");
- assertEquals(1, foo.getVersionID());
- assertTrue(foo.isLayeredFile());
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
-
- // add dir in user's sandbox
- fService.createDirectory("mainB--layer:/a", "b");
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
- assertEquals(1, fService.lookup(-1, "mainB--layer:/a/b").getVersionID());
-
- foo = fService.lookup(-1, "mainB--layer:/a/foo");
- assertEquals(1, foo.getVersionID());
- assertTrue(foo.isLayeredFile());
-
- logger.debug("created dir: mainB--layer:/a/b");
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
-
- foo = fService.lookup(-1, "mainB--layer:/a/foo");
- assertTrue(foo.isLayeredFile());
-
- assertEquals("[mainB--layer:/a/b[-1] > mainB:/a/b[-1]]", diffs.toString());
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
-
- foo = fService.lookup(-1, "mainB--layer:/a/foo");
- assertTrue(foo.isLayeredFile());
-
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- foo = fService.lookup(-1, "mainB--layer:/a/foo");
- assertTrue(foo.isLayeredFile());
-
- assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
- assertEquals(2, fService.lookup(-1, "mainB:/a/foo").getVersionID());
- assertEquals(2, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
-
- snapshots = fService.getStoreVersions("mainB--layer");
- assertEquals(2, snapshots.size());
- assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
-
- snapshots = fService.getStoreVersions("mainB");
- assertEquals(3, snapshots.size());
- assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
-
- logger.debug("submitted dir: mainB--layer:/a/b -> mainB:/a/b");
-
- foo = fService.lookup(-1, "mainB--layer:/a/foo");
- assertEquals(2, foo.getVersionID());
- assertTrue(foo.isLayeredFile());
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFolder1() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainA:/a", "b");
-
- fService.createDirectory("mainB:/", "a");
-
- fService.createStore("mainB--layer");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a/b", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
- out.println("I am mainA:/a/b/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/b/c/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to mainA:/a/b)
- fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
-
- logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
-
- fService.createDirectory("mainB--layer:/a", "c");
-
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("created dir: mainB--layer:/a/c");
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/c[-1] > mainB:/a/c[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated: created dir: mainB:/a/d");
-
- assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
-
- fService.createDirectory("mainB--layer:/a/b", "c");
-
- assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
-
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("created dir: mainB--layer:/a/b/c");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/c[-1] > mainB:/a/b/c[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated: created dir: mainB:/a/b/c");
-
- assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFolderDelete1() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainA:/a", "b");
-
- fService.createDirectory("mainB:/", "a");
-
- fService.createStore("mainB--layer");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a/b", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
- out.println("I am mainA:/a/b/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/b/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
- fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
- out.println("I am mainB--layer:/a/b/foo");
- out.close();
-
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("updated file: mainB--layer:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated: created file: mainB:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- // delete file - note: short-cut - removed directly from "staging" area (don't bother with sandbox mainA--layer for now)
- fService.removeNode("mainA:/a/b", "foo");
- fService.createSnapshot("mainA", null, null);
-
- logger.debug("removed file & snapshot: mainA:/a/b/foo");
-
- // ETHREEOH-2297
- fService.removeNode("mainB--layer:/a/b", "foo");
- fService.createSnapshot("mainB--layer", null, null);
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("updated: removed file: mainB:/a/b/foo");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFolderDelete2() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainA:/a", "b");
-
- fService.createDirectory("mainB:/", "a");
-
- fService.createStore("mainB--layer");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a/b", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
- out.println("I am mainA:/a/b/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/b/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
- fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
- out.println("I am mainB--layer:/a/b/foo");
- out.close();
-
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("updated file: mainB--layer:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated: created file: mainB:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- // delete folder - note: short-cut - remove directly from "staging" area (don't bother with sandbox mainA--layer for now)
- fService.removeNode("mainA:/a", "b");
- fService.createSnapshot("mainA", null, null);
-
- logger.debug("removed folder & snapshot: mainA:/a/b");
-
- fService.removeNode("mainB--layer:/a/b", "foo");
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("removed file & snapshot: mainB--layer:/a/b/foo");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated & flattened: removed file: mainB:/a/b/foo");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFolderDelete3() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainA:/a", "b");
-
- fService.createDirectory("mainB:/", "a");
-
- fService.createStore("mainB--layer");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a/b", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
- out.println("I am mainA:/a/b/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/b/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
- fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
- out.println("I am mainB--layer:/a/b/foo");
- out.close();
-
- logger.debug("updated file: mainB--layer:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated: created file: mainB:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- // delete folder - note: short-cut - remove directly from "staging" area (don't bother with sandbox mainA--layer for now)
- fService.removeNode("mainA:/a", "b");
- fService.createSnapshot("mainA", null, null);
-
- logger.debug("removed folder & snapshot: mainA:/a/b");
-
- fService.createFile("mainB--layer:/a/b", "bar");
-
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/bar"));
- out.println("I am mainB--layer:/a/b/bar");
- out.close();
-
- logger.debug("created file: mainB--layer:/a/b/bar");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/bar[-1] > mainB:/a/b/bar[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "two", "two");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated & flattened: created file: mainB:/a/b/bar");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFolderDelete4() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainA:/a", "b");
-
- fService.createDirectory("mainB:/", "a");
-
- fService.createStore("mainB--layer");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a/b", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
- out.println("I am mainA:/a/b/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/b/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
- fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
- out.println("I am mainB--layer:/a/b/foo");
- out.close();
-
- logger.debug("updated file: mainB--layer:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated & flattened: updated file: mainB:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- // delete folder - note: short-cut - remove directly from "staging" area (don't bother with sandbox mainA--layer for now)
- fService.removeNode("mainA:/a", "b");
- fService.createSnapshot("mainA", null, null);
-
- logger.debug("removed folder & snapshot: mainA:/a/b");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
- out.println("I am mainB--layer:/a/b/foo V2");
- out.close();
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo V2", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo", line);
-
- logger.debug("updated file: mainB--layer:/a/b/foo");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(1, diffs.size());
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "two", "two");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated & flattened: updated file: mainB:/a/b/foo");
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainB--layer:/a/b/foo V2", line);
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFileDeleteFile1() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
- fService.createStore("mainB--layer");
-
- logger.debug("created 3 stores: mainA, mainB, mainB--layer");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainB:/", "a");
-
- logger.debug("created 2 plain dirs: mainA:/a and mainB:/a");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
- out.println("I am mainA:/a/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
- fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
-
- logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created 2 snapshots: mainA and mainB");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(0, diffs.size());
-
- fService.removeNode("mainB--layer:/a", "foo");
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("removed file & snapshot: mainB--layer:/a/foo");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
-
- // ETHREEOH-2844
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated & flattened: removed file: mainB:/a/foo");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFileDeleteFile2() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
- fService.createStore("mainB--layer");
-
- logger.debug("created 3 stores: mainA, mainB, mainB--layer");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainB:/", "a");
-
- logger.debug("created 2 plain dirs: mainA:/a and mainB:/a");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
-
- // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
- fService.createFile("mainA:/a", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
- out.println("I am mainA:/a/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/foo");
-
- // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
- fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
-
- logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created 2 snapshots: mainA and mainB");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(0, diffs.size());
-
- // note: short-cut - removed directly from "staging" area (don't bother with sandbox mainA--layer for now)
- fService.removeNode("mainA:/a", "foo");
- fService.createSnapshot("mainA", null, null);
-
- logger.debug("removed file & snapshot: mainA:/a/foo");
-
- try
- {
- fService.getFileInputStream(-1, "mainA:/a/foo");
- fail("Unexpected");
- }
- catch (AVMNotFoundException nfe)
- {
- // expected
- }
-
- try
- {
- fService.getFileInputStream(-1, "mainB:/a/foo");
- fail("Unexpected");
- }
- catch (AVMNotFoundException nfe)
- {
- // expected
- }
-
- try
- {
- fService.getFileInputStream(-1, "mainB--layer:/a/foo");
- fail("Unexpected");
- }
- catch (AVMNotFoundException nfe)
- {
- // expected
- }
-
- fService.removeNode("mainB--layer:/a", "foo");
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("removed file & snapshot: mainB--layer:/a/foo");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
-
- // ETHREEOH-2829
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("updated & flattened: removed file: mainB:/a/foo");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- }
- }
-
- public void testLayeredFileDeleteFile3() throws Exception
- {
- try
- {
- fService.createStore("mainB");
- fService.createStore("mainB--layer");
-
- logger.debug("created 2 stores: mainB, mainB--layer");
-
- fService.createDirectory("mainB:/", "a");
-
- logger.debug("created plain dir: mainB:/a");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
-
- // create equivalent of WCM layered file between web project staging sandboxes (mainB:/a/b/foo pointing to mainA:/a/b/foo)
- fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo"); // note: unbacked/stale here ... even store does not exist !!
-
- logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals(0, diffs.size());
-
- // create file
- fService.createFile("mainB--layer:/a", "bar");
-
- logger.debug("created file: mainB--layer:/a/bar");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals("[mainB--layer:/a/bar[-1] > mainB:/a/bar[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
-
- logger.debug("updated: created file: mainB:/a/bar");
-
- fSyncService.flatten("mainB--layer:/a", "mainB:/a");
-
- logger.debug("flattened: created file: mainB:/a/bar");
-
- // delete layered file (from mainB--layer)
- fService.removeNode("mainB--layer:/a", "foo");
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("removed file & snapshot: mainB--layer:/a/foo");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
- assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
-
- fService.createStore("mainB--workflow1");
-
- logger.debug("created store: mainB--workflow1");
-
- recursiveList("mainB--workflow1");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--workflow1:/", "a");
-
- logger.debug("created layered dir: mainB--workflow1:/a -> mainB:/a");
-
- recursiveList("mainB");
- recursiveList("mainB--layer");
- recursiveList("mainB--workflow1");
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null);
- assertEquals(0, diffs.size());
-
- diffs = new ArrayList(1);
- diffs.add(new AVMDifference(-1, "mainB--layer:/a/foo", -1, "mainB--workflow1:/a/foo", AVMDifference.NEWER));
-
- // ETHREEOH-2868
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- logger.debug("updated: removed file: mainB--workflow1:/a/foo");
-
- recursiveList("mainB");
- recursiveList("mainB--layer");
- recursiveList("mainB--workflow1");
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null);
- assertEquals("[mainB--workflow1:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, true, true, "one", "one");
- fSyncService.flatten("mainB--workflow1:/a", "mainB:/a");
-
- logger.debug("updated & flattened: removed file: mainB:/a/foo");
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null);
- assertEquals(0, diffs.size());
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB--layer:/a", null);
- assertEquals(0, diffs.size());
-
- fSyncService.update(diffs, null, true, true, false, false, null, null);
- fSyncService.flatten("mainB--layer:/a", "mainB--workflow1:/a");
-
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- if (fService.getStore("mainB--workflow1") != null) { fService.purgeStore("mainB--workflow1"); }
- }
- }
-
- public void testLayeredFileDeleteFile4() throws Exception
- {
- try
- {
- fService.createStore("mainA");
- fService.createStore("mainB");
- fService.createStore("mainB--layer");
-
- logger.debug("created 3 stores: mainA, mainB, mainB--layer");
-
- fService.createDirectory("mainA:/", "a");
- fService.createDirectory("mainB:/", "a");
-
- logger.debug("created 2 plain dirs: mainA:/a and mainB:/a");
-
- fService.createSnapshot("mainA", null, null);
- fService.createSnapshot("mainB", null, null);
-
- logger.debug("created 2 snapshots: mainA and mainB");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
-
- logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
-
- // note: short-cut - created directly in "staging" areas (don't bother with sandbox mainA--layer or mainB--layer for now)
- fService.createDirectory("mainA:/a", "b");
- fService.createDirectory("mainB:/a", "b");
-
- logger.debug("created directories: mainA:/a/b & mainB:/a/b");
-
- fService.createFile("mainA:/a/b", "foo");
-
- PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
- out.println("I am mainA:/a/b/foo");
- out.close();
-
- logger.debug("created file: mainA:/a/b/foo");
-
- // create equivalent of WCM layered file between web project staging sandboxes (mainB:/a/b/foo pointing to mainA:/a/b/foo)
- fService.createLayeredFile("mainA:/a/b/foo", "mainB:/a/b", "foo");
-
- logger.debug("created layered file: mainB:/a/b/foo -> mainA:/a/b/foo");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
- String line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
- line = reader.readLine();
- reader.close();
- assertEquals("I am mainA:/a/b/foo", line);
-
- List diffs = fSyncService.compare(-1, "mainB--layer:/a/b", -1, "mainB:/a/b", null);
- assertEquals(0, diffs.size());
-
- // create file
- fService.createFile("mainB--layer:/a/b", "bar");
-
- logger.debug("created file: mainB--layer:/a/b/bar");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a/b", -1, "mainB:/a/b", null);
- assertEquals("[mainB--layer:/a/b/bar[-1] > mainB:/a/b/bar[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, false, false, "one", "one");
- fSyncService.flatten("mainB--layer:/a/b", "mainB:/a/b");
-
- logger.debug("updated & flattened: created file: mainB:/a/b/bar");
-
- // delete layered file (from mainB--layer)
- fService.removeNode("mainB--layer:/a/b", "foo");
- fService.createSnapshot("mainB--layer", null, null);
-
- logger.debug("removed file & snapshot: mainB--layer:/a/b/foo");
-
- diffs = fSyncService.compare(-1, "mainB--layer:/a/b", -1, "mainB:/a/b", null);
- assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fService.createStore("mainB--workflow1");
-
- fService.createLayeredDirectory("mainB:/a", "mainB--workflow1:/", "a");
-
- logger.debug("created layered dir: mainB--workflow1:/a -> mainB:/a");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- recursiveList("mainB--workflow1");
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB:/a/b", null);
- assertEquals(0, diffs.size());
-
- diffs = new ArrayList(1);
- diffs.add(new AVMDifference(-1, "mainB--layer:/a/b/foo", -1, "mainB--workflow1:/a/b/foo", AVMDifference.NEWER));
-
- // ETHREEOH-2868
- fSyncService.update(diffs, null, false, false, false, false, null, null);
-
- logger.debug("updated: removed file: mainB--workflow1:/a/b/foo");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- recursiveList("mainB--workflow1");
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB:/a/b", null);
- assertEquals("[mainB--workflow1:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
-
- fSyncService.update(diffs, null, false, false, true, true, "one", "one");
- fSyncService.flatten("mainB--workflow1:/a/b", "mainB:/a/b");
-
- logger.debug("updated & flattened: removed file: mainB:/a/b/foo");
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB:/a/b", null);
- assertEquals(0, diffs.size());
-
- diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB--layer:/a/b", null);
- assertEquals(0, diffs.size());
-
- fSyncService.update(diffs, null, true, true, false, false, null, null);
- fSyncService.flatten("mainB--layer:/a/b", "mainB--workflow1:/a/b");
-
- recursiveList("mainA");
- recursiveList("mainB");
- recursiveList("mainB--layer");
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- throw e;
- }
- finally
- {
- fService.purgeStore("mainA");
- fService.purgeStore("mainB");
- fService.purgeStore("mainB--layer");
- if (fService.getStore("mainB--workflow1") != null) { fService.purgeStore("mainB--workflow1"); }
- }
- }
-
- protected void recursiveContents(String path)
- {
- String contentsStr = recursiveContents(path, -1, true);
- if (logger.isDebugEnabled())
- {
- logger.debug(contentsStr);
- }
- }
-
- /**
- * Get the recursive contents of the given path and version.
- * @param path
- * @param version
- * @return A string representation of the contents.
- */
- protected String recursiveContents(String path, int version, boolean followLinks)
- {
- String val = recursiveList(path, version, 0, followLinks);
- return val.substring(val.indexOf('\n'));
- }
-
- protected void recursiveList(String store)
- {
- String list = recursiveList(store, -1, true);
- if (logger.isDebugEnabled())
- {
- logger.debug("\n\n"+store+":"+"\n"+list+"\n");
- }
- }
-
- /**
- * Helper to write a recursive listing of an AVMStore at a given version.
- * @param repoName The name of the AVMStore.
- * @param version The version to look under.
- */
- protected String recursiveList(String repoName, int version, boolean followLinks)
- {
- return recursiveList(repoName + ":/", version, 0, followLinks);
- }
-
- /**
- * Recursive list the given path.
- * @param path The path.
- * @param version The version.
- * @param indent The current indent level.
- */
- protected String recursiveList(String path, int version, int indent, boolean followLinks)
- {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < indent; i++)
- {
- builder.append(' ');
- }
- builder.append(path.substring(path.lastIndexOf('/') + 1));
- builder.append(' ');
- AVMNodeDescriptor desc = fService.lookup(version, path, true);
- builder.append(desc.toString());
-
- List ancs = fService.getHistory(desc, -1);
- for (AVMNodeDescriptor anc : ancs)
- {
- builder.append("--->").append(anc.toString());
- }
-
- builder.append('\n');
- if (desc.getType() == AVMNodeType.PLAIN_DIRECTORY ||
- (desc.getType() == AVMNodeType.LAYERED_DIRECTORY && followLinks))
- {
- String basename = path.endsWith("/") ? path : path + "/";
- Map listing = fService.getDirectoryListing(version, path);
- for (String name : listing.keySet())
- {
- if (logger.isTraceEnabled()) { logger.trace(name); }
- builder.append(recursiveList(basename + name, version, indent + 2, followLinks));
- }
- List deletedList = fService.getDeleted(version, path);
- for (String name : deletedList)
- {
- if (logger.isTraceEnabled()) { logger.trace(name); }
- builder.append(recursiveList(basename + name, version, indent + 2, followLinks));
- }
- }
- return builder.toString();
- }
-
- /**
- * Setup a basic tree.
- */
- protected void setupBasicTree()
- throws IOException
- {
- fService.createDirectory("main:/", "a");
- fService.createDirectory("main:/a", "b");
- fService.createDirectory("main:/a/b", "c");
- fService.createDirectory("main:/", "d");
- fService.createDirectory("main:/d", "e");
- fService.createDirectory("main:/d/e", "f");
-
-
- OutputStream out = fService.createFile("main:/a/b/c", "foo");
- byte [] buff = "I am main:/a/b/c/foo".getBytes();
- out.write(buff);
- out.close();
-
- /*
- fService.createFile("main:/a/b/c", "foo").close();
- ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo");
- writer.setEncoding("UTF-8");
- writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
- writer.putContent("I am main:/a/b/c/foo");
- */
-
- out = fService.createFile("main:/a/b/c", "bar");
- buff = "I am main:/a/b/c/bar".getBytes();
- out.write(buff);
- out.close();
-
- /*
- fService.createFile("main:/a/b/c", "bar").close();
- writer = fService.getContentWriter("main:/a/b/c/bar");
- // Force a conversion
- writer.setEncoding("UTF-16");
- writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
- writer.putContent("I am main:/a/b/c/bar");
- */
-
- fService.createSnapshot("main", null, null);
- }
-}
+/*
+ * 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.avm;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.avm.util.RemoteBulkLoader;
+import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
+import org.alfresco.service.cmr.avm.AVMNotFoundException;
+import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
+import org.alfresco.service.cmr.avm.VersionDescriptor;
+import org.alfresco.service.cmr.avmsync.AVMDifference;
+import org.alfresco.service.cmr.avmsync.AVMSyncException;
+import org.alfresco.service.cmr.avmsync.AVMSyncService;
+import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.remote.AVMRemote;
+import org.alfresco.service.cmr.security.AuthenticationService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.ApplicationContextHelper;
+import org.alfresco.util.NameMatcher;
+import org.springframework.extensions.surf.util.Pair;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * Local unit tests of AVM (AVMSyncService & AVMService)
+ */
+public class AVMServiceLocalTest extends TestCase
+{
+ private static Log logger = LogFactory.getLog(AVMServiceLocalTest.class);
+
+ /**
+ * The AVMRemote - can be local (AVMRemoteLocal) or remote (AVMRemote)
+ */
+ protected static AVMRemote fService;
+
+ /**
+ * The AVMSyncService - can be local (AVMSyncService) or remote (AVMSyncServiceRemote)
+ */
+ protected static AVMSyncService fSyncService;
+
+ /**
+ * The application context.
+ */
+ protected static ApplicationContext fContext;
+
+ protected static NameMatcher excluder;
+
+
+ protected void setUp() throws Exception
+ {
+ if (fContext == null)
+ {
+ // local (embedded) test setup
+ fContext = ApplicationContextHelper.getApplicationContext();
+ fService = (AVMRemote)fContext.getBean("avmRemote");
+ fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");
+ excluder = (NameMatcher) fContext.getBean("globalPathExcluder");
+
+ AuthenticationService authService = (AuthenticationService)fContext.getBean("AuthenticationService");
+ authService.authenticate(AuthenticationUtil.getAdminUserName(), "admin".toCharArray());
+ }
+
+ if (fService.getStore("main") == null)
+ {
+ fService.createStore("main");
+ }
+ if (fService.getStore("layer") == null)
+ {
+ fService.createStore("layer");
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ fService.purgeStore("main");
+ fService.purgeStore("layer");
+ }
+
+ public void testSetup() throws Exception
+ {
+ setUp();
+ }
+
+ public void testGetAPath() throws Exception
+ {
+ try
+ {
+ fService.createStore("test2932");
+ fService.createDirectory("test2932:/", "a");
+ fService.createFile("test2932:/a", "foo.txt").close();
+ AVMNodeDescriptor found = fService.lookup(-1, "test2932:/a/foo.txt");
+ Pair path = fService.getAPath(found);
+ assertEquals(path.getSecond(), "test2932:/a/foo.txt");
+ explorePaths("test2932:/");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("test2932");
+ }
+ }
+
+ /**
+ * Do a simple hello world test.
+ */
+ public void testSimple() throws Throwable
+ {
+ try
+ {
+ List stores = fService.getStores();
+
+ for (AVMStoreDescriptor store : stores)
+ {
+ if (logger.isDebugEnabled()) { logger.debug(store); }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ protected void explorePaths(String path) throws Exception
+ {
+ Map listing = fService.getDirectoryListing(-1, path);
+ for (Map.Entry entry : listing.entrySet())
+ {
+ Pair childPath = fService.getAPath(entry.getValue());
+ if (logger.isDebugEnabled()) { logger.debug(childPath); }
+ if (entry.getValue().isDirectory())
+ {
+ explorePaths(entry.getValue().getPath());
+ }
+ }
+ }
+
+ /**
+ * Test reading and writing.
+ */
+ public void testReadWrite() throws Throwable
+ {
+ try
+ {
+ // Create a test store.
+ fService.createStore("test2933");
+ // Create a directory.
+ fService.createDirectory("test2933:/", "a");
+ // Write out a file.
+ OutputStream out =
+ fService.createFile("test2933:/a", "foo.txt");
+ byte [] buff = "This is a plain old text file.\n".getBytes();
+ out.write(buff);
+ buff = "It contains text.\n".getBytes();
+ out.write(buff);
+ out.close();
+ // Read back that file.
+ InputStream in =
+ fService.getFileInputStream(-1, "test2933:/a/foo.txt");
+ buff = new byte[1024];
+ assertEquals(49, in.read(buff));
+ if (logger.isDebugEnabled()) { logger.debug(new String(buff)); }
+ assertEquals(-1, in.read(buff));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("test2933");
+ }
+ }
+
+ /**
+ * Another test of reading.
+ */
+ public void testRead() throws Throwable
+ {
+ try
+ {
+ fService.createStore("froo");
+ // Create a file.
+ byte [] buff = new byte[64];
+ for (int i = 0; i < 64; i++)
+ {
+ buff[i] = (byte)i;
+ }
+ OutputStream out =
+ fService.createFile("froo:/", "foo.dat");
+ out.write(buff, 32, 32);
+ out.close();
+ // Read it back in.
+ InputStream in =
+ fService.getFileInputStream(-1, "froo:/foo.dat");
+ buff = new byte[1024];
+ assertEquals(32, in.read(buff));
+ in.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("froo");
+ }
+ }
+
+ /**
+ * Test a call that should return null;
+ */
+ public void testErrorState() throws Throwable
+ {
+ try
+ {
+ assertNull(fService.lookup(-1, "main:/fizz/fazz"));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+
+ /**
+ * Test update to branch
+ */
+ public void testSimpleUpdateBR() throws Throwable
+ {
+ try
+ {
+ // Create a store.
+ fService.createStore("froo");
+ // Create a directory.
+ fService.createDirectory("froo:/", "a");
+ // Create a file.
+ fService.createFile("froo:/a", "foo").close();
+ // Create another store.
+ fService.createStore("broo");
+ // Create a branch.
+ fService.createBranch(-1, "froo:/a", "broo:/", "a");
+ List diffs = fSyncService.compare(-1, "froo:/a", -1, "broo:/a", null);
+ assertEquals(0, diffs.size());
+ fService.createFile("froo:/a", "bar").close();
+ diffs = fSyncService.compare(-1, "froo:/a", -1, "broo:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[froo:/a/bar[-1] > broo:/a/bar[-1]]", diffs.toString());
+ // Update.
+ fSyncService.update(diffs, null, false, false, false, false, "flippy", "Stuff");
+ diffs = fSyncService.compare(-1, "froo:/a", -1, "broo:/a", null);
+ assertEquals(0, diffs.size());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("broo");
+ fService.purgeStore("froo");
+ }
+ }
+
+ //
+ // Test updates to layered directories
+ //
+
+ public void testSimpleUpdateLD1() throws Throwable
+ {
+ try
+ {
+ List diffs = fSyncService.compare(-1, "main:/", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ diffs = fSyncService.compare(-1, "layer:/", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ // create file f-a in main root dir
+ fService.createFile("main:/", "f-a").close();
+
+ diffs = fSyncService.compare(-1, "layer:/", -1, "main:/", null);
+ assertEquals("[layer:/f-a[-1] < main:/f-a[-1]]", diffs.toString());
+ assertEquals(1, diffs.size());
+
+ fService.createLayeredDirectory("main:/", "layer:/", "layer");
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ // create file f-b in main root dir
+ fService.createFile("main:/", "f-b").close();
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ // edit file f-b in layer
+ fService.getFileOutputStream("layer:/layer/f-b").close();
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals("[layer:/layer/f-b[-1] > main:/f-b[-1]]", diffs.toString());
+ assertEquals(1, diffs.size());
+
+ // update main from layer
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ public void testSimpleUpdateLD2() throws Throwable
+ {
+ try
+ {
+ // create directories base/d-a and file f-aa in main
+ fService.createDirectory("main:/", "base");
+ fService.createDirectory("main:/base", "d-a");
+ fService.createFile("main:/base/d-a", "f-aa").close();
+
+ List diffs = fSyncService.compare(-1, "layer" + ":/", -1, "main:/", null);
+ assertEquals("[layer:/base[-1] < main:/base[-1]]", diffs.toString());
+ assertEquals(1, diffs.size());
+
+ fService.createLayeredDirectory("main:/base", "layer:/", "layer-to-base");
+
+ diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals(0, diffs.size());
+
+ // edit file f-aa in main
+ fService.getFileOutputStream("main:/base/d-a/f-aa").close();
+
+ diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals(0, diffs.size());
+
+ // edit file f-aa in layer
+ fService.getFileOutputStream("layer:/layer-to-base/d-a/f-aa").close();
+
+ diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals("[layer:/layer-to-base/d-a/f-aa[-1] > main:/base/d-a/f-aa[-1]]", diffs.toString());
+ assertEquals(1, diffs.size());
+
+ // update main from layer
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals(0, diffs.size());
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ public void testSimpleUpdateLD3() throws Throwable
+ {
+ try
+ {
+ fService.createDirectory("main:/", "base");
+
+ fService.createLayeredDirectory("main:/base", "layer:/", "layer-to-base");
+
+ List diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals(0, diffs.size());
+
+ // create directory d-a and file f-aa in layer
+ fService.createDirectory("layer:/layer-to-base", "d-a");
+ fService.createFile("layer:/layer-to-base/d-a", "f-aa").close();
+
+ diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals("[layer:/layer-to-base/d-a[-1] > "+"main:/base/d-a[-1]]", diffs.toString());
+ assertEquals(1, diffs.size());
+
+ // update main from layer
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer-to-base", -1, "main:/base", null);
+ assertEquals(0, diffs.size());
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ public void testSimpleUpdateLD4() throws Exception
+ {
+ try
+ {
+ fService.createLayeredDirectory("main:/", "layer:/", "layer");
+
+ // create directory b and file foo in layer
+ fService.createDirectory("layer:/layer", "b");
+ fService.createFile("layer:/layer/b", "foo").close();
+
+ List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fService.createSnapshot("layer", null, null);
+
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ fService.createSnapshot("main", null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ fService.createStore("layer2");
+ fService.createLayeredDirectory("layer:/layer", "layer2:/", "layer");
+
+ // create directory c and file foo in layer2
+ fService.createDirectory("layer2:/layer/", "c");
+ fService.createFile("layer2:/layer/c", "foo").close();
+
+ fService.createSnapshot("layer2", null, null);
+
+ diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer2:/layer/c[-1] > layer:/layer/c[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer2:/layer", "layer:/layer");
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/c[-1] > main:/c[-1]]", diffs.toString());
+
+ recursiveList("main");
+ recursiveList("layer");
+ recursiveList("layer2");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("layer2");
+ }
+ }
+
+ public void testSimpleUpdateLD5() throws Exception
+ {
+ try
+ {
+ logger.debug("created 2 stores: main, layer");
+
+ fService.createLayeredDirectory("main:/", "layer:/", "layer");
+
+ logger.debug("created layered dir: layer:/layer -> main:/");
+
+ fService.createDirectory("layer:/layer", "b");
+
+ logger.debug("created dir in layer: layer:/layer/b");
+
+ List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ logger.debug("updated & flattened: created directory: main:/b");
+
+ fService.createFile("layer:/layer/b", "foo").close();
+ fService.createFile("layer:/layer/b", "bar").close();
+
+ logger.debug("created 2 files in layer: layer:/layer/b/foo and layer:/layer/b/bar");
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(2, diffs.size());
+ assertEquals("[layer:/layer/b/bar[-1] > main:/b/bar[-1], layer:/layer/b/foo[-1] > main:/b/foo[-1]]", diffs.toString());
+
+ // submit only first diff
+ List selected = new ArrayList(1);
+ selected.add(diffs.get(1));
+
+ assertEquals("[layer:/layer/b/foo[-1] > main:/b/foo[-1]]", selected.toString());
+
+ fSyncService.update(selected, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/b/bar[-1] > main:/b/bar[-1]]", diffs.toString());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ logger.debug("updated & flattened: created file: main:/b/foo");
+
+ fService.removeNode("layer:/layer", "b");
+ fService.createSnapshot("layer", null, null);
+
+ logger.debug("removed dir in layer & snapshot: layer:/layer/b");
+
+ // ETWOTWO-1266
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ logger.debug("updated & flattened: deleted dir: main:/b");
+
+ recursiveList("main");
+ recursiveList("layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ public void testDeleteLD1() throws Exception
+ {
+ try
+ {
+ logger.debug("created 2 stores: main, layer");
+
+ fService.createDirectory("main:/", "a");
+
+ OutputStream o = fService.createFile("main:/a", "foo");
+ PrintStream out = new PrintStream(o);
+ out.println("I am main:/a/foo");
+ out.close();
+
+ logger.debug("created file in main: main:/a/foo");
+
+ fService.createLayeredDirectory("main:/a", "layer:/", "a");
+
+ logger.debug("created layered dir: layer:/a -> main:/a");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
+ out.println("I am layer:/a/foo");
+ out.close();
+
+ logger.debug("update file in layer: layer:/a/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/a/foo[-1] > main:/a/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/a", "main:/a");
+
+ logger.debug("updated & flattened: updated file: main:/a/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ fService.removeNode("main:/", "a");
+ fService.createSnapshot("main", null, null);
+
+ logger.debug("remove directory in main & snapshot: main:/a");
+
+ assertNotNull(fService.lookup(-1, "layer:/a"));
+ assertNull(fService.lookup(-1, "layer:/a/foo"));
+
+ try
+ {
+ fService.getFileInputStream(-1, "layer:/a/foo");
+ fail();
+ }
+ catch (AVMNotFoundException nfe)
+ {
+ // expected
+ }
+
+ try
+ {
+ fService.getFileOutputStream("layer:/a/foo");
+ fail();
+ }
+ catch (AVMNotFoundException nfe)
+ {
+ // expected
+ }
+
+ recursiveList("main");
+ recursiveList("layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ public void testDeleteLD2() throws Exception
+ {
+ try
+ {
+ logger.debug("created 2 stores: main, layer");
+
+ fService.createDirectory("main:/", "a");
+
+ OutputStream o = fService.createFile("main:/a", "foo");
+ PrintStream out = new PrintStream(o);
+ out.println("I am main:/a/foo");
+ out.close();
+
+ logger.debug("created file in main: main:/a/foo");
+
+ fService.createLayeredDirectory("main:/a", "layer:/", "a");
+
+ logger.debug("created layered dir: layer:/a -> main:/a");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
+ out.println("I am layer:/a/foo");
+ out.close();
+
+ logger.debug("update file in layer: layer:/a/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ fService.removeNode("main:/", "a");
+
+ logger.debug("remove directory in main: main:/a");
+
+ fService.createSnapshot("main", null, null);
+
+ logger.debug("snapshot: main:/a");
+
+ assertNull(fService.lookup(-1, "main:/a"));
+ assertNull(fService.lookup(-1, "main:/a/foo"));
+
+ try
+ {
+ fService.getFileInputStream(-1, "main:/a/foo");
+ fail();
+ }
+ catch (AVMNotFoundException nfe)
+ {
+ // expected
+ }
+
+ assertNotNull(fService.lookup(-1, "layer:/a"));
+ assertNotNull(fService.lookup(-1, "layer:/a/foo"));
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
+ out.println("I am layer:/a/foo V2");
+ out.close();
+
+ List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/a[-1] > main:/a[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(0, diffs.size());
+
+ logger.debug("updated: updated dir & file: main:/a/foo");
+
+ fSyncService.flatten("layer:/a", "main:/a");
+
+ logger.debug("flattened: layer:/a -> main:/a");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo V2", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo V2", line);
+
+ recursiveList("main");
+ recursiveList("layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ /**
+ * Test bulk update (using layered directory).
+ */
+ public void testBulkUpdateLD() throws Exception
+ {
+ try
+ {
+ RemoteBulkLoader loader = new RemoteBulkLoader();
+ loader.setAvmRemoteService(fService);
+
+ fService.createLayeredDirectory("main:/", "layer:/", "layer");
+ loader.recursiveLoad("config/alfresco/bootstrap", "layer:/layer");
+ List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/bootstrap[-1] > main:/bootstrap[-1]]", diffs.toString());
+ fService.createSnapshot("layer", null, null);
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+ fSyncService.flatten("layer:/layer", "main:/");
+ recursiveList("layer");
+ recursiveList("main");
+ fService.createStore("layer2");
+ fService.createLayeredDirectory("layer:/layer", "layer2:/", "layer");
+ loader.recursiveLoad("config/alfresco/bootstrap", "layer2:/layer/bootstrap");
+ fService.createSnapshot("layer2", null, null);
+ diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer2:/layer/bootstrap/bootstrap[-1] > layer:/layer/bootstrap/bootstrap[-1]]", diffs.toString());
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer", null);
+ assertEquals(0, diffs.size());
+ fSyncService.flatten("layer2:/layer", "layer:/layer");
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/layer/bootstrap/bootstrap[-1] > main:/bootstrap/bootstrap[-1]]", diffs.toString());
+ recursiveList("layer2");
+ recursiveList("layer");
+ recursiveList("main");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("layer2");
+ }
+ }
+
+ /**
+ * Test the flatten operation, with a little bit of compare and update.
+ */
+ public void testFlatten() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createLayeredDirectory("main:/a", "main:/", "layer");
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ // Change some stuff.
+ fService.createFile("main:/layer/b", "fig").close();
+ fService.getFileOutputStream("main:/layer/b/c/foo").close();
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ // Do a compare.
+ List diffs = fSyncService.compare(-1, "main:/layer", -1, "main:/a", null);
+ assertEquals(2, diffs.size());
+ assertEquals("[main:/layer/b/c/foo[-1] > main:/a/b/c/foo[-1], main:/layer/b/fig[-1] > main:/a/b/fig[-1]]", diffs.toString());
+ // Update.
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ recursiveList("main");
+ // Flatten.
+ fSyncService.flatten("main:/layer", "main:/a");
+ recursiveList("main");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ /**
+ * Test partial flatten.
+ */
+ public void testPartialFlatten() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createLayeredDirectory("main:/a", "layer:/", "a");
+ fService.getFileOutputStream("layer:/a/b/c/foo").close();
+ fService.createFile("layer:/a/b", "bing").close();
+ List diffs = new ArrayList();
+ diffs.add(new AVMDifference(-1, "layer:/a/b/c/foo", -1, "main:/a/b/c/foo", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fSyncService.flatten("layer:/a", "main:/a");
+ AVMNodeDescriptor b = fService.lookup(-1, "layer:/a/b");
+ assertTrue(b.isLayeredDirectory());
+ AVMNodeDescriptor c = fService.lookup(-1, "layer:/a/b/c");
+ assertTrue(c.isPlainDirectory());
+ diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[layer:/a/b/bing[-1] > main:/a/b/bing[-1]]", diffs.toString());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ /**
+ * Test AVMSyncService resetLayer.
+ */
+ public void testResetLayer() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createLayeredDirectory("main:/a", "main:/", "layer");
+ fService.createFile("main:/layer", "figs").close();
+ assertFalse(recursiveContents("main:/a", -1, true).equals(recursiveContents("main:/layer", -1, true)));
+ recursiveList("main");
+ fSyncService.resetLayer("main:/layer");
+ assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true));
+ recursiveList("main");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ /**
+ * Test AVMSyncService update.
+ */
+ public void testUpdate() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ // Try branch to branch update.
+ fService.createBranch(-1, "main:/a", "main:/", "abranch");
+ fService.createFile("main:/abranch", "monkey").close();
+ fService.createFile("main:/abranch", "#foo").close();
+ fService.createFile("main:/abranch", "figs.tmp").close();
+ fService.getFileOutputStream("main:/abranch/b/c/foo").close();
+ recursiveList("main");
+ List cmp = fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder);
+ assertEquals(2, cmp.size());
+ assertEquals("[main:/abranch/b/c/foo[-1] > main:/a/b/c/foo[-1], main:/abranch/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
+ List diffs = new ArrayList();
+ diffs.add(new AVMDifference(-1, "main:/abranch/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
+ diffs.add(new AVMDifference(-1, "main:/abranch/b/c/foo", -1, "main:/a/b/c/foo", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ assertEquals(fService.lookup(-1, "main:/abranch/monkey").getId(), fService.lookup(-1, "main:/a/monkey").getId());
+ assertEquals(fService.lookup(-1, "main:/abranch/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/c/foo").getId());
+ // Try updating a deletion.
+ fService.removeNode("main:/abranch", "monkey");
+ recursiveList("main");
+ cmp = fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder);
+ assertEquals(1, cmp.size());
+ assertEquals("[main:/abranch/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/abranch/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ assertEquals(0, fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder).size());
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ assertEquals(fService.lookup(-1, "main:/abranch/monkey", true).getId(), fService.lookup(-1, "main:/a/monkey", true).getId());
+ // Try one that should fail.
+ fService.createFile("main:/abranch", "monkey").close();
+ cmp = fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder);
+ assertEquals(1, cmp.size());
+ assertEquals("[main:/abranch/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/abranch/monkey", AVMDifference.NEWER));
+ try
+ {
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fail();
+ }
+ catch (AVMSyncException se)
+ {
+ // Do nothing.
+ }
+ // Get synced again by doing an override older.
+ recursiveList("main");
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/abranch/monkey", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, true, null, null);
+ assertEquals(0, fSyncService.compare(-1, "main:/abranch", -1, "main:/a", excluder).size());
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ assertEquals(fService.lookup(-1, "main:/a/monkey", true).getId(), fService.lookup(-1, "main:/abranch/monkey", true).getId());
+ // Cleanup for layered tests.
+ fService.purgeStore("main");
+ fService.createStore("main");
+ setupBasicTree();
+ fService.createLayeredDirectory("main:/a", "main:/", "layer");
+ fService.createFile("main:/layer", "monkey").close();
+ fService.getFileOutputStream("main:/layer/b/c/foo").close();
+ cmp = fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder);
+ assertEquals(2, cmp.size());
+ assertEquals("[main:/layer/b/c/foo[-1] > main:/a/b/c/foo[-1], main:/layer/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
+ recursiveList("main");
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/layer/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
+ diffs.add(new AVMDifference(-1, "main:/layer/b/c/foo", -1, "main:/a/b/c/foo", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ assertEquals(0, fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder).size());
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ assertEquals(fService.lookup(-1, "main:/layer/monkey").getId(), fService.lookup(-1, "main:/a/monkey").getId());
+ assertEquals(fService.lookup(-1, "main:/layer/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/c/foo").getId());
+ // Try updating a deletion.
+ fService.removeNode("main:/layer", "monkey");
+ recursiveList("main");
+ cmp = fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder);
+ assertEquals(1, cmp.size());
+ assertEquals("[main:/layer/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/layer/monkey", -1, "main:/a/monkey", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ assertEquals(0, fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder).size());
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ assertEquals(fService.lookup(-1, "main:/layer/monkey", true).getId(), fService.lookup(-1, "main:/a/monkey", true).getId());
+ // Try one that should fail.
+ fService.createFile("main:/layer", "monkey").close();
+ cmp = fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder);
+ assertEquals(1, cmp.size());
+ assertEquals("[main:/layer/monkey[-1] > main:/a/monkey[-1]]", cmp.toString());
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/layer/monkey", AVMDifference.NEWER));
+ try
+ {
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fail();
+ }
+ catch (AVMSyncException se)
+ {
+ // Do nothing.
+ }
+ // Get synced again by doing an override older.
+ recursiveList("main");
+ diffs.clear();
+ diffs.add(new AVMDifference(-1, "main:/a/monkey", -1, "main:/layer/monkey", AVMDifference.NEWER));
+ fSyncService.update(diffs, null, false, false, false, true, null, null);
+ assertEquals(0, fSyncService.compare(-1, "main:/layer", -1, "main:/a", excluder).size());
+ fService.createSnapshot("main", null, null);
+ recursiveList("main");
+ assertEquals(fService.lookup(-1, "main:/a/monkey", true).getId(), fService.lookup(-1, "main:/layer/monkey", true).getId());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ /**
+ * Test that an update forces a snapshot on the source.
+ */
+ public void testUpdateSnapshot() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createStore("branch");
+ fService.createBranch(-1, "main:/", "branch:/", "branch");
+ // Modify some things in the branch.
+ fService.createFile("branch:/branch/a/b", "fing").close();
+ fService.getFileOutputStream("branch:/branch/a/b/c/foo").close();
+ fService.removeNode("branch:/branch/a/b/c", "bar");
+ List diffs = fSyncService.compare(-1, "branch:/branch", -1, "main:/", null);
+ assertEquals(3, diffs.size());
+ assertEquals("[branch:/branch/a/b/c/bar[-1] > main:/a/b/c/bar[-1], branch:/branch/a/b/c/foo[-1] > main:/a/b/c/foo[-1], branch:/branch/a/b/fing[-1] > main:/a/b/fing[-1]]", diffs.toString());
+ // Now update.
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ diffs = fSyncService.compare(-1, "branch:/branch", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+ fService.getFileOutputStream("branch:/branch/a/b/fing").close();
+ assertTrue(fService.lookup(-1, "branch:/branch/a/b/fing").getId() != fService.lookup(-1, "main:/a/b/fing").getId());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("branch");
+ }
+ }
+
+ /**
+ * Test a noodle update.
+ */
+ public void testNoodleUpdate() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createStore("staging");
+ List diffs = fSyncService.compare(-1, "main:/", -1, "staging:/", null);
+ assertEquals(2, diffs.size());
+ assertEquals("[main:/a[-1] > staging:/a[-1], main:/d[-1] > staging:/d[-1]]", diffs.toString());
+ List noodle = new ArrayList();
+ noodle.add(new AVMDifference(-1, "main:/a/b/c/foo", -1, "staging:/a/b/c/foo", AVMDifference.NEWER));
+ noodle.add(new AVMDifference(-1, "main:/d", -1, "staging:/d", AVMDifference.NEWER));
+ fSyncService.update(noodle, null, false, false, false, false, null, null);
+ diffs = fSyncService.compare(-1, "main:/", -1, "staging:/", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[main:/a/b/c/bar[-1] > staging:/a/b/c/bar[-1]]", diffs.toString());
+ assertEquals("main:/a/b/c/bar", diffs.get(0).getSourcePath());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("staging");
+ }
+ }
+
+
+ public void testRename6() throws Exception
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createLayeredDirectory("main:/a", "layer:/", "a");
+ fService.rename("layer:/a/b", "c", "layer:/a/b", "z");
+ recursiveContents("layer:/");
+ List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(2, diffs.size());
+ assertEquals("[layer:/a/b/c[-1] > main:/a/b/c[-1], layer:/a/b/z[-1] > main:/a/b/z[-1]]", diffs.toString());
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ recursiveContents("layer:/");
+ recursiveContents("main:/");
+ fSyncService.flatten("layer:/a", "main:/a");
+ recursiveContents("layer:/");
+ recursiveContents("main:/");
+ fService.createFile("layer:/a/b/z", "fudge").close();
+ fService.rename("layer:/a/b", "z", "layer:/a/b", "y");
+ recursiveContents("layer:/");
+ diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(2, diffs.size());
+ assertEquals("[layer:/a/b/y[-1] > main:/a/b/y[-1], layer:/a/b/z[-1] > main:/a/b/z[-1]]", diffs.toString());
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ recursiveContents("layer:/");
+ recursiveContents("main:/");
+ fSyncService.flatten("layer:/a", "main:/a");
+ recursiveContents("layer:/");
+ recursiveContents("main:/");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ /**
+ * Test file properties update ...
+ */
+ public void testUpdateFileTitleAndDescription() throws Exception
+ {
+ try
+ {
+ fService.createLayeredDirectory("main:/", "layer:/", "layer");
+ fService.createDirectory("layer:/layer", "b");
+ fService.createFile("layer:/layer/b", "foo").close();
+
+ List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fService.createSnapshot("layer", null, null);
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ assertEquals(0, fService.getNodeProperties(-1, "main:/b/foo").size());
+ assertEquals(0, fService.getNodeProperties(-1, "layer:/layer/b/foo").size());
+
+ Map properties = new HashMap();
+ properties.put(ContentModel.PROP_TITLE, new PropertyValue(DataTypeDefinition.TEXT, "foo title"));
+ properties.put(ContentModel.PROP_DESCRIPTION, new PropertyValue(DataTypeDefinition.TEXT, "foo descrip"));
+ fService.setNodeProperties("layer:/layer/b/foo", properties);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals("[layer:/layer/b/foo[-1] > main:/b/foo[-1]]", diffs.toString());
+
+ fService.createSnapshot("layer", null, null);
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ assertEquals(2, fService.getNodeProperties(-1, "main:/b/foo").size());
+
+ assertEquals("foo title", fService.getNodeProperty(-1, "main:/b/foo", ContentModel.PROP_TITLE).getStringValue());
+ assertEquals("foo descrip", fService.getNodeProperty(-1, "main:/b/foo", ContentModel.PROP_DESCRIPTION).getStringValue());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ /**
+ * Test directory properties update ...
+ */
+ public void testUpdateDirectoryTitleAndDescription() throws Exception
+ {
+ try
+ {
+ fService.createLayeredDirectory("main:/", "layer:/", "layer");
+ fService.createDirectory("layer:/layer", "b");
+ fService.createFile("layer:/layer/b", "foo").close();
+
+ List diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fService.createSnapshot("layer", null, null);
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ assertEquals(0, fService.getNodeProperties(-1, "main:/b").size());
+ assertEquals(0, fService.getNodeProperties(-1, "layer:/layer/b").size());
+
+ Map properties = new HashMap();
+ properties.put(ContentModel.PROP_TITLE, new PropertyValue(DataTypeDefinition.TEXT, "b title"));
+ properties.put(ContentModel.PROP_DESCRIPTION, new PropertyValue(DataTypeDefinition.TEXT, "b descrip"));
+ fService.setNodeProperties("layer:/layer/b", properties);
+
+ assertEquals(0, fService.getNodeProperties(-1, "main:/b").size());
+ assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fService.createSnapshot("layer", null, null);
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+
+ assertEquals(2, fService.getNodeProperties(-1, "main:/b").size());
+ assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ assertEquals(2, fService.getNodeProperties(-1, "main:/b").size());
+ assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
+
+ assertEquals("b title", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_TITLE).getStringValue());
+ assertEquals("b descrip", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_DESCRIPTION).getStringValue());
+
+ fService.setNodeProperty("layer:/layer/b", ContentModel.PROP_TITLE, new PropertyValue(DataTypeDefinition.TEXT, "b title2"));
+ fService.setNodeProperty("layer:/layer/b", ContentModel.PROP_DESCRIPTION, new PropertyValue(DataTypeDefinition.TEXT, "b descrip2"));
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals("[layer:/layer/b[-1] > main:/b[-1]]", diffs.toString());
+
+ fService.createSnapshot("layer", null, null);
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+ fService.createSnapshot("main", null, null);
+
+ diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.flatten("layer:/layer", "main:/");
+
+ assertEquals(2, fService.getNodeProperties(-1, "main:/b").size());
+ assertEquals(2, fService.getNodeProperties(-1, "layer:/layer/b").size());
+
+ assertEquals("b title2", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_TITLE).getStringValue());
+ assertEquals("b descrip2", fService.getNodeProperty(-1, "main:/b", ContentModel.PROP_DESCRIPTION).getStringValue());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ public void testSimpleUpdateLF1() throws Exception
+ {
+ try
+ {
+ List snapshots = fService.getStoreVersions("main");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("layer");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ fService.createDirectory("main:/", "a");
+ fService.createDirectory("layer:/", "a");
+
+ logger.debug("created 2 plain dirs: main:/a, layer:/a");
+
+ fService.createFile("main:/a", "foo");
+
+ assertEquals(1, fService.lookup(-1, "main:/a/foo").getVersionID());
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("main:/a/foo"));
+ out.println("I am main:/a/foo");
+ out.close();
+
+ AVMNodeDescriptor node = fService.lookup(-1, "main:/a/foo");
+ assertEquals(1, node.getVersionID());
+ List history = fService.getHistory(node, -1);
+ assertEquals(0, history.size());
+
+ fService.createSnapshot("main", null, null);
+
+ snapshots = fService.getStoreVersions("main");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ snapshots = fService.getStoreVersions("layer");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ assertEquals(1, fService.lookup(-1, "main:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(1, "main:/a/foo").getVersionID());
+
+ logger.debug("created plain file: main:/a/foo");
+
+ fService.createLayeredFile("main:/a/foo", "layer:/a", "foo");
+
+ assertEquals(1, fService.lookup(-1, "layer:/a/foo").getVersionID());
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ node = fService.lookup(-1, "layer:/a/foo");
+ assertEquals(1, node.getVersionID());
+
+ history = fService.getHistory(node, -1);
+ assertEquals(0, history.size());
+
+ fService.createSnapshot("layer", null, null);
+
+ snapshots = fService.getStoreVersions("main");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ snapshots = fService.getStoreVersions("layer");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ assertEquals(1, fService.lookup(-1, "layer:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(1, "layer:/a/foo").getVersionID());
+
+ List diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(0, diffs.size());
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ logger.debug("created layered file: layer:/a/foo -> main:/a/foo");
+
+ out = new PrintStream(fService.getFileOutputStream("layer:/a/foo"));
+ out.println("I am layer:/a/foo");
+ out.close();
+
+ logger.debug("modified file: layer:/a/foo");
+
+ assertEquals(2, fService.lookup(-1, "layer:/a/foo").getVersionID());
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/foo", line);
+
+ diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null);
+ assertEquals(1, diffs.size());
+
+ // TODO - review behaviour
+ assertEquals("[layer:/a/foo[-1] > main:/a/foo[-1]]", diffs.toString());
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+
+ // update will implicitly snapshot (src and dst)
+ snapshots = fService.getStoreVersions("main");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ snapshots = fService.getStoreVersions("layer");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ node = fService.lookup(-1, "layer:/a/foo");
+ assertEquals(2, node.getVersionID());
+ history = fService.getHistory(node, -1);
+
+ assertEquals(1, history.size());
+ assertEquals(1, history.get(0).getVersionID());
+
+ assertEquals(1, fService.lookup(1, "layer:/a/foo").getVersionID());
+ assertEquals(2, fService.lookup(2, "layer:/a/foo").getVersionID());
+
+ logger.debug("submitted/updated file: layer:/a/foo -> main:/a/foo");
+
+ fSyncService.flatten("layer:/a", "main:/a");
+
+ logger.debug("flatten dir: layer:/a -> main:/a");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am layer:/a/foo", line);
+
+ snapshots = fService.getStoreVersions("main");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ snapshots = fService.getStoreVersions("layer");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ recursiveList("main");
+ recursiveList("layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+
+ public void testSimpleUpdateLF2() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+ fService.createStore("mainB--layer");
+
+ List snapshots = fService.getStoreVersions("mainA");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB--layer");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ logger.debug("created 3 stores: mainA, mainB, mainB-layer");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainB:/", "a");
+
+ logger.debug("created 2 plain dirs: mainA:/a, mainB:/a");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
+
+ // note: unlike WCM, edit staging directly (ie. don't bother with mainA--layer for now)
+ fService.createFile("mainA:/a", "foo");
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertNull(fService.lookup(-1, "mainB:/a/foo"));
+ assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
+ out.println("I am mainA:/a/foo");
+ out.close();
+
+ logger.debug("created plain file: mainA:/a/foo");
+
+ fService.createSnapshot("mainA", null, null);
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertNull(fService.lookup(-1, "mainB:/a/foo"));
+ assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
+
+ snapshots = fService.getStoreVersions("mainA");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ logger.debug("created snapshot: mainA");
+
+ // note: WCM does not expose layered file (between web project staging sandboxes)
+ fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
+
+ // modify file in user's sandbox
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/foo"));
+ out.println("I am mainB--layer:/a/foo");
+ out.close();
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
+ assertEquals(2, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
+
+ logger.debug("modified file: mainB--layer:/a/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+
+ // TODO - review behaviour
+ assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertEquals(2, fService.lookup(-1, "mainB:/a/foo").getVersionID());
+ assertEquals(2, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB--layer");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ logger.debug("submit/update file: mainB--layer:/a/foo -> mainB:/a/foo");
+
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("flatten dir: mainB--layer:/a/foo -> mainB:/a/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testSimpleUpdateLF3() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+ fService.createStore("mainB--layer");
+
+ List snapshots = fService.getStoreVersions("mainA");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB--layer");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ logger.debug("created 3 stores: mainA, mainB, mainB-layer");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainB:/", "a");
+
+ logger.debug("created 2 plain dirs: mainA:/a, mainB:/a");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
+
+ // note: unlike WCM, edit staging directly (ie. don't bother with mainA--layer for now)
+ fService.createFile("mainA:/a", "foo");
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertNull(fService.lookup(-1, "mainB:/a/foo"));
+ assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
+ out.println("I am mainA:/a/foo");
+ out.close();
+
+ logger.debug("created plain file: mainA:/a/foo");
+
+ fService.createSnapshot("mainA", null, null);
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertNull(fService.lookup(-1, "mainB:/a/foo"));
+ assertNull(fService.lookup(-1, "mainB--layer:/a/foo"));
+
+ snapshots = fService.getStoreVersions("mainA");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ logger.debug("created snapshot: mainA");
+
+ // note: WCM does not expose layered file (between web project staging sandboxes)
+ fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
+
+ AVMNodeDescriptor foo = fService.lookup(-1, "mainB--layer:/a/foo");
+ assertEquals(1, foo.getVersionID());
+ assertTrue(foo.isLayeredFile());
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
+
+ // add dir in user's sandbox
+ fService.createDirectory("mainB--layer:/a", "b");
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(-1, "mainB:/a/foo").getVersionID());
+ assertEquals(1, fService.lookup(-1, "mainB--layer:/a/b").getVersionID());
+
+ foo = fService.lookup(-1, "mainB--layer:/a/foo");
+ assertEquals(1, foo.getVersionID());
+ assertTrue(foo.isLayeredFile());
+
+ logger.debug("created dir: mainB--layer:/a/b");
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+
+ foo = fService.lookup(-1, "mainB--layer:/a/foo");
+ assertTrue(foo.isLayeredFile());
+
+ assertEquals("[mainB--layer:/a/b[-1] > mainB:/a/b[-1]]", diffs.toString());
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+
+ foo = fService.lookup(-1, "mainB--layer:/a/foo");
+ assertTrue(foo.isLayeredFile());
+
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ foo = fService.lookup(-1, "mainB--layer:/a/foo");
+ assertTrue(foo.isLayeredFile());
+
+ assertEquals(1, fService.lookup(-1, "mainA:/a/foo").getVersionID());
+ assertEquals(2, fService.lookup(-1, "mainB:/a/foo").getVersionID());
+ assertEquals(2, fService.lookup(-1, "mainB--layer:/a/foo").getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB--layer");
+ assertEquals(2, snapshots.size());
+ assertEquals(1, snapshots.get(snapshots.size()-1).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ logger.debug("submitted dir: mainB--layer:/a/b -> mainB:/a/b");
+
+ foo = fService.lookup(-1, "mainB--layer:/a/foo");
+ assertEquals(2, foo.getVersionID());
+ assertTrue(foo.isLayeredFile());
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFolder1() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainA:/a", "b");
+
+ fService.createDirectory("mainB:/", "a");
+
+ fService.createStore("mainB--layer");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to mainA:/a/b)
+ fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
+
+ logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
+
+ fService.createDirectory("mainB--layer:/a", "c");
+
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("created dir: mainB--layer:/a/c");
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/c[-1] > mainB:/a/c[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated: created dir: mainB:/a/c");
+
+ assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
+
+ fService.createDirectory("mainB--layer:/a/b", "c");
+
+ assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
+
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("created dir: mainB--layer:/a/b/c");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/c[-1] > mainB:/a/b/c[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated: created dir: mainB:/a/b/c");
+
+ assertTrue(fService.lookup(-1, "mainB--layer:/a/b").isLayeredDirectory());
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFolder2() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainA:/a", "b");
+
+ fService.createDirectory("mainB:/", "a");
+
+ fService.createStore("mainB--layer");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ List snapshots = fService.getStoreVersions("mainA");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ snapshots = fService.getStoreVersions("mainB--layer");
+ assertEquals(1, snapshots.size());
+ assertEquals(0, snapshots.get(0).getVersionID());
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to mainA:/a/b)
+ fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
+
+ logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ fService.createFile("mainB--layer:/a/b", "bar");
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/bar"));
+ out.println("I am mainB--layer:/a/b/bar");
+ out.close();
+
+ logger.debug("created file: mainB--layer:/a/b/bar");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/bar[-1] > mainB:/a/b/bar[-1]]", diffs.toString());
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(1, snapshots.size());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(3, snapshots.size());
+
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated: created file: mainB:/a/b/bar");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(3, snapshots.size());
+ assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID());
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "baz");
+
+ out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/baz"));
+ out.println("I am mainA:/a/b/baz");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/baz");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ fService.createSnapshot("mainB", "two", "two");
+
+ logger.debug("snapshot: mainB");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ snapshots = fService.getStoreVersions("mainB");
+ assertEquals(4, snapshots.size());
+ assertEquals(3, snapshots.get(snapshots.size()-1).getVersionID());
+
+ // ETHREEOH-3340
+ diffs = fSyncService.compare(2, "mainB:/a", 3, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB:/a/b/baz[2] < mainB:/a/b/baz[3]]", diffs.toString());
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+
+ logger.debug("list mainB [2]");
+
+ recursiveList("mainB", 2);
+
+ logger.debug("list mainB [3]");
+
+ recursiveList("mainB", 3);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFolderDelete1() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainA:/a", "b");
+
+ fService.createDirectory("mainB:/", "a");
+
+ fService.createStore("mainB--layer");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
+ fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
+ out.println("I am mainB--layer:/a/b/foo");
+ out.close();
+
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("updated file: mainB--layer:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated: created file: mainB:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ // delete file - note: short-cut - removed directly from "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.removeNode("mainA:/a/b", "foo");
+ fService.createSnapshot("mainA", null, null);
+
+ logger.debug("removed file & snapshot: mainA:/a/b/foo");
+
+ // ETHREEOH-2297
+ fService.removeNode("mainB--layer:/a/b", "foo");
+ fService.createSnapshot("mainB--layer", null, null);
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("updated: removed file: mainB:/a/b/foo");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFolderDelete2() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainA:/a", "b");
+
+ fService.createDirectory("mainB:/", "a");
+
+ fService.createStore("mainB--layer");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
+ fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
+ out.println("I am mainB--layer:/a/b/foo");
+ out.close();
+
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("updated file: mainB--layer:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated: created file: mainB:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ // delete folder - note: short-cut - remove directly from "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.removeNode("mainA:/a", "b");
+ fService.createSnapshot("mainA", null, null);
+
+ logger.debug("removed folder & snapshot: mainA:/a/b");
+
+ fService.removeNode("mainB--layer:/a/b", "foo");
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("removed file & snapshot: mainB--layer:/a/b/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: removed file: mainB:/a/b/foo");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFolderDelete3() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainA:/a", "b");
+
+ fService.createDirectory("mainB:/", "a");
+
+ fService.createStore("mainB--layer");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
+ fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
+ out.println("I am mainB--layer:/a/b/foo");
+ out.close();
+
+ logger.debug("updated file: mainB--layer:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated: created file: mainB:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ // delete folder - note: short-cut - remove directly from "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.removeNode("mainA:/a", "b");
+ fService.createSnapshot("mainA", null, null);
+
+ logger.debug("removed folder & snapshot: mainA:/a/b");
+
+ fService.createFile("mainB--layer:/a/b", "bar");
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/bar"));
+ out.println("I am mainB--layer:/a/b/bar");
+ out.close();
+
+ logger.debug("created file: mainB--layer:/a/b/bar");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/bar[-1] > mainB:/a/b/bar[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "two", "two");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: created file: mainB:/a/b/bar");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFolderDelete4() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainA:/a", "b");
+
+ fService.createDirectory("mainB:/", "a");
+
+ fService.createStore("mainB--layer");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
+ fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
+ out.println("I am mainB--layer:/a/b/foo");
+ out.close();
+
+ logger.debug("updated file: mainB--layer:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: updated file: mainB:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ // delete folder - note: short-cut - remove directly from "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.removeNode("mainA:/a", "b");
+ fService.createSnapshot("mainA", null, null);
+
+ logger.debug("removed folder & snapshot: mainA:/a/b");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/foo"));
+ out.println("I am mainB--layer:/a/b/foo V2");
+ out.close();
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo V2", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo", line);
+
+ logger.debug("updated file: mainB--layer:/a/b/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(1, diffs.size());
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "two", "two");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: updated file: mainB:/a/b/foo");
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainB--layer:/a/b/foo V2", line);
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFileDeleteFile1() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+ fService.createStore("mainB--layer");
+
+ logger.debug("created 3 stores: mainA, mainB, mainB--layer");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainB:/", "a");
+
+ logger.debug("created 2 plain dirs: mainA:/a and mainB:/a");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
+ out.println("I am mainA:/a/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
+ fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
+
+ logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created 2 snapshots: mainA and mainB");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(0, diffs.size());
+
+ fService.removeNode("mainB--layer:/a", "foo");
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("removed file & snapshot: mainB--layer:/a/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
+
+ // ETHREEOH-2844
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: removed file: mainB:/a/foo");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFileDeleteFile2() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+ fService.createStore("mainB--layer");
+
+ logger.debug("created 3 stores: mainA, mainB, mainB--layer");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainB:/", "a");
+
+ logger.debug("created 2 plain dirs: mainA:/a and mainB:/a");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
+
+ // note: short-cut - created directly in "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.createFile("mainA:/a", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo"));
+ out.println("I am mainA:/a/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/foo");
+
+ // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to ,mainA:/a/b)
+ fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo");
+
+ logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created 2 snapshots: mainA and mainB");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(0, diffs.size());
+
+ // note: short-cut - removed directly from "staging" area (don't bother with sandbox mainA--layer for now)
+ fService.removeNode("mainA:/a", "foo");
+ fService.createSnapshot("mainA", null, null);
+
+ logger.debug("removed file & snapshot: mainA:/a/foo");
+
+ try
+ {
+ fService.getFileInputStream(-1, "mainA:/a/foo");
+ fail("Unexpected");
+ }
+ catch (AVMNotFoundException nfe)
+ {
+ // expected
+ }
+
+ try
+ {
+ fService.getFileInputStream(-1, "mainB:/a/foo");
+ fail("Unexpected");
+ }
+ catch (AVMNotFoundException nfe)
+ {
+ // expected
+ }
+
+ try
+ {
+ fService.getFileInputStream(-1, "mainB--layer:/a/foo");
+ fail("Unexpected");
+ }
+ catch (AVMNotFoundException nfe)
+ {
+ // expected
+ }
+
+ fService.removeNode("mainB--layer:/a", "foo");
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("removed file & snapshot: mainB--layer:/a/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
+
+ // ETHREEOH-2829
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: removed file: mainB:/a/foo");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ }
+ }
+
+ public void testLayeredFileDeleteFile3() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainB");
+ fService.createStore("mainB--layer");
+
+ logger.debug("created 2 stores: mainB, mainB--layer");
+
+ fService.createDirectory("mainB:/", "a");
+
+ logger.debug("created plain dir: mainB:/a");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
+
+ // create equivalent of WCM layered file between web project staging sandboxes (mainB:/a/b/foo pointing to mainA:/a/b/foo)
+ fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo"); // note: unbacked/stale here ... even store does not exist !!
+
+ logger.debug("created layered file: mainB:/a/foo -> mainA:/a/foo");
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals(0, diffs.size());
+
+ // create file
+ fService.createFile("mainB--layer:/a", "bar");
+
+ logger.debug("created file: mainB--layer:/a/bar");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals("[mainB--layer:/a/bar[-1] > mainB:/a/bar[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+
+ logger.debug("updated: created file: mainB:/a/bar");
+
+ fSyncService.flatten("mainB--layer:/a", "mainB:/a");
+
+ logger.debug("flattened: created file: mainB:/a/bar");
+
+ // delete layered file (from mainB--layer)
+ fService.removeNode("mainB--layer:/a", "foo");
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("removed file & snapshot: mainB--layer:/a/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null);
+ assertEquals("[mainB--layer:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
+
+ fService.createStore("mainB--workflow1");
+
+ logger.debug("created store: mainB--workflow1");
+
+ recursiveList("mainB--workflow1");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--workflow1:/", "a");
+
+ logger.debug("created layered dir: mainB--workflow1:/a -> mainB:/a");
+
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ recursiveList("mainB--workflow1");
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null);
+ assertEquals(0, diffs.size());
+
+ diffs = new ArrayList(1);
+ diffs.add(new AVMDifference(-1, "mainB--layer:/a/foo", -1, "mainB--workflow1:/a/foo", AVMDifference.NEWER));
+
+ // ETHREEOH-2868
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ logger.debug("updated: removed file: mainB--workflow1:/a/foo");
+
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ recursiveList("mainB--workflow1");
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null);
+ assertEquals("[mainB--workflow1:/a/foo[-1] > mainB:/a/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, true, true, "one", "one");
+ fSyncService.flatten("mainB--workflow1:/a", "mainB:/a");
+
+ logger.debug("updated & flattened: removed file: mainB:/a/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null);
+ assertEquals(0, diffs.size());
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB--layer:/a", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.update(diffs, null, true, true, false, false, null, null);
+ fSyncService.flatten("mainB--layer:/a", "mainB--workflow1:/a");
+
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ if (fService.getStore("mainB--workflow1") != null) { fService.purgeStore("mainB--workflow1"); }
+ }
+ }
+
+ public void testLayeredFileDeleteFile4() throws Exception
+ {
+ try
+ {
+ fService.createStore("mainA");
+ fService.createStore("mainB");
+ fService.createStore("mainB--layer");
+
+ logger.debug("created 3 stores: mainA, mainB, mainB--layer");
+
+ fService.createDirectory("mainA:/", "a");
+ fService.createDirectory("mainB:/", "a");
+
+ logger.debug("created 2 plain dirs: mainA:/a and mainB:/a");
+
+ fService.createSnapshot("mainA", null, null);
+ fService.createSnapshot("mainB", null, null);
+
+ logger.debug("created 2 snapshots: mainA and mainB");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a");
+
+ logger.debug("created layered dir: mainB--layer:/a -> mainB:/a");
+
+ // note: short-cut - created directly in "staging" areas (don't bother with sandbox mainA--layer or mainB--layer for now)
+ fService.createDirectory("mainA:/a", "b");
+ fService.createDirectory("mainB:/a", "b");
+
+ logger.debug("created directories: mainA:/a/b & mainB:/a/b");
+
+ fService.createFile("mainA:/a/b", "foo");
+
+ PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/b/foo"));
+ out.println("I am mainA:/a/b/foo");
+ out.close();
+
+ logger.debug("created file: mainA:/a/b/foo");
+
+ // create equivalent of WCM layered file between web project staging sandboxes (mainB:/a/b/foo pointing to mainA:/a/b/foo)
+ fService.createLayeredFile("mainA:/a/b/foo", "mainB:/a/b", "foo");
+
+ logger.debug("created layered file: mainB:/a/b/foo -> mainA:/a/b/foo");
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/b/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/b/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am mainA:/a/b/foo", line);
+
+ List diffs = fSyncService.compare(-1, "mainB--layer:/a/b", -1, "mainB:/a/b", null);
+ assertEquals(0, diffs.size());
+
+ // create file
+ fService.createFile("mainB--layer:/a/b", "bar");
+
+ logger.debug("created file: mainB--layer:/a/b/bar");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a/b", -1, "mainB:/a/b", null);
+ assertEquals("[mainB--layer:/a/b/bar[-1] > mainB:/a/b/bar[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, false, false, "one", "one");
+ fSyncService.flatten("mainB--layer:/a/b", "mainB:/a/b");
+
+ logger.debug("updated & flattened: created file: mainB:/a/b/bar");
+
+ // delete layered file (from mainB--layer)
+ fService.removeNode("mainB--layer:/a/b", "foo");
+ fService.createSnapshot("mainB--layer", null, null);
+
+ logger.debug("removed file & snapshot: mainB--layer:/a/b/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--layer:/a/b", -1, "mainB:/a/b", null);
+ assertEquals("[mainB--layer:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fService.createStore("mainB--workflow1");
+
+ fService.createLayeredDirectory("mainB:/a", "mainB--workflow1:/", "a");
+
+ logger.debug("created layered dir: mainB--workflow1:/a -> mainB:/a");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ recursiveList("mainB--workflow1");
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB:/a/b", null);
+ assertEquals(0, diffs.size());
+
+ diffs = new ArrayList(1);
+ diffs.add(new AVMDifference(-1, "mainB--layer:/a/b/foo", -1, "mainB--workflow1:/a/b/foo", AVMDifference.NEWER));
+
+ // ETHREEOH-2868
+ fSyncService.update(diffs, null, false, false, false, false, null, null);
+
+ logger.debug("updated: removed file: mainB--workflow1:/a/b/foo");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ recursiveList("mainB--workflow1");
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB:/a/b", null);
+ assertEquals("[mainB--workflow1:/a/b/foo[-1] > mainB:/a/b/foo[-1]]", diffs.toString());
+
+ fSyncService.update(diffs, null, false, false, true, true, "one", "one");
+ fSyncService.flatten("mainB--workflow1:/a/b", "mainB:/a/b");
+
+ logger.debug("updated & flattened: removed file: mainB:/a/b/foo");
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB:/a/b", null);
+ assertEquals(0, diffs.size());
+
+ diffs = fSyncService.compare(-1, "mainB--workflow1:/a/b", -1, "mainB--layer:/a/b", null);
+ assertEquals(0, diffs.size());
+
+ fSyncService.update(diffs, null, true, true, false, false, null, null);
+ fSyncService.flatten("mainB--layer:/a/b", "mainB--workflow1:/a/b");
+
+ recursiveList("mainA");
+ recursiveList("mainB");
+ recursiveList("mainB--layer");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ finally
+ {
+ fService.purgeStore("mainA");
+ fService.purgeStore("mainB");
+ fService.purgeStore("mainB--layer");
+ if (fService.getStore("mainB--workflow1") != null) { fService.purgeStore("mainB--workflow1"); }
+ }
+ }
+
+ protected void recursiveContents(String path)
+ {
+ String contentsStr = recursiveContents(path, -1, true);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(contentsStr);
+ }
+ }
+
+ /**
+ * Get the recursive contents of the given path and version.
+ * @param path
+ * @param version
+ * @return A string representation of the contents.
+ */
+ protected String recursiveContents(String path, int version, boolean followLinks)
+ {
+ String val = recursiveList(path, version, 0, followLinks);
+ return val.substring(val.indexOf('\n'));
+ }
+
+ protected void recursiveList(String store)
+ {
+ recursiveList(store, -1);
+ }
+
+ protected void recursiveList(String store, int version)
+ {
+ String list = recursiveList(store, version, true);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("\n\n"+store+":"+"\n"+list+"\n");
+ }
+ }
+
+ /**
+ * Helper to write a recursive listing of an AVMStore at a given version.
+ * @param repoName The name of the AVMStore.
+ * @param version The version to look under.
+ */
+ protected String recursiveList(String repoName, int version, boolean followLinks)
+ {
+ return recursiveList(repoName + ":/", version, 0, followLinks);
+ }
+
+ /**
+ * Recursive list the given path.
+ * @param path The path.
+ * @param version The version.
+ * @param indent The current indent level.
+ */
+ protected String recursiveList(String path, int version, int indent, boolean followLinks)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < indent; i++)
+ {
+ builder.append(' ');
+ }
+ builder.append(path.substring(path.lastIndexOf('/') + 1));
+ builder.append(' ');
+ AVMNodeDescriptor desc = fService.lookup(version, path, true);
+ builder.append(desc.toString());
+
+ List ancs = fService.getHistory(desc, -1);
+ for (AVMNodeDescriptor anc : ancs)
+ {
+ builder.append("--->").append(anc.toString());
+ }
+
+ builder.append('\n');
+ if (desc.getType() == AVMNodeType.PLAIN_DIRECTORY ||
+ (desc.getType() == AVMNodeType.LAYERED_DIRECTORY && followLinks))
+ {
+ String basename = path.endsWith("/") ? path : path + "/";
+ Map listing = fService.getDirectoryListing(version, path);
+ for (String name : listing.keySet())
+ {
+ if (logger.isTraceEnabled()) { logger.trace(name); }
+ builder.append(recursiveList(basename + name, version, indent + 2, followLinks));
+ }
+ List deletedList = fService.getDeleted(version, path);
+ for (String name : deletedList)
+ {
+ if (logger.isTraceEnabled()) { logger.trace(name); }
+ builder.append(recursiveList(basename + name, version, indent + 2, followLinks));
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Setup a basic tree.
+ */
+ protected void setupBasicTree()
+ throws IOException
+ {
+ fService.createDirectory("main:/", "a");
+ fService.createDirectory("main:/a", "b");
+ fService.createDirectory("main:/a/b", "c");
+ fService.createDirectory("main:/", "d");
+ fService.createDirectory("main:/d", "e");
+ fService.createDirectory("main:/d/e", "f");
+
+
+ OutputStream out = fService.createFile("main:/a/b/c", "foo");
+ byte [] buff = "I am main:/a/b/c/foo".getBytes();
+ out.write(buff);
+ out.close();
+
+ /*
+ fService.createFile("main:/a/b/c", "foo").close();
+ ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo");
+ writer.setEncoding("UTF-8");
+ writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+ writer.putContent("I am main:/a/b/c/foo");
+ */
+
+ out = fService.createFile("main:/a/b/c", "bar");
+ buff = "I am main:/a/b/c/bar".getBytes();
+ out.write(buff);
+ out.close();
+
+ /*
+ fService.createFile("main:/a/b/c", "bar").close();
+ writer = fService.getContentWriter("main:/a/b/c/bar");
+ // Force a conversion
+ writer.setEncoding("UTF-16");
+ writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+ writer.putContent("I am main:/a/b/c/bar");
+ */
+
+ fService.createSnapshot("main", null, null);
+ }
+}
diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java
index 27f004a34b..d2f4c55010 100644
--- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java
@@ -593,7 +593,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer
// If we are not opaque, get the underlying base listing.
if (!getOpacity())
{
- Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, dir.getIndirection());
+ Lookup lookup = AVMRepository.GetInstance().lookupDirectory(dir.getIndirectionVersion(), dir.getIndirection());
if (lookup != null)
{
DirectoryNode dirNode = (DirectoryNode) lookup.getCurrentNode();
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
index a2451749a5..8dee217801 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
@@ -469,15 +469,17 @@ public class DictionaryDAOImpl implements DictionaryDAO
*/
public DataTypeDefinition getDataType(QName typeName)
{
- List models = getModelsForUri(typeName.getNamespaceURI());
- for (CompiledModel model : models)
- {
- DataTypeDefinition dataType = model.getDataType(typeName);
- if (dataType != null)
- {
- return dataType;
- }
- }
+ if (typeName != null) {
+ List models = getModelsForUri(typeName.getNamespaceURI());
+ for (CompiledModel model : models)
+ {
+ DataTypeDefinition dataType = model.getDataType(typeName);
+ if (dataType != null)
+ {
+ return dataType;
+ }
+ }
+ }
return null;
}
@@ -542,19 +544,21 @@ public class DictionaryDAOImpl implements DictionaryDAO
*/
public TypeDefinition getType(QName typeName)
{
- List models = getModelsForUri(typeName.getNamespaceURI());
- for (CompiledModel model : models)
- {
- TypeDefinition type = model.getType(typeName);
- if (type != null)
- {
- return type;
- }
- }
-
- if (logger.isWarnEnabled())
- {
- logger.warn("Type not found: "+typeName);
+ if (typeName != null) {
+ List models = getModelsForUri(typeName.getNamespaceURI());
+ for (CompiledModel model : models)
+ {
+ TypeDefinition type = model.getType(typeName);
+ if (type != null)
+ {
+ return type;
+ }
+ }
+
+ if (logger.isWarnEnabled())
+ {
+ logger.warn("Type not found: "+typeName);
+ }
}
return null;
}
@@ -614,14 +618,16 @@ public class DictionaryDAOImpl implements DictionaryDAO
*/
public AspectDefinition getAspect(QName aspectName)
{
- List models = getModelsForUri(aspectName.getNamespaceURI());
- for (CompiledModel model : models)
- {
- AspectDefinition aspect = model.getAspect(aspectName);
- if (aspect != null)
- {
- return aspect;
- }
+ if (aspectName != null) {
+ List models = getModelsForUri(aspectName.getNamespaceURI());
+ for (CompiledModel model : models)
+ {
+ AspectDefinition aspect = model.getAspect(aspectName);
+ if (aspect != null)
+ {
+ return aspect;
+ }
+ }
}
return null;
}
diff --git a/source/java/org/alfresco/repo/domain/locks/AbstractLockDAOImpl.java b/source/java/org/alfresco/repo/domain/locks/AbstractLockDAOImpl.java
index b4e4558300..fd8551026c 100644
--- a/source/java/org/alfresco/repo/domain/locks/AbstractLockDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/locks/AbstractLockDAOImpl.java
@@ -1,359 +1,368 @@
-/*
- * 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.domain.locks;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.alfresco.repo.domain.QNameDAO;
-import org.alfresco.repo.lock.LockAcquisitionException;
-import org.alfresco.service.namespace.QName;
-import org.alfresco.util.EqualsHelper;
-import org.springframework.dao.ConcurrencyFailureException;
-
-/**
- * Abstract implementation of the Locks DAO.
- *
- * @author Derek Hulley
- * @since 3.2
- */
-public abstract class AbstractLockDAOImpl implements LockDAO
-{
- private static final String LOCK_TOKEN_RELEASED = "not-locked";
-
- private QNameDAO qnameDAO;
-
- /**
- * @return Returns the DAO for namespace ID resolution
- */
- protected QNameDAO getQNameDAO()
- {
- return qnameDAO;
- }
-
- /**
- * @param qnameDAO DAO for namespace ID resolution
- */
- public void setQnameDAO(QNameDAO qnameDAO)
- {
- this.qnameDAO = qnameDAO;
- }
-
- public void getLock(QName lockQName, String lockToken, long timeToLive)
- {
- String qnameNamespaceUri = lockQName.getNamespaceURI();
- String qnameLocalName = lockQName.getLocalName();
- // Force lower case for case insensitivity
- if (!qnameLocalName.toLowerCase().equals(qnameLocalName))
- {
- lockQName = QName.createQName(qnameNamespaceUri, qnameLocalName.toLowerCase());
- qnameLocalName = lockQName.getLocalName();
- }
- // Force the lock token to lowercase
- lockToken = lockToken.toLowerCase();
-
- // Resolve the namespace
- Long qnameNamespaceId = qnameDAO.getOrCreateNamespace(qnameNamespaceUri).getFirst();
-
- // Get the lock resource for the exclusive lock.
- // All the locks that are created will need the exclusive case.
- LockResourceEntity exclusiveLockResource = getLockResource(qnameNamespaceId, qnameLocalName);
- if (exclusiveLockResource == null)
- {
- // Create it
- exclusiveLockResource = createLockResource(qnameNamespaceId, qnameLocalName);
- }
- Long requiredExclusiveLockResourceId = exclusiveLockResource.getId();
- // Split the lock name
- List lockQNames = splitLockQName(lockQName);
- List requiredLockResourceIds = new ArrayList(lockQNames.size());
- // Create the lock resources
- for (QName lockQNameIter : lockQNames)
- {
- String localname = lockQNameIter.getLocalName();
- // Get the basic lock resource, forcing a create
- LockResourceEntity lockResource = getLockResource(qnameNamespaceId, localname);
- if (lockResource == null)
- {
- // Create it
- lockResource = createLockResource(qnameNamespaceId, localname);
- }
- requiredLockResourceIds.add(lockResource.getId());
- }
-
- // Now, get all locks for the resources we will need
- List existingLocks = getLocksBySharedResourceIds(requiredLockResourceIds);
- Map existingLocksMap = new HashMap();
- // Check them and make sure they don't prevent locks
- for (LockEntity existingLock : existingLocks)
- {
- boolean canTakeLock = canTakeLock(existingLock, lockToken, requiredExclusiveLockResourceId);
- if (!canTakeLock)
- {
- throw new LockAcquisitionException(
- LockAcquisitionException.ERR_EXCLUSIVE_LOCK_EXISTS,
- lockQName, lockToken, existingLock);
- }
- existingLocksMap.put(existingLock, existingLock);
- }
- // Take the locks for the resources.
- // Existing locks must be updated, if required.
- for (Long requiredLockResourceId : requiredLockResourceIds)
- {
- LockEntity requiredLock = new LockEntity();
- requiredLock.setSharedResourceId(requiredLockResourceId);
- requiredLock.setExclusiveResourceId(requiredExclusiveLockResourceId);
- // Does it exist?
- if (existingLocksMap.containsKey(requiredLock))
- {
- requiredLock = existingLocksMap.get(requiredLock);
- // Do an update
- updateLock(requiredLock, lockToken, timeToLive);
- }
- else
- {
- // Create it
- requiredLock = createLock(
- requiredLockResourceId,
- requiredExclusiveLockResourceId,
- lockToken,
- timeToLive);
- }
- }
- // Done
- }
-
- public void refreshLock(QName lockQName, String lockToken, long timeToLive)
- {
- updateLocks(lockQName, lockToken, lockToken, timeToLive);
- }
-
- public void releaseLock(QName lockQName, String lockToken)
- {
- updateLocks(lockQName, lockToken, LOCK_TOKEN_RELEASED, 0L);
- }
-
- /**
- * Put new values against the given exclusive lock. This works against the related locks as
- * well.
- * @throws LockAcquisitionException on failure
- */
- private void updateLocks(QName lockQName, String lockToken, String newLockToken, long timeToLive)
- {
- String qnameNamespaceUri = lockQName.getNamespaceURI();
- String qnameLocalName = lockQName.getLocalName();
- // Force lower case for case insensitivity
- if (!qnameLocalName.toLowerCase().equals(qnameLocalName))
- {
- lockQName = QName.createQName(qnameNamespaceUri, qnameLocalName.toLowerCase());
- qnameLocalName = lockQName.getLocalName();
- }
- // Force the lock token to lowercase
- lockToken = lockToken.toLowerCase();
-
- // Resolve the namespace
- Long qnameNamespaceId = qnameDAO.getOrCreateNamespace(qnameNamespaceUri).getFirst();
-
- // Get the lock resource for the exclusive lock.
- // All the locks that are created will need the exclusive case.
- LockResourceEntity exclusiveLockResource = getLockResource(qnameNamespaceId, qnameLocalName);
- if (exclusiveLockResource == null)
- {
- // If the exclusive lock doesn't exist, the locks don't exist
- throw new LockAcquisitionException(
- LockAcquisitionException.ERR_LOCK_RESOURCE_MISSING,
- lockQName, lockToken);
- }
- Long exclusiveLockResourceId = exclusiveLockResource.getId();
- // Split the lock name
- List lockQNames = splitLockQName(lockQName);
- // We just need to know how many resources needed updating.
- // They will all share the same exclusive lock resource
- int requiredUpdateCount = lockQNames.size();
- // Update
- int updateCount = updateLocks(exclusiveLockResourceId, lockToken, newLockToken, timeToLive);
- // Check
- if (updateCount != requiredUpdateCount)
- {
- throw new LockAcquisitionException(
- LockAcquisitionException.ERR_LOCK_UPDATE_COUNT,
- lockQName, lockToken, new Integer(updateCount), new Integer(requiredUpdateCount));
- }
- // Done
- }
-
- /**
- * Validate if a lock can be taken or not.
- */
- private boolean canTakeLock(LockEntity existingLock, String lockToken, Long desiredExclusiveLock)
- {
- if (EqualsHelper.nullSafeEquals(existingLock.getLockToken(), lockToken))
- {
- // The lock token is the same.
- // Regardless of lock expiry, the lock can be taken
- return true;
- }
- else if (existingLock.hasExpired())
- {
- // Expired locks are fair game
- return true;
- }
- else if (existingLock.isExclusive())
- {
- // It's a valid, exclusive lock held using a different token ...
- return false;
- }
- else if (desiredExclusiveLock.equals(existingLock.getSharedResourceId()))
- {
- // We can't take an exclusive lock if a shared lock is active
- return false;
- }
- else
- {
- // Good to go
- return true;
- }
- }
-
- /**
- * Override to get the unique, lock resource entity if one exists.
- *
- * @param qnameNamespaceId the namespace entity ID
- * @param qnameLocalName the lock localname
- * @return Returns the lock resource entity,
- * or null if it doesn't exist
- */
- protected abstract LockResourceEntity getLockResource(Long qnameNamespaceId, String qnameLocalName);
-
- /**
- * Create a unique lock resource
- *
- * @param qnameNamespaceId the namespace entity ID
- * @param qnameLocalName the lock localname
- * @return Returns the newly created lock resource entity
- */
- protected abstract LockResourceEntity createLockResource(Long qnameNamespaceId, String qnameLocalName);
-
- /**
- * @param id the lock instance ID
- * @return Returns the lock, if it exists, otherwise null
- */
- protected abstract LockEntity getLock(Long id);
-
- /**
- * @param sharedResourceId the shared lock resource ID
- * @param exclusiveResourceId the exclusive lock resource ID
- * @return Returns the lock, if it exists, otherwise null
- */
- protected abstract LockEntity getLock(Long sharedResourceId, Long exclusiveResourceId);
-
- /**
- * Get any existing lock data for the shared resources. The locks returned are not filtered and
- * may be expired.
- *
- * @param lockResourceIds a list of shared resource IDs for which to retrieve the current locks
- * @return Returns a list of locks (expired or not) for the given lock resources
- */
- protected abstract List getLocksBySharedResourceIds(List sharedLockResourceIds);
-
- /**
- * Create a new lock.
- * @param sharedResourceId the specific resource to lock
- * @param exclusiveResourceId the exclusive lock that is being sought
- * @param lockToken the lock token to assign
- * @param timeToLive the time, in milliseconds, for the lock to remain valid
- * @return Returns the new lock
- * @throws ConcurrencyFailureException if the lock was already taken at the time of creation
- */
- protected abstract LockEntity createLock(
- Long sharedResourceId,
- Long exclusiveResourceId,
- String lockToken,
- long timeToLive);
-
- /**
- * Update an existing lock
- * @param lockEntity the specific lock to update
- * @param lockApplicant the new lock token
- * @param timeToLive the new lock time, in milliseconds, for the lock to remain valid
- * @return Returns the updated lock
- */
- protected abstract LockEntity updateLock(
- LockEntity lockEntity,
- String lockToken,
- long timeToLive);
-
- /**
- * @param exclusiveLockResourceId the exclusive resource ID being locks
- * @param oldLockToken the lock token to change from
- * @param newLockToken the new lock token
- * @param timeToLive the new time to live (in milliseconds)
- * @return the number of rows updated
- */
- protected abstract int updateLocks(
- Long exclusiveLockResourceId,
- String oldLockToken,
- String newLockToken,
- long timeToLive);
-
- /**
- * Split a lock's qualified name into the component parts using the '.' (period) as a
- * separator on the localname. The namespace is preserved. The provided qualified
- * name will always be the last component in the returned list.
- *
- * @param lockQName the lock name to split into it's higher-level paths
- * @return Returns the namespace ID along with the ordered localnames
- */
- protected List splitLockQName(QName lockQName)
- {
- String ns = lockQName.getNamespaceURI();
- String name = lockQName.getLocalName();
-
- StringTokenizer tokenizer = new StringTokenizer(name, ".");
- List ret = new ArrayList(tokenizer.countTokens());
- StringBuilder sb = new StringBuilder();
- // Fill it
- boolean first = true;
- while (tokenizer.hasMoreTokens())
- {
- if (first)
- {
- first = false;
- }
- else
- {
- sb.append(".");
- }
- sb.append(tokenizer.nextToken());
- QName parentLockQName = QName.createQName(ns, sb.toString());
- ret.add(parentLockQName);
- }
- // Done
- return ret;
- }
-}
+/*
+ * 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.domain.locks;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.alfresco.repo.domain.QNameDAO;
+import org.alfresco.repo.lock.LockAcquisitionException;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.EqualsHelper;
+import org.springframework.dao.ConcurrencyFailureException;
+
+/**
+ * Abstract implementation of the Locks DAO.
+ *
+ * @author Derek Hulley
+ * @since 3.2
+ */
+public abstract class AbstractLockDAOImpl implements LockDAO
+{
+ private static final String LOCK_TOKEN_RELEASED = "not-locked";
+
+ private QNameDAO qnameDAO;
+
+ /**
+ * @return Returns the DAO for namespace ID resolution
+ */
+ protected QNameDAO getQNameDAO()
+ {
+ return qnameDAO;
+ }
+
+ /**
+ * @param qnameDAO DAO for namespace ID resolution
+ */
+ public void setQnameDAO(QNameDAO qnameDAO)
+ {
+ this.qnameDAO = qnameDAO;
+ }
+
+ public void getLock(QName lockQName, String lockToken, long timeToLive)
+ {
+ String qnameNamespaceUri = lockQName.getNamespaceURI();
+ String qnameLocalName = lockQName.getLocalName();
+ // Force lower case for case insensitivity
+ if (!qnameLocalName.toLowerCase().equals(qnameLocalName))
+ {
+ lockQName = QName.createQName(qnameNamespaceUri, qnameLocalName.toLowerCase());
+ qnameLocalName = lockQName.getLocalName();
+ }
+ // Force the lock token to lowercase
+ lockToken = lockToken.toLowerCase();
+
+ // Resolve the namespace
+ Long qnameNamespaceId = qnameDAO.getOrCreateNamespace(qnameNamespaceUri).getFirst();
+
+ // Get the lock resource for the exclusive lock.
+ // All the locks that are created will need the exclusive case.
+ LockResourceEntity exclusiveLockResource = getLockResource(qnameNamespaceId, qnameLocalName);
+ if (exclusiveLockResource == null)
+ {
+ // Create it
+ exclusiveLockResource = createLockResource(qnameNamespaceId, qnameLocalName);
+ }
+ Long requiredExclusiveLockResourceId = exclusiveLockResource.getId();
+ // Split the lock name
+ List lockQNames = splitLockQName(lockQName);
+ List requiredLockResourceIds = new ArrayList(lockQNames.size());
+ // Create the lock resources
+ for (QName lockQNameIter : lockQNames)
+ {
+ String localname = lockQNameIter.getLocalName();
+ // Get the basic lock resource, forcing a create
+ LockResourceEntity lockResource = getLockResource(qnameNamespaceId, localname);
+ if (lockResource == null)
+ {
+ // Create it
+ lockResource = createLockResource(qnameNamespaceId, localname);
+ }
+ requiredLockResourceIds.add(lockResource.getId());
+ }
+
+ // Now, get all locks for the resources we will need
+ List existingLocks = getLocksBySharedResourceIds(requiredLockResourceIds);
+ Map existingLocksMap = new HashMap();
+ // Check them and make sure they don't prevent locks
+ for (LockEntity existingLock : existingLocks)
+ {
+ boolean canTakeLock = canTakeLock(existingLock, lockToken, requiredExclusiveLockResourceId);
+ if (!canTakeLock)
+ {
+ throw new LockAcquisitionException(
+ LockAcquisitionException.ERR_EXCLUSIVE_LOCK_EXISTS,
+ lockQName, lockToken, existingLock);
+ }
+ existingLocksMap.put(existingLock, existingLock);
+ }
+ // Take the locks for the resources.
+ // Existing locks must be updated, if required.
+ for (Long requiredLockResourceId : requiredLockResourceIds)
+ {
+ LockEntity requiredLock = new LockEntity();
+ requiredLock.setSharedResourceId(requiredLockResourceId);
+ requiredLock.setExclusiveResourceId(requiredExclusiveLockResourceId);
+ // Does it exist?
+ if (existingLocksMap.containsKey(requiredLock))
+ {
+ requiredLock = existingLocksMap.get(requiredLock);
+ // Do an update
+ updateLock(requiredLock, lockToken, timeToLive);
+ }
+ else
+ {
+ // Create it
+ requiredLock = createLock(
+ requiredLockResourceId,
+ requiredExclusiveLockResourceId,
+ lockToken,
+ timeToLive);
+ }
+ }
+ // Done
+ }
+
+ public void refreshLock(QName lockQName, String lockToken, long timeToLive)
+ {
+ updateLocks(lockQName, lockToken, lockToken, timeToLive);
+ }
+
+ public void releaseLock(QName lockQName, String lockToken)
+ {
+ updateLocks(lockQName, lockToken, LOCK_TOKEN_RELEASED, 0L);
+ }
+
+ /**
+ * Put new values against the given exclusive lock. This works against the related locks as
+ * well.
+ * @throws LockAcquisitionException on failure
+ */
+ private void updateLocks(QName lockQName, String lockToken, String newLockToken, long timeToLive)
+ {
+ String qnameNamespaceUri = lockQName.getNamespaceURI();
+ String qnameLocalName = lockQName.getLocalName();
+ // Force lower case for case insensitivity
+ if (!qnameLocalName.toLowerCase().equals(qnameLocalName))
+ {
+ lockQName = QName.createQName(qnameNamespaceUri, qnameLocalName.toLowerCase());
+ qnameLocalName = lockQName.getLocalName();
+ }
+ // Force the lock token to lowercase
+ lockToken = lockToken.toLowerCase();
+
+ // Resolve the namespace
+ Long qnameNamespaceId = qnameDAO.getOrCreateNamespace(qnameNamespaceUri).getFirst();
+
+ // Get the lock resource for the exclusive lock.
+ // All the locks that are created will need the exclusive case.
+ LockResourceEntity exclusiveLockResource = getLockResource(qnameNamespaceId, qnameLocalName);
+ if (exclusiveLockResource == null)
+ {
+ // If the exclusive lock doesn't exist, the locks don't exist
+ throw new LockAcquisitionException(
+ LockAcquisitionException.ERR_LOCK_RESOURCE_MISSING,
+ lockQName, lockToken);
+ }
+ Long exclusiveLockResourceId = exclusiveLockResource.getId();
+ // Split the lock name
+ List lockQNames = splitLockQName(lockQName);
+ // We just need to know how many resources needed updating.
+ // They will all share the same exclusive lock resource
+ int requiredUpdateCount = lockQNames.size();
+ // Update
+ int updateCount = updateLocks(exclusiveLockResourceId, lockToken, newLockToken, timeToLive);
+ // Check
+ if (updateCount != requiredUpdateCount)
+ {
+ if (LOCK_TOKEN_RELEASED.equals(newLockToken))
+ {
+ throw new LockAcquisitionException(
+ LockAcquisitionException.ERR_FAILED_TO_RELEASE_LOCK,
+ lockQName, lockToken);
+ }
+ else
+ {
+ throw new LockAcquisitionException(
+ LockAcquisitionException.ERR_LOCK_UPDATE_COUNT,
+ lockQName, lockToken, new Integer(updateCount), new Integer(requiredUpdateCount));
+ }
+ }
+ // Done
+ }
+
+ /**
+ * Validate if a lock can be taken or not.
+ */
+ private boolean canTakeLock(LockEntity existingLock, String lockToken, Long desiredExclusiveLock)
+ {
+ if (EqualsHelper.nullSafeEquals(existingLock.getLockToken(), lockToken))
+ {
+ // The lock token is the same.
+ // Regardless of lock expiry, the lock can be taken
+ return true;
+ }
+ else if (existingLock.hasExpired())
+ {
+ // Expired locks are fair game
+ return true;
+ }
+ else if (existingLock.isExclusive())
+ {
+ // It's a valid, exclusive lock held using a different token ...
+ return false;
+ }
+ else if (desiredExclusiveLock.equals(existingLock.getSharedResourceId()))
+ {
+ // We can't take an exclusive lock if a shared lock is active
+ return false;
+ }
+ else
+ {
+ // Good to go
+ return true;
+ }
+ }
+
+ /**
+ * Override to get the unique, lock resource entity if one exists.
+ *
+ * @param qnameNamespaceId the namespace entity ID
+ * @param qnameLocalName the lock localname
+ * @return Returns the lock resource entity,
+ * or null if it doesn't exist
+ */
+ protected abstract LockResourceEntity getLockResource(Long qnameNamespaceId, String qnameLocalName);
+
+ /**
+ * Create a unique lock resource
+ *
+ * @param qnameNamespaceId the namespace entity ID
+ * @param qnameLocalName the lock localname
+ * @return Returns the newly created lock resource entity
+ */
+ protected abstract LockResourceEntity createLockResource(Long qnameNamespaceId, String qnameLocalName);
+
+ /**
+ * @param id the lock instance ID
+ * @return Returns the lock, if it exists, otherwise null
+ */
+ protected abstract LockEntity getLock(Long id);
+
+ /**
+ * @param sharedResourceId the shared lock resource ID
+ * @param exclusiveResourceId the exclusive lock resource ID
+ * @return Returns the lock, if it exists, otherwise null
+ */
+ protected abstract LockEntity getLock(Long sharedResourceId, Long exclusiveResourceId);
+
+ /**
+ * Get any existing lock data for the shared resources. The locks returned are not filtered and
+ * may be expired.
+ *
+ * @param lockResourceIds a list of shared resource IDs for which to retrieve the current locks
+ * @return Returns a list of locks (expired or not) for the given lock resources
+ */
+ protected abstract List getLocksBySharedResourceIds(List sharedLockResourceIds);
+
+ /**
+ * Create a new lock.
+ * @param sharedResourceId the specific resource to lock
+ * @param exclusiveResourceId the exclusive lock that is being sought
+ * @param lockToken the lock token to assign
+ * @param timeToLive the time, in milliseconds, for the lock to remain valid
+ * @return Returns the new lock
+ * @throws ConcurrencyFailureException if the lock was already taken at the time of creation
+ */
+ protected abstract LockEntity createLock(
+ Long sharedResourceId,
+ Long exclusiveResourceId,
+ String lockToken,
+ long timeToLive);
+
+ /**
+ * Update an existing lock
+ * @param lockEntity the specific lock to update
+ * @param lockApplicant the new lock token
+ * @param timeToLive the new lock time, in milliseconds, for the lock to remain valid
+ * @return Returns the updated lock
+ */
+ protected abstract LockEntity updateLock(
+ LockEntity lockEntity,
+ String lockToken,
+ long timeToLive);
+
+ /**
+ * @param exclusiveLockResourceId the exclusive resource ID being locks
+ * @param oldLockToken the lock token to change from
+ * @param newLockToken the new lock token
+ * @param timeToLive the new time to live (in milliseconds)
+ * @return the number of rows updated
+ */
+ protected abstract int updateLocks(
+ Long exclusiveLockResourceId,
+ String oldLockToken,
+ String newLockToken,
+ long timeToLive);
+
+ /**
+ * Split a lock's qualified name into the component parts using the '.' (period) as a
+ * separator on the localname. The namespace is preserved. The provided qualified
+ * name will always be the last component in the returned list.
+ *
+ * @param lockQName the lock name to split into it's higher-level paths
+ * @return Returns the namespace ID along with the ordered localnames
+ */
+ protected List splitLockQName(QName lockQName)
+ {
+ String ns = lockQName.getNamespaceURI();
+ String name = lockQName.getLocalName();
+
+ StringTokenizer tokenizer = new StringTokenizer(name, ".");
+ List ret = new ArrayList(tokenizer.countTokens());
+ StringBuilder sb = new StringBuilder();
+ // Fill it
+ boolean first = true;
+ while (tokenizer.hasMoreTokens())
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.append(".");
+ }
+ sb.append(tokenizer.nextToken());
+ QName parentLockQName = QName.createQName(ns, sb.toString());
+ ret.add(parentLockQName);
+ }
+ // Done
+ return ret;
+ }
+}
diff --git a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java
index c4fd9e5189..39adba6350 100644
--- a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java
+++ b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java
@@ -739,9 +739,15 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
// add an association to the child doc (as an attachment which is defined on an aspect not applied)
//data.addField("assoc_cm_attachments_added", this.childDoc.toString());
- // try and update non-existent properties (make sure there are no exceptions)
+ // try and update non-existent properties and assocs (make sure there are no exceptions)
data.addFieldData("prop_cm_wrong", "This should not be persisted");
data.addFieldData("cm_wrong", "This should not be persisted");
+ data.addFieldData("prop_cm_wrong_property", "This should not be persisted");
+ data.addFieldData("prop_cm_wrong_property_name", "This should not be persisted");
+ data.addFieldData("assoc_cm_wrong_association", "This should be ignored");
+ data.addFieldData("assoc_cm_wrong_association_added", "This should be ignored");
+ data.addFieldData("assoc_cm_wrong_association_removed", "This should be ignored");
+ data.addFieldData("assoc_cm_added", "This should be ignored");
// persist the data
this.formService.saveForm(new Item(NODE_FORM_ITEM_KIND, this.document.toString()), data);
diff --git a/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java b/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java
index b83c362b51..0c0ef953ed 100644
--- a/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java
+++ b/source/java/org/alfresco/repo/forms/processor/node/ContentModelFormProcessor.java
@@ -111,7 +111,7 @@ public abstract class ContentModelFormProcessor extends
* names will look like "prop_cm_name"
. The pattern can also be
* used to extract the "cm" and the "name" parts.
*/
- protected Pattern propertyNamePattern = Pattern.compile(PROP_DATA_PREFIX + "(.*){1}?_(.*){1}?");
+ protected Pattern propertyNamePattern = Pattern.compile(PROP_DATA_PREFIX + "([a-zA-Z0-9]+)_(.*)");
/**
* A regular expression which can be used to match tranisent property names.
@@ -126,7 +126,7 @@ public abstract class ContentModelFormProcessor extends
* pattern can also be used to extract the "cm", the "name" and the suffix
* parts.
*/
- protected Pattern associationNamePattern = Pattern.compile(ASSOC_DATA_PREFIX + "(.*){1}?_(.*){1}?(_[a-zA-Z]+)");
+ protected Pattern associationNamePattern = Pattern.compile(ASSOC_DATA_PREFIX + "([a-zA-Z0-9]+)_(.*)(_[a-zA-Z]+)");
/**
* Sets the node service
@@ -1115,8 +1115,9 @@ public abstract class ContentModelFormProcessor extends
{
if (getLogger().isWarnEnabled())
{
- getLogger().warn("Definition for association " + fullQName + " not recognised and not persisted.");
+ getLogger().warn("Ignoring field '" + fieldName + "' as an association definition can not be found");
}
+
return;
}
@@ -1162,10 +1163,10 @@ public abstract class ContentModelFormProcessor extends
if (getLogger().isWarnEnabled())
{
StringBuilder msg = new StringBuilder();
- msg.append("fieldName ").append(fieldName).append(
- " does not have one of the expected suffixes [").append(
- ASSOC_DATA_ADDED_SUFFIX).append(", ").append(ASSOC_DATA_REMOVED_SUFFIX)
- .append("] and has been ignored.");
+ msg.append("Ignoring 'fieldName ").append(fieldName).append(
+ "' as it does not have one of the expected suffixes (").append(
+ ASSOC_DATA_ADDED_SUFFIX).append(" or ").append(ASSOC_DATA_REMOVED_SUFFIX)
+ .append(")");
getLogger().warn(msg.toString());
}
}
@@ -1183,6 +1184,10 @@ public abstract class ContentModelFormProcessor extends
}
}
}
+ else if (getLogger().isWarnEnabled())
+ {
+ getLogger().warn("Ignoring unrecognised field '" + fieldName + "'");
+ }
}
/**
diff --git a/source/java/org/alfresco/repo/lock/LockAcquisitionException.java b/source/java/org/alfresco/repo/lock/LockAcquisitionException.java
index 753a14c54f..fbb8ffcc58 100644
--- a/source/java/org/alfresco/repo/lock/LockAcquisitionException.java
+++ b/source/java/org/alfresco/repo/lock/LockAcquisitionException.java
@@ -60,6 +60,13 @@ public class LockAcquisitionException extends AlfrescoRuntimeException
*
*/
public static final String ERR_LOCK_UPDATE_COUNT = "system.locks.err.lock_update_count";
+ /**
+ *
+ * - 1: the qname
+ * - 2: the lock token
+ *
+ */
+ public static final String ERR_FAILED_TO_RELEASE_LOCK = "system.locks.err.failed_to_release_lock";
/**
*
* - 1: the qname
diff --git a/source/java/org/alfresco/repo/model/ml/MultilingualDocumentAspect.java b/source/java/org/alfresco/repo/model/ml/MultilingualDocumentAspect.java
index 2f30a892ef..9e05a10b11 100644
--- a/source/java/org/alfresco/repo/model/ml/MultilingualDocumentAspect.java
+++ b/source/java/org/alfresco/repo/model/ml/MultilingualDocumentAspect.java
@@ -124,20 +124,12 @@ public class MultilingualDocumentAspect implements
}
/**
- * If this is not an empty translation, then ensure that the node is properly
- * unhooked from the translation mechanism first.
+ * Ensure that the node is properly unhooked from the translation mechanism first.
*/
public void beforeDeleteNode(NodeRef nodeRef)
{
- if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
- {
- // We just let it get deleted
- }
- else
- {
- // First unhook it
- multilingualContentService.unmakeTranslation(nodeRef);
- }
+ // First unhook it
+ multilingualContentService.unmakeTranslation(nodeRef);
}
/**
diff --git a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java
index 62af5cf676..abee4c560f 100644
--- a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java
+++ b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
+ * 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
@@ -105,6 +105,10 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
{
public static final String NAMESPACE = "http://www.alfresco.org/test/BaseNodeServiceTest";
public static final String TEST_PREFIX = "test";
+
+ public static final String DEFAULT_VALUE = "defaultValue";
+ public static final String NOT_DEFAULT_VALUE = "notDefaultValue";
+
public static final QName TYPE_QNAME_TEST_CONTENT = QName.createQName(NAMESPACE, "content");
public static final QName TYPE_QNAME_TEST_MANY_PROPERTIES = QName.createQName(NAMESPACE, "many-properties");
public static final QName TYPE_QNAME_TEST_MANY_ML_PROPERTIES = QName.createQName(NAMESPACE, "many-ml-properties");
@@ -134,8 +138,8 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
public static final QName PROP_QNAME_LOCALE_VALUE = QName.createQName(NAMESPACE, "localeValue");
public static final QName PROP_QNAME_NULL_VALUE = QName.createQName(NAMESPACE, "nullValue");
public static final QName PROP_QNAME_MULTI_VALUE = QName.createQName(NAMESPACE, "multiValue");
- public static final QName PROP_QNAME_PERIOD_VALUE = QName.createQName(NAMESPACE, "periodValue");
- public static final QName PROP_QNAME_MULTI_ML_VALUE = QName.createQName(NAMESPACE, "multiMLValue");
+ public static final QName PROP_QNAME_PERIOD_VALUE = QName.createQName(NAMESPACE, "periodValue");
+ public static final QName PROP_QNAME_MULTI_ML_VALUE = QName.createQName(NAMESPACE, "multiMLValue");
public static final QName PROP_QNAME_MARKER_PROP = QName.createQName(NAMESPACE, "markerProp");
public static final QName PROP_QNAME_PROP1 = QName.createQName(NAMESPACE, "prop1");
public static final QName PROP_QNAME_PROP2 = QName.createQName(NAMESPACE, "prop2");
@@ -566,12 +570,19 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
rootNodeRef,
ASSOC_TYPE_QNAME_TEST_CHILDREN,
QName.createQName("setTypeTest"),
- TYPE_QNAME_TEST_CONTENT).getChildRef();
+ TYPE_QNAME_TEST_CONTENT).getChildRef();
assertEquals(TYPE_QNAME_TEST_CONTENT, this.nodeService.getType(nodeRef));
+ assertNull(this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP1));
+
// Now change the type
this.nodeService.setType(nodeRef, TYPE_QNAME_EXTENDED_CONTENT);
- assertEquals(TYPE_QNAME_EXTENDED_CONTENT, this.nodeService.getType(nodeRef));
+ assertEquals(TYPE_QNAME_EXTENDED_CONTENT, this.nodeService.getType(nodeRef));
+
+ // Check new defaults
+ Serializable defaultValue = this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP1);
+ assertNotNull("No default property value assigned", defaultValue);
+ assertEquals(DEFAULT_VALUE, defaultValue);
}
/**
@@ -2409,25 +2420,25 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
rootNodeRef,
ASSOC_TYPE_QNAME_TEST_CHILDREN,
QName.createQName("testDefaultValues"),
- TYPE_QNAME_EXTENDED_CONTENT).getChildRef();
- assertEquals("defaultValue", this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP1));
+ TYPE_QNAME_EXTENDED_CONTENT).getChildRef();
+ assertEquals(DEFAULT_VALUE, this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP1));
this.nodeService.addAspect(nodeRef, ASPECT_QNAME_WITH_DEFAULT_VALUE, null);
- assertEquals("defaultValue", this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP2));
+ assertEquals(DEFAULT_VALUE, this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP2));
// Ensure that default values do not overrite already set values
Map props = new HashMap(1);
- props.put(PROP_QNAME_PROP1, "notDefaultValue");
+ props.put(PROP_QNAME_PROP1, NOT_DEFAULT_VALUE);
NodeRef nodeRef2 = nodeService.createNode(
rootNodeRef,
ASSOC_TYPE_QNAME_TEST_CHILDREN,
QName.createQName("testDefaultValues"),
TYPE_QNAME_EXTENDED_CONTENT,
props).getChildRef();
- assertEquals("notDefaultValue", this.nodeService.getProperty(nodeRef2, PROP_QNAME_PROP1));
+ assertEquals(NOT_DEFAULT_VALUE, this.nodeService.getProperty(nodeRef2, PROP_QNAME_PROP1));
Map prop2 = new HashMap(1);
- prop2.put(PROP_QNAME_PROP2, "notDefaultValue");
+ prop2.put(PROP_QNAME_PROP2, NOT_DEFAULT_VALUE);
this.nodeService.addAspect(nodeRef2, ASPECT_QNAME_WITH_DEFAULT_VALUE, prop2);
- assertEquals("notDefaultValue", this.nodeService.getProperty(nodeRef2, PROP_QNAME_PROP2));
+ assertEquals(NOT_DEFAULT_VALUE, this.nodeService.getProperty(nodeRef2, PROP_QNAME_PROP2));
}
diff --git a/source/java/org/alfresco/repo/node/FullNodeServiceTest.java b/source/java/org/alfresco/repo/node/FullNodeServiceTest.java
index 4c632a0b8d..3c18068dd6 100644
--- a/source/java/org/alfresco/repo/node/FullNodeServiceTest.java
+++ b/source/java/org/alfresco/repo/node/FullNodeServiceTest.java
@@ -25,17 +25,25 @@
package org.alfresco.repo.node;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
-import org.springframework.extensions.surf.util.I18NUtil;
+import javax.transaction.UserTransaction;
+
import org.alfresco.repo.node.db.DbNodeServiceImpl;
+import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.repository.MLText;
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.QName;
+import org.springframework.extensions.surf.util.I18NUtil;
/**
* Tests the fully-intercepted version of the NodeService
@@ -245,4 +253,168 @@ public class FullNodeServiceTest extends BaseNodeServiceTest
String strValue = mlTextValue.getDefaultValue();
checkProperties.put(PROP_QNAME_ML_TEXT_VALUE, strValue);
}
+
+ @SuppressWarnings("unchecked")
+ public void testMultiProp() throws Exception
+ {
+ QName undeclaredPropQName = QName.createQName(NAMESPACE, getName());
+ // create node
+ NodeRef nodeRef = nodeService.createNode(
+ rootNodeRef,
+ ASSOC_TYPE_QNAME_TEST_CHILDREN,
+ QName.createQName("pathA"),
+ TYPE_QNAME_TEST_MULTIPLE_TESTER).getChildRef();
+ ArrayList values = new ArrayList(1);
+ values.add("ABC");
+ values.add("DEF");
+ // test allowable conditions
+ nodeService.setProperty(nodeRef, PROP_QNAME_STRING_PROP_SINGLE, "ABC");
+ // nodeService.setProperty(nodeRef, PROP_QNAME_STRING_PROP_SINGLE, values); -- should fail
+ nodeService.setProperty(nodeRef, PROP_QNAME_STRING_PROP_MULTIPLE, "ABC");
+ nodeService.setProperty(nodeRef, PROP_QNAME_STRING_PROP_MULTIPLE, values);
+ nodeService.setProperty(nodeRef, PROP_QNAME_ANY_PROP_SINGLE, "ABC");
+ nodeService.setProperty(nodeRef, PROP_QNAME_ANY_PROP_SINGLE, values);
+ nodeService.setProperty(nodeRef, PROP_QNAME_ANY_PROP_MULTIPLE, "ABC");
+ nodeService.setProperty(nodeRef, PROP_QNAME_ANY_PROP_MULTIPLE, values);
+ nodeService.setProperty(nodeRef, undeclaredPropQName, "ABC");
+ nodeService.setProperty(nodeRef, undeclaredPropQName, values);
+
+ // commit as we will be breaking the transaction in the next test
+ setComplete();
+ endTransaction();
+
+ UserTransaction txn = transactionService.getUserTransaction();
+ try
+ {
+ txn.begin();
+ // this should fail as we are passing multiple values into a non-any that is multiple=false
+ nodeService.setProperty(nodeRef, PROP_QNAME_STRING_PROP_SINGLE, values);
+ }
+ catch (DictionaryException e)
+ {
+ // expected
+ }
+ finally
+ {
+ try { txn.rollback(); } catch (Throwable e) {}
+ }
+
+ txn = transactionService.getUserTransaction();
+ try
+ {
+ txn.begin();
+ // Check that multi-valued d:mltext can be collections of MLText
+ values.clear();
+ values.add(new MLText("ABC"));
+ values.add(new MLText("DEF"));
+ nodeService.setProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE, values);
+ List checkValues = (List) nodeService.getProperty(
+ nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("Expected 2 MLText values back", 2, checkValues.size());
+ assertTrue("Incorrect type in collection", checkValues.get(0) instanceof String);
+ assertTrue("Incorrect type in collection", checkValues.get(1) instanceof String);
+
+ // Check that multi-valued d:any properties can be collections of collections (empty)
+ // We put ArrayLists and HashSets into the Collection of d:any, so that is exactly what should come out
+ values.clear();
+ ArrayList arrayListVal = new ArrayList(2);
+ HashSet hashSetVal = new HashSet(2);
+ values.add(arrayListVal);
+ values.add(hashSetVal);
+ nodeService.setProperty(nodeRef, PROP_QNAME_ANY_PROP_MULTIPLE, values);
+ checkValues = (List) nodeService.getProperty(
+ nodeRef, PROP_QNAME_ANY_PROP_MULTIPLE);
+ assertEquals("Expected 2 Collection values back", 2, checkValues.size());
+ assertTrue("Incorrect type in collection", checkValues.get(0) instanceof ArrayList); // ArrayList in - ArrayList out
+ assertTrue("Incorrect type in collection", checkValues.get(1) instanceof HashSet); // HashSet in - HashSet out
+
+ // Check that multi-valued d:any properties can be collections of collections (with values)
+ // We put ArrayLists and HashSets into the Collection of d:any, so that is exactly what should come out
+ arrayListVal.add("ONE");
+ arrayListVal.add("TWO");
+ hashSetVal.add("ONE");
+ hashSetVal.add("TWO");
+ values.clear();
+ values.add(arrayListVal);
+ values.add(hashSetVal);
+ nodeService.setProperty(nodeRef, PROP_QNAME_ANY_PROP_MULTIPLE, values);
+ checkValues = (List) nodeService.getProperty(
+ nodeRef, PROP_QNAME_ANY_PROP_MULTIPLE);
+ assertEquals("Expected 2 Collection values back", 2, checkValues.size());
+ assertTrue("Incorrect type in collection", checkValues.get(0) instanceof ArrayList); // ArrayList in - ArrayList out
+ assertTrue("Incorrect type in collection", checkValues.get(1) instanceof HashSet); // HashSet in - HashSet out
+ assertEquals("First collection incorrect", 2, ((Collection)checkValues.get(0)).size());
+ assertEquals("Second collection incorrect", 2, ((Collection)checkValues.get(1)).size());
+ }
+ catch (DictionaryException e)
+ {
+ // expected
+ }
+ finally
+ {
+ try { txn.rollback(); } catch (Throwable e) {}
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testMultiValueMLTextProperties() throws Exception
+ {
+ NodeRef nodeRef = nodeService.createNode(
+ rootNodeRef,
+ ASSOC_TYPE_QNAME_TEST_CHILDREN,
+ QName.createQName("pathA"),
+ TYPE_QNAME_TEST_MANY_ML_PROPERTIES).getChildRef();
+
+ // Create MLText properties and add to a collection
+ List mlTextCollection = new ArrayList(2);
+ MLText mlText0 = new MLText();
+ mlText0.addValue(Locale.ENGLISH, "Hello");
+ mlText0.addValue(Locale.FRENCH, "Bonjour");
+ mlTextCollection.add(mlText0);
+ MLText mlText1 = new MLText();
+ mlText1.addValue(Locale.ENGLISH, "Bye bye");
+ mlText1.addValue(Locale.FRENCH, "Au revoir");
+ mlTextCollection.add(mlText1);
+
+ nodeService.setProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE, (Serializable) mlTextCollection);
+
+ I18NUtil.setContentLocale(Locale.ENGLISH);
+ Collection mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"Hello", "Bye bye"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.FRENCH);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"Bonjour", "Au revoir"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.GERMAN);
+ nodeService.setProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE, (Serializable)Arrays.asList(new String[]{"eins", "zwei", "drie", "vier"}));
+
+ I18NUtil.setContentLocale(Locale.ENGLISH);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"Hello", "Bye bye"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.FRENCH);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"Bonjour", "Au revoir"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.GERMAN);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"eins", "zwei", "drie", "vier"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.GERMAN);
+ nodeService.setProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE, (Serializable)Arrays.asList(new String[]{"eins"}));
+
+ I18NUtil.setContentLocale(Locale.ENGLISH);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"Hello", "Bye bye"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.FRENCH);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"Bonjour", "Au revoir"}), mlTextCollectionCheck);
+
+ I18NUtil.setContentLocale(Locale.GERMAN);
+ mlTextCollectionCheck = (Collection) nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_ML_VALUE);
+ assertEquals("MLText collection didn't come back correctly.", Arrays.asList(new String[]{"eins"}), mlTextCollectionCheck);
+
+ }
}
diff --git a/source/java/org/alfresco/repo/node/MLPropertyInterceptor.java b/source/java/org/alfresco/repo/node/MLPropertyInterceptor.java
index 24ffd9995d..57209b6b18 100644
--- a/source/java/org/alfresco/repo/node/MLPropertyInterceptor.java
+++ b/source/java/org/alfresco/repo/node/MLPropertyInterceptor.java
@@ -25,11 +25,15 @@
package org.alfresco.repo.node;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
@@ -352,6 +356,22 @@ public class MLPropertyInterceptor implements MethodInterceptor
MLText mlText = (MLText) outboundValue;
ret = mlText.getClosestValue(contentLocale);
}
+ else if(isCollectionOfMLText(outboundValue))
+ {
+ Collection> col = (Collection>)outboundValue;
+ ArrayList answer = new ArrayList(col.size());
+ Locale closestLocale = getClosestLocale(col, contentLocale);
+ for(Object o : col)
+ {
+ MLText mlText = (MLText) o;
+ String value = mlText.get(closestLocale);
+ if(value != null)
+ {
+ answer.add(value);
+ }
+ }
+ ret = answer;
+ }
else if (pivotNodeRef != null) // It is an empty translation
{
if (propertyQName.equals(ContentModel.PROP_MODIFIED))
@@ -397,6 +417,58 @@ public class MLPropertyInterceptor implements MethodInterceptor
return ret;
}
+ public Locale getClosestLocale(Collection> collection, Locale locale)
+ {
+ if (collection.size() == 0)
+ {
+ return null;
+ }
+ // Use the available keys as options
+ HashSet locales = new HashSet();
+ for(Object o : collection)
+ {
+ MLText mlText = (MLText)o;
+ locales.addAll(mlText.keySet());
+ }
+ // Get a match
+ Locale match = I18NUtil.getNearestLocale(locale, locales);
+ if (match == null)
+ {
+ // No close matches for the locale - go for the default locale
+ locale = I18NUtil.getLocale();
+ match = I18NUtil.getNearestLocale(locale, locales);
+ if (match == null)
+ {
+ // just get any locale
+ match = I18NUtil.getNearestLocale(null, locales);
+ }
+ }
+ return match;
+ }
+
+ /**
+ * @param outboundValue
+ * @return
+ */
+ private boolean isCollectionOfMLText(Serializable outboundValue)
+ {
+ if(outboundValue instanceof Collection)
+ {
+ for(Object o : (Collection>)outboundValue)
+ {
+ if(!(o instanceof MLText))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
private Map convertInboundProperties(
Map currentProperties,
Map newProperties,
@@ -443,10 +515,83 @@ public class MLPropertyInterceptor implements MethodInterceptor
else if (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
{
// Don't mess with multivalued properties or instances already of type MLText
- if (propertyDef.isMultiValued() || (inboundValue instanceof MLText) )
+ if (inboundValue instanceof MLText)
{
ret = inboundValue;
}
+ else if(propertyDef.isMultiValued())
+ {
+ // leave collectios of ML text alone
+ if(isCollectionOfMLText(inboundValue))
+ {
+ ret = inboundValue;
+ }
+ else
+ {
+ // Anything else we assume is localised
+ if (currentValue == null && nodeRef != null)
+ {
+ currentValue = nodeService.getProperty(nodeRef, propertyQName);
+ }
+ ArrayList returnMLList = new ArrayList();
+ if (currentValue != null)
+ {
+ Collection currentCollection = DefaultTypeConverter.INSTANCE.getCollection(MLText.class, currentValue);
+ returnMLList.addAll(currentCollection);
+ }
+ Collection inboundCollection = DefaultTypeConverter.INSTANCE.getCollection(String.class, inboundValue);
+ int count = 0;
+ for(String current : inboundCollection)
+ {
+ MLText newMLValue;
+ if(count < returnMLList.size())
+ {
+ MLText currentMLValue = returnMLList.get(count);
+ newMLValue = new MLText();
+ if (currentMLValue != null)
+ {
+ newMLValue.putAll(currentMLValue);
+ }
+ }
+ else
+ {
+ newMLValue = new MLText();
+ }
+ newMLValue.addValue(contentLocale, current);
+ if(count < returnMLList.size())
+ {
+ returnMLList.set(count, newMLValue);
+ }
+ else
+ {
+ returnMLList.add(newMLValue);
+ }
+ count++;
+ }
+ // remove locale settings for anything after
+ for(int i = count; i < returnMLList.size(); i++)
+ {
+ MLText currentMLValue = returnMLList.get(i);
+ MLText newMLValue = new MLText();
+ if (currentMLValue != null)
+ {
+ newMLValue.putAll(currentMLValue);
+ }
+ newMLValue.remove(contentLocale);
+ returnMLList.set(i, newMLValue);
+ }
+ // tidy up empty locales
+ ArrayList tidy = new ArrayList();
+ for(MLText mlText : returnMLList)
+ {
+ if(mlText.keySet().size() > 0)
+ {
+ tidy.add(mlText);
+ }
+ }
+ ret = tidy;
+ }
+ }
else
{
// This is a multilingual single-valued property
diff --git a/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptor.java b/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptor.java
index 3cb470613d..9551e39984 100644
--- a/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptor.java
+++ b/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptor.java
@@ -28,6 +28,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import org.alfresco.model.ContentModel;
@@ -85,7 +86,7 @@ public class NodeRefPropertyMethodInterceptor implements MethodInterceptor
{
this.dictionaryService = dictionaryService;
}
-
+
private DictionaryService getDictionaryService()
{
return dictionaryService;
@@ -95,12 +96,12 @@ public class NodeRefPropertyMethodInterceptor implements MethodInterceptor
{
this.nodeService = nodeService;
}
-
+
private NodeService getNodeService()
{
return nodeService;
}
-
+
public void init()
{
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
@@ -302,7 +303,8 @@ public class NodeRefPropertyMethodInterceptor implements MethodInterceptor
{
if (inboundValue instanceof Collection)
{
- Collection in = (Collection) inboundValue;
+ HashSet categories = new HashSet();
+ Collection> in = (Collection>) inboundValue;
ArrayList out = new ArrayList(in.size());
for (Object o : in)
{
@@ -323,7 +325,11 @@ public class NodeRefPropertyMethodInterceptor implements MethodInterceptor
QName type = getNodeService().getType(test);
if (getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY))
{
- out.add(test);
+ if (!categories.contains(test))
+ {
+ out.add(test);
+ categories.add(test);
+ }
}
}
else
diff --git a/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptorTest.java b/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptorTest.java
index e1d9d923aa..4a7f3e25ad 100644
--- a/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptorTest.java
+++ b/source/java/org/alfresco/repo/node/NodeRefPropertyMethodInterceptorTest.java
@@ -1436,6 +1436,7 @@ public class NodeRefPropertyMethodInterceptorTest extends BaseSpringTest
ArrayList values = new ArrayList();
values.add(cat);
+ values.add(cat);
nodeService.setProperty(n1, typeCategoriesProp, values);
nodeService.setProperty(n1, typeNoderefsProp, values);
@@ -1443,19 +1444,19 @@ public class NodeRefPropertyMethodInterceptorTest extends BaseSpringTest
assertNotNull(mlAwareNodeService.getProperty(n1, typeCategoriesProp));
assertEquals(1, ((Collection) mlAwareNodeService.getProperty(n1, typeCategoriesProp)).size());
assertNotNull(mlAwareNodeService.getProperty(n1, typeNoderefsProp));
- assertEquals(1, ((Collection) mlAwareNodeService.getProperty(n1, typeNoderefsProp)).size());
+ assertEquals(2, ((Collection) mlAwareNodeService.getProperty(n1, typeNoderefsProp)).size());
assertNotNull(mlAwareNodeService.getProperties(n1).get(typeCategoriesProp));
assertEquals(1, ((Collection) mlAwareNodeService.getProperties(n1).get(typeCategoriesProp)).size());
assertNotNull(mlAwareNodeService.getProperties(n1).get(typeNoderefsProp));
- assertEquals(1, ((Collection) mlAwareNodeService.getProperties(n1).get(typeNoderefsProp)).size());
+ assertEquals(2, ((Collection) mlAwareNodeService.getProperties(n1).get(typeNoderefsProp)).size());
assertNotNull(nodeService.getProperty(n1, typeCategoriesProp));
assertEquals(1, ((Collection) nodeService.getProperty(n1, typeCategoriesProp)).size());
assertNotNull(nodeService.getProperty(n1, typeNoderefsProp));
- assertEquals(1, ((Collection) nodeService.getProperty(n1, typeNoderefsProp)).size());
+ assertEquals(2, ((Collection) nodeService.getProperty(n1, typeNoderefsProp)).size());
assertNotNull(nodeService.getProperties(n1).get(typeCategoriesProp));
assertEquals(1, ((Collection) nodeService.getProperties(n1).get(typeCategoriesProp)).size());
assertNotNull(nodeService.getProperties(n1).get(typeNoderefsProp));
- assertEquals(1, ((Collection) nodeService.getProperties(n1).get(typeNoderefsProp)).size());
+ assertEquals(2, ((Collection) nodeService.getProperties(n1).get(typeNoderefsProp)).size());
}
public void testSetPropertyMixedList()
diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java
index 52e9524fb8..4235ff3779 100644
--- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java
+++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java
@@ -45,7 +45,6 @@ import org.alfresco.repo.node.StoreArchiveMap;
import org.alfresco.repo.node.index.NodeIndexer;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
-import org.alfresco.repo.transaction.TransactionListener;
import org.alfresco.repo.transaction.TransactionListenerAdapter;
import org.alfresco.repo.transaction.TransactionalResourceHelper;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
@@ -276,18 +275,20 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
properties = Collections.emptyMap();
}
- // check the parent node has not been deleted in this txn
- if(isDeletedNodeRef(parentRef))
- {
- throw new InvalidNodeRefException("The parent node has been deleted", parentRef);
- }
-
// get/generate an ID for the node
String newUuid = generateGuid(properties);
// Remove any system properties
extractIntrinsicProperties(properties);
+ /**
+ * Check the parent node has not been deleted in this txn.
+ */
+ if(isDeletedNodeRef(parentRef))
+ {
+ throw new InvalidNodeRefException("The parent node has been deleted", parentRef);
+ }
+
// Invoke policy behaviour
invokeBeforeCreateNode(parentRef, assocTypeQName, assocQName, nodeTypeQName);
@@ -348,6 +349,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
* now and commit!
*/
trackNewNodeRef(childAssocRef.getChildRef());
+ untrackDeletedNodeRef(childAssocRef.getChildRef());
// Index
nodeIndexer.indexCreateNode(childAssocRef);
@@ -393,6 +395,22 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
deletedNodes.add(deletedNodeRef);
}
+ /**
+ * Untrack a deleted node ref
+ *
+ * Used when a deleted node is restored.
+ *
+ * @param deletedNodeRef
+ */
+ private void untrackDeletedNodeRef(NodeRef deletedNodeRef)
+ {
+ Set deletedNodes = TransactionalResourceHelper.getSet(KEY_DELETED_NODES);
+ if (deletedNodes.size() > 0)
+ {
+ deletedNodes.remove(deletedNodeRef);
+ }
+ }
+
private boolean isDeletedNodeRef(NodeRef deletedNodeRef)
{
Set deletedNodes = TransactionalResourceHelper.getSet(KEY_DELETED_NODES);
@@ -654,8 +672,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
// Set the type
nodeDaoService.updateNode(nodePair.getFirst(), null, null, typeQName);
- // Add the default aspects to the node (update the properties with any new default values)
- addDefaultAspects(nodePair, typeQName);
+ // Add the default aspects and properties required for the given type. Existing values will not be overridden.
+ addDefaults(nodePair, typeQName);
// Index
nodeIndexer.indexUpdateNode(nodeRef);
@@ -936,7 +954,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
}
else
{
- /**
+ /*
* Go ahead and archive the node
*
* Archiving will take responsibility for firing the policy behaviours on
@@ -1007,7 +1025,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
nodeDaoService.deleteNode(childNodeId);
invokeOnDeleteNode(childParentAssocRef, childNodeType, childNodeQNames, false);
- // loose interest in tracking this node ref
+ // lose interest in tracking this node ref
untrackNewNodeRef(childNodeRef);
}
}
diff --git a/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java b/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java
index 8288071442..8d56362828 100644
--- a/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java
+++ b/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java
@@ -32,6 +32,7 @@ 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.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
@@ -104,16 +105,30 @@ public class CreateNodeRuleTrigger extends RuleTriggerAbstractBase
// Only fire the rule if the node is question has no potential to contain content
// TODO we need to find a better way to do this .. how can this be resolved in CIFS??
boolean triggerRule = false;
- QName type = this.nodeService.getType(childAssocRef.getChildRef());
- ClassDefinition classDefinition = this.dictionaryService.getClass(type);
- if (classDefinition != null)
+
+ NodeRef nodeRef = childAssocRef.getChildRef();
+
+ // This is a "tempory" fix to identify object created via a web client and trigger the rule immediately
+ Boolean value = (Boolean)nodeService.getProperty(nodeRef, QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "editInline"));
+ boolean editInline = false;
+ if (value != null)
{
- for (PropertyDefinition propertyDefinition : classDefinition.getProperties().values())
+ editInline = value.booleanValue();
+ }
+
+ if (editInline == false)
+ {
+ QName type = this.nodeService.getType(nodeRef);
+ ClassDefinition classDefinition = this.dictionaryService.getClass(type);
+ if (classDefinition != null)
{
- if (propertyDefinition.getDataType().getName().equals(DataTypeDefinition.CONTENT) == true)
+ for (PropertyDefinition propertyDefinition : classDefinition.getProperties().values())
{
- triggerRule = true;
- break;
+ if (propertyDefinition.getDataType().getName().equals(DataTypeDefinition.CONTENT) == true)
+ {
+ triggerRule = true;
+ break;
+ }
}
}
}
@@ -132,7 +147,7 @@ public class CreateNodeRuleTrigger extends RuleTriggerAbstractBase
triggerRules(childAssocRef.getParentRef(), childAssocRef.getChildRef());
}
- // Reguadless of whether the rule is triggered, mark this transaction as having created this node
+ // Regardless of whether the rule is triggered, mark this transaction as having created this node
AlfrescoTransactionSupport.bindResource(childAssocRef.getChildRef().toString(), childAssocRef.getChildRef().toString());
}
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java
index 73e0205943..2dd9336fc5 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/AbstractLuceneIndexerAndSearcherFactory.java
@@ -87,15 +87,14 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* @author andyh
*/
-public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource,
- ApplicationContextAware
+public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource, ApplicationContextAware
{
private static Log logger = LogFactory.getLog(AbstractLuceneIndexerAndSearcherFactory.class);
private int queryMaxClauses;
private int indexerBatchSize;
-
+
protected Map queryLanguages = new HashMap();
/**
@@ -155,6 +154,12 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int maxDocsForInMemoryMerge = 10000;
+ private int maxDocsForInMemoryIndex = 10000;
+
+ private double maxRamInMbForInMemoryMerge = 16.0;
+
+ private double maxRamInMbForInMemoryIndex = 16.0;
+
private int maxDocumentCacheSize = 100;
private int maxIsCategoryCacheSize = -1;
@@ -172,8 +177,10 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int mergerMergeFactor = 5;
private int mergerMergeBlockingFactor = 1;
-
- private int mergerMinMergeDocs = 1000;
+
+ private int mergerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
+
+ private double mergerRamBufferSizeMb = 16.0;
private int mergerTargetIndexCount = 5;
@@ -181,7 +188,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int mergerTargetOverlaysBlockingFactor = 1;
- private int termIndexInterval =IndexWriter.DEFAULT_TERM_INDEX_INTERVAL;
+ private int termIndexInterval = IndexWriter.DEFAULT_TERM_INDEX_INTERVAL;
private boolean useNioMemoryMapping = true;
@@ -189,7 +196,9 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int writerMergeFactor = 5;
- private int writerMinMergeDocs = 1000;
+ private int writerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
+
+ private double writerRamBufferSizeMb = 16.0;
private boolean cacheEnabled = true;
@@ -206,7 +215,6 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
super();
}
-
/*
* (non-Javadoc)
* @seeorg.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
@@ -219,6 +227,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
/*
* (non-Javadoc)
+ *
* @see org.alfresco.repo.search.impl.lucene.LuceneConfig#getApplicationContext()
*/
public ConfigurableApplicationContext getApplicationContext()
@@ -404,7 +413,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
if (indexers == null)
{
indexers = new HashMap();
- AlfrescoTransactionSupport.bindResource(indexersKey, indexers);
+ AlfrescoTransactionSupport.bindResource(indexersKey, indexers);
}
LuceneIndexer indexer = indexers.get(storeRef);
if (indexer == null)
@@ -431,8 +440,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
}
else if (TransactionSynchronizationManager.isSynchronizationActive())
{
- Map indexers = (Map) AlfrescoTransactionSupport
- .getResource(indexersKey);
+ Map indexers = (Map) AlfrescoTransactionSupport.getResource(indexersKey);
if (indexers != null)
{
LuceneIndexer indexer = indexers.get(storeRef);
@@ -474,7 +482,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
LuceneSearcher searcher = getSearcher(storeRef, indexer);
return searcher;
}
-
+
/**
* Get node-based searcher (for "selectNodes / selectProperties")
*/
@@ -776,7 +784,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
if (indexers != null)
{
indexers.clear();
- AlfrescoTransactionSupport.unbindResource(indexersKey);
+ AlfrescoTransactionSupport.unbindResource(indexersKey);
}
}
}
@@ -1031,7 +1039,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
*
* @author Derek Hulley
*/
- public static class LuceneIndexBackupComponent /*implements InitializingBean*/
+ public static class LuceneIndexBackupComponent /* implements InitializingBean */
{
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
@@ -1590,7 +1598,6 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
defaultMLSearchAnalysisMode = mode;
}
-
public int getMaxDocIdCacheSize()
{
return maxDocIdCacheSize;
@@ -1690,7 +1697,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
{
this.mergerMergeFactor = mergerMergeFactor;
}
-
+
public int getMergerMergeBlockingFactor()
{
return mergerMergeBlockingFactor;
@@ -1701,14 +1708,14 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
this.mergerMergeBlockingFactor = mergerMergeBlockingFactor;
}
- public int getMergerMinMergeDocs()
+ public int getMergerMaxBufferedDocs()
{
- return mergerMinMergeDocs;
+ return mergerMaxBufferedDocs;
}
- public void setMergerMinMergeDocs(int mergerMinMergeDocs)
+ public void setMergerMaxBufferedDocs(int mergerMaxBufferedDocs)
{
- this.mergerMinMergeDocs = mergerMinMergeDocs;
+ this.mergerMaxBufferedDocs = mergerMaxBufferedDocs;
}
public int getMergerTargetIndexCount()
@@ -1730,7 +1737,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
{
this.mergerTargetOverlayCount = mergerTargetOverlayCount;
}
-
+
public int getMergerTargetOverlaysBlockingFactor()
{
return mergerTargetOverlaysBlockingFactor;
@@ -1781,14 +1788,14 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
this.writerMergeFactor = writerMergeFactor;
}
- public int getWriterMinMergeDocs()
+ public int getWriterMaxBufferedDocs()
{
- return writerMinMergeDocs;
+ return writerMaxBufferedDocs;
}
- public void setWriterMinMergeDocs(int writerMinMergeDocs)
+ public void setWriterMaxBufferedDocs(int writerMaxBufferedDocs)
{
- this.writerMinMergeDocs = writerMinMergeDocs;
+ this.writerMaxBufferedDocs = writerMaxBufferedDocs;
}
public boolean isCacheEnabled()
@@ -1800,29 +1807,112 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
{
this.cacheEnabled = cacheEnabled;
}
-
+
public boolean getPostSortDateTime()
{
- return postSortDateTime;
- }
-
- public void setPostSortDateTime(boolean postSortDateTime)
- {
- this.postSortDateTime = postSortDateTime;
+ return postSortDateTime;
+ }
+
+ public void setPostSortDateTime(boolean postSortDateTime)
+ {
+ this.postSortDateTime = postSortDateTime;
}
-
public void registerQueryLanguage(LuceneQueryLanguageSPI queryLanguage)
{
this.queryLanguages.put(queryLanguage.getName().toLowerCase(), queryLanguage);
}
-
+
+ /**
+ * @return the maxDocsForInMemoryIndex
+ */
+ public int getMaxDocsForInMemoryIndex()
+ {
+ return maxDocsForInMemoryIndex;
+ }
+
+ /**
+ * @param maxDocsForInMemoryIndex
+ * the maxDocsForInMemoryIndex to set
+ */
+ public void setMaxDocsForInMemoryIndex(int maxDocsForInMemoryIndex)
+ {
+ this.maxDocsForInMemoryIndex = maxDocsForInMemoryIndex;
+ }
+
+ /**
+ * @return the maxRamInMbForInMemoryMerge
+ */
+ public double getMaxRamInMbForInMemoryMerge()
+ {
+ return maxRamInMbForInMemoryMerge;
+ }
+
+ /**
+ * @param maxRamInMbForInMemoryMerge
+ * the maxRamInMbForInMemoryMerge to set
+ */
+ public void setMaxRamInMbForInMemoryMerge(double maxRamInMbForInMemoryMerge)
+ {
+ this.maxRamInMbForInMemoryMerge = maxRamInMbForInMemoryMerge;
+ }
+
+ /**
+ * @return the maxRamInMbForInMemoryIndex
+ */
+ public double getMaxRamInMbForInMemoryIndex()
+ {
+ return maxRamInMbForInMemoryIndex;
+ }
+
+ /**
+ * @param maxRamInMbForInMemoryIndex
+ * the maxRamInMbForInMemoryIndex to set
+ */
+ public void setMaxRamInMbForInMemoryIndex(double maxRamInMbForInMemoryIndex)
+ {
+ this.maxRamInMbForInMemoryIndex = maxRamInMbForInMemoryIndex;
+ }
+
+ /**
+ * @return the mergerRamBufferSizeMb
+ */
+ public double getMergerRamBufferSizeMb()
+ {
+ return mergerRamBufferSizeMb;
+ }
+
+ /**
+ * @param mergerRamBufferSizeMb
+ * the mergerRamBufferSizeMb to set
+ */
+ public void setMergerRamBufferSizeMb(double mergerRamBufferSizeMb)
+ {
+ this.mergerRamBufferSizeMb = mergerRamBufferSizeMb;
+ }
+
+ /**
+ * @return the writerRamBufferSizeMb
+ */
+ public double getWriterRamBufferSizeMb()
+ {
+ return writerRamBufferSizeMb;
+ }
+
+ /**
+ * @param writerRamBufferSizeMb
+ * the writerRamBufferSizeMb to set
+ */
+ public void setWriterRamBufferSizeMb(double writerRamBufferSizeMb)
+ {
+ this.writerRamBufferSizeMb = writerRamBufferSizeMb;
+ }
+
protected LuceneQueryLanguageSPI getQueryLanguage(String name)
{
return this.queryLanguages.get(name);
}
-
-
+
protected abstract List getAllStores();
public R doWithAllWriteLocks(WithAllWriteLocksWork lockWork)
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
index ea887faa0f..031fee310f 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
@@ -110,7 +110,7 @@ public interface LuceneConfig
* Lucene writer config
* @return
*/
- public int getWriterMinMergeDocs();
+ public int getWriterMaxBufferedDocs();
/**
* Lucene writer config
@@ -128,7 +128,7 @@ public interface LuceneConfig
* Lucene merger config
* @return
*/
- public int getMergerMinMergeDocs();
+ public int getMergerMaxBufferedDocs();
/**
* Lucene merger config
@@ -244,4 +244,34 @@ public interface LuceneConfig
*/
public ConfigurableApplicationContext getApplicationContext();
+ /**
+ * Ram based limit for in memory merges
+ * @return
+ */
+ public double getMaxRamInMbForInMemoryMerge();
+
+ /**
+ * Ram based limit for in memory portion of writer index.
+ * @return
+ */
+ public double getWriterRamBufferSizeMb();
+
+ /**
+ * Ram based limit for in memory portion of merger index.
+ * @return
+ */
+ public double getMergerRamBufferSizeMb();
+
+ /**
+ * Max docs to allow for in memory indexes (does no apply to merges)
+ * @return
+ */
+ public int getMaxDocsForInMemoryIndex();
+
+ /**
+ * Max Ram to allow for in memory indexes (does not apply to merges)
+ * @return
+ */
+ public double getMaxRamInMbForInMemoryIndex();
+
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
index d940967a3c..67a05bf09b 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
@@ -74,6 +74,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.TraceableThreadFactory;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
@@ -99,6 +100,7 @@ import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.RAMDirectory;
+import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM2.FollowingSiblingIterator;
import org.safehaus.uuid.UUID;
import org.saxpath.SAXPathException;
import org.springframework.context.ApplicationContext;
@@ -229,7 +231,7 @@ public class IndexInfo implements IndexMonitor
* Lock for the index entries
*/
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
-
+
/**
* Read only index readers that also do reference counting.
*/
@@ -295,14 +297,22 @@ public class IndexInfo implements IndexMonitor
*/
private static HashMap indexInfos = new HashMap();
- // Properties that cotrol lucene indexing
+ // Properties that control lucene indexing
// --------------------------------------
// Properties for indexes that are created by transactions ...
private int maxDocsForInMemoryMerge = 10000;
+
+ private int maxDocsForInMemoryIndex = 10000;
- private int writerMinMergeDocs = 1000;
+ private double maxRamInMbForInMemoryMerge = 16.0;
+
+ private double maxRamInMbForInMemoryIndex = 16.0;
+
+ private int writerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
+
+ private double writerRamBufferSizeMb = 16.0;
private int writerMergeFactor = 5;
@@ -312,7 +322,9 @@ public class IndexInfo implements IndexMonitor
// Properties for indexes created by merging
- private int mergerMinMergeDocs = 1000;
+ private int mergerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
+
+ private double mergerRamBufferSizeMb = 16.0;
private int mergerMergeFactor = 5;
@@ -404,10 +416,15 @@ public class IndexInfo implements IndexMonitor
this.threadPoolExecutor = config.getThreadPoolExecutor();
IndexInfo.useNIOMemoryMapping = config.getUseNioMemoryMapping();
this.maxDocsForInMemoryMerge = config.getMaxDocsForInMemoryMerge();
- this.writerMinMergeDocs = config.getWriterMinMergeDocs();
+ this.maxRamInMbForInMemoryMerge = config.getMaxRamInMbForInMemoryMerge();
+ this.maxDocsForInMemoryIndex = config.getMaxDocsForInMemoryIndex();
+ this.maxRamInMbForInMemoryIndex = config.getMaxRamInMbForInMemoryIndex();
+ this.writerMaxBufferedDocs = config.getWriterMaxBufferedDocs();
+ this.writerRamBufferSizeMb = config.getWriterRamBufferSizeMb();
this.writerMergeFactor = config.getWriterMergeFactor();
this.writerMaxMergeDocs = config.getWriterMaxMergeDocs();
- this.mergerMinMergeDocs = config.getMergerMinMergeDocs();
+ this.mergerMaxBufferedDocs = config.getMergerMaxBufferedDocs();
+ this.mergerRamBufferSizeMb = config.getMergerRamBufferSizeMb();
this.mergerMergeFactor = config.getMergerMergeFactor();
this.mergerMergeBlockingFactor = config.getMergerMergeBlockingFactor();
this.mergerMaxMergeDocs = config.getMergerMaxMergeDocs();
@@ -464,7 +481,8 @@ public class IndexInfo implements IndexMonitor
{
writer = new IndexWriter(emptyIndex, new AlfrescoStandardAnalyser(), true, MaxFieldLength.LIMITED);
writer.setUseCompoundFile(writerUseCompoundFile);
- writer.setMaxBufferedDocs(writerMinMergeDocs);
+ writer.setMaxBufferedDocs(writerMaxBufferedDocs);
+ writer.setRAMBufferSizeMB(writerRamBufferSizeMb);
writer.setMergeFactor(writerMergeFactor);
writer.setMaxMergeDocs(writerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
@@ -531,7 +549,8 @@ public class IndexInfo implements IndexMonitor
{
writer = new IndexWriter(oldIndex, new AlfrescoStandardAnalyser(), false, MaxFieldLength.LIMITED);
writer.setUseCompoundFile(writerUseCompoundFile);
- writer.setMaxBufferedDocs(writerMinMergeDocs);
+ writer.setMaxBufferedDocs(writerMaxBufferedDocs);
+ writer.setRAMBufferSizeMB(writerRamBufferSizeMb);
writer.setMergeFactor(writerMergeFactor);
writer.setMaxMergeDocs(writerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
@@ -821,7 +840,7 @@ public class IndexInfo implements IndexMonitor
{
indexEntries.put(id, new IndexEntry(IndexType.DELTA, id, "", TransactionStatus.ACTIVE, "", 0, 0, false));
}
-
+
}
finally
{ // Downgrade lock
@@ -858,7 +877,8 @@ public class IndexInfo implements IndexMonitor
writer = new IndexWriter(location, analyzer, false, MaxFieldLength.LIMITED);
}
writer.setUseCompoundFile(writerUseCompoundFile);
- writer.setMaxBufferedDocs(writerMinMergeDocs);
+ writer.setMaxBufferedDocs(writerMaxBufferedDocs);
+ writer.setRAMBufferSizeMB(writerRamBufferSizeMb);
writer.setMergeFactor(writerMergeFactor);
writer.setMaxMergeDocs(writerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
@@ -1081,7 +1101,7 @@ public class IndexInfo implements IndexMonitor
getWriteLock();
try
{
- mainIndexReader = null;
+ mainIndexReader = null;
}
finally
{
@@ -1116,7 +1136,7 @@ public class IndexInfo implements IndexMonitor
mainIndexReader = createMainIndexReader();
}
-
+
}
finally
{
@@ -1128,17 +1148,18 @@ public class IndexInfo implements IndexMonitor
mainIndexReader.incRef();
if (s_logger.isDebugEnabled())
{
- s_logger.debug("Main index reader references = " + ((ReferenceCounting)mainIndexReader).getReferenceCount());
+ s_logger.debug("Main index reader references = " + ((ReferenceCounting) mainIndexReader).getReferenceCount());
}
-
+
// Prevent close calls from really closing the main reader
- return new FilterIndexReader(mainIndexReader) {
-
+ return new FilterIndexReader(mainIndexReader)
+ {
+
@Override
protected void doClose() throws IOException
{
in.decRef();
- }
+ }
};
}
@@ -1239,11 +1260,12 @@ public class IndexInfo implements IndexMonitor
filterReader.decRef();
}
- // The reference count would have been incremented automatically by MultiReader / FilterIndexReaderByStringId
+ // The reference count would have been incremented automatically by MultiReader /
+ // FilterIndexReaderByStringId
deltaReader.decRef();
if (s_logger.isDebugEnabled())
{
- s_logger.debug("Main index reader references = " + ((ReferenceCounting)mainIndexReader).getReferenceCount());
+ s_logger.debug("Main index reader references = " + ((ReferenceCounting) mainIndexReader).getReferenceCount());
}
reader = ReferenceCountingReadOnlyIndexReaderFactory.createReader(MAIN_READER + id, reader, false, config);
ReferenceCounting refCounting = (ReferenceCounting) reader;
@@ -1298,8 +1320,7 @@ public class IndexInfo implements IndexMonitor
}
getReadLock();
}
-
-
+
releaseReadLock();
getWriteLock();
try
@@ -1992,13 +2013,53 @@ public class IndexInfo implements IndexMonitor
referenceCountingReadOnlyIndexReaders.put(id, reader);
}
+ private double getSizeInMb(File file)
+ {
+ long size = getSize(file);
+ return size/1024.0d/1024.0d;
+ }
+
+ private long getSize(File file)
+ {
+ long size = 0l;
+ if (file == null)
+ {
+ return size;
+ }
+ if (file.isFile())
+ {
+ return file.length();
+ }
+ else
+ {
+ File[] files = file.listFiles();
+ if(files == null)
+ {
+ return size;
+ }
+ for (File current : files)
+ {
+ if (current.isDirectory())
+ {
+ size += getSize(current);
+ }
+ else
+ {
+ size += current.length();
+ }
+ }
+ }
+ return size;
+ }
+
private IndexReader buildReferenceCountingIndexReader(String id, long size) throws IOException
{
IndexReader reader;
File location = new File(indexDirectory, id).getCanonicalFile();
+ double folderSize = getSizeInMb(location);
if (IndexReader.indexExists(location))
{
- if ((config != null) && (size < config.getMaxDocsForInMemoryMerge()))
+ if ((size < maxDocsForInMemoryIndex) && (folderSize < maxRamInMbForInMemoryIndex))
{
RAMDirectory rd = new RAMDirectory(location);
reader = IndexReader.open(rd);
@@ -2947,9 +3008,9 @@ public class IndexInfo implements IndexMonitor
private abstract class AbstractSchedulable implements Schedulable, Runnable
{
ScheduledState scheduledState = ScheduledState.UN_SCHEDULED;
-
+
private int scheduledCount;
-
+
public synchronized int getScheduledCount()
{
return scheduledCount;
@@ -3767,6 +3828,7 @@ public class IndexInfo implements IndexMonitor
IndexWriter writer = null;
File outputLocation = null;
+ double mergeSize = 0;
for (IndexEntry entry : toMerge.values())
{
File location = new File(indexDirectory, entry.getName()).getCanonicalFile();
@@ -3784,12 +3846,13 @@ public class IndexInfo implements IndexMonitor
}
readers[count++] = reader;
docCount += entry.getDocumentCount();
+ mergeSize += getSizeInMb(location);
}
else if (entry.getStatus() == TransactionStatus.MERGE_TARGET)
{
mergeTargetId = entry.getName();
outputLocation = location;
- if (docCount < maxDocsForInMemoryMerge)
+ if ((docCount < maxDocsForInMemoryMerge) && (mergeSize < maxRamInMbForInMemoryMerge))
{
ramDirectory = new RAMDirectory();
writer = new IndexWriter(ramDirectory, new AlfrescoStandardAnalyser(), true, MaxFieldLength.UNLIMITED);
@@ -3800,7 +3863,8 @@ public class IndexInfo implements IndexMonitor
}
writer.setUseCompoundFile(mergerUseCompoundFile);
- writer.setMaxBufferedDocs(mergerMinMergeDocs);
+ writer.setMaxBufferedDocs(mergerMaxBufferedDocs);
+ writer.setRAMBufferSizeMB(mergerRamBufferSizeMb);
writer.setMergeFactor(mergerMergeFactor);
writer.setMaxMergeDocs(mergerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
diff --git a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java
index 001ac8d5f3..8de6eafd79 100644
--- a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java
+++ b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java
@@ -31,19 +31,19 @@ import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
-import org.alfresco.repo.domain.hibernate.DirtySessionMethodInterceptor;
import org.alfresco.repo.node.NodeServicePolicies;
+import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
+import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
+import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
@@ -141,7 +141,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
private PermissionsManager permissionsManager;
/** a transactionally-safe cache to be injected */
- private SimpleCache> personCache;
+ private SimpleCache> personCache;
/** People Container ref cache (Tennant aware) */
private Map peopleContainerRefs = new ConcurrentHashMap(4);
@@ -190,12 +190,18 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
PropertyCheck.mandatory(this, "aclDao", aclDao);
PropertyCheck.mandatory(this, "homeFolderManager", homeFolderManager);
- this.policyComponent
- .bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode"));
- this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this,
- "beforeDeleteNode"));
- this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), ContentModel.TYPE_PERSON, new JavaBehaviour(this,
- "onUpdateProperties"));
+ this.policyComponent.bindClassBehaviour(
+ OnCreateNodePolicy.QNAME,
+ ContentModel.TYPE_PERSON,
+ new JavaBehaviour(this, "onCreateNode"));
+ this.policyComponent.bindClassBehaviour(
+ BeforeDeleteNodePolicy.QNAME,
+ ContentModel.TYPE_PERSON,
+ new JavaBehaviour(this, "beforeDeleteNode"));
+ this.policyComponent.bindClassBehaviour(
+ OnUpdatePropertiesPolicy.QNAME,
+ ContentModel.TYPE_PERSON,
+ new JavaBehaviour(this, "onUpdateProperties"));
}
public UserNameMatcher getUserNameMatcher()
@@ -254,7 +260,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
* @param personCache
* a transactionally safe cache
*/
- public void setPersonCache(SimpleCache> personCache)
+ public void setPersonCache(SimpleCache> personCache)
{
this.personCache = personCache;
}
@@ -346,30 +352,32 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
private NodeRef getPersonOrNull(String searchUserName)
{
String cacheKey = searchUserName.toLowerCase();
- Map allRefs = this.personCache.get(cacheKey);
+ Set allRefs = this.personCache.get(cacheKey);
if (allRefs == null)
{
- List childRefs = nodeService.getChildAssocs(getPeopleContainer(),
- ContentModel.ASSOC_CHILDREN, QName.createQName("cm", searchUserName.toLowerCase(),
- namespacePrefixResolver), false);
- allRefs = new LinkedHashMap(childRefs.size() * 2);
+ List childRefs = nodeService.getChildAssocs(
+ getPeopleContainer(),
+ ContentModel.ASSOC_CHILDREN,
+ QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, searchUserName.toLowerCase()),
+ false);
+ allRefs = new LinkedHashSet(childRefs.size() * 2);
// add to cache
personCache.put(cacheKey, allRefs);
for (ChildAssociationRef childRef : childRefs)
{
NodeRef nodeRef = childRef.getChildRef();
- Serializable value = nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
- String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, value);
- allRefs.put(realUserName, nodeRef);
+ allRefs.add(nodeRef);
}
}
List refs = new ArrayList(allRefs.size());
- for (Entry entry : allRefs.entrySet())
+ for (NodeRef nodeRef : allRefs)
{
- if (userNameMatcher.matches(searchUserName, entry.getKey()))
+ Serializable value = nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
+ String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, value);
+ if (userNameMatcher.matches(searchUserName, realUserName))
{
- refs.add(entry.getValue());
+ refs.add(nodeRef);
}
}
NodeRef returnRef = null;
@@ -836,10 +844,8 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
// Policies
- /*
- * (non-Javadoc)
- *
- * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef)
+ /**
+ * {@inheritDoc}
*/
public void onCreateNode(ChildAssociationRef childAssocRef)
{
@@ -854,10 +860,8 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
homeFolderManager.onCreateNode(childAssocRef);
}
- /*
- * (non-Javadoc)
- *
- * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
+ /**
+ * {@inheritDoc}
*/
public void beforeDeleteNode(NodeRef nodeRef)
{
diff --git a/source/java/org/alfresco/repo/security/person/PersonTest.java b/source/java/org/alfresco/repo/security/person/PersonTest.java
index 40995383ed..9542338125 100644
--- a/source/java/org/alfresco/repo/security/person/PersonTest.java
+++ b/source/java/org/alfresco/repo/security/person/PersonTest.java
@@ -477,7 +477,6 @@ public class PersonTest extends BaseSpringTest
private void testProperties(NodeRef nodeRef, String userName, String firstName, String lastName, String email, String orgId)
{
- Map props = nodeService.getProperties(nodeRef);
assertEquals(userName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME)));
assertNotNull(nodeService.getProperty(nodeRef, ContentModel.PROP_HOMEFOLDER));
assertEquals(firstName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_FIRSTNAME)));
@@ -597,8 +596,23 @@ public class PersonTest extends BaseSpringTest
transactionService.getRetryingTransactionHelper().doInTransaction(deletePersonWork, false, true);
}
+
+ public void testSplitPersonCleanupManyTimes() throws Throwable
+ {
+ for (int i = 0; i < 100; i++) // Bump this number up to 1000 for 'real' testing
+ {
+ try
+ {
+ forceSplitPersonCleanup();
+ }
+ catch (Throwable e)
+ {
+ throw new RuntimeException("Failed on iteration " + i + " of forcing split person.", e);
+ }
+ }
+ }
- public void testSplitPersonCleanup() throws Exception
+ private void forceSplitPersonCleanup() throws Exception
{
// Kill the annoying Spring-managed txn
super.setComplete();