From 49856600ae5f503b6679d5a42619e737fc31d5dc Mon Sep 17 00:00:00 2001 From: Jan Vonka Date: Thu, 18 Mar 2010 17:33:21 +0000 Subject: [PATCH] WCM: consolidate getWebProject & deleteSandbox (also precursor for SAIL-359) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19378 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/avm/AVMInterpreter.java | 49 +- .../repo/avm/AVMLockingAwareService.java | 20 +- .../org/alfresco/repo/avm/AVMServiceTest.java | 471 +++++++++--------- .../avm/actions/AVMUndoSandboxListAction.java | 59 +-- .../repo/avm/wf/AVMRemoveWFStoreHandler.java | 45 +- .../repo/avm/wf/AVMSubmitPackageHandler.java | 51 +- .../alfresco/service/cmr/avm/AVMService.java | 4 + .../service/cmr/remote/AVMRemote.java | 39 +- .../alfresco/wcm/sandbox/SandboxFactory.java | 84 ++-- .../wcm/sandbox/SandboxServiceImpl.java | 61 +-- .../java/org/alfresco/wcm/util/WCMUtil.java | 15 +- 11 files changed, 459 insertions(+), 439 deletions(-) diff --git a/source/java/org/alfresco/repo/avm/AVMInterpreter.java b/source/java/org/alfresco/repo/avm/AVMInterpreter.java index 4c7e39e9c2..e80392e9c5 100644 --- a/source/java/org/alfresco/repo/avm/AVMInterpreter.java +++ b/source/java/org/alfresco/repo/avm/AVMInterpreter.java @@ -1,20 +1,21 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ package org.alfresco.repo.avm; @@ -51,9 +52,9 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.ISO8601DateFormat; import org.alfresco.wcm.util.WCMUtil; import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.springframework.extensions.surf.util.ISO8601DateFormat; /** * An interactive console for the AVM repository. @@ -433,7 +434,7 @@ public class AVMInterpreter String storeName = command[1]; int ver =Integer.parseInt(command[2]); - String wpStoreId = getWebProject(storeName); + String wpStoreId = WCMUtil.getWebProject(fService, storeName); if ((wpStoreId != null) && (ver <= 2)) { return "WCM store - cannot delete versions 0-2"; @@ -447,7 +448,7 @@ public class AVMInterpreter return "Syntax Error."; } String storeName = command[1]; - String wpStoreId = getWebProject(storeName); + String wpStoreId = WCMUtil.getWebProject(fService, storeName); Date fromDate = ISO8601DateFormat.parse(command[2]); Date toDate = ISO8601DateFormat.parse(command[3]); @@ -971,14 +972,4 @@ public class AVMInterpreter } return elements; } - - private String getWebProject(String name) - { - String wpStoreId = WCMUtil.getWebProjectStoreId(name); - if (WCMUtil.getWebProjectNodeFromWebProjectStore(fService, wpStoreId) != null) - { - return wpStoreId; - } - return null; - } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java index c7ab9fc0df..c298fb30b8 100644 --- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java +++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java @@ -702,7 +702,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa fService.removeNode(parent, name); String[] storePath = AVMUtil.splitPath(parent); fService.createSnapshot(storePath[0], null, "Removed "+path); - String webProject = getWebProject(storePath[0]); + String webProject = WCMUtil.getWebProject(fService, storePath[0]); if (webProject != null) { fLockingService.removeLocksInDirectory(webProject, storePath[0], AVMUtil.extendAVMPath(storePath[1], name)); @@ -718,7 +718,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa fService.removeNode(path); String[] storePath = AVMUtil.splitPath(path); fService.createSnapshot(storePath[0], null, "Removed "+path); - String webProject = getWebProject(storePath[0]); + String webProject = WCMUtil.getWebProject(fService, storePath[0]); if (webProject != null) { fLockingService.removeLocksInDirectory(webProject, storePath[0], storePath[1]); @@ -749,8 +749,8 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa String[] srcStorePath = AVMUtil.splitPath(srcPath); String[] dstStorePath = AVMUtil.splitPath(dstPath); - String srcWebProject = getWebProject(srcStorePath[0]); - String dstWebProject = getWebProject(dstStorePath[0]); + String srcWebProject = WCMUtil.getWebProject(fService, srcStorePath[0]); + String dstWebProject = WCMUtil.getWebProject(fService, dstStorePath[0]); if ((dstWebProject != null) && (dstWebProject.equals(srcWebProject))) { @@ -889,16 +889,6 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa fService.uncover(dirPath, name); } - private String getWebProject(String name) - { - String wpStoreId = WCMUtil.getWebProjectStoreId(name); - if (WCMUtil.getWebProjectNodeFromWebProjectStore(fService, wpStoreId) != null) - { - return wpStoreId; - } - return null; - } - private void grabLock(String path) { AVMNodeDescriptor desc = fService.lookup(-1, path, false); @@ -907,7 +897,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa return; } String[] storePath = AVMUtil.splitPath(path); - String webProject = getWebProject(storePath[0]); + String webProject = WCMUtil.getWebProject(fService, storePath[0]); if (webProject != null && webProject.equals(storePath[0])) { // Don't do locking in staging. diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index 6262473817..77a8972690 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -14,7 +14,8 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ + * along with Alfresco. If not, see . + */ package org.alfresco.repo.avm; @@ -64,7 +65,7 @@ import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.remote.RepoRemote; -import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; import org.alfresco.service.cmr.repository.NodeRef; @@ -3981,84 +3982,84 @@ public class AVMServiceTest extends AVMServiceTestBase throw e; } } - - public void testLayeredFile4() throws Exception - { - try - { - fService.createStore("mainA"); - fService.createStore("mainB"); - fService.createStore("mainB--layer"); - - fService.createDirectory("mainA:/", "a"); - fService.createDirectory("mainB:/", "a"); - - fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a"); - - // note: unlike WCM, edit staging directly (ie. don't bother with 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(); - - fService.createSnapshot("mainA", null, null); - - // note: WCM does not expose layered file (between web project staging sandboxes) - fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo"); - - - AVMNodeDescriptor foo = fService.lookup(-1, "mainB--layer:/a/foo"); - assertEquals(1, foo.getVersionID()); - assertTrue(foo.isLayeredFile()); - - ContentData cData = fService.getContentDataForRead(foo); - assertNotNull(cData); - - 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); - - - foo = fService.lookup(-1, "mainB:/a/foo"); - assertEquals(1, foo.getVersionID()); - assertTrue(foo.isLayeredFile()); - - cData = fService.getContentDataForRead(foo); - assertNotNull(cData); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am mainA:/a/foo", line); - - - foo = fService.lookup(-1, "mainA:/a/foo"); - assertEquals(1, foo.getVersionID()); - assertTrue(foo.isPlainFile()); - - cData = fService.getContentDataForRead(foo); - assertNotNull(cData); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am mainA:/a/foo", line); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("mainA"); - fService.purgeStore("mainB"); - fService.purgeStore("mainB--layer"); - } - } - + + public void testLayeredFile4() throws Exception + { + try + { + fService.createStore("mainA"); + fService.createStore("mainB"); + fService.createStore("mainB--layer"); + + fService.createDirectory("mainA:/", "a"); + fService.createDirectory("mainB:/", "a"); + + fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a"); + + // note: unlike WCM, edit staging directly (ie. don't bother with 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(); + + fService.createSnapshot("mainA", null, null); + + // note: WCM does not expose layered file (between web project staging sandboxes) + fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo"); + + + AVMNodeDescriptor foo = fService.lookup(-1, "mainB--layer:/a/foo"); + assertEquals(1, foo.getVersionID()); + assertTrue(foo.isLayeredFile()); + + ContentData cData = fService.getContentDataForRead(foo); + assertNotNull(cData); + + 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); + + + foo = fService.lookup(-1, "mainB:/a/foo"); + assertEquals(1, foo.getVersionID()); + assertTrue(foo.isLayeredFile()); + + cData = fService.getContentDataForRead(foo); + assertNotNull(cData); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am mainA:/a/foo", line); + + + foo = fService.lookup(-1, "mainA:/a/foo"); + assertEquals(1, foo.getVersionID()); + assertTrue(foo.isPlainFile()); + + cData = fService.getContentDataForRead(foo); + assertNotNull(cData); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am mainA:/a/foo", line); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("mainA"); + fService.purgeStore("mainB"); + fService.purgeStore("mainB--layer"); + } + } + /** * Test rename. @@ -5158,152 +5159,152 @@ public class AVMServiceTest extends AVMServiceTestBase throw e; } } - - public void testVersionedRead2() throws Exception - { - try - { - assertNull(fService.lookup(-1, "main:/foo")); - assertNull(fService.lookup(-1, "main:/afoo")); - - try - { - fService.getFileInputStream(-1, "main:/afoo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - PrintStream out = new PrintStream(fService.createFile("main:/", "foo")); - out.print("version1"); - out.close(); - - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - assertEquals("version1", reader.readLine()); - reader.close(); - - fService.createLayeredFile("main:/foo", "main:/", "afoo"); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/afoo"))); - assertEquals("version1", reader.readLine()); - reader.close(); - - fService.createSnapshot("main", null, null); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/foo"))); - assertEquals("version1", reader.readLine()); - reader.close(); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo"))); - assertEquals("version1", reader.readLine()); - reader.close(); - - assertEquals(8, fService.lookup(-1, "main:/foo").getLength()); - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.print("version2"); - out.close(); - - fService.createSnapshot("main", null, null); - - fService.createSnapshot("main", null, null); - - fService.removeNode("main:/foo"); - - fService.createSnapshot("main", null, null); - - // check versions of the plain file (main:/foo) - - try - { - fService.getFileInputStream(0, "main:/foo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/foo"))); - assertEquals("version1", reader.readLine()); - reader.close(); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/foo"))); - assertEquals("version2", reader.readLine()); - reader.close(); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(3, "main:/foo"))); - assertEquals("version2", reader.readLine()); - reader.close(); - - try - { - fService.getFileInputStream(4, "main:/foo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/foo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - // check versions of the layered file (main:/afoo) - - try - { - fService.getFileInputStream(0, "main:/afoo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo"))); - assertEquals("version1", reader.readLine()); - reader.close(); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/afoo"))); - assertEquals("version2", reader.readLine()); - reader.close(); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(3, "main:/afoo"))); - assertEquals("version2", reader.readLine()); - reader.close(); - - try - { - fService.getFileInputStream(4, "main:/afoo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/afoo"); - fail(); - } - catch (AVMNotFoundException nfe) - { - // expected - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } + + public void testVersionedRead2() throws Exception + { + try + { + assertNull(fService.lookup(-1, "main:/foo")); + assertNull(fService.lookup(-1, "main:/afoo")); + + try + { + fService.getFileInputStream(-1, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + PrintStream out = new PrintStream(fService.createFile("main:/", "foo")); + out.print("version1"); + out.close(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + fService.createLayeredFile("main:/foo", "main:/", "afoo"); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/afoo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + fService.createSnapshot("main", null, null); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/foo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + assertEquals(8, fService.lookup(-1, "main:/foo").getLength()); + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.print("version2"); + out.close(); + + fService.createSnapshot("main", null, null); + + fService.createSnapshot("main", null, null); + + fService.removeNode("main:/foo"); + + fService.createSnapshot("main", null, null); + + // check versions of the plain file (main:/foo) + + try + { + fService.getFileInputStream(0, "main:/foo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/foo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/foo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(3, "main:/foo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + + try + { + fService.getFileInputStream(4, "main:/foo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/foo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + // check versions of the layered file (main:/afoo) + + try + { + fService.getFileInputStream(0, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/afoo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(3, "main:/afoo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + + try + { + fService.getFileInputStream(4, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } /** * Test rename of an overlayed directory contained in an overlayed directory. @@ -6279,25 +6280,25 @@ public class AVMServiceTest extends AVMServiceTestBase { try { - fService.setStoreProperty("main", QName.createQName(null, ".dns.alice--preview"), new PropertyValue(null, "alice-preview")); + fService.setStoreProperty("main", QName.createQName(null, SandboxConstants.PROP_DNS+"alice--preview"), new PropertyValue(null, "alice-preview")); fService.setStoreProperty("main", QName.createQName("", ".other.property"), new PropertyValue(null, "other value")); - Map result = fService.queryStorePropertyKey("main", QName.createQName("", ".dns.%")); + Map result = fService.queryStorePropertyKey("main", QName.createQName("", SandboxConstants.PROP_DNS+"%")); assertEquals(1, result.size()); fService.createStore("second"); - fService.setStoreProperty("second", QName.createQName("", ".dns.alice"), new PropertyValue(null, "alice-space")); - Map> matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.%")); + fService.setStoreProperty("second", QName.createQName("", SandboxConstants.PROP_DNS+"alice"), new PropertyValue(null, "alice-space")); + Map> matches = fService.queryStoresPropertyKeys(QName.createQName("", SandboxConstants.PROP_DNS+"%")); assertEquals(1, matches.get("main").size()); assertEquals(1, matches.get("second").size()); - assertEquals("alice-preview", matches.get("main").get(QName.createQName(null, ".dns.alice--preview")).getStringValue()); - assertEquals("alice-space", matches.get("second").get(QName.createQName(null, ".dns.alice")).getStringValue()); + assertEquals("alice-preview", matches.get("main").get(QName.createQName(null, SandboxConstants.PROP_DNS+"alice--preview")).getStringValue()); + assertEquals("alice-space", matches.get("second").get(QName.createQName(null, SandboxConstants.PROP_DNS+"alice")).getStringValue()); fService.createStore("third"); - fService.setStoreProperty("third", QName.createQName("", ".dns.someUPPERcase"), new PropertyValue(null, "someUPPERcase-space")); - matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.someuppercase%")); + fService.setStoreProperty("third", QName.createQName("", SandboxConstants.PROP_DNS+"someUPPERcase"), new PropertyValue(null, "someUPPERcase-space")); + matches = fService.queryStoresPropertyKeys(QName.createQName("", SandboxConstants.PROP_DNS+"someuppercase%")); assertNotNull(matches.get("third")); assertEquals(1, matches.get("third").size()); - assertEquals("someUPPERcase-space", matches.get("third").get(QName.createQName(null, ".dns.someUPPERcase")).getStringValue()); + assertEquals("someUPPERcase-space", matches.get("third").get(QName.createQName(null, SandboxConstants.PROP_DNS+"someUPPERcase")).getStringValue()); } catch (Exception e) { diff --git a/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java b/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java index d3f8576f53..47535b906c 100644 --- a/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java +++ b/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java @@ -1,30 +1,29 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ package org.alfresco.repo.avm.actions; import java.util.List; -import java.util.Map; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; -import org.alfresco.repo.domain.PropertyValue; 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; @@ -32,9 +31,9 @@ import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; +import org.alfresco.wcm.util.WCMUtil; +import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** @@ -84,12 +83,13 @@ public class AVMUndoSandboxListAction extends ActionExecuterAbstractBase (List>)action.getParameterValue(PARAM_NODE_LIST); for (Pair item : versionPaths) { - AVMNodeDescriptor desc = fAVMService.lookup(-1, item.getSecond(), true); + String avmPath = item.getSecond(); + AVMNodeDescriptor desc = fAVMService.lookup(-1, avmPath, true); if (desc == null) { continue; } - String [] parentChild = AVMNodeConverter.SplitBase(item.getSecond()); + String [] parentChild = AVMNodeConverter.SplitBase(avmPath); if (parentChild.length != 2) { continue; @@ -101,18 +101,21 @@ public class AVMUndoSandboxListAction extends ActionExecuterAbstractBase fgLogger.debug("reverting " + parentChild[1] + " in " + parentChild[0]); fAVMService.makeTransparent(parentChild[0], parentChild[1]); } - + if (desc.isFile() || desc.isDeletedFile()) { - final Map dnsProperties = fAVMService.queryStorePropertyKey(item.getSecond().split(":")[0], QName.createQName(null, ".dns%")); - if (dnsProperties.size() == 1) + String parts[] = AVMUtil.splitPath(avmPath); + String avmStore = parts[0]; + String path = parts[1]; // store relative path + + String webProject = WCMUtil.getWebProject(fAVMService, avmStore); + if (webProject != null) { - String webProject = dnsProperties.keySet().iterator().next().getLocalName(); - webProject = webProject.substring(webProject.lastIndexOf('.') + 1, webProject.length()); - String path = item.getSecond().substring(item.getSecond().indexOf(":") + 1); if (fgLogger.isDebugEnabled()) + { fgLogger.debug("unlocking file " + path + " in web project " + webProject); - + } + if (fAVMLockingService.getLock(webProject, path) != null) { fAVMLockingService.removeLock(webProject, path); diff --git a/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java index 06f2e7db55..34064e3a34 100644 --- a/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java +++ b/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java @@ -18,16 +18,17 @@ */ package org.alfresco.repo.avm.wf; -import java.util.Map; +import java.util.List; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.workflow.jbpm.JBPMNode; import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; +import org.alfresco.wcm.sandbox.SandboxService; +import org.alfresco.wcm.util.WCMUtil; import org.jbpm.graph.exe.ExecutionContext; import org.springframework.beans.factory.BeanFactory; @@ -40,12 +41,11 @@ import org.springframework.beans.factory.BeanFactory; public class AVMRemoveWFStoreHandler extends JBPMSpringActionHandler { private static final long serialVersionUID = 4113360751217684995L; - + /** - * The AVMService instance. + * The WCM SandboxService instance. */ - private AVMService fAVMService; - + private SandboxService sbService; /** * Initialize service references. @@ -54,9 +54,9 @@ public class AVMRemoveWFStoreHandler extends JBPMSpringActionHandler @Override protected void initialiseHandler(BeanFactory factory) { - fAVMService = (AVMService)factory.getBean("AVMService"); + sbService = (SandboxService)factory.getBean("SandboxService"); } - + /** * Do the actual work. * @param executionContext The context to get stuff from. @@ -69,18 +69,19 @@ public class AVMRemoveWFStoreHandler extends JBPMSpringActionHandler // retrieve submitted package NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef(); Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg); - - // Now delete the stores in the workflow sandbox. - String [] storePath = pkgPath.getSecond().split(":"); - // Get the sandbox id for the package. - Map matches = fAVMService.queryStorePropertyKey(storePath[0], QName.createQName(null, ".sandbox-id%")); - QName sandboxID = matches.keySet().iterator().next(); - // Get all the stores in the sandbox. - Map> stores = fAVMService.queryStoresPropertyKeys(sandboxID); - for (String storeName : stores.keySet()) + + // Now delete the stores in the WCM workflow sandbox + final String avmPath = pkgPath.getSecond(); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { - fAVMService.purgeStore(storeName); - } + public Object doWork() throws Exception + { + sbService.deleteSandbox(WCMUtil.getSandboxStoreId(avmPath)); + + return null; + } + }, AuthenticationUtil.getSystemUserName()); + } - } diff --git a/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java index 21ad59ad91..b80fa8527b 100644 --- a/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java +++ b/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ package org.alfresco.repo.avm.wf; @@ -23,7 +23,7 @@ import java.util.List; import java.util.Map; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.avm.util.AVMUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.workflow.jbpm.JBPMNode; @@ -35,7 +35,6 @@ import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; import org.alfresco.wcm.util.WCMUtil; import org.apache.commons.logging.Log; @@ -111,10 +110,9 @@ public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements // submit the package changes final String description = (String) executionContext.getContextInstance().getVariable("bpm_workflowDescription"); final String tag = (String) executionContext.getContextInstance().getVariable("wcmwf_label"); - - final Map dnsProperties = this.fAVMService.queryStorePropertyKey(targetPath.split(":")[0], QName.createQName(null, ".dns%")); - String localName = dnsProperties.keySet().iterator().next().getLocalName(); - final String webProject = localName.substring(localName.lastIndexOf('.') + 1, localName.length()); + + final String webProject = WCMUtil.getWebProject(fAVMService, AVMUtil.getStoreName(targetPath)); + final List stagingDiffs = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, targetPath, null); // Allow AVMSubmitTransactionListener to inspect the staging diffs @@ -135,9 +133,16 @@ public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements fAVMSyncService.update(stagingDiffs, null, false, false, true, true, tag, description); fAVMSyncService.flatten(pkgPath.getSecond(), targetPath); - for (final AVMDifference diff : stagingDiffs) + if (webProject != null) { - recursivelyRemoveLocks(webProject, -1, diff.getSourcePath()); + for (final AVMDifference diff : stagingDiffs) + { + recursivelyRemoveLocks(webProject, -1, diff.getSourcePath()); + } + } + else + { + logger.warn("No webproject (hence no locks removed) for submit of " + pkgPath.getSecond() + " from " + from + " to " + targetPath); } // flatten source folder where changes were submitted from diff --git a/source/java/org/alfresco/service/cmr/avm/AVMService.java b/source/java/org/alfresco/service/cmr/avm/AVMService.java index b561058e3b..42b1fc699c 100644 --- a/source/java/org/alfresco/service/cmr/avm/AVMService.java +++ b/source/java/org/alfresco/service/cmr/avm/AVMService.java @@ -848,6 +848,8 @@ public interface AVMService * @param store The name of the store. * @param keyPattern The sql 'like' pattern, inserted into a QName. * @return A Map of the matching key value pairs. + * + * @deprecated */ public Map queryStorePropertyKey(String store, QName keyPattern); @@ -958,6 +960,8 @@ public interface AVMService * @param keyPattern The sql 'like' pattern, inserted into a QName. * @return A Map of store names to Maps of property key value pairs that match * the pattern. + * + * @deprecated */ public Map> queryStoresPropertyKeys(QName keyPattern); diff --git a/source/java/org/alfresco/service/cmr/remote/AVMRemote.java b/source/java/org/alfresco/service/cmr/remote/AVMRemote.java index 54923bf8a2..d6fd3540e0 100644 --- a/source/java/org/alfresco/service/cmr/remote/AVMRemote.java +++ b/source/java/org/alfresco/service/cmr/remote/AVMRemote.java @@ -1,22 +1,21 @@ -/*----------------------------------------------------------------------------- -* Copyright 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . -* -*----------------------------------------------------------------------------*/ + */ package org.alfresco.service.cmr.remote; @@ -828,6 +827,8 @@ public interface AVMRemote * @param store The name of the store. * @param keyPattern The sql 'like' pattern, inserted into a QName. * @return A Map of the matching key value pairs. + * + * @deprecated */ public Map queryStorePropertyKey(String store, QName keyPattern); @@ -838,6 +839,8 @@ public interface AVMRemote * @param store The name of the store. * @param keyPattern The sql 'like' pattern, inserted into a QName. * @return A Map of the matching key value pairs. + * + * @deprecated */ public Map> queryStoresPropertyKey(QName keyPattern); diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java index 13145c9587..4c2cb6538c 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java @@ -225,14 +225,13 @@ public final class SandboxFactory extends WCMUtil // tag all related stores to indicate that they are part of a single sandbox - final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); + final String sandboxGuid = GUID.generate(); - avmService.setStoreProperty(stagingStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(previewStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); + props = new HashMap(2); + addSandboxGuid(sandboxGuid, props); + + avmService.setStoreProperties(stagingStoreName, props); + avmService.setStoreProperties(previewStoreName, props); if (logger.isTraceEnabled()) { @@ -572,7 +571,7 @@ public final class SandboxFactory extends WCMUtil return userSandboxInfo; } - QName sandboxIdProp = QName.createQName(null, SandboxConstants.PROP_SANDBOXID + GUID.generate()); + final String sandboxGuid = GUID.generate(); String stagingStoreName = WCMUtil.buildStagingStoreName(storeId); @@ -582,10 +581,11 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the base name of the website so that corresponding staging areas can be found. props.put(SandboxConstants.PROP_WEBSITE_NAME, new PropertyValue(DataTypeDefinition.TEXT, storeId)); + // tag the store, oddly enough, with its own store name for querying. - props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + userStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxPrefix(userStoreName, props); // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property addStoreDNSPath(userStoreName, props, storeId, username); // The user store depends on the main staging store (dist=1) @@ -630,8 +630,9 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_AUTHOR_PREVIEW, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with its own store name for querying. props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property addStoreDNSPath(previewStoreName, props, storeId, username, "preview"); // The preview user store depends on the main user store (dist=1) @@ -698,7 +699,7 @@ public final class SandboxFactory extends WCMUtil String packageName = WCMUtil.STORE_WORKFLOW + "-" + GUID.generate(); String mainStoreName = WCMUtil.buildWorkflowMainStoreName(storeId, packageName); - final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); + final String sandboxGuid = GUID.generate(); // tag store with properties Map props = new HashMap(6); @@ -706,10 +707,11 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_WORKFLOW_MAIN, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the base name of the website so that corresponding staging areas can be found. props.put(SandboxConstants.PROP_WEBSITE_NAME, new PropertyValue(DataTypeDefinition.TEXT, storeId)); + // tag the store, oddly enough, with its own store name for querying. - props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + mainStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxPrefix(mainStoreName, props); // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property addStoreDNSPath(mainStoreName, props, storeId, packageName); // The main workflow store depends on the main staging store (dist=1) @@ -739,8 +741,10 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with its own store name for querying. props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxGuid(sandboxGuid, props); + // tag the store with the DNS name property addStoreDNSPath(previewStoreName, props, storeId, packageName, "preview"); // The preview workflow store depends on the main workflow store (dist=1) @@ -800,7 +804,7 @@ public final class SandboxFactory extends WCMUtil String packageName = WCMUtil.STORE_WORKFLOW + "-" + GUID.generate(); String mainStoreName = WCMUtil.buildWorkflowMainStoreName(storeId, packageName); - final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); + final String sandboxGuid = GUID.generate(); // tag store with properties Map props = new HashMap(6); @@ -808,14 +812,15 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_WORKFLOW_MAIN, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the base name of the website so that corresponding staging areas can be found. props.put(SandboxConstants.PROP_WEBSITE_NAME, new PropertyValue(DataTypeDefinition.TEXT, storeId)); + // tag the store, oddly enough, with its own store name for querying. - props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + mainStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxPrefix(mainStoreName, props); + // tag all related stores to indicate that they are part of a single sandbox + addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property addStoreDNSPath(mainStoreName, props, storeId, packageName); // The main workflow store depends on the main staging store (dist=1) addStoreBackgroundLayer(props, stagingStoreName, 1); - // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); avmService.createStore(mainStoreName, props); @@ -853,7 +858,7 @@ public final class SandboxFactory extends WCMUtil String packageName = "workflow-" + GUID.generate(); String workflowStoreName = userStore + STORE_SEPARATOR + packageName; - final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); + final String sandboxGuid = GUID.generate(); // tag store with properties Map props = new HashMap(7); @@ -861,16 +866,17 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the name of the author's store this one is layered over props.put(SandboxConstants.PROP_AUTHOR_NAME, new PropertyValue(DataTypeDefinition.TEXT, userStore)); + // tag the store, oddly enough, with its own store name for querying. - props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + workflowStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + addSandboxPrefix(workflowStoreName, props); + // tag all related stores to indicate that they are part of a single sandbox + addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property addStoreDNSPath(workflowStoreName, props, stagingStore, packageName); // the main workflow store depends on the main user store (dist=1) addStoreBackgroundLayer(props, userStore, 1); // The main workflow store depends on the main staging store (dist=2) addStoreBackgroundLayer(props, stagingStore, 2); - // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); avmService.createStore(workflowStoreName, props); @@ -896,6 +902,9 @@ public final class SandboxFactory extends WCMUtil props.put(SandboxConstants.PROP_SANDBOX_AUTHOR_WORKFLOW_PREVIEW, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with its own store name for querying. props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag all related stores to indicate that they are part of a single sandbox + addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property addStoreDNSPath(previewStoreName, props, userStore, packageName, "preview"); // The preview worfkflow store depends on the main workflow store (dist=1) @@ -905,9 +914,6 @@ public final class SandboxFactory extends WCMUtil // The preview workflow store depends on the main staging store (dist=3) addStoreBackgroundLayer(props, stagingStore, 3); - // tag all related stores to indicate that they are part of a single sandbox - props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.createStore(previewStoreName, props); if (logger.isDebugEnabled()) @@ -961,8 +967,11 @@ public final class SandboxFactory extends WCMUtil public void deleteSandbox(String wpStoreId, String sbStoreId) { - SandboxInfo sbInfo = getSandbox(wpStoreId, sbStoreId, true); - + deleteSandbox(getSandbox(wpStoreId, sbStoreId, true)); + } + + public void deleteSandbox(SandboxInfo sbInfo) + { if (sbInfo != null) { String mainSandboxStore = sbInfo.getMainStoreName(); @@ -989,7 +998,7 @@ public final class SandboxFactory extends WCMUtil WCMUtil.removeAllVServerWebapps(virtServerRegistry, path, true); - // TODO: Use the .sandbox-id. property to delete all sandboxes, + // NOTE: Could use the .sandbox-id. GUID property to delete all sandboxes, // rather than assume a sandbox always had a single preview // layer attached. @@ -1166,10 +1175,11 @@ public final class SandboxFactory extends WCMUtil { String path = WCMUtil.buildSandboxRootPath(store); // DNS name mangle the property name - can only contain value DNS characters! - String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(components); + String dnsName = DNSNameMangler.MakeDNSName(components); + String dnsProp = SandboxConstants.PROP_DNS + dnsName; props.put(QName.createQName(null, dnsProp), new PropertyValue(DataTypeDefinition.TEXT, path)); } - + /** * Tags a store with a property that indicates one of its * backgroundStore layers, and the distance of that layer. @@ -1202,6 +1212,18 @@ public final class SandboxFactory extends WCMUtil String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + backgroundStore; props.put(QName.createQName(null, prop_key), new PropertyValue(DataTypeDefinition.INT, distance)); } + + private static void addSandboxGuid(String sandboxGuid, Map props) + { + final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + sandboxGuid); + props.put(sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); + } + + private static void addSandboxPrefix(String storeName, Map props) + { + props.put(QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + storeName), new PropertyValue(DataTypeDefinition.TEXT, null)); + } + /** * Debug helper method to dump the properties of a store diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java index b1ab839cab..4d6b57a6d3 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java @@ -378,26 +378,34 @@ public class SandboxServiceImpl implements SandboxService String wpStoreId = WCMUtil.getWebProjectStoreId(sbStoreId); - String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser(); - if (sbStoreId.equals(WCMUtil.buildUserMainStoreName(wpStoreId, currentUserName))) + if (AuthenticationUtil.isRunAsUserTheSystemUser()) { - // author may delete their own sandbox + // system may delete (eg. workflow) sandbox sandboxFactory.deleteSandbox(sbStoreId); } else - { - if (! wpService.isContentManager(wpStoreId)) + { + String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser(); + if (sbStoreId.equals(WCMUtil.buildUserMainStoreName(wpStoreId, currentUserName))) { - throw new AccessDeniedException("Only content managers may delete sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")"); + // author may delete their own sandbox + sandboxFactory.deleteSandbox(sbStoreId); } - - if (sbStoreId.equals(wpStoreId)) + else { - throw new AccessDeniedException("Cannot delete staging sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")"); + if (! wpService.isContentManager(wpStoreId, currentUserName)) + { + throw new AccessDeniedException("Only content managers may delete sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")"); + } + + if (sbStoreId.equals(wpStoreId)) + { + throw new AccessDeniedException("Cannot delete staging sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")"); + } + + // content manager may delete sandboxes, except staging sandbox + sandboxFactory.deleteSandbox(sbStoreId); } - - // content manager may delete sandboxes, except staging sandbox - sandboxFactory.deleteSandbox(sbStoreId); } if (logger.isInfoEnabled()) @@ -834,7 +842,7 @@ public class SandboxServiceImpl implements SandboxService /** * Cleans up the workflow sandbox created by the first transaction. This - * action is itself preformed in a separate transaction. + * action is itself performed in a separate transaction. */ private void cleanupWorkflowSandbox(final SandboxInfo sandboxInfo) { @@ -844,12 +852,12 @@ public class SandboxServiceImpl implements SandboxService { public String execute() throws Throwable { - // call the actual implementation - cleanupWorkflowSandboxImpl(sandboxInfo); + // delete AVM stores in the workflow sandbox + sandboxFactory.deleteSandbox(sandboxInfo); return null; } }; - + try { // Execute the cleanup handler @@ -861,27 +869,6 @@ public class SandboxServiceImpl implements SandboxService logger.error("Failed to cleanup workflow sandbox after workflow failure", e); } } - - /** - * Performs the actual deletion of stores in the workflow sandbox. - */ - private void cleanupWorkflowSandboxImpl(SandboxInfo sandboxInfo) - { - if (sandboxInfo != null) - { - String mainWorkflowStore = sandboxInfo.getMainStoreName(); - Map matches = avmService.queryStorePropertyKey(mainWorkflowStore, - QName.createQName(null, ".sandbox-id%")); - - QName sandboxID = matches.keySet().iterator().next(); - // Get all the stores in the sandbox. - Map> stores = avmService.queryStoresPropertyKeys(sandboxID); - for (String storeName : stores.keySet()) - { - avmService.purgeStore(storeName); - } - } - } /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#revertAll(java.lang.String) diff --git a/source/java/org/alfresco/wcm/util/WCMUtil.java b/source/java/org/alfresco/wcm/util/WCMUtil.java index c7d577d0d4..b0a252d876 100644 --- a/source/java/org/alfresco/wcm/util/WCMUtil.java +++ b/source/java/org/alfresco/wcm/util/WCMUtil.java @@ -438,7 +438,7 @@ public class WCMUtil extends AVMUtil public static String lookupStoreDNS(AVMService avmService, String store) { ParameterCheck.mandatoryString("store", store); - + final Map props = avmService.queryStorePropertyKey(store, QName.createQName(null, SandboxConstants.PROP_DNS + '%')); @@ -470,6 +470,19 @@ public class WCMUtil extends AVMUtil return wpNodeRef; } + /** + * Returns web project store id for an AVM store name (or null for vanilla AVM store) + */ + public static String getWebProject(AVMService avmService, String avmStoreName) + { + String wpStoreId = WCMUtil.getWebProjectStoreId(avmStoreName); + if (WCMUtil.getWebProjectNodeFromWebProjectStore(avmService, wpStoreId) != null) + { + return wpStoreId; + } + return null; + } + /** * Converts the provided path to an absolute path within the avm. *