diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml
index 73a133d9b2..f525758b20 100644
--- a/config/alfresco/action-services-context.xml
+++ b/config/alfresco/action-services-context.xml
@@ -567,10 +567,10 @@
-
+
-
+
false
@@ -590,7 +590,7 @@
-
+
diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java
index 48542b8ad4..99e860289e 100644
--- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java
+++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java
@@ -34,6 +34,7 @@ import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
+import org.alfresco.repo.avm.util.AVMUtil;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -703,10 +704,11 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
*/
public void removeNode(String parent, String name)
{
- grabLock(parent + '/' + name);
+ String path = AVMUtil.extendAVMPath(parent, name);
+ grabLock(path);
fService.removeNode(parent, name);
String[] storePath = parent.split(":");
- fService.createSnapshot(storePath[0], null, null);
+ fService.createSnapshot(storePath[0], null, "Removed "+path);
String webProject = getWebProject(storePath[0]);
if (webProject != null)
{
@@ -722,7 +724,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
grabLock(path);
fService.removeNode(path);
String[] storePath = path.split(":");
- fService.createSnapshot(storePath[0], null, null);
+ fService.createSnapshot(storePath[0], null, "Removed "+path);
String webProject = getWebProject(storePath[0]);
if (webProject != null)
{
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
index 58bfbdccf9..f40618154c 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
@@ -1259,47 +1259,62 @@ public class AVMServiceTest extends AVMServiceTestBase
try
{
setupBasicTree();
+
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 V1");
fService.createSnapshot("main", "v1", null);
+
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 V2");
fService.createSnapshot("main", "v2", null);
+
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 V3");
fService.createSnapshot("main", "v3", null);
+
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 V4");
fService.createSnapshot("main", "v4", null);
+
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 V5");
fService.createSnapshot("main", "v5", null);
+
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 HEAD");
+
StoreRef storeRef = AVMNodeConverter.ToStoreRef("main");
+
SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true);
+
ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\"");
assertEquals(0, results.length());
results.close();
+
results = searchService.query(storeRef, "lucene", "TEXT:\"V5\"");
assertEquals(1, results.length());
results.close();
-
+
+ results = searchService.query(storeRef, "lucene", "TEXT:\"V2\"");
+ assertEquals(0, results.length());
+ results.close();
+
AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo");
List history = fService.getHistory(desc, 100);
AVMNodeDescriptor toRevert = history.get(3);
+
final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertToVersionAction.NAME);
action.setParameterValue(AVMRevertToVersionAction.TOREVERT, toRevert);
final AVMRevertToVersionAction revert = (AVMRevertToVersionAction) fContext.getBean("avm-revert-to-version");
@@ -1307,26 +1322,15 @@ public class AVMServiceTest extends AVMServiceTestBase
{
public Object execute() throws Exception
{
+ // note: including implicit snapshot
revert.execute(action, AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo"));
return null;
}
- }
- ;
+ };
+
TransactionService transactionService = (TransactionService) fContext.getBean("transactionService");
transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork());
-
- results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\"");
- assertEquals(0, results.length());
- results.close();
- results = searchService.query(storeRef, "lucene", "TEXT:\"V5\"");
- assertEquals(1, results.length());
- results.close();
- results = searchService.query(storeRef, "lucene", "TEXT:\"V2\"");
- assertEquals(0, results.length());
- results.close();
-
- fService.createSnapshot("main", "reverted", null);
-
+
results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\"");
assertEquals(0, results.length());
results.close();
@@ -1336,7 +1340,6 @@ public class AVMServiceTest extends AVMServiceTestBase
results = searchService.query(storeRef, "lucene", "TEXT:\"V2\"");
assertEquals(1, results.length());
results.close();
-
}
catch (Exception e)
{
diff --git a/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java b/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java
index 257cf9f23c..9b0d669ad4 100644
--- a/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java
+++ b/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java
@@ -29,6 +29,7 @@ import java.util.List;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.avm.AVMNodeConverter;
+import org.alfresco.repo.avm.util.AVMUtil;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -77,9 +78,12 @@ public class AVMRevertToVersionAction extends ActionExecuterAbstractBase
{
Pair versionPath =
AVMNodeConverter.ToAVMVersionPath(actionedUponNodeRef);
- AVMNodeDescriptor toRevert =
+ AVMNodeDescriptor toRevertTo =
(AVMNodeDescriptor)action.getParameterValue(TOREVERT);
- fAVMService.revert(versionPath.getSecond(), toRevert);
+ fAVMService.revert(versionPath.getSecond(), toRevertTo);
+
+ String[] storePath = AVMUtil.splitPath(versionPath.getSecond());
+ fAVMService.createSnapshot(storePath[0], null, "Reverted "+versionPath.getSecond()+" to version "+toRevertTo.getVersionID());
}
/* (non-Javadoc)
diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java
index b6ef34514e..71d3813293 100644
--- a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java
+++ b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java
@@ -961,30 +961,28 @@ public class SandboxServiceImpl implements SandboxService
List assetsToRevert = new ArrayList(assets.size());
- List tasks = null;
+ List wfRelativePaths = WCMWorkflowUtil.getAssociatedPathsForSandbox(avmSyncService, workflowService, sbStoreId);
+
for (AssetInfo asset : assets)
{
- if (tasks == null)
+ if (! asset.getSandboxId().equals(sbStoreId))
{
- tasks = WCMWorkflowUtil.getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(asset.getAvmPath()));
+ // belts-and-braces
+ logger.warn("revertListAssets: Skip assert "+asset.getPath()+" (was "+asset.getSandboxId()+", expected "+sbStoreId+")");
+ continue;
}
- // TODO refactor getAssociatedTasksForNode to use AssetInfo instead of AVMNodeDescriptor
- AVMNodeDescriptor node = ((AssetInfoImpl)asset).getAVMNodeDescriptor();
-
- if (node != null)
+ // check if in workflow
+ if (! wfRelativePaths.contains(asset.getPath()))
{
- if (WCMWorkflowUtil.getAssociatedTasksForNode(avmService, node, tasks).size() == 0)
- {
- assetsToRevert.add(asset);
-
- if (VirtServerUtils.requiresUpdateNotification(asset.getAvmPath()))
- {
- // Bind the post-commit transaction listener with data required for virtualization server notification
- UpdateSandboxTransactionListener tl = new UpdateSandboxTransactionListener(asset.getAvmPath());
- AlfrescoTransactionSupport.bindListener(tl);
- }
- }
+ assetsToRevert.add(asset);
+
+ if (VirtServerUtils.requiresUpdateNotification(asset.getAvmPath()))
+ {
+ // Bind the post-commit transaction listener with data required for virtualization server notification
+ UpdateSandboxTransactionListener tl = new UpdateSandboxTransactionListener(asset.getAvmPath());
+ AlfrescoTransactionSupport.bindListener(tl);
+ }
}
}
diff --git a/source/java/org/alfresco/wcm/util/WCMWorkflowUtil.java b/source/java/org/alfresco/wcm/util/WCMWorkflowUtil.java
index d863feee3e..328c5d2231 100644
--- a/source/java/org/alfresco/wcm/util/WCMWorkflowUtil.java
+++ b/source/java/org/alfresco/wcm/util/WCMWorkflowUtil.java
@@ -24,6 +24,7 @@
*/
package org.alfresco.wcm.util;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -36,6 +37,8 @@ import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.LayeringDescriptor;
+import org.alfresco.service.cmr.avmsync.AVMDifference;
+import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowService;
@@ -56,7 +59,7 @@ import org.apache.commons.logging.LogFactory;
public class WCMWorkflowUtil
{
private static final Log logger = LogFactory.getLog(WCMWorkflowUtil.class);
-
+
public static NodeRef createWorkflowPackage(WorkflowService workflowService, AVMService avmService, SandboxInfo sandboxInfo)
{
// create package paths (layered to user sandbox area as target)
@@ -81,25 +84,30 @@ public class WCMWorkflowUtil
public static List getAssociatedTasksForSandbox(WorkflowService workflowService, final String storeName)
{
+ long start = System.currentTimeMillis();
+
String fromPath = WCMUtil.buildStoreRootPath(storeName);
WorkflowTaskQuery query = new WorkflowTaskQuery();
-
+
HashMap props = new HashMap(1, 1.0f);
-
+
props.put(WCMWorkflowModel.PROP_FROM_PATH, fromPath);
query.setProcessCustomProps(props);
query.setActive(true);
-
+
List tasks = workflowService.queryTasks(query);
-
- if (logger.isDebugEnabled())
+
+ if (logger.isTraceEnabled())
{
- logger.debug("found " + tasks.size() + " tasks originating user sandbox " + fromPath);
+ logger.trace("getAssociatedTasksForSandbox: "+storeName+" (found "+tasks.size()+" tasks originating user sandbox "+fromPath+") in "+(System.currentTimeMillis()-start)+" msecs");
}
return tasks;
}
-
+
+ /**
+ * @deprecated since 3.2
+ */
public static List getAssociatedTasksForNode(AVMService avmService, AVMNodeDescriptor node, List tasks)
{
List result = new LinkedList();
@@ -139,10 +147,58 @@ public class WCMWorkflowUtil
return result;
}
-
+
+ /**
+ * @deprecated since 3.2
+ */
public static List getAssociatedTasksForNode(WorkflowService workflowService, AVMService avmService, AVMNodeDescriptor node)
{
- final List tasks = WCMWorkflowUtil.getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(node.getPath()));
+ final List tasks = getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(node.getPath()));
return getAssociatedTasksForNode(avmService, node, tasks);
}
+
+ public static List getAssociatedPathsForSandbox(AVMSyncService avmSyncService, WorkflowService workflowService, String sandboxName)
+ {
+ long start = System.currentTimeMillis();
+
+ List tasks = getAssociatedTasksForSandbox(workflowService, sandboxName);
+ List storeRelativePaths = getAssociatedPathsForSandboxTasks(avmSyncService, sandboxName, tasks);
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("getAssociatedPathsForSandbox: "+sandboxName+" (tasks="+tasks.size()+", paths="+storeRelativePaths.size()+") in "+(System.currentTimeMillis()-start)+" msecs");
+ }
+
+ return storeRelativePaths;
+ }
+
+ private static List getAssociatedPathsForSandboxTasks(AVMSyncService avmSyncService, String sandboxName, List tasks)
+ {
+ long start = System.currentTimeMillis();
+
+ String stagingSandboxName = WCMUtil.buildStagingStoreName(WCMUtil.getWebProjectStoreId(sandboxName));
+ List storeRelativePaths = new ArrayList(tasks.size());
+
+ for (WorkflowTask task : tasks)
+ {
+ final NodeRef ref = task.path.instance.workflowPackage;
+
+ String wfPath = AVMNodeConverter.ToAVMVersionPath(ref).getSecond();
+ String stagingSandboxPath = WCMUtil.getCorrespondingPath(wfPath, stagingSandboxName);
+
+ List diffs = avmSyncService.compare(-1, wfPath, -1, stagingSandboxPath, null);
+
+ for (AVMDifference diff : diffs)
+ {
+ storeRelativePaths.add(WCMUtil.getStoreRelativePath(diff.getSourcePath()));
+ }
+ }
+
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("getAssociatedPathsForSandboxTasks: "+sandboxName+" (tasks="+tasks.size()+", paths="+storeRelativePaths.size()+") in "+(System.currentTimeMillis()-start)+" msecs");
+ }
+
+ return storeRelativePaths;
+ }
}