diff --git a/config/alfresco/wcm-services-context.xml b/config/alfresco/wcm-services-context.xml index 3c25e90d56..678c65f99a 100644 --- a/config/alfresco/wcm-services-context.xml +++ b/config/alfresco/wcm-services-context.xml @@ -56,7 +56,99 @@ + + + + + + org.alfresco.wcm.asset.AssetService + + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + ${server.transaction.mode.default} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mlAwareLockingAwareNodeService + + + + org.alfresco.service.cmr.repository.NodeService + + + + + mlPropertyInterceptorLockingAware + + + + + + + + + + + + + + + + + + @@ -98,6 +190,7 @@ + @@ -135,6 +228,7 @@ + diff --git a/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java b/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java index 8cea3bc893..7f625be4ee 100644 --- a/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java +++ b/source/java/org/alfresco/repo/avm/actions/AVMUndoSandboxListAction.java @@ -30,7 +30,6 @@ import org.apache.commons.logging.LogFactory; */ public class AVMUndoSandboxListAction extends ActionExecuterAbstractBase { - @SuppressWarnings("unused") private static Log fgLogger = LogFactory.getLog(AVMUndoSandboxListAction.class); public static final String NAME = "avm-undo-list"; @@ -85,22 +84,25 @@ public class AVMUndoSandboxListAction extends ActionExecuterAbstractBase fAVMService.makeTransparent(parentChild[0], parentChild[1]); } - final Map dnsProperties = fAVMService.queryStorePropertyKey(item.getSecond().split(":")[0], QName.createQName(null, ".dns%")); - if (dnsProperties.size() == 1) + if (desc.isFile() || desc.isDeletedFile()) { - 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) + final Map dnsProperties = fAVMService.queryStorePropertyKey(item.getSecond().split(":")[0], QName.createQName(null, ".dns%")); + if (dnsProperties.size() == 1) { - fAVMLockingService.removeLock(webProject, path); - } - else - { - fgLogger.warn("expected file " + path + " in " + webProject + " to be locked"); + 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); + } + else + { + fgLogger.warn("expected file " + path + " in " + webProject + " to be locked"); + } } } } diff --git a/source/java/org/alfresco/repo/jscript/AVM.java b/source/java/org/alfresco/repo/jscript/AVM.java index cf50a2b0eb..28b5578701 100644 --- a/source/java/org/alfresco/repo/jscript/AVM.java +++ b/source/java/org/alfresco/repo/jscript/AVM.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2008 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 @@ -33,6 +33,7 @@ import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.util.ParameterCheck; +import org.alfresco.wcm.asset.AssetInfo; import org.alfresco.wcm.sandbox.SandboxService; import org.alfresco.wcm.util.WCMUtil; import org.mozilla.javascript.Context; @@ -154,14 +155,14 @@ public final class AVM extends BaseScopableProcessorExtension SandboxService sbService = this.services.getSandboxService(); // get modified items - not including deleted - List nodes = sbService.listChangedWebApp(storeId, webapp, false); + List assets = sbService.listChangedWebApp(storeId, webapp, false); - List items = new ArrayList(nodes.size()); + List items = new ArrayList(assets.size()); - for (AVMNodeDescriptor node : nodes) + for (AssetInfo asset : assets) { // convert each diff/node record into an AVM Node wrapper - items.add(new AVMNode(node.getPath(), -1, this.services, getScope())); + items.add(new AVMNode(asset.getAvmPath(), -1, this.services, getScope())); } return items; diff --git a/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java b/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java index eadc8c12ad..ceedaa2bf1 100644 --- a/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java +++ b/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java @@ -70,6 +70,7 @@ import org.alfresco.service.descriptor.DescriptorService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; +import org.alfresco.wcm.asset.AssetService; import org.alfresco.wcm.sandbox.SandboxService; import org.alfresco.wcm.webproject.WebProjectService; import org.springframework.beans.BeansException; @@ -467,7 +468,7 @@ public class ServiceDescriptorRegistry /* (non-Javadoc) * @see org.alfresco.service.ServiceRegistry#getWebProjectService() */ - public WebProjectService getWebProjectService() + public WebProjectService getWebProjectService() { return (WebProjectService)getService(WEBPROJECT_SERVICE); } @@ -475,11 +476,19 @@ public class ServiceDescriptorRegistry /* (non-Javadoc) * @see org.alfresco.service.ServiceRegistry#getSandboxService() */ - public SandboxService getSandboxService() + public SandboxService getSandboxService() { return (SandboxService)getService(SANDBOX_SERVICE); } + /* (non-Javadoc) + * @see org.alfresco.service.ServiceRegistry#getAssetService() + */ + public AssetService getAssetService() + { + return (AssetService)getService(ASSET_SERVICE); + } + /* (non-Javadoc) * @see org.alfresco.service.ServiceRegistry#getFormService() */ diff --git a/source/java/org/alfresco/repo/template/AVM.java b/source/java/org/alfresco/repo/template/AVM.java index 5e6bd4334d..0551d6ecbf 100644 --- a/source/java/org/alfresco/repo/template/AVM.java +++ b/source/java/org/alfresco/repo/template/AVM.java @@ -32,6 +32,7 @@ import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.util.ParameterCheck; +import org.alfresco.wcm.asset.AssetInfo; import org.alfresco.wcm.sandbox.SandboxService; import org.alfresco.wcm.util.WCMUtil; @@ -144,14 +145,14 @@ public class AVM extends BaseTemplateProcessorExtension SandboxService sbService = this.services.getSandboxService(); // get modified items - not including deleted - List nodes = sbService.listChangedWebApp(storeId, webapp, false); + List assets = sbService.listChangedWebApp(storeId, webapp, false); - List items = new ArrayList(nodes.size()); + List items = new ArrayList(assets.size()); - for (AVMNodeDescriptor node : nodes) + for (AssetInfo asset : assets) { // convert each diff/node record into an AVM Node template wrapper - items.add(new AVMTemplateNode(node, this.services, getTemplateImageResolver())); + items.add(new AVMTemplateNode(asset.getAvmPath(), -1, this.services, getTemplateImageResolver())); } return items; diff --git a/source/java/org/alfresco/service/ServiceRegistry.java b/source/java/org/alfresco/service/ServiceRegistry.java index 8a9bfbd316..b4d86dd386 100644 --- a/source/java/org/alfresco/service/ServiceRegistry.java +++ b/source/java/org/alfresco/service/ServiceRegistry.java @@ -69,6 +69,7 @@ import org.alfresco.service.descriptor.DescriptorService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; +import org.alfresco.wcm.asset.AssetService; import org.alfresco.wcm.sandbox.SandboxService; import org.alfresco.wcm.webproject.WebProjectService; @@ -132,6 +133,7 @@ public interface ServiceRegistry static final QName DEPLOYMENT_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "DeploymentService"); static final QName WEBPROJECT_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "WebProjectService"); static final QName SANDBOX_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "SandboxService"); + static final QName ASSET_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "AssetService"); static final QName FORM_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "FormService"); /** @@ -428,19 +430,26 @@ public interface ServiceRegistry DeploymentService getDeploymentService(); /** - * Get the WebProject Service + * Get the WCM WebProject Service * @return */ @NotAuditable WebProjectService getWebProjectService(); /** - * Get the Sandbox Service + * Get the WCM Sandbox Service * @return */ @NotAuditable SandboxService getSandboxService(); + /** + * Get the WCM Asset Service + * @return + */ + @NotAuditable + AssetService getAssetService(); + /** * Get the form service (or null if one is not provided) * @return diff --git a/source/java/org/alfresco/service/cmr/avm/locking/AVMLock.java b/source/java/org/alfresco/service/cmr/avm/locking/AVMLock.java index 0784674bd1..9dfaeb6a95 100644 --- a/source/java/org/alfresco/service/cmr/avm/locking/AVMLock.java +++ b/source/java/org/alfresco/service/cmr/avm/locking/AVMLock.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2008 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 @@ -83,16 +83,7 @@ public class AVMLock implements Serializable { fWebProject = webProject; fStore = store; - fPath = path; - while (fPath.startsWith("/")) - { - fPath = fPath.substring(1); - } - while (fPath.endsWith("/")) - { - fPath = fPath.substring(0, fPath.length() - 1); - } - fPath = fPath.replaceAll("/+", "/"); + fPath = normalizePath(path); fType = type; fOwners = owners; } @@ -148,7 +139,7 @@ public class AVMLock implements Serializable */ public void setPath(String path) { - fPath = path; + fPath = normalizePath(path); } /** @@ -194,4 +185,22 @@ public class AVMLock implements Serializable buffer.append(" owners=").append(this.fOwners).append(")"); return buffer.toString(); } + + /** + * Utility to get relative paths into canonical form. + * @param path The incoming path. + * @return The normalized path. + */ + private String normalizePath(String path) + { + while (path.startsWith("/")) + { + path = path.substring(1); + } + while (path.endsWith("/")) + { + path = path.substring(0, path.length() - 1); + } + return path.replaceAll("/+", "/"); + } } diff --git a/source/java/org/alfresco/wcm/WCMTestSuite.java b/source/java/org/alfresco/wcm/WCMTestSuite.java index 816699316c..d4d881a510 100644 --- a/source/java/org/alfresco/wcm/WCMTestSuite.java +++ b/source/java/org/alfresco/wcm/WCMTestSuite.java @@ -27,6 +27,7 @@ package org.alfresco.wcm; import junit.framework.Test; import junit.framework.TestSuite; +import org.alfresco.wcm.asset.AssetServiceImplTest; import org.alfresco.wcm.sandbox.SandboxServiceImplTest; import org.alfresco.wcm.webproject.WebProjectServiceImplTest; import org.alfresco.wcm.webproject.script.ScriptWebProjectsTest; @@ -48,6 +49,7 @@ public class WCMTestSuite extends TestSuite TestSuite suite = new TestSuite(); suite.addTestSuite(WebProjectServiceImplTest.class); + suite.addTestSuite(AssetServiceImplTest.class); suite.addTestSuite(SandboxServiceImplTest.class); suite.addTestSuite(ScriptWebProjectsTest.class); diff --git a/source/java/org/alfresco/wcm/asset/AssetInfo.java b/source/java/org/alfresco/wcm/asset/AssetInfo.java new file mode 100644 index 0000000000..82fe42e285 --- /dev/null +++ b/source/java/org/alfresco/wcm/asset/AssetInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2008 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.wcm.asset; + +import java.util.Date; + +/** +* Provides basic information about a WCM asset +*/ +public interface AssetInfo +{ + public String getName(); + + public String getSandboxId(); + + public int getSandboxVersion(); + + public String getPath(); // full path, eg. include /www/avm_webapps/... + + public boolean isFile(); + + public boolean isFolder(); + + public boolean isDeleted(); + + public boolean isLocked(); // files only, false for folder + + public long getFileSize(); // files only, -1 for folder + + public String getLockOwner(); // files only, null if no lock (or folder) + + public String getCreator(); + + public Date getCreatedDate(); + + public String getModifier(); + + public Date getModifiedDate(); + + public String getAvmPath(); // absolute AVM path, eg. : +} diff --git a/source/java/org/alfresco/wcm/asset/AssetInfoImpl.java b/source/java/org/alfresco/wcm/asset/AssetInfoImpl.java new file mode 100644 index 0000000000..8f69c01328 --- /dev/null +++ b/source/java/org/alfresco/wcm/asset/AssetInfoImpl.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2005-2008 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.wcm.asset; + +import java.util.Date; + +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.wcm.util.WCMUtil; + +/** + * Provides information about a WCM asset + */ +public class AssetInfoImpl implements AssetInfo +{ + private AVMNodeDescriptor node; + private String lockOwner = null; // null if not locked + private int sandboxVersion = -1; + + /* package */ AssetInfoImpl(int sandboxVersion, AVMNodeDescriptor node, String lockOwner) + { + this.sandboxVersion = sandboxVersion; + this.node = node; + this.lockOwner = lockOwner; + } + + public String getName() + { + return node.getName(); + } + + public String getSandboxId() + { + return WCMUtil.getSandboxStoreId(node.getPath()); + } + + public String getPath() + { + return WCMUtil.getStoreRelativePath(node.getPath()); + } + + public boolean isFile() + { + return (node.isFile() || node.isDeletedFile()); + } + + public boolean isFolder() + { + return (node.isDirectory() || node.isDeletedDirectory()); + } + + public boolean isDeleted() + { + return node.isDeleted(); + } + + public String getCreator() + { + return node.getCreator(); + } + + public Date getCreatedDate() + { + return new Date(node.getCreateDate()); + } + + public String getModifier() + { + return node.getLastModifier(); + } + + public Date getModifiedDate() + { + return new Date(node.getModDate()); + } + + public int getSandboxVersion() + { + return sandboxVersion; + } + + public boolean isLocked() + { + return (lockOwner != null); + } + + public long getFileSize() + { + return node.getLength(); + } + + public String getLockOwner() + { + return lockOwner; + } + + public AVMNodeDescriptor getAVMNodeDescriptor() + { + return node; + } + + public String getAvmPath() + { + return node.getPath(); + } +} diff --git a/source/java/org/alfresco/wcm/asset/AssetService.java b/source/java/org/alfresco/wcm/asset/AssetService.java new file mode 100644 index 0000000000..20554da879 --- /dev/null +++ b/source/java/org/alfresco/wcm/asset/AssetService.java @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2005-2008 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.wcm.asset; + +import java.io.File; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.namespace.QName; + + + +/** + * Asset Service fundamental API. + *

+ * This service API is designed to support the public facing Asset APIs. + * + * @author janv + */ +public interface AssetService +{ + /** + * Create folder within given sandbox and webApp + * + * @param sbStoreId + * @param webApp + * @param parentFolderPathRelativeToWebApp + * @param name + */ + public void createFolderWebApp(String sbStoreId, String webApp, String parentFolderPathRelativeToWebApp, String name); + + /** + * Create folder within given sandbox + * + * @param sbStoreId + * @param parentFolderPath + * @param name + * @param properties + */ + public void createFolder(String sbStoreId, String parentFolderPath, String name, Map properties); + + /** + * Create (empty) file within given sandbox and webApp, return content writer for file contents + * + * @param sbStoreId + * @param webApp + * @param parentFolderPath + * @param name + * @return + */ + public ContentWriter createFileWebApp(String sbStoreId, String webApp, String parentFolderPath, String name); + + /** + * Create (empty) file within given sandbox, return content writer for file contents + * + * @param sbStoreId + * @param parentFolderPath + * @param name + * @param properties + * @return + */ + public ContentWriter createFile(String sbStoreId, String parentFolderPath, String name, Map properties); + + /** + * Get asset (file or folder) for given sandbox, webApp and path (within webApp) + *

+ * Returns null if the asset can not be found + * + * @param sbStoreId + * @param webApp + * @param pathRelativeToWebApp + * @return + */ + public AssetInfo getAssetWebApp(String sbStoreId, String webApp, String pathRelativeToWebApp); + + /** + * Get asset (file or folder) for given sandbox, webApp and path (within webApp), optionally include deleted assets + *

+ * Returns null if the asset can not be found + * + * @param sbStoreId + * @param webApp + * @param pathRelativeToWebApp + * @param includeDeleted + * @return AssetInfo asset info + */ + public AssetInfo getAssetWebApp(String sbStoreId, String webApp, String pathRelativeToWebApp, boolean includeDeleted); + + /** + * Get asset (file or folder) for given sandbox and path + *

+ * Returns null if the asset can not be found + * + * @param sbStoreId sandbox store id + * @param path asset path (eg. /www/avm_webapps/ROOT/myFile) + * @return AssetInfo asset info + */ + public AssetInfo getAsset(String sbStoreId, String path); + + /** + * Get asset (file or folder) for given sandbox version and path, optionally include deleted assets + *

+ * Returns null if the asset can not be found + * + * @param sbStoreId + * @param version + * @param path + * @param includeDeleted + * @return AssetInfo asset info + */ + public AssetInfo getAsset(String sbStoreId, int version, String path, boolean includeDeleted); + + /** + * Get content writer for given file asset, to allow file contents to be written or updated + * + * @param asset + * @return + */ + public ContentWriter getContentWriter(AssetInfo fileAsset); + + /** + * Get content reader for given file asset, to allow file contents to be read + * + * @param asset + * @return + */ + public ContentReader getContentReader(AssetInfo fileAsset); + + /** + * Get asset properties + * + * @param asset + * @return + */ + public Map getAssetProperties(AssetInfo asset); + + /** + * Set asset properties (will replace all existing properties) + * + * @param asset + * @param properties + */ + public void setAssetProperties(AssetInfo asset, Map properties); + + /** + * Update asset properties (will replace given set of properties, if they already exist) + * + * @param asset + * @param properties + */ + public void updateAssetProperties(AssetInfo asset, Map properties); + + /** + * List assets within given sandbox and webApp and path (within webApp), optionally include deleted + * + * @param sbStoreId + * @param webApp + * @param parentFolderPathRelativeToWebApp + * @param includeDeleted + * @return + */ + public List listAssetsWebApp(String sbStoreId, String webApp, String parentFolderPathRelativeToWebApp, boolean includeDeleted); + + /** + * List assets within given sandbox and path, optionally include deleted + * + * @param sbStoreId + * @param parentFolderPath + * @param includeDeleted + * @return + */ + public List listAssets(String sbStoreId, String parentFolderPath, boolean includeDeleted); + + /** + * List assets within given sandbox version and path, optionally include deleted + * + * @param sbStoreId + * @param version + * @param parentFolderPath + * @param includeDeleted + * @return + */ + public List listAssets(String sbStoreId, int version, String parentFolderPath, boolean includeDeleted); + + /** + * Delete asset + * + * @param asset + */ + public void deleteAsset(AssetInfo asset); + + /** + * Rename asset + * + * @param asset + * @param newName + * @return AssetInfo asset info + */ + public AssetInfo renameAsset(AssetInfo asset, String newName); + + /** + * Copy asset(s) within sandbox + *

+ * Note: folder asset will be recursively copied + * Note: file asset(s) must have content + * + * @param asset + * @param parentFolderPath + * @return AssetInfo asset info + */ + public AssetInfo copyAsset(AssetInfo asset, String parentFolderPath); + + // TODO - copy asset to different sandbox ? + + /** + * Move asset within sandbox + * + * @param asset + * @param parentFolderPath + * @return AssetInfo asset info + */ + public AssetInfo moveAsset(AssetInfo asset, String parentFolderPath); + + /** + * Bulk import assets into sandbox + * + * @param sbStoreId + * @param parentFolderPath + * @param zipFile + */ + public void bulkImport(String sbStoreId, String parentFolderPath, File zipFile, boolean isHighByteZip); + + /** + * Runtime check to get lock (and owner) for asset - null if not locked + * + * @param asset + * @return String lock owner (null if path not locked) + */ + public String getLockOwner(AssetInfo fileAsset); + + /** + * Runtime check to check if the current user can perform (write) operations on the asset when locked + * + * @param asset + * @return boolean true if current user has write access + */ + public boolean hasLockAccess(AssetInfo fileAsset); +} diff --git a/source/java/org/alfresco/wcm/asset/AssetServiceImpl.java b/source/java/org/alfresco/wcm/asset/AssetServiceImpl.java new file mode 100644 index 0000000000..2ff97345c1 --- /dev/null +++ b/source/java/org/alfresco/wcm/asset/AssetServiceImpl.java @@ -0,0 +1,771 @@ +/* + * Copyright (C) 2005-2008 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.wcm.asset; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.mbeans.VirtServerRegistry; +import org.alfresco.model.ApplicationModel; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.executer.ImporterActionExecuter; +import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.permissions.AccessDeniedException; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.repo.transaction.TransactionListenerAdapter; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.locking.AVMLock; +import org.alfresco.service.cmr.avm.locking.AVMLockingService; +import org.alfresco.service.cmr.model.FileExistsException; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.ParameterCheck; +import org.alfresco.util.TempFileProvider; +import org.alfresco.wcm.sandbox.SandboxConstants; +import org.alfresco.wcm.util.WCMUtil; +import org.apache.tools.zip.ZipFile; + +/** + * Asset Service fundamental API. + *

+ * This service API is designed to support the public facing Asset APIs. + * + * @author janv + */ +public class AssetServiceImpl implements AssetService +{ + /** Logger */ + //private static Log logger = LogFactory.getLog(AssetServiceImpl.class); + + private static char PATH_SEPARATOR = '/'; + + private static final int BUFFER_SIZE = 16384; + + private AVMService avmService; + private AVMLockingService avmLockingService; + private NodeService avmNodeService; // AVM node service (ML-aware) + private VirtServerRegistry virtServerRegistry; + + public void setAvmService(AVMService avmService) + { + this.avmService = avmService; + } + + public void setAvmLockingService(AVMLockingService avmLockingService) + { + this.avmLockingService = avmLockingService; + } + + public void setNodeService(NodeService avmNodeService) + { + this.avmNodeService = avmNodeService; + } + + public void setVirtServerRegistry(VirtServerRegistry virtServerRegistry) + { + this.virtServerRegistry = virtServerRegistry; + } + + + private String addLeadingSlash(String path) + { + if (path.charAt(0) != PATH_SEPARATOR) + { + path = PATH_SEPARATOR + path; + } + + return path; + } + + private void checkMandatoryPath(String path) + { + ParameterCheck.mandatoryString("path", path); + + if (path.indexOf(WCMUtil.AVM_STORE_SEPARATOR) != -1) + { + throw new IllegalArgumentException("Unexpected path '"+path+"' - should not contain '"+WCMUtil.AVM_STORE_SEPARATOR+"'"); + } + } + + private boolean isWebProjectStagingSandbox(String sbStoreId) + { + PropertyValue propVal = avmService.getStoreProperty(sbStoreId, SandboxConstants.PROP_WEB_PROJECT_NODE_REF); + return ((propVal != null) && (WCMUtil.isStagingStore(sbStoreId))); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#createFolderWebApp(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void createFolderWebApp(String sbStoreId, String webApp, String parentFolderPathRelativeToWebApp, String name) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("webApp", webApp); + checkMandatoryPath(parentFolderPathRelativeToWebApp); + ParameterCheck.mandatoryString("name", name); + + if (! isWebProjectStagingSandbox(sbStoreId)) + { + parentFolderPathRelativeToWebApp = addLeadingSlash(parentFolderPathRelativeToWebApp); + + String avmParentPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp) + parentFolderPathRelativeToWebApp; + + createFolderAVM(avmParentPath, name, null); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + sbStoreId); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#createFolder(java.lang.String, java.lang.String, java.lang.String, java.util.Map) + */ + public void createFolder(String sbStoreId, String parentFolderPath, String name, Map properties) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("parentFolderPath", parentFolderPath); + ParameterCheck.mandatoryString("name", name); + + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmParentPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + createFolderAVM(avmParentPath, name, properties); + } + + private void createFolderAVM(String avmParentPath, String name, Map properties) + { + ParameterCheck.mandatoryString("avmParentPath", avmParentPath); + ParameterCheck.mandatoryString("name", name); + + String sbStoreId = WCMUtil.getSandboxStoreId(avmParentPath); + if (! isWebProjectStagingSandbox(sbStoreId)) + { + avmService.createDirectory(avmParentPath, name); + + String avmPath = avmParentPath + PATH_SEPARATOR + name; + + // for WCM Web Client (Alfresco Explorer) + avmService.addAspect(avmPath, ApplicationModel.ASPECT_UIFACETS); + + if ((properties != null) && (properties.size() > 0)) + { + setProperties(avmPath, properties); + } + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + sbStoreId); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#createFileWebApp(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public ContentWriter createFileWebApp(String sbStoreId, String webApp, String parentFolderPathRelativeToWebApp, String name) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("webApp", webApp); + ParameterCheck.mandatoryString("parentFolderPathRelativeToWebApp", parentFolderPathRelativeToWebApp); + ParameterCheck.mandatoryString("name", name); + + parentFolderPathRelativeToWebApp = addLeadingSlash(parentFolderPathRelativeToWebApp); + + String avmParentPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp) + parentFolderPathRelativeToWebApp; + + createFileAVM(avmParentPath, name); + + String avmPath = avmParentPath + PATH_SEPARATOR + name; + + return avmService.getContentWriter(avmPath); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#createFile(java.lang.String, java.lang.String, java.lang.String, java.util.Map) + */ + public ContentWriter createFile(String sbStoreId, String parentFolderPath, String name, Map properties) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("parentFolderPath", parentFolderPath); + ParameterCheck.mandatoryString("name", name); + + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmParentPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + createFileAVM(avmParentPath, name); + + String avmPath = avmParentPath + PATH_SEPARATOR + name; + + if ((properties != null) && (properties.size() > 0)) + { + setProperties(avmPath, properties); + } + + return avmService.getContentWriter(avmPath); + } + + private void createFileAVM(String avmParentPath, String name) + { + ParameterCheck.mandatoryString("avmParentPath", avmParentPath); + ParameterCheck.mandatoryString("name", name); + + String sbStoreId = WCMUtil.getSandboxStoreId(avmParentPath); + if (! isWebProjectStagingSandbox(sbStoreId)) + { + avmService.createFile(avmParentPath, name); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + sbStoreId); + } + } + + private void createFileAVM(String avmParentPath, String name, InputStream in) + { + ParameterCheck.mandatoryString("avmParentPath", avmParentPath); + + String sbStoreId = WCMUtil.getSandboxStoreId(avmParentPath); + if (! isWebProjectStagingSandbox(sbStoreId)) + { + avmService.createFile(avmParentPath, name, in, null, null); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + sbStoreId); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getContentWriter(org.alfresco.wcm.asset.AssetInfo) + */ + public ContentWriter getContentWriter(AssetInfo asset) + { + ParameterCheck.mandatory("asset", asset); + + if (! isWebProjectStagingSandbox(asset.getSandboxId())) + { + return avmService.getContentWriter(asset.getAvmPath()); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + asset.getSandboxId()); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getContentReader(org.alfresco.wcm.asset.AssetInfo) + */ + public ContentReader getContentReader(AssetInfo asset) + { + ParameterCheck.mandatory("asset", asset); + + return avmService.getContentReader(asset.getSandboxVersion(), asset.getAvmPath()); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getAssetWebApp(java.lang.String, java.lang.String, java.lang.String) + */ + public AssetInfo getAssetWebApp(String sbStoreId, String webApp, String pathRelativeToWebApp) + { + return getAssetWebApp(sbStoreId, webApp, pathRelativeToWebApp, false); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getAssetWebApp(java.lang.String, java.lang.String, java.lang.String, boolean) + */ + public AssetInfo getAssetWebApp(String sbStoreId, String webApp, String pathRelativeToWebApp, boolean includeDeleted) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("webApp", webApp); + ParameterCheck.mandatoryString("pathRelativeToWebApp", pathRelativeToWebApp); + + pathRelativeToWebApp = addLeadingSlash(pathRelativeToWebApp); + + String avmPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp) + pathRelativeToWebApp; + + return getAssetAVM(-1, avmPath, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getAsset(java.lang.String, java.lang.String) + */ + public AssetInfo getAsset(String sbStoreId, String path) + { + return getAsset(sbStoreId, -1, path, false); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getAsset(java.lang.String, int, java.lang.String, boolean) + */ + public AssetInfo getAsset(String sbStoreId, int version, String path, boolean includeDeleted) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("path", path); + + path = addLeadingSlash(path); + + String avmPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + path; + + return getAssetAVM(version, avmPath, includeDeleted); + } + + private AssetInfo getAssetAVM(int version, String avmPath, boolean includeDeleted) + { + ParameterCheck.mandatoryString("avmPath", avmPath); + + AVMNodeDescriptor node = avmService.lookup(version, avmPath, includeDeleted); + + AssetInfo asset = null; + + if (node != null) + { + String lockOwner = null; + if (avmLockingService != null) + { + String wpStoreId = WCMUtil.getWebProjectStoreIdFromPath(avmPath); + String[] parts = WCMUtil.splitPath(avmPath); + lockOwner = getLockOwner(wpStoreId, parts[1]); + } + + asset = new AssetInfoImpl(version, node, lockOwner); + } + + return asset; + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getLockOwner(org.alfresco.wcm.asset.AssetInfo) + */ + public String getLockOwner(AssetInfo asset) + { + ParameterCheck.mandatory("asset", asset); + + return getLockOwner(WCMUtil.getWebProjectStoreId(asset.getSandboxId()), asset.getPath()); + } + + private String getLockOwner(String wpStoreId, String filePath) + { + String lockOwner = null; + + if (avmLockingService != null) + { + AVMLock lock = avmLockingService.getLock(wpStoreId, filePath); + + if (lock != null) + { + // for now assume single lock owner (if more than one, then return first in list) + List lockUsers = lock.getOwners(); + if (lockUsers.size() > 0) + { + lockOwner = lockUsers.get(0); + } + } + } + + return lockOwner; + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#hasLockAccess(org.alfresco.wcm.asset.AssetInfo) + */ + public boolean hasLockAccess(AssetInfo asset) + { + ParameterCheck.mandatory("asset", asset); + + return avmLockingService.hasAccess(WCMUtil.getWebProjectStoreId(asset.getSandboxId()), asset.getAvmPath(), AuthenticationUtil.getFullyAuthenticatedUser()); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#updateAssetProperties(org.alfresco.wcm.asset.AssetInfo, java.util.Map) + */ + public void updateAssetProperties(AssetInfo asset, Map properties) + { + ParameterCheck.mandatory("asset", asset); + ParameterCheck.mandatory("properties", properties); + + NodeRef avmNodeRef = AVMNodeConverter.ToNodeRef(-1, asset.getAvmPath()); + for (Map.Entry prop : properties.entrySet()) + { + avmNodeService.setProperty(avmNodeRef, prop.getKey(), prop.getValue()); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#setAssetProperties(org.alfresco.wcm.asset.AssetInfo, java.util.Map) + */ + public void setAssetProperties(AssetInfo asset, Map properties) + { + ParameterCheck.mandatory("asset", asset); + ParameterCheck.mandatory("properties", properties); + + setProperties(asset.getAvmPath(), properties); + } + + private void setProperties(String avmPath, Map properties) + { + NodeRef avmNodeRef = AVMNodeConverter.ToNodeRef(-1, avmPath); + avmNodeService.setProperties(avmNodeRef, properties); // note: assumes lock, if applicable, is taken by caller + } + + private void addAspect(String avmPath, QName aspect, Map properties) + { + NodeRef avmNodeRef = AVMNodeConverter.ToNodeRef(-1, avmPath); + avmNodeService.addAspect(avmNodeRef, aspect, properties); // note: assumes lock, if applicable, is taken by caller + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#getAssetProperties(org.alfresco.wcm.asset.AssetInfo) + */ + public Map getAssetProperties(AssetInfo asset) + { + ParameterCheck.mandatory("asset", asset); + + return getProperties(asset.getSandboxVersion(), asset.getAvmPath()); + } + + private Map getProperties(int version, String avmPath) + { + NodeRef avmNodeRef = AVMNodeConverter.ToNodeRef(version, avmPath); + return avmNodeService.getProperties(avmNodeRef); // note: includes built-in properties + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#listAssetsWebApp(java.lang.String, java.lang.String, java.lang.String, boolean) + */ + public List listAssetsWebApp(String sbStoreId, String webApp, String parentFolderPathRelativeToWebApp, boolean includeDeleted) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("webApp", webApp); + ParameterCheck.mandatoryString("parentFolderPathRelativeToWebApp", parentFolderPathRelativeToWebApp); + + parentFolderPathRelativeToWebApp = addLeadingSlash(parentFolderPathRelativeToWebApp); + + String avmPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp) + parentFolderPathRelativeToWebApp; + + return listAssetsAVM(-1, avmPath, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#listAssets(java.lang.String, java.lang.String, boolean) + */ + public List listAssets(String sbStoreId, String parentFolderPath, boolean includeDeleted) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("parentFolderPath", parentFolderPath); + + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + return listAssetsAVM(-1, avmPath, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#listAssets(java.lang.String, int, java.lang.String, boolean) + */ + public List listAssets(String sbStoreId, int version, String parentFolderPath, boolean includeDeleted) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + ParameterCheck.mandatoryString("parentFolderPath", parentFolderPath); + + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + return listAssetsAVM(version, avmPath, includeDeleted); + } + + private List listAssetsAVM(int version, String avmPath, boolean includeDeleted) + { + ParameterCheck.mandatoryString("avmPath", avmPath); + + Map nodes = avmService.getDirectoryListing(version, avmPath, includeDeleted); + + List assets = new ArrayList(nodes.size()); + + for (AVMNodeDescriptor node : nodes.values()) + { + String lockOwner = null; + if (avmLockingService != null) + { + String wpStoreId = WCMUtil.getWebProjectStoreIdFromPath(avmPath); + String[] parts = WCMUtil.splitPath(avmPath); + lockOwner = getLockOwner(wpStoreId, parts[1]); + } + + assets.add(new AssetInfoImpl(version, node, lockOwner)); + } + + return assets; + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#deleteAsset(org.alfresco.wcm.asset.AssetInfo) + */ + public void deleteAsset(AssetInfo asset) + { + ParameterCheck.mandatory("asset", asset); + + if (! isWebProjectStagingSandbox(asset.getSandboxId())) + { + avmService.removeNode(asset.getAvmPath()); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + asset.getSandboxId()); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#renameAsset(org.alfresco.wcm.asset.AssetInfo, java.lang.String) + */ + public AssetInfo renameAsset(AssetInfo asset, String newName) + { + ParameterCheck.mandatory("asset", asset); + + if (! isWebProjectStagingSandbox(asset.getSandboxId())) + { + String avmParentPath = AVMNodeConverter.SplitBase(asset.getAvmPath())[0]; + String oldName = asset.getName(); + + avmService.rename(avmParentPath, oldName, avmParentPath, newName); + + return getAsset(asset.getSandboxId(), WCMUtil.getStoreRelativePath(avmParentPath)+"/"+newName); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + asset.getSandboxId()); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#moveAsset(org.alfresco.wcm.asset.AssetInfo, java.lang.String) + */ + public AssetInfo moveAsset(AssetInfo asset, String parentFolderPath) + { + ParameterCheck.mandatory("asset", asset); + + if (! isWebProjectStagingSandbox(asset.getSandboxId())) + { + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmDstPath = asset.getSandboxId() + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + String avmSrcPath = AVMNodeConverter.SplitBase(asset.getAvmPath())[0]; + String name = asset.getName(); + + avmService.rename(avmSrcPath, name, avmDstPath, name); + + return getAsset(asset.getSandboxId(), WCMUtil.getStoreRelativePath(avmDstPath)+"/"+name); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + asset.getSandboxId()); + } + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.asset.AssetService#copyAsset(org.alfresco.wcm.asset.AssetInfo, java.lang.String) + */ + public AssetInfo copyAsset(AssetInfo asset, String parentFolderPath) + { + ParameterCheck.mandatory("asset", asset); + + if (! isWebProjectStagingSandbox(asset.getSandboxId())) + { + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmDstParentPath = asset.getSandboxId() + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + String avmSrcPath = asset.getAvmPath(); + String name = asset.getName(); + + avmService.copy(-1, avmSrcPath, avmDstParentPath, name); + + return getAsset(asset.getSandboxId(), WCMUtil.getStoreRelativePath(avmDstParentPath+"/"+name)); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + asset.getSandboxId()); + } + } + + // TODO should this be in sandbox service ? + public void bulkImport(String sbStoreId, String parentFolderPath, File zipFile, boolean isHighByteZip) + { + if (! isWebProjectStagingSandbox(sbStoreId)) + { + parentFolderPath = addLeadingSlash(parentFolderPath); + + String avmDstPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + parentFolderPath; + + // convert the AVM path to a NodeRef so we can use the NodeService to perform import + NodeRef importRef = AVMNodeConverter.ToNodeRef(-1, avmDstPath); + processZipImport(zipFile, isHighByteZip, importRef); + + // After a bulk import, snapshot the store + avmService.createSnapshot(sbStoreId, "Import of file: " + zipFile.getName(), null); + + // Bind the post-commit transaction listener with data required for virtualization server notification + UpdateSandboxTransactionListener tl = new UpdateSandboxTransactionListener(avmDstPath); + AlfrescoTransactionSupport.bindListener(tl); + } + else + { + throw new AccessDeniedException("Not allowed to write in: " + sbStoreId); + } + + } + + /** + * Process ZIP file for import into an AVM repository store location + * + * @param file ZIP format file + * @param rootRef Root reference of the AVM location to import into + */ + private void processZipImport(File file, boolean isHighByteZip, NodeRef rootRef) + { + try + { + // NOTE: This encoding allows us to workaround bug: + // http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4820807 + ZipFile zipFile = new ZipFile(file, isHighByteZip ? "Cp437" : null); + File alfTempDir = TempFileProvider.getTempDir(); + // build a temp dir name based on the name of the file we are importing + File tempDir = new File(alfTempDir.getPath() + File.separatorChar + file.getName() + "_unpack"); + try + { + ImporterActionExecuter.extractFile(zipFile, tempDir.getPath()); + importDirectory(tempDir.getPath(), rootRef); + } + finally + { + if (tempDir.exists()) + { + ImporterActionExecuter.deleteDir(tempDir); + } + } + } + catch (IOException e) + { + throw new AlfrescoRuntimeException("Unable to process Zip file. File may not be of the expected format.", e); + } + } + + /** + * Recursively import a directory structure into the specified root node + * + * @param dir The directory of files and folders to import + * @param root The root node to import into + */ + private void importDirectory(String dir, NodeRef root) + { + File topdir = new File(dir); + if (!topdir.exists()) return; + for (File file : topdir.listFiles()) + { + try + { + if (file.isFile()) + { + // Create a file in the AVM store + String avmPath = AVMNodeConverter.ToAVMVersionPath(root).getSecond(); + String fileName = file.getName(); + + Map titledProps = new HashMap(); + titledProps.put(ContentModel.PROP_TITLE, fileName); + + createFileAVM(avmPath, fileName, new BufferedInputStream(new FileInputStream(file), BUFFER_SIZE)); + + addAspect(avmPath, ContentModel.ASPECT_TITLED, titledProps); + } + else + { + // Create a directory in the AVM store + String avmPath = AVMNodeConverter.ToAVMVersionPath(root).getSecond(); + + createFolderAVM(avmPath, file.getName(), null); + + String folderPath = avmPath + '/' + file.getName(); + NodeRef folderRef = AVMNodeConverter.ToNodeRef(-1, folderPath); + importDirectory(file.getPath(), folderRef); + } + } + catch (FileNotFoundException e) + { + // TODO: add failed file info to status message? + throw new AlfrescoRuntimeException("Failed to process ZIP file.", e); + } + catch (FileExistsException e) + { + // TODO: add failed file info to status message? + throw new AlfrescoRuntimeException("Failed to process ZIP file.", e); + } + } + } + + /** + * Update Sandbox Transaction listener - invoked after bulk import + */ + private class UpdateSandboxTransactionListener extends TransactionListenerAdapter + { + private String virtUpdatePath; + + public UpdateSandboxTransactionListener(String virtUpdatePath) + { + this.virtUpdatePath = virtUpdatePath; + } + + /** + * @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit() + */ + @Override + public void afterCommit() + { + // Reload virtualisation server as required + if (this.virtUpdatePath != null) + { + WCMUtil.updateVServerWebapp(virtServerRegistry, this.virtUpdatePath, true); + } + } + } +} diff --git a/source/java/org/alfresco/wcm/asset/AssetServiceImplTest.java b/source/java/org/alfresco/wcm/asset/AssetServiceImplTest.java new file mode 100644 index 0000000000..be9a3a4461 --- /dev/null +++ b/source/java/org/alfresco/wcm/asset/AssetServiceImplTest.java @@ -0,0 +1,903 @@ +/* + * Copyright (C) 2005-2008 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.wcm.asset; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +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.content.MimetypeMap; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.service.cmr.avm.AVMNotFoundException; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.ApplicationContextHelper; +import org.alfresco.util.PropertyMap; +import org.alfresco.wcm.sandbox.SandboxInfo; +import org.alfresco.wcm.sandbox.SandboxService; +import org.alfresco.wcm.util.WCMUtil; +import org.alfresco.wcm.webproject.WebProjectInfo; +import org.alfresco.wcm.webproject.WebProjectService; +import org.springframework.context.ApplicationContext; + +/** + * Asset Service implementation unit test + * + * @author janv + */ +public class AssetServiceImplTest extends TestCase +{ + private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); + + // + // test data + // + + private static final String TEST_RUN = ""+System.currentTimeMillis(); + private static final boolean CLEAN = true; // cleanup during teardown + + // base web project + private static final String TEST_WEBPROJ_DNS = "testAsset-"+TEST_RUN; + private static final String TEST_WEBPROJ_NAME = "testAsset Web Project Display Name - "+TEST_RUN; + private static final String TEST_WEBPROJ_TITLE = "This is my title"; + private static final String TEST_WEBPROJ_DESCRIPTION = "This is my description"; + private static final String TEST_WEBPROJ_DEFAULT_WEBAPP = WCMUtil.DIR_ROOT; + private static final boolean TEST_WEBPROJ_DONT_USE_AS_TEMPLATE = false; + + private static final String USER_ADMIN = "admin"; + + private static final String TEST_USER = "testAssetUser-"+TEST_RUN; + + private static final String USER_ONE = TEST_USER+"-One"; + private static final String USER_TWO = TEST_USER+"-Two"; + private static final String USER_THREE = TEST_USER+"-Three"; + + // + // services + // + + private WebProjectService wpService; + private SandboxService sbService; + private AssetService assetService; + + private AuthenticationService authenticationService; + private PersonService personService; + + @Override + protected void setUp() throws Exception + { + // Get the required services + wpService = (WebProjectService)ctx.getBean("WebProjectService"); + sbService = (SandboxService)ctx.getBean("SandboxService"); + assetService = (AssetService)ctx.getBean("AssetService"); + + authenticationService = (AuthenticationService)ctx.getBean("AuthenticationService"); + personService = (PersonService)ctx.getBean("PersonService"); + + // By default run as Admin + AuthenticationUtil.setFullyAuthenticatedUser(USER_ADMIN); + + createUser(USER_ONE); + createUser(USER_TWO); + createUser(USER_THREE); + } + + @Override + protected void tearDown() throws Exception + { + if (CLEAN) + { + // Switch back to Admin + AuthenticationUtil.setFullyAuthenticatedUser(USER_ADMIN); + + List webProjects = wpService.listWebProjects(); + for (WebProjectInfo wpInfo : webProjects) + { + if (wpInfo.getStoreId().startsWith(TEST_WEBPROJ_DNS)) + { + wpService.deleteWebProject(wpInfo.getNodeRef()); + } + } + + deleteUser(USER_ONE); + deleteUser(USER_TWO); + deleteUser(USER_THREE); + } + + AuthenticationUtil.clearCurrentSecurityContext(); + super.tearDown(); + } + + private void createUser(String userName) + { + if (authenticationService.authenticationExists(userName) == false) + { + authenticationService.createAuthentication(userName, "PWD".toCharArray()); + + PropertyMap ppOne = new PropertyMap(4); + ppOne.put(ContentModel.PROP_USERNAME, userName); + ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName"); + ppOne.put(ContentModel.PROP_LASTNAME, "lastName"); + ppOne.put(ContentModel.PROP_EMAIL, "email@email.com"); + ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle"); + + personService.createPerson(ppOne); + } + } + + private void deleteUser(String userName) + { + if (authenticationService.authenticationExists(userName) == true) + { + personService.deletePerson(userName); + authenticationService.deleteAuthentication(userName); + } + } + + private void checkAssetInfo(AssetInfo assetInfo, String expectedName, String expectedPath, String expectedCreator, boolean expectedIsFile, boolean expectedIsFolder, boolean expectedIsDeleted, boolean expectedIsLocked, String expectedLockOwner) + { + assertNotNull(assetInfo); + + assertEquals(expectedName, assetInfo.getName()); + assertEquals(expectedPath, assetInfo.getPath()); + assertEquals(expectedCreator, assetInfo.getCreator()); + + assertEquals(expectedIsFile, assetInfo.isFile()); + assertEquals(expectedIsFolder, assetInfo.isFolder()); + assertEquals(expectedIsDeleted, assetInfo.isDeleted()); + + assertNotNull(assetInfo.getCreatedDate()); + + assertEquals(expectedIsLocked, assetInfo.isLocked()); + assertEquals(expectedLockOwner, assetInfo.getLockOwner()); + } + + public void testSimple() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-simple", TEST_WEBPROJ_NAME+"-simple", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + + // get admin's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + wpInfo.getDefaultWebApp(); + + // create folder + assetService.createFolder(sbStoreId, path, "myFolder1", null); + + // create (empty) file + assetService.createFile(sbStoreId, path+"/myFolder1", "myFile1", null); + + // get assets + + AssetInfo myFolder1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1"); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ADMIN, false, true, false, false, null); + + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFile1", USER_ADMIN, true, false, false, true, USER_ADMIN); + + // delete folder + assetService.deleteAsset(myFolder1Asset); // also deletes myFile1 + + // try to get assets (including deleted) + + myFolder1Asset = assetService.getAsset(sbStoreId, -1, path+"/myFolder1", true); + assertNull(myFolder1Asset); + + myFile1Asset = assetService.getAsset(sbStoreId, -1, path+"/myFolder1/myFile1", true); + assertNull(myFile1Asset); + } + + /** + * Test CRUD - create, retrieve (get, list), update and delete + */ + public void testCRUD() throws IOException + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-crud", TEST_WEBPROJ_NAME+"-crud", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // get non-existent assets + assertNull(assetService.getAsset(sbStoreId, path+"/myFolder1")); + assertNull(assetService.getAsset(sbStoreId, path+"/myFile1")); + assertNull(assetService.getAsset(sbStoreId, path+"/myFolder1/myFile2")); + + assertEquals(0, assetService.listAssets(sbStoreId, path, false).size()); + + // create folder + assetService.createFolder(sbStoreId, path, "myFolder1", null); + + assertEquals(1, assetService.listAssets(sbStoreId, path, false).size()); + assertEquals(0, assetService.listAssets(sbStoreId, path+"/myFolder1", false).size()); + + // create file (and add content) + final String MYFILE1 = "This is myFile1"; + ContentWriter writer = assetService.createFile(sbStoreId, path, "myFile1", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); + + assertEquals(2, assetService.listAssets(sbStoreId, path, false).size()); + + final String MYFILE2 = "This is myFile2"; + writer = assetService.createFile(sbStoreId, path+"/myFolder1", "myFile2", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2); + + assertEquals(1, assetService.listAssets(sbStoreId, path+"/myFolder1", false).size()); + + // get assets (not including deleted) + + AssetInfo myFolder1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1"); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ONE, false, true, false, false, null); + + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + // get content + + ContentReader reader = assetService.getContentReader(myFile1Asset); + InputStream in = reader.getContentInputStream(); + byte[] buff = new byte[1024]; + in.read(buff); + in.close(); + assertEquals(MYFILE1, new String(buff, 0, MYFILE1.length())); // assumes 1byte=1char + + AssetInfo myFile2Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFile2"); + checkAssetInfo(myFile2Asset, "myFile2", path+"/myFolder1/myFile2", USER_ONE, true, false, false, true, USER_ONE); + + reader = assetService.getContentReader(myFile2Asset); + in = reader.getContentInputStream(); + buff = new byte[1024]; + in.read(buff); + in.close(); + assertEquals(MYFILE2, new String(buff, 0, MYFILE2.length())); // assumes 1byte=1char + + // update content + + final String MYFILE2_MODIFIED = "This is myFile2 ... modified"; + writer = assetService.getContentWriter(myFile2Asset); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2_MODIFIED); + + // get updated content + + reader = assetService.getContentReader(myFile2Asset); + in = reader.getContentInputStream(); + buff = new byte[1024]; + in.read(buff); + in.close(); + assertEquals(MYFILE2_MODIFIED, new String(buff, 0, MYFILE2_MODIFIED.length())); // assumes 1byte=1char + + // delete folders and files + assetService.deleteAsset(myFile1Asset); + assetService.deleteAsset(myFolder1Asset); // also deletes myFile2 + + // try to get assets (including deleted) + + myFolder1Asset = assetService.getAsset(sbStoreId, -1, path+"/myFolder1", true); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ONE, false, true, true, false, null); // TODO - unlike admin (testSimple) + + myFile1Asset = assetService.getAsset(sbStoreId, -1, path+"/myFile1", true); + assertNull(myFile1Asset); + + myFile2Asset = assetService.getAsset(sbStoreId, -1, path+"/myFolder1/myFile2", true); + assertNull(myFile2Asset); + + assertEquals(0, assetService.listAssets(sbStoreId, path, false).size()); + + try + { + // -ve test + assertEquals(0, assetService.listAssets(sbStoreId, path+"/myFolder1", false).size()); + fail("Cannot list assets within non-existant folder"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + } + + /** + * Test CRUD in a webApp - create, retrieve (get, list), update and delete + */ + public void testCRUDinWebApp() throws IOException + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-crudwebapp", TEST_WEBPROJ_NAME+"-crudwebapp", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + + String myWebApp1 = "myWebApp1"; + wpService.createWebApp(wpInfo.getStoreId(), myWebApp1, null); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + // get non-existent assets + assertNull(assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFolder1")); + assertNull(assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFile1")); + assertNull(assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFolder1/myFile2")); + + assertEquals(0, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/", false).size()); + + // create folder + assetService.createFolderWebApp(sbStoreId, myWebApp1, "/", "myFolder1"); + + assertEquals(1, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/", false).size()); + assertEquals(0, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/myFolder1", false).size()); + + // create file (and add content) + final String MYFILE1 = "This is myFile1"; + ContentWriter writer = assetService.createFileWebApp(sbStoreId, myWebApp1, "/", "myFile1"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); + + assertEquals(2, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/", false).size()); + + final String MYFILE2 = "This is myFile2"; + writer = assetService.createFileWebApp(sbStoreId, myWebApp1, "/myFolder1", "myFile2"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2); + + assertEquals(1, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/myFolder1", false).size()); + + // get assets (not including deleted) + String path = sbInfo.getSandboxRootPath() + "/" + myWebApp1; + AssetInfo myFolder1Asset = assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFolder1"); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ONE, false, true, false, false, null); + + AssetInfo myFile1Asset = assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + // get content + + ContentReader reader = assetService.getContentReader(myFile1Asset); + InputStream in = reader.getContentInputStream(); + byte[] buff = new byte[1024]; + in.read(buff); + in.close(); + assertEquals(MYFILE1, new String(buff, 0, MYFILE1.length())); // assumes 1byte=1char + + AssetInfo myFile2Asset = assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFolder1/myFile2"); + checkAssetInfo(myFile2Asset, "myFile2", path+"/myFolder1/myFile2", USER_ONE, true, false, false, true, USER_ONE); + + reader = assetService.getContentReader(myFile2Asset); + in = reader.getContentInputStream(); + buff = new byte[1024]; + in.read(buff); + in.close(); + assertEquals(MYFILE2, new String(buff, 0, MYFILE2.length())); // assumes 1byte=1char + + // update content + + final String MYFILE2_MODIFIED = "This is myFile2 ... modified"; + writer = assetService.getContentWriter(myFile2Asset); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2_MODIFIED); + + // get updated content + + reader = assetService.getContentReader(myFile2Asset); + in = reader.getContentInputStream(); + buff = new byte[1024]; + in.read(buff); + in.close(); + assertEquals(MYFILE2_MODIFIED, new String(buff, 0, MYFILE2_MODIFIED.length())); // assumes 1byte=1char + + // delete folders and files + assetService.deleteAsset(myFile1Asset); + assetService.deleteAsset(myFolder1Asset); // also deletes myFile2 + + // try to get assets (including deleted) + + myFolder1Asset = assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFolder1", true); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ONE, false, true, true, false, null); // TODO - unlike admin (testSimple) + + myFile1Asset = assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFile1", true); + assertNull(myFile1Asset); + + myFile2Asset = assetService.getAssetWebApp(sbStoreId, myWebApp1, "/myFolder1/myFile2", true); + assertNull(myFile2Asset); + + assertEquals(0, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/", false).size()); + + try + { + // -ve test + assertEquals(0, assetService.listAssetsWebApp(sbStoreId, myWebApp1, "/myFolder1", false).size()); + fail("Cannot list assets within non-existant folder"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + } + + public void testRenameFile() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-renamefile", TEST_WEBPROJ_NAME+"-renamefile", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folders + assetService.createFolder(sbStoreId, path, "myFolder1", null); + assetService.createFolder(sbStoreId, path+"/myFolder1", "myFolder2", null); + + // create file + assetService.createFile(sbStoreId, path+"/myFolder1/myFolder2", "myFile1", null); + + // rename file + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + myFile1Asset = assetService.renameAsset(myFile1Asset, "myFile1Renamed"); + checkAssetInfo(myFile1Asset, "myFile1Renamed", path+"/myFolder1/myFolder2/myFile1Renamed", USER_ONE, true, false, false, true, USER_ONE); + } + + /* + // TODO lock issue ... + // org.alfresco.service.cmr.avm.AVMNotFoundException: Lock not found for testAsset-1228476617644-rename:/www/avm_webapps/ROOT/myFolder1 + // at org.alfresco.repo.avm.locking.AVMLockingServiceImpl.modifyLock(AVMLockingServiceImpl.java:490) + // at org.alfresco.repo.avm.AVMLockingAwareService.rename(AVMLockingAwareService.java:712) + + public void testRenameFolder() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-renamefolder", TEST_WEBPROJ_NAME+"-renamefolder", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folders + assetService.createFolder(sbStoreId, path, "myFolder1", null); + assetService.createFolder(sbStoreId, path+"/myFolder1", "myFolder2", null); + + AssetInfo myFolder1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1"); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ONE, false, true, false, false, null); + + AssetInfo myFolder2Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2"); + checkAssetInfo(myFolder2Asset, "myFolder2", path+"/myFolder1/myFolder2", USER_ONE, false, true, false, false, null); + + // TODO lock issue ... + // org.alfresco.service.cmr.avm.AVMNotFoundException: Lock not found for testAsset-1228476617644-rename:/www/avm_webapps/ROOT/myFolder1 + // at org.alfresco.repo.avm.locking.AVMLockingServiceImpl.modifyLock(AVMLockingServiceImpl.java:490) + //at org.alfresco.repo.avm.AVMLockingAwareService.rename(AVMLockingAwareService.java:712) + + // rename folder + myFolder1Asset = assetService.renameAsset(myFolder1Asset, "myFolder1Renamed"); + checkAssetInfo(myFolder1Asset, "myFolder1Renamed", path+"/myFolder1Renamed", USER_ONE, false, true, false, false, null); + + // rename folder + myFolder2Asset = assetService.renameAsset(myFolder2Asset, "myFolder2Renamed"); + checkAssetInfo(myFolder2Asset, "myFolder2Renamed", path+"/myFolder1/myFolder2Renamed", USER_ONE, false, true, false, false, null); + } + */ + + public void testCopyFile() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-copyfile", TEST_WEBPROJ_NAME+"-copyfile", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folders + assetService.createFolder(sbStoreId, path, "myFolder1", null); + assetService.createFolder(sbStoreId, path+"/myFolder1", "myFolder2", null); + + // create (nn-empty) file + final String MYFILE1 = "This is myFile1"; + ContentWriter writer = assetService.createFile(sbStoreId, path+"/myFolder1/myFolder2", "myFile1", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); + + // copy file - note: must have content + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + myFile1Asset = assetService.copyAsset(myFile1Asset, path+"/myFolder1"); + + // TODO review - copied files are not locked ? + //checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFile1", USER_ONE, true, false, false, true, USER_ONE); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFile1", USER_ONE, true, false, false, false, null); + } + + public void testCopyFolder() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-copyfolder", TEST_WEBPROJ_NAME+"-copyfolder", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folders + assetService.createFolder(sbStoreId, path, "myFolder1", null); + assetService.createFolder(sbStoreId, path+"/myFolder1", "myFolder2", null); + + // create (non-empty) file + final String MYFILE1 = "This is myFile1"; + ContentWriter writer = assetService.createFile(sbStoreId, path+"/myFolder1/myFolder2", "myFile1", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); + + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + AssetInfo myFolder2Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2"); + checkAssetInfo(myFolder2Asset, "myFolder2", path+"/myFolder1/myFolder2", USER_ONE, false, true, false, false, null); + + // recursively copy folder + myFolder2Asset = assetService.copyAsset(myFolder2Asset, path); + + checkAssetInfo(myFolder2Asset, "myFolder2", path+"/myFolder2", USER_ONE, false, true, false, false, null); + + AssetInfo myCopiedFolder2Asset = assetService.getAsset(sbStoreId, path+"/myFolder2"); + checkAssetInfo(myCopiedFolder2Asset, "myFolder2", path+"/myFolder2", USER_ONE, false, true, false, false, null); + + AssetInfo myCopiedFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder2/myFile1"); + + // TODO review - copied files are not locked ? + //checkAssetInfo(myCopiedFile1Asset, "myFile1", path+"/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + checkAssetInfo(myCopiedFile1Asset, "myFile1", path+"/myFolder2/myFile1", USER_ONE, true, false, false, false, null); + } + + public void testMoveFile() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-movefile", TEST_WEBPROJ_NAME+"-movefile", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folders + assetService.createFolder(sbStoreId, path, "myFolder1", null); + assetService.createFolder(sbStoreId, path+"/myFolder1", "myFolder2", null); + + // create (empty) file + assetService.createFile(sbStoreId, path+"/myFolder1/myFolder2", "myFile1", null); + + // move file + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + myFile1Asset = assetService.moveAsset(myFile1Asset, path+"/myFolder1"); + + // TODO review - moved files are not locked ? + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFile1", USER_ONE, true, false, false, true, USER_ONE); + //checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFile1", USER_ONE, true, false, false, false, null); + } + + /* + // TODO lock issue ... + // org.alfresco.service.cmr.avm.AVMNotFoundException: Lock not found for testAsset-1228830920248-movefolder:/www/avm_webapps/ROOT/myFolder1/myFolder2 + // at org.alfresco.repo.avm.locking.AVMLockingServiceImpl.modifyLock(AVMLockingServiceImpl.java:490) + // at org.alfresco.repo.avm.AVMLockingAwareService.rename(AVMLockingAwareService.java:712) + + public void testMoveFolder() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-movefolder", TEST_WEBPROJ_NAME+"-movefolder", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folders + assetService.createFolder(sbStoreId, path, "myFolder1", null); + assetService.createFolder(sbStoreId, path+"/myFolder1", "myFolder2", null); + + // create (non-empty) file + //final String MYFILE1 = "This is myFile1"; + ContentWriter writer = assetService.createFile(sbStoreId, path+"/myFolder1/myFolder2", "myFile1", null); + //writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + //writer.setEncoding("UTF-8"); + //writer.putContent(MYFILE1); + + AssetInfo myFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + AssetInfo myFolder2Asset = assetService.getAsset(sbStoreId, path+"/myFolder1/myFolder2"); + checkAssetInfo(myFolder2Asset, "myFolder2", path+"/myFolder1/myFolder2", USER_ONE, false, true, false, false, null); + + // recursively move folder + myFolder2Asset = assetService.moveAsset(myFolder2Asset, path); + + checkAssetInfo(myFolder2Asset, "myFolder2", path+"/myFolder2", USER_ONE, false, true, false, false, null); + + AssetInfo myMovedFolder2Asset = assetService.getAsset(sbStoreId, path+"/myFolder2"); + checkAssetInfo(myMovedFolder2Asset, "myFolder2", path+"/myFolder2", USER_ONE, false, true, false, false, null); + + AssetInfo myMovedFile1Asset = assetService.getAsset(sbStoreId, path+"/myFolder2/myFile1"); + + // TODO review - moved files are not locked ? + checkAssetInfo(myMovedFile1Asset, "myFile1", path+"/myFolder2/myFile1", USER_ONE, true, false, false, true, USER_ONE); + //checkAssetInfo(myMovedFile1Asset, "myFile1", path+"/myFolder2/myFile1", USER_ONE, true, false, false, false, null); + } + */ + + public void testProperties() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-properties", TEST_WEBPROJ_NAME+"-properties", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_CONTRIBUTOR, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folder + assetService.createFolderWebApp(sbStoreId, defaultWebApp, "/", "myFolder1"); + AssetInfo myFolder1Asset = assetService.getAssetWebApp(sbStoreId, defaultWebApp, "/myFolder1"); + checkAssetInfo(myFolder1Asset, "myFolder1", path+"/myFolder1", USER_ONE, false, true, false, false, null); + + Map props = assetService.getAssetProperties(myFolder1Asset); + assertNotNull(props); + int countFolderInbuiltProps = props.size(); + + // create file + assetService.createFileWebApp(sbStoreId, defaultWebApp, "/myFolder1", "myFile1"); + AssetInfo myFile1Asset = assetService.getAssetWebApp(sbStoreId, defaultWebApp, "/myFolder1/myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFolder1/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + props = assetService.getAssetProperties(myFile1Asset); + assertNotNull(props); + int countFileInbuiltProps = props.size(); + + assertEquals(USER_ONE, assetService.getLockOwner(myFile1Asset)); + + sbService.submitWebApp(sbStoreId, defaultWebApp, "submit1 label", "submit1 comment"); + + assertNull(assetService.getLockOwner(myFile1Asset)); + + // update (or set, if not already set) specific properties - eg. title and description + + Map newProps = new HashMap(2); + newProps.put(ContentModel.PROP_TITLE, "folder title"); + newProps.put(ContentModel.PROP_DESCRIPTION, "folder description"); + + assetService.updateAssetProperties(myFolder1Asset, newProps); + props = assetService.getAssetProperties(myFolder1Asset); + assertEquals((countFolderInbuiltProps+2), props.size()); + + assertEquals("folder title", props.get(ContentModel.PROP_TITLE)); + assertEquals("folder description", props.get(ContentModel.PROP_DESCRIPTION)); + + // set all (or replace existing) properties - eg. just title + + newProps = new HashMap(1); + newProps.put(ContentModel.PROP_TITLE, "folder title2"); + + assetService.setAssetProperties(myFolder1Asset, newProps); + props = assetService.getAssetProperties(myFolder1Asset); + assertEquals((countFolderInbuiltProps+1), props.size()); + + assertEquals("folder title2", props.get(ContentModel.PROP_TITLE)); + assertNull(props.get(ContentModel.PROP_DESCRIPTION)); + + // set all (or replace existing) properties - eg. title and description + + newProps = new HashMap(2); + newProps.put(ContentModel.PROP_TITLE, "file title"); + newProps.put(ContentModel.PROP_DESCRIPTION, "file description"); + + assetService.setAssetProperties(myFile1Asset, newProps); + props = assetService.getAssetProperties(myFile1Asset); + assertEquals((countFileInbuiltProps+2), props.size()); + + assertEquals("file title", props.get(ContentModel.PROP_TITLE)); + assertEquals("file description", props.get(ContentModel.PROP_DESCRIPTION)); + + assertEquals(USER_ONE, assetService.getLockOwner(myFile1Asset)); + } + + public void testSimpleLockFile() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-simpleLock", TEST_WEBPROJ_NAME+"-simpleLock", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web users and auto-create their (author) sandboxs + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_CONTRIBUTOR, true); + wpService.inviteWebUser(wpInfo.getStoreId(), USER_TWO, WCMUtil.ROLE_CONTENT_CONTRIBUTOR, true); + wpService.inviteWebUser(wpInfo.getStoreId(), USER_THREE, WCMUtil.ROLE_CONTENT_MANAGER, true); + + // switch to user one + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create file + assetService.createFileWebApp(sbStoreId, defaultWebApp, "/", "myFile1"); + AssetInfo myFile1Asset = assetService.getAssetWebApp(sbStoreId, defaultWebApp, "myFile1"); + checkAssetInfo(myFile1Asset, "myFile1", path+"/myFile1", USER_ONE, true, false, false, true, USER_ONE); + + assertEquals(USER_ONE, assetService.getLockOwner(myFile1Asset)); + assertTrue(assetService.hasLockAccess(myFile1Asset)); + + // switch to user two + AuthenticationUtil.setFullyAuthenticatedUser(USER_TWO); + + assertEquals(USER_ONE, assetService.getLockOwner(myFile1Asset)); + assertFalse(assetService.hasLockAccess(myFile1Asset)); + + // switch to user three + AuthenticationUtil.setFullyAuthenticatedUser(USER_THREE); + + assertEquals(USER_ONE, assetService.getLockOwner(myFile1Asset)); + assertTrue(assetService.hasLockAccess(myFile1Asset)); // content manager + + // switch to user one + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + sbService.submitWebApp(sbStoreId, defaultWebApp, "submit1 label", "submit1 comment"); + + assertNull(assetService.getLockOwner(myFile1Asset)); + assertTrue(assetService.hasLockAccess(myFile1Asset)); + + // switch to user two + AuthenticationUtil.setFullyAuthenticatedUser(USER_TWO); + + assertNull(assetService.getLockOwner(myFile1Asset)); + assertTrue(assetService.hasLockAccess(myFile1Asset)); + } + + public void testSimpleImport() + { + // create web project (also creates staging sandbox and admin's author sandbox) + WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-simpleImport", TEST_WEBPROJ_NAME+"-simpleImport", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); + String defaultWebApp = wpInfo.getDefaultWebApp(); + + // invite web user and auto-create their (author) sandbox + wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_CONTRIBUTOR, true); + + // switch to user + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // get user's author sandbox + SandboxInfo sbInfo = sbService.getAuthorSandbox(wpInfo.getStoreId()); + String sbStoreId = sbInfo.getSandboxId(); + + String path = sbInfo.getSandboxRootPath() + "/" + defaultWebApp; + + // create folder + assetService.createFolder(sbStoreId, path, "myFolder1", null); + AssetInfo myFolder1Asset = assetService.getAsset(sbStoreId, path+"/myFolder1"); + + // bulk import + String testFile = System.getProperty("user.dir") + "/source/test-resources/module/test.war"; + + File zipFile = new File(testFile); + assetService.bulkImport(sbStoreId, myFolder1Asset.getPath(), zipFile, false); + } +} diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java index ec059f328c..127f460a36 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java @@ -227,7 +227,7 @@ public final class SandboxFactory extends WCMUtil * @param sandboxId * @return SandboxInfo returns sandbox info or null if sandbox does not exist or is not visible */ - public SandboxInfo getSandbox(String sandboxId) + /* package */ SandboxInfo getSandbox(String sandboxId) { AVMStoreDescriptor storeDesc = avmService.getStore(sandboxId); if (storeDesc == null) @@ -680,6 +680,12 @@ public final class SandboxFactory extends WCMUtil this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, dnsProp), new PropertyValue(DataTypeDefinition.TEXT, path)); + // TODO review above and replace with common call to ... + /* + // tag the store with the DNS name property + tagStoreDNSPath(avmService, workflowStoreName, storeId, packageName); + */ + // the main workflow store depends on the main user store (dist=1) String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore; this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key), @@ -721,6 +727,12 @@ public final class SandboxFactory extends WCMUtil dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(userStore, packageName, "preview"); this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, dnsProp), new PropertyValue(DataTypeDefinition.TEXT, path)); + + // TODO review above and replace with common call to ... + /* + // tag the store with the DNS name property + tagStoreDNSPath(avmService, previewStoreName, storeId, packageName, "preview"); + */ // The preview worfkflow store depends on the main workflow store (dist=1) prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + workflowStoreName; diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxService.java b/source/java/org/alfresco/wcm/sandbox/SandboxService.java index 1b5bc5cbe6..678fc28974 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxService.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxService.java @@ -28,9 +28,9 @@ import java.util.Date; import java.util.List; import java.util.Map; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.VersionDescriptor; import org.alfresco.service.namespace.QName; +import org.alfresco.wcm.asset.AssetInfo; /** @@ -156,7 +156,7 @@ public interface SandboxService * @param includeDeleted if true, include deleted assets as well as new/modified assets * @return List list of all changed assets */ - public List listChangedAll(String sbStoreId, boolean includeDeleted); + public List listChangedAll(String sbStoreId, boolean includeDeleted); /** * List changed assets for given sandbox and web app (eg. in user sandbox) @@ -168,7 +168,7 @@ public interface SandboxService * @param includeDeleted if true, include deleted assets as well as new/modified assets * @return List list of changed assets */ - public List listChangedWebApp(String sbStoreId, String webApp, boolean includeDeleted); + public List listChangedWebApp(String sbStoreId, String webApp, boolean includeDeleted); /** * List changed assets for given sandbox path (eg. between user sandbox and staging sandbox) @@ -180,7 +180,7 @@ public interface SandboxService * @param includeDeleted if true, include deleted assets as well as new/modified assets * @return List list of changed assets */ - public List listChanged(String sbStoreId, String relativePath, boolean includeDeleted); + public List listChanged(String sbStoreId, String relativePath, boolean includeDeleted); /** * List changed (new/modified/deleted) assets between any two sandbox paths @@ -192,7 +192,7 @@ public interface SandboxService * @param includeDeleted if true, include deleted assets as well as new/modified assets * @return List list of changed assets */ - public List listChanged(String srcSandboxStoreId, String srcRelativePath, String dstSandboxStoreId, String dstRelativePath, boolean includeDeleted); + public List listChanged(String srcSandboxStoreId, String srcRelativePath, String dstSandboxStoreId, String dstRelativePath, boolean includeDeleted); /** * Submit all changed assets for given sandbox (eg. from user sandbox to staging sandbox) @@ -239,15 +239,16 @@ public interface SandboxService */ public void submitList(String sbStoreId, List relativePaths, String submitLabel, String submitComment); + public void submitList(String sbStoreId, List relativePaths, Map expirationDates, String submitLabel, String submitComment); /** * Submit list of changed assets for given sandbox (eg. from user sandbox to staging sandbox) * * @param sbStoreId sandbox store id - * @param assetNodes list of assets, as AVM node descriptors + * @param assetNodes list of assets, as AVM node descriptors * @param submitLabel label for submitted snapshot * @param submitComment comment for submitted snapshot */ - public void submitListNodes(String sbStoreId, List assets, String submitLabel, String submitComment); + public void submitListAssets(String sbStoreId, List assets, String submitLabel, String submitComment); /** * Submit list of changed assets for given sandbox (eg. from user sandbox to staging sandbox) @@ -258,7 +259,7 @@ public interface SandboxService * @param submitLabel label for submitted snapshot * @param submitComment comment for submitted snapshot */ - public void submitListNodes(String sbStoreId, List assets, Map expirationDates, String submitLabel, String submitComment); + public void submitListAssets(String sbStoreId, List assets, Map expirationDates, String submitLabel, String submitComment); /** * Revert all changed assets for given sandbox (eg. in user sandbox) @@ -302,7 +303,7 @@ public interface SandboxService * * @param assets list of AVM node descriptors */ - public void revertListNodes(String sbStoreId, List assets); + public void revertListNodes(String sbStoreId, List assets); /** * Revert sandbox to a specific snapshot version ID (ie. for staging sandbox) diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java index ab2710bdf2..7e810bd50c 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java @@ -61,6 +61,8 @@ import org.alfresco.util.NameMatcher; import org.alfresco.util.Pair; import org.alfresco.util.ParameterCheck; import org.alfresco.util.VirtServerUtils; +import org.alfresco.wcm.asset.AssetInfo; +import org.alfresco.wcm.asset.AssetService; import org.alfresco.wcm.util.WCMUtil; import org.alfresco.wcm.util.WCMWorkflowUtil; import org.alfresco.wcm.webproject.WebProjectInfo; @@ -76,7 +78,7 @@ import org.apache.commons.logging.LogFactory; * * @author janv */ -public class SandboxServiceImpl extends WCMUtil implements SandboxService +public class SandboxServiceImpl implements SandboxService { /** Logger */ private static Log logger = LogFactory.getLog(SandboxServiceImpl.class); @@ -90,6 +92,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService private VirtServerRegistry virtServerRegistry; private ActionService actionService; private WorkflowService workflowService; + private AssetService assetService; public void setWebProjectService(WebProjectService wpService) { @@ -135,7 +138,11 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService { this.workflowService = workflowService; } - + + public void setAssetService(AssetService assetService) + { + this.assetService = assetService; + } /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#createAuthorSandbox(java.lang.String) @@ -350,7 +357,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#listChangedAll(java.lang.String, boolean) */ - public List listChangedAll(String sbStoreId, boolean includeDeleted) + public List listChangedAll(String sbStoreId, boolean includeDeleted) { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); @@ -361,7 +368,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#listChangedWebApp(java.lang.String, java.lang.String, boolean) */ - public List listChangedWebApp(String sbStoreId, String webApp, boolean includeDeleted) + public List listChangedWebApp(String sbStoreId, String webApp, boolean includeDeleted) { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); ParameterCheck.mandatoryString("webApp", webApp); @@ -374,7 +381,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#listChanged(java.lang.String, java.lang.String, boolean) */ - public List listChanged(String sbStoreId, String relativePath, boolean includeDeleted) + public List listChanged(String sbStoreId, String relativePath, boolean includeDeleted) { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); ParameterCheck.mandatoryString("relativePath", relativePath); @@ -395,7 +402,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#listChanged(java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean) */ - public List listChanged(String srcSandboxStoreId, String srcRelativePath, String dstSandboxStoreId, String dstRelativePath, boolean includeDeleted) + public List listChanged(String srcSandboxStoreId, String srcRelativePath, String dstSandboxStoreId, String dstRelativePath, boolean includeDeleted) { ParameterCheck.mandatoryString("srcSandboxStoreId", srcSandboxStoreId); ParameterCheck.mandatoryString("srcRelativePath", srcRelativePath); @@ -403,28 +410,30 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService ParameterCheck.mandatoryString("dstSandboxStoreId", dstSandboxStoreId); ParameterCheck.mandatoryString("dstRelativePath", dstRelativePath); - String avmSrcPath = srcSandboxStoreId + AVM_STORE_SEPARATOR + srcRelativePath; - String avmDstPath = dstSandboxStoreId + AVM_STORE_SEPARATOR + dstRelativePath; + String avmSrcPath = srcSandboxStoreId + WCMUtil.AVM_STORE_SEPARATOR + srcRelativePath; + String avmDstPath = dstSandboxStoreId + WCMUtil.AVM_STORE_SEPARATOR + dstRelativePath; return listChanged(-1, avmSrcPath, -1, avmDstPath, includeDeleted); } - private List listChanged(int srcVersion, String srcPath, int dstVersion, String dstPath, boolean includeDeleted) + private List listChanged(int srcVersion, String srcPath, int dstVersion, String dstPath, boolean includeDeleted) { long start = System.currentTimeMillis(); List diffs = avmSyncService.compare(srcVersion, srcPath, dstVersion, dstPath, nameMatcher); - List assets = new ArrayList(diffs.size()); + List assets = new ArrayList(diffs.size()); for (AVMDifference diff : diffs) { // convert each diff record into an AVM node descriptor String sourcePath = diff.getSourcePath(); - AVMNodeDescriptor node = avmService.lookup(-1, sourcePath, includeDeleted); - if (node != null) + + String[] parts = WCMUtil.splitPath(sourcePath); + AssetInfo asset = assetService.getAsset(parts[0], -1, parts[1], includeDeleted); + if (asset != null) { - assets.add(node); + assets.add(asset); } } @@ -467,9 +476,9 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService ParameterCheck.mandatoryString("sbStoreId", sbStoreId); ParameterCheck.mandatoryString("relativePath", relativePath); - List assets = listChanged(sbStoreId, relativePath, true); + List assets = listChanged(sbStoreId, relativePath, true); - submitListNodes(sbStoreId, assets, submitLabel, submitComment); + submitListAssets(sbStoreId, assets, submitLabel, submitComment); } /* (non-Javadoc) @@ -479,35 +488,42 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); - List assets = new ArrayList(relativePaths.size()); - - for (String relativePath : relativePaths) - { - // convert each path into an AVM node descriptor - AVMNodeDescriptor node = avmService.lookup(-1, sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + relativePath, true); - if (node != null) - { - assets.add(node); - } - } - - submitListNodes(sbStoreId, assets, null, submitLabel, submitComment); + submitList(sbStoreId, relativePaths, null, submitLabel, submitComment); } - /* (non-Javadoc) - * @see org.alfresco.wcm.sandbox.SandboxService#submitListNodes(java.lang.String, java.util.List, java.lang.String, java.lang.String) - */ - public void submitListNodes(String sbStoreId, List assets, String submitLabel, String submitComment) + public void submitList(String sbStoreId, List relativePaths, Map expirationDates, String submitLabel, String submitComment) { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); - submitListNodes(sbStoreId, assets, null, submitLabel, submitComment); + List assets = new ArrayList(relativePaths.size()); + + for (String relativePath : relativePaths) + { + // convert each path into an asset + AssetInfo asset = assetService.getAsset(sbStoreId, -1, relativePath, true); + if (asset != null) + { + assets.add(asset); + } + } + + submitListAssets(sbStoreId, assets, expirationDates, submitLabel, submitComment); } /* (non-Javadoc) - * @see org.alfresco.wcm.sandbox.SandboxService#submitListNodes(java.lang.String, java.util.List, java.util.Map, java.lang.String, java.lang.String) + * @see org.alfresco.wcm.sandbox.SandboxService#submitListAssets(java.lang.String, java.util.List, java.lang.String, java.lang.String) */ - public void submitListNodes(String sbStoreId, List assets, Map expirationDates, final String submitLabel, final String submitComment) + public void submitListAssets(String sbStoreId, List assets, String submitLabel, String submitComment) + { + ParameterCheck.mandatoryString("sbStoreId", sbStoreId); + + submitListAssets(sbStoreId, assets, null, submitLabel, submitComment); + } + + /* (non-Javadoc) + * @see org.alfresco.wcm.sandbox.SandboxService#submitListAssets(java.lang.String, java.util.List, java.util.Map, java.lang.String, java.lang.String) + */ + public void submitListAssets(String sbStoreId, List assets, Map expirationDates, final String submitLabel, final String submitComment) { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); @@ -525,12 +541,12 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService final List diffs = new ArrayList(assets.size()); - for (AVMNodeDescriptor item : assets) + for (AssetInfo asset : assets) { - String relativePath = WCMUtil.getStoreRelativePath(item.getPath()); + String relativePath = WCMUtil.getStoreRelativePath(asset.getAvmPath()); - String srcPath = sbStoreId + AVM_STORE_SEPARATOR + relativePath; - String dstPath = stagingSandboxId + AVM_STORE_SEPARATOR + relativePath; + String srcPath = sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + relativePath; + String dstPath = stagingSandboxId + WCMUtil.AVM_STORE_SEPARATOR + relativePath; AVMDifference diff = new AVMDifference(-1, srcPath, -1, dstPath, AVMDifference.NEWER); diffs.add(diff); @@ -607,7 +623,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService ParameterCheck.mandatoryString("sbStoreId", sbStoreId); ParameterCheck.mandatoryString("relativePath", relativePath); - List assets = listChanged(sbStoreId, relativePath, true); + List assets = listChanged(sbStoreId, relativePath, true); revertListNodes(sbStoreId, assets); } @@ -619,15 +635,15 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); - List assets = new ArrayList(relativePaths.size()); + List assets = new ArrayList(relativePaths.size()); for (String relativePath : relativePaths) { - // convert each path into an AVM node descriptor - AVMNodeDescriptor node = avmService.lookup(-1, sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + relativePath, true); - if (node != null) + // convert each path into an asset + AssetInfo asset = assetService.getAsset(sbStoreId, -1, relativePath, true); + if (asset != null) { - assets.add(node); + assets.add(asset); } } @@ -637,22 +653,26 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService /* (non-Javadoc) * @see org.alfresco.wcm.sandbox.SandboxService#revertListNodes(java.lang.String, java.util.List) */ - public void revertListNodes(String sbStoreId, List assets) + public void revertListNodes(String sbStoreId, List assets) { ParameterCheck.mandatoryString("sbStoreId", sbStoreId); List> versionPaths = new ArrayList>(assets.size()); List tasks = null; - for (AVMNodeDescriptor node : assets) + for (AssetInfo asset : assets) { if (tasks == null) { - tasks = WCMWorkflowUtil.getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(node.getPath())); + tasks = WCMWorkflowUtil.getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(asset.getAvmPath())); } + + // TODO ... extra lookup ... either return AVMNodeDescriptor or change getAssociatedTasksForNode ... + AVMNodeDescriptor node = avmService.lookup(-1, asset.getAvmPath()); + if (WCMWorkflowUtil.getAssociatedTasksForNode(avmService, node, tasks).size() == 0) { - String revertPath = node.getPath(); + String revertPath = asset.getAvmPath(); versionPaths.add(new Pair(-1, revertPath)); if (VirtServerUtils.requiresUpdateNotification(revertPath)) @@ -747,7 +767,7 @@ public class SandboxServiceImpl extends WCMUtil implements SandboxService Map args = new HashMap(1, 1.0f); args.put(AVMRevertStoreAction.PARAM_VERSION, version); Action action = actionService.createAction(AVMRevertStoreAction.NAME, args); - actionService.executeAction(action, AVMNodeConverter.ToNodeRef(-1, sbStoreId + AVM_STORE_SEPARATOR + "/")); + actionService.executeAction(action, AVMNodeConverter.ToNodeRef(-1, sbStoreId + WCMUtil.AVM_STORE_SEPARATOR + "/")); return diffs; } }, AuthenticationUtil.getSystemUserName()); diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImplTest.java b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImplTest.java index 411f87daf0..8bd9ef8a70 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxServiceImplTest.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxServiceImplTest.java @@ -26,7 +26,6 @@ package org.alfresco.wcm.sandbox; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -36,17 +35,21 @@ import junit.framework.TestCase; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; -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.VersionDescriptor; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.PropertyMap; +import org.alfresco.wcm.asset.AssetInfo; +import org.alfresco.wcm.asset.AssetService; import org.alfresco.wcm.util.WCMUtil; import org.alfresco.wcm.webproject.WebProjectInfo; import org.alfresco.wcm.webproject.WebProjectService; @@ -61,8 +64,6 @@ public class SandboxServiceImplTest extends TestCase { private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); - private char AVM_STORE_SEPARATOR = ':'; - // // test data // @@ -100,11 +101,15 @@ public class SandboxServiceImplTest extends TestCase private WebProjectService wpService; private SandboxService sbService; + private AssetService assetService; + private AuthenticationService authenticationService; private PersonService personService; - private AVMService avmLockingAwareService; - private AVMService avmNonLockingAwareService; + private AVMService avmService; // non-locking-aware + + //private AVMService avmLockingAwareService; + //private AVMService avmNonLockingAwareService; @Override @@ -113,14 +118,18 @@ public class SandboxServiceImplTest extends TestCase // Get the required services wpService = (WebProjectService)ctx.getBean("WebProjectService"); sbService = (SandboxService)ctx.getBean("SandboxService"); + assetService = (AssetService)ctx.getBean("AssetService"); + authenticationService = (AuthenticationService)ctx.getBean("AuthenticationService"); personService = (PersonService)ctx.getBean("PersonService"); + avmService = (AVMService)ctx.getBean("AVMService"); + // WCM locking - avmLockingAwareService = (AVMService)ctx.getBean("AVMLockingAwareService"); + //avmLockingAwareService = (AVMService)ctx.getBean("AVMLockingAwareService"); // without WCM locking - avmNonLockingAwareService = (AVMService)ctx.getBean("AVMService"); + //avmNonLockingAwareService = (AVMService)ctx.getBean("AVMService"); // By default run as Admin AuthenticationUtil.setFullyAuthenticatedUser(USER_ADMIN); @@ -184,7 +193,7 @@ public class SandboxServiceImplTest extends TestCase public void testSimple() { - int storeCnt = avmLockingAwareService.getStores().size(); + int storeCnt = avmService.getStores().size(); // create web project (also creates staging sandbox and admin's author sandbox) WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-simple", TEST_WEBPROJ_NAME+"-simple", TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null); @@ -194,7 +203,7 @@ public class SandboxServiceImplTest extends TestCase assertEquals(2, sbService.listSandboxes(wpStoreId).size()); // list 4 extra AVM stores (2 per sandbox) - assertEquals(storeCnt+4, avmLockingAwareService.getStores().size()); // 2x stating (main,preview), 2x admin author (main, preview) + assertEquals(storeCnt+4, avmService.getStores().size()); // 2x stating (main,preview), 2x admin author (main, preview) // get admin's sandbox SandboxInfo sbInfo = sbService.getAuthorSandbox(wpStoreId); @@ -222,7 +231,7 @@ public class SandboxServiceImplTest extends TestCase // delete web project (also deletes staging sandbox) wpService.deleteWebProject(wpStoreId); - assertEquals(storeCnt, avmLockingAwareService.getStores().size()); + assertEquals(storeCnt, avmService.getStores().size()); } public void testCreateAuthorSandbox() @@ -508,38 +517,35 @@ public class SandboxServiceImplTest extends TestCase String sbStoreId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(sbStoreId, true); + List assets = sbService.listChangedAll(sbStoreId, true); assertEquals(0, assets.size()); String authorSandboxMyWebAppRelativePath = sbInfo.getSandboxRootPath() + "/" + myWebApp; // in this case, my web app is 'myWebApp' - String authorSandboxMyWebAppPath = sbStoreId + AVM_STORE_SEPARATOR + authorSandboxMyWebAppRelativePath; - String authorSandboxDefaultWebAppRelativePath = sbInfo.getSandboxRootPath() + "/" + wpInfo.getDefaultWebApp(); // in this case, default web app is 'ROOT' - String authorSandboxDefaultWebAppPath = sbStoreId + AVM_STORE_SEPARATOR + authorSandboxDefaultWebAppRelativePath; - avmLockingAwareService.createFile(authorSandboxMyWebAppPath, "myFile1"); + assetService.createFile(sbStoreId, authorSandboxMyWebAppRelativePath, "myFile1", null); assets = sbService.listChangedAll(sbStoreId, false); assertEquals(1, assets.size()); assertEquals("myFile1", assets.get(0).getName()); - avmLockingAwareService.createDirectory(authorSandboxDefaultWebAppPath, "myDir1"); - avmLockingAwareService.createFile(authorSandboxDefaultWebAppPath+"/myDir1", "myFile2"); - avmLockingAwareService.createDirectory(authorSandboxDefaultWebAppPath+"/myDir1", "myDir2"); - avmLockingAwareService.createFile(authorSandboxDefaultWebAppPath+"/myDir1/myDir2", "myFile3"); - avmLockingAwareService.createFile(authorSandboxDefaultWebAppPath+"/myDir1/myDir2", "myFile4"); - avmLockingAwareService.createDirectory(authorSandboxDefaultWebAppPath+"/myDir1", "myDir3"); + assetService.createFolder(sbStoreId, authorSandboxDefaultWebAppRelativePath, "myDir1", null); + assetService.createFile(sbStoreId, authorSandboxDefaultWebAppRelativePath+"/myDir1", "myFile2", null); + assetService.createFolder(sbStoreId, authorSandboxDefaultWebAppRelativePath+"/myDir1", "myDir2", null); + assetService.createFile(sbStoreId, authorSandboxDefaultWebAppRelativePath+"/myDir1/myDir2", "myFile3", null); + assetService.createFile(sbStoreId, authorSandboxDefaultWebAppRelativePath+"/myDir1/myDir2", "myFile4", null); + assetService.createFolder(sbStoreId, authorSandboxDefaultWebAppRelativePath+"/myDir1", "myDir3", null); assets = sbService.listChangedAll(sbStoreId, false); assertEquals(2, assets.size()); // new dir with new dirs/files is returned as single change - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { if (asset.getName().equals("myFile1") && asset.isFile()) { continue; } - else if (asset.getName().equals("myDir1") && asset.isDirectory()) + else if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } @@ -552,9 +558,9 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChangedWebApp(sbStoreId, wpInfo.getDefaultWebApp(), false); assertEquals(1, assets.size()); - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { - if (asset.getName().equals("myDir1") && asset.isDirectory()) + if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } @@ -567,9 +573,9 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChanged(sbStoreId, authorSandboxDefaultWebAppRelativePath+"/myDir1", false); assertEquals(1, assets.size()); - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { - if (asset.getName().equals("myDir1") && asset.isDirectory()) + if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } @@ -596,12 +602,10 @@ public class SandboxServiceImplTest extends TestCase SandboxInfo sbInfo1 = sbService.getAuthorSandbox(wpStoreId); String sbStoreId = sbInfo1.getSandboxId(); - List assets = sbService.listChangedAll(sbStoreId, true); + List assets = sbService.listChangedAll(sbStoreId, true); assertEquals(0, assets.size()); - - String authorSandboxRootPath = sbStoreId + AVM_STORE_SEPARATOR + sbInfo1.getSandboxRootPath(); - - avmLockingAwareService.createFile(authorSandboxRootPath, "myFile1"); + + assetService.createFile(sbStoreId, sbInfo1.getSandboxRootPath(), "myFile1", null); assets = sbService.listChangedAll(sbStoreId, false); assertEquals(1, assets.size()); @@ -615,16 +619,14 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChangedAll(sbStoreId, true); assertEquals(0, assets.size()); - - authorSandboxRootPath = sbStoreId + AVM_STORE_SEPARATOR + sbInfo2.getSandboxRootPath(); - - avmLockingAwareService.createFile(authorSandboxRootPath, "myFile2"); - avmLockingAwareService.createFile(authorSandboxRootPath, "myFile3"); + + assetService.createFile(sbStoreId, sbInfo2.getSandboxRootPath(), "myFile2", null); + assetService.createFile(sbStoreId, sbInfo2.getSandboxRootPath(), "myFile3", null); assets = sbService.listChangedAll(sbStoreId, false); assertEquals(2, assets.size()); - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { if (asset.getName().equals("myFile2") && asset.isFile()) { @@ -650,10 +652,10 @@ public class SandboxServiceImplTest extends TestCase assertEquals(1, assets.size()); assertEquals("myFile1", assets.get(0).getName()); - assets = sbService.listChanged(sbInfo2.getSandboxId(), sbInfo1.getSandboxRootPath(), sbInfo1.getSandboxId(), sbInfo2.getSandboxRootPath(), false); + assets = sbService.listChanged(sbInfo2.getSandboxId(), sbInfo2.getSandboxRootPath(), sbInfo1.getSandboxId(), sbInfo1.getSandboxRootPath(), false); assertEquals(2, assets.size()); - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { if (asset.getName().equals("myFile2") && asset.isFile()) { @@ -670,6 +672,7 @@ public class SandboxServiceImplTest extends TestCase } } + /* // list changed (in this test, new) assets in two different user sandboxes compared to each other - without locking public void testListNewItems3() { @@ -686,7 +689,7 @@ public class SandboxServiceImplTest extends TestCase SandboxInfo sbInfo1 = sbService.getAuthorSandbox(wpStoreId); String sbStoreId = sbInfo1.getSandboxId(); - List assets = sbService.listChangedAll(sbStoreId, true); + List assets = sbService.listChangedAll(sbStoreId, true); assertEquals(0, assets.size()); String authorSandboxRootPath = sbStoreId + AVM_STORE_SEPARATOR + sbInfo1.getSandboxRootPath(); @@ -715,7 +718,7 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChangedAll(sbStoreId, false); assertEquals(3, assets.size()); - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { if (asset.getName().equals("myFile1") && asset.isFile()) { @@ -748,7 +751,7 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChanged(sbInfo2.getSandboxId(), sbInfo1.getSandboxRootPath(), sbInfo1.getSandboxId(), sbInfo2.getSandboxRootPath(), false); assertEquals(3, assets.size()); - for (AVMNodeDescriptor asset : assets) + for (AssetInfo asset : assets) { if (asset.getName().equals("myFile1") && asset.isFile()) { @@ -768,6 +771,7 @@ public class SandboxServiceImplTest extends TestCase } } } + */ // submit new assets in user sandbox to staging sandbox public void testSubmitNewItems1() @@ -788,25 +792,25 @@ public class SandboxServiceImplTest extends TestCase String authorSandboxId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(authorSandboxId, true); + List assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + String authorSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; - avmLockingAwareService.createFile(authorSandboxWebppPath, "myFile1"); - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir1"); - avmLockingAwareService.createFile(authorSandboxWebppPath+"/myDir1", "myFile2"); - avmLockingAwareService.createDirectory(authorSandboxWebppPath+"/myDir1", "myDir2"); - avmLockingAwareService.createFile(authorSandboxWebppPath+"/myDir1/myDir2", "myFile3"); - avmLockingAwareService.createFile(authorSandboxWebppPath+"/myDir1/myDir2", "myFile4"); - avmLockingAwareService.createDirectory(authorSandboxWebppPath+"/myDir1", "myDir3"); + assetService.createFile(authorSandboxId, authorSandboxPath, "myFile1", null); + assetService.createFolder(authorSandboxId, authorSandboxPath, "myDir1", null); + assetService.createFile(authorSandboxId, authorSandboxPath+"/myDir1", "myFile2", null); + assetService.createFolder(authorSandboxId, authorSandboxPath+"/myDir1", "myDir2", null); + assetService.createFile(authorSandboxId, authorSandboxPath+"/myDir1/myDir2", "myFile3", null); + assetService.createFile(authorSandboxId, authorSandboxPath+"/myDir1/myDir2", "myFile4", null); + assetService.createFolder(authorSandboxId, authorSandboxPath+"/myDir1", "myDir3", null); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(2, assets.size()); // new dir with new dirs/files is returned as single change // check staging before - String stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - assertEquals(0, avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false).size()); + String stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; + assertEquals(0, assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false).size()); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); @@ -815,16 +819,16 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - Map listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + List listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(2, listing.size()); - for (AVMNodeDescriptor asset : listing.values()) + for (AssetInfo asset : listing) { if (asset.getName().equals("myFile1") && asset.isFile()) { continue; } - else if (asset.getName().equals("myDir1") && asset.isDirectory()) + else if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } @@ -855,31 +859,31 @@ public class SandboxServiceImplTest extends TestCase String authorSandboxId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(authorSandboxId, true); + List assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + //String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; final String MYFILE1 = "This is myFile1"; - OutputStream out = avmLockingAwareService.createFile(authorSandboxWebppPath, "myFile1"); - byte [] buff = MYFILE1.getBytes(); - out.write(buff); - out.close(); + ContentWriter writer = assetService.createFileWebApp(authorSandboxId, webApp, "/", "myFile1"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir1"); + assetService.createFolderWebApp(authorSandboxId, webApp, "/", "myDir1"); final String MYFILE2 = "This is myFile2"; - out = avmLockingAwareService.createFile(authorSandboxWebppPath+"/myDir1", "myFile2"); - buff = MYFILE2.getBytes(); - out.write(buff); - out.close(); + writer = assetService.createFileWebApp(authorSandboxId, webApp, "/myDir1", "myFile2"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(2, assets.size()); // check staging before - String stagingSandboxWebppPath = stagingSandboxId + ":" + sbInfo.getSandboxRootPath() + "/" + webApp; - assertEquals(0, avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false).size()); + String stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; + assertEquals(0, assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false).size()); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); @@ -888,7 +892,7 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - Map listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + List listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(2, listing.size()); // Switch to USER_TWO @@ -900,34 +904,35 @@ public class SandboxServiceImplTest extends TestCase // no changes yet assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - - authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; final String MYFILE1_MODIFIED = "This is myFile1 ... modified by "+USER_TWO; - out = avmLockingAwareService.getFileOutputStream(authorSandboxWebppPath+"/myFile1"); - buff = (MYFILE1_MODIFIED).getBytes(); - out.write(buff); - out.close(); + + writer = assetService.getContentWriter(assetService.getAssetWebApp(authorSandboxId, webApp, "/myFile1")); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1_MODIFIED); final String MYFILE2_MODIFIED = "This is myFile2 ... modified by "+USER_TWO; - out = avmLockingAwareService.getFileOutputStream(authorSandboxWebppPath+"/myDir1/myFile2"); - buff = (MYFILE2_MODIFIED).getBytes(); - out.write(buff); - out.close(); + writer = assetService.getContentWriter(assetService.getAssetWebApp(authorSandboxId, webApp, "/myDir1/myFile2")); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2_MODIFIED); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(2, assets.size()); // check staging before - stagingSandboxWebppPath = stagingSandboxId + ":" + sbInfo.getSandboxRootPath() + "/" + webApp; + stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; - InputStream in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myFile1"); - buff = new byte[1024]; + ContentReader reader = assetService.getContentReader(assetService.getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myFile1", false)); + InputStream in = reader.getContentInputStream(); + byte[] buff = new byte[1024]; in.read(buff); in.close(); assertEquals(MYFILE1, new String(buff, 0, MYFILE1.length())); // assumes 1byte=1char - in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myDir1/myFile2"); + reader = assetService.getContentReader(assetService.getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myDir1/myFile2", false)); + in = reader.getContentInputStream(); buff = new byte[1024]; in.read(buff); in.close(); @@ -940,13 +945,15 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myFile1"); + reader = assetService.getContentReader(assetService.getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myFile1", false)); + in = reader.getContentInputStream(); buff = new byte[1024]; in.read(buff); in.close(); assertEquals(MYFILE1_MODIFIED, new String(buff, 0, MYFILE1_MODIFIED.length())); - in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myDir1/myFile2"); + reader = assetService.getContentReader(assetService.getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myDir1/myFile2", false)); + in = reader.getContentInputStream(); buff = new byte[1024]; in.read(buff); in.close(); @@ -973,32 +980,32 @@ public class SandboxServiceImplTest extends TestCase String authorSandboxId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(authorSandboxId, true); + List assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + String authorSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; final String MYFILE1 = "This is myFile1"; - OutputStream out = avmLockingAwareService.createFile(authorSandboxWebppPath, "myFile1"); - byte [] buff = MYFILE1.getBytes(); - out.write(buff); - out.close(); + ContentWriter writer = assetService.createFile(authorSandboxId, authorSandboxPath, "myFile1", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir1"); - avmLockingAwareService.createDirectory(authorSandboxWebppPath+"/myDir1", "myDir2"); + assetService.createFolder(authorSandboxId, authorSandboxPath, "myDir1", null); + assetService.createFolder(authorSandboxId, authorSandboxPath+"/myDir1", "myDir2", null); final String MYFILE2 = "This is myFile2"; - out = avmLockingAwareService.createFile(authorSandboxWebppPath+"/myDir1", "myFile2"); - buff = MYFILE2.getBytes(); - out.write(buff); - out.close(); + writer = assetService.createFile(authorSandboxId, authorSandboxPath+"/myDir1", "myFile2", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(2, assets.size()); // check staging before - String stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - assertEquals(0, avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false).size()); + String stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; + assertEquals(0, assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false).size()); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); @@ -1007,7 +1014,7 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - Map listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + List listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(2, listing.size()); // Switch to USER_TWO @@ -1020,10 +1027,11 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + //authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - avmLockingAwareService.removeNode(authorSandboxWebppPath+"/myFile1"); - avmLockingAwareService.removeNode(authorSandboxWebppPath+"/myDir1/myDir2"); + + assetService.deleteAsset(assetService.getAssetWebApp(authorSandboxId, webApp, "myFile1")); + assetService.deleteAsset(assetService.getAssetWebApp(authorSandboxId, webApp, "/myDir1/myDir2")); // do not list deleted assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); @@ -1034,12 +1042,12 @@ public class SandboxServiceImplTest extends TestCase assertEquals(2, assets.size()); // check staging before - stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + //stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - assertNotNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myFile1")); - assertNotNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myDir1")); - assertNotNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myDir1/myDir2")); - assertNotNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myDir1/myFile2")); + assertNotNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myFile1")); + assertNotNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myDir1")); + assertNotNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myDir1/myDir2")); + assertNotNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myDir1/myFile2")); // submit (deleted assets) ! sbService.submitWebApp(authorSandboxId, webApp, null, null); @@ -1048,11 +1056,11 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - assertNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myFile1")); - assertNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myDir1/myDir2")); + assertNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myFile1")); + assertNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myDir1/myDir2")); - assertNotNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myDir1")); - assertNotNull(avmLockingAwareService.lookup(-1, stagingSandboxWebppPath+"/myDir1/myFile2")); + assertNotNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myDir1")); + assertNotNull(assetService.getAssetWebApp(stagingSandboxId, webApp, "/myDir1/myFile2")); } // revert all (changed) assets in user sandbox @@ -1079,31 +1087,31 @@ public class SandboxServiceImplTest extends TestCase String authorSandboxId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(authorSandboxId, true); + List assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + String authorSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; final String MYFILE1 = "This is myFile1"; - OutputStream out = avmLockingAwareService.createFile(authorSandboxWebppPath, "myFile1"); - byte [] buff = MYFILE1.getBytes(); - out.write(buff); - out.close(); + ContentWriter writer = assetService.createFile(authorSandboxId, authorSandboxPath, "myFile1", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1); - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir1"); + assetService.createFolder(authorSandboxId, authorSandboxPath, "myDir1", null); final String MYFILE2 = "This is myFile2"; - out = avmLockingAwareService.createFile(authorSandboxWebppPath+"/myDir1", "myFile2"); - buff = MYFILE2.getBytes(); - out.write(buff); - out.close(); + writer = assetService.createFile(authorSandboxId, authorSandboxPath+"/myDir1", "myFile2", null); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(2, assets.size()); // check staging before - String stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - assertEquals(0, avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false).size()); + String stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; + assertEquals(0, assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false).size()); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); @@ -1112,7 +1120,7 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - Map listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + List listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(2, listing.size()); // Switch to USER_TWO @@ -1125,33 +1133,35 @@ public class SandboxServiceImplTest extends TestCase assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + //authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; final String MYFILE1_MODIFIED = "This is myFile1 ... modified by "+USER_TWO; - out = avmLockingAwareService.getFileOutputStream(authorSandboxWebppPath+"/myFile1"); - buff = (MYFILE1_MODIFIED).getBytes(); - out.write(buff); - out.close(); + writer = assetService.getContentWriter(assetService.getAssetWebApp(authorSandboxId, webApp, "/myFile1")); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE1_MODIFIED); final String MYFILE2_MODIFIED = "This is myFile2 ... modified by "+USER_TWO; - out = avmLockingAwareService.getFileOutputStream(authorSandboxWebppPath+"/myDir1/myFile2"); - buff = (MYFILE2_MODIFIED).getBytes(); - out.write(buff); - out.close(); + writer = assetService.getContentWriter(assetService.getAssetWebApp(authorSandboxId, webApp, "/myDir1/myFile2")); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.setEncoding("UTF-8"); + writer.putContent(MYFILE2_MODIFIED); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(2, assets.size()); // check staging before - stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; - InputStream in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myFile1"); - buff = new byte[1024]; + ContentReader reader = assetService.getContentReader(assetService. getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myFile1", false)); + InputStream in = reader.getContentInputStream(); + byte[] buff = new byte[1024]; in.read(buff); in.close(); assertEquals(MYFILE1, new String(buff, 0, MYFILE1.length())); // assumes 1byte = 1char - in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myDir1/myFile2"); + reader = assetService.getContentReader(assetService. getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myDir1/myFile2", false)); + in = reader.getContentInputStream(); buff = new byte[1024]; in.read(buff); in.close(); @@ -1164,13 +1174,15 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myFile1"); + reader = assetService.getContentReader(assetService.getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myFile1", false)); + in = reader.getContentInputStream(); buff = new byte[1024]; in.read(buff); in.close(); assertEquals(MYFILE1, new String(buff, 0, MYFILE1.length())); - in = avmLockingAwareService.getFileInputStream(-1, stagingSandboxWebppPath+"/myDir1/myFile2"); + reader = assetService.getContentReader(assetService.getAsset(stagingSandboxId, -1, stagingSandboxPath+"/myDir1/myFile2", false)); + in = reader.getContentInputStream(); buff = new byte[1024]; in.read(buff); in.close(); @@ -1197,21 +1209,19 @@ public class SandboxServiceImplTest extends TestCase String authorSandboxId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(authorSandboxId, true); + List assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir1"); - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir2"); - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir3"); + assetService.createFolderWebApp(authorSandboxId, webApp, "/", "myDir1"); + assetService.createFolderWebApp(authorSandboxId, webApp, "/", "myDir2"); + assetService.createFolderWebApp(authorSandboxId, webApp, "/", "myDir3"); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(3, assets.size()); // check staging before - String stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - assertEquals(0, avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false).size()); + String stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; + assertEquals(0, assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false).size()); List sbVersions = sbService.listSnapshots(stagingSandboxId, fromDate, new Date(), false); assertEquals(0, sbVersions.size()); @@ -1223,20 +1233,20 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - Map listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + List listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(3, listing.size()); sbVersions = sbService.listSnapshots(stagingSandboxId, fromDate, new Date(), false); assertEquals(1, sbVersions.size()); // more changes ... - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir4"); + assetService.createFolderWebApp(authorSandboxId, webApp, "/", "myDir4"); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); // check staging after - listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(4, listing.size()); sbVersions = sbService.listSnapshots(stagingSandboxId, fromDate, new Date(), false); @@ -1267,19 +1277,19 @@ public class SandboxServiceImplTest extends TestCase String authorSandboxId = sbInfo.getSandboxId(); // no changes yet - List assets = sbService.listChangedAll(authorSandboxId, true); + List assets = sbService.listChangedAll(authorSandboxId, true); assertEquals(0, assets.size()); - String authorSandboxWebppPath = authorSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; + String authorSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir1"); + assetService.createFolder(authorSandboxId, authorSandboxPath, "myDir1", null); assets = sbService.listChangedWebApp(authorSandboxId, webApp, false); assertEquals(1, assets.size()); // check staging before - String stagingSandboxWebppPath = stagingSandboxId + AVM_STORE_SEPARATOR + sbInfo.getSandboxRootPath() + "/" + webApp; - assertEquals(0, avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false).size()); + String stagingSandboxPath = sbInfo.getSandboxRootPath() + "/" + webApp; + assertEquals(0, assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false).size()); List sbVersions = sbService.listSnapshots(stagingSandboxId, fromDate, new Date(), false); assertEquals(0, sbVersions.size()); @@ -1291,11 +1301,11 @@ public class SandboxServiceImplTest extends TestCase assertEquals(0, assets.size()); // check staging after - Map listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + List listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(1, listing.size()); - for (AVMNodeDescriptor asset : listing.values()) + for (AssetInfo asset : listing) { - if (asset.getName().equals("myDir1") && asset.isDirectory()) + if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } @@ -1309,21 +1319,21 @@ public class SandboxServiceImplTest extends TestCase assertEquals(1, sbVersions.size()); // more changes ... - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir2"); + assetService.createFolder(authorSandboxId, authorSandboxPath, "myDir2", null); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); // check staging after - listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(2, listing.size()); - for (AVMNodeDescriptor asset : listing.values()) + for (AssetInfo asset : listing) { - if (asset.getName().equals("myDir1") && asset.isDirectory()) + if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } - else if (asset.getName().equals("myDir2") && asset.isDirectory()) + else if (asset.getName().equals("myDir2") && asset.isFolder()) { continue; } @@ -1337,25 +1347,25 @@ public class SandboxServiceImplTest extends TestCase assertEquals(2, sbVersions.size()); // more changes ... - avmLockingAwareService.createDirectory(authorSandboxWebppPath, "myDir3"); + assetService.createFolderWebApp(authorSandboxId, webApp, "/", "myDir3"); // submit (new assets) ! sbService.submitWebApp(authorSandboxId, webApp, "a submit label", "a submit comment"); // check staging after - listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(3, listing.size()); - for (AVMNodeDescriptor asset : listing.values()) + for (AssetInfo asset : listing) { - if (asset.getName().equals("myDir1") && asset.isDirectory()) + if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } - else if (asset.getName().equals("myDir2") && asset.isDirectory()) + else if (asset.getName().equals("myDir2") && asset.isFolder()) { continue; } - else if (asset.getName().equals("myDir3") && asset.isDirectory()) + else if (asset.getName().equals("myDir3") && asset.isFolder()) { continue; } @@ -1379,15 +1389,15 @@ public class SandboxServiceImplTest extends TestCase assertEquals(4, sbVersions.size()); // check staging after - listing = avmLockingAwareService.getDirectoryListing(-1, stagingSandboxWebppPath, false); + listing = assetService.listAssets(stagingSandboxId, -1, stagingSandboxPath, false); assertEquals(2, listing.size()); - for (AVMNodeDescriptor asset : listing.values()) + for (AssetInfo asset : listing) { - if (asset.getName().equals("myDir1") && asset.isDirectory()) + if (asset.getName().equals("myDir1") && asset.isFolder()) { continue; } - else if (asset.getName().equals("myDir2") && asset.isDirectory()) + else if (asset.getName().equals("myDir2") && asset.isFolder()) { continue; } diff --git a/source/java/org/alfresco/wcm/sandbox/script/Asset.java b/source/java/org/alfresco/wcm/sandbox/script/Asset.java index e93453c053..f3e1b68a17 100644 --- a/source/java/org/alfresco/wcm/sandbox/script/Asset.java +++ b/source/java/org/alfresco/wcm/sandbox/script/Asset.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2008 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 @@ -28,8 +28,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.util.ISO8601DateFormat; +import org.alfresco.wcm.asset.AssetInfo; import org.alfresco.wcm.sandbox.SandboxService; /** @@ -39,13 +39,13 @@ import org.alfresco.wcm.sandbox.SandboxService; */ public class Asset { - private AVMNodeDescriptor desc; + private AssetInfo asset; private Sandbox sandbox; - public Asset(Sandbox sandbox, AVMNodeDescriptor desc) + public Asset(Sandbox sandbox, AssetInfo asset) { this.sandbox = sandbox; - this.desc = desc; + this.asset = asset; } /** @@ -54,12 +54,12 @@ public class Asset */ public String getCreator() { - return desc.getCreator(); + return asset.getCreator(); } public Date getCreatedDate() { - return new Date(desc.getCreateDate()); + return asset.getCreatedDate(); } public String getCreatedDateAsISO8601() @@ -69,12 +69,12 @@ public class Asset public String getModifier() { - return desc.getLastModifier(); + return asset.getModifier(); } public Date getModifiedDate() { - return new Date(desc.getModDate()); + return asset.getModifiedDate(); } public String getModifiedDateAsISO8601() @@ -82,14 +82,16 @@ public class Asset return ISO8601DateFormat.format(getModifiedDate()); } + /* public String getAssetRef() { - return desc.getGuid(); + return asset.getGuid(); } + */ public String getName() { - return desc.getName(); + return asset.getName(); } /** @@ -98,39 +100,35 @@ public class Asset */ public String getPath() { - String path = desc.getPath(); - - if (path != null) - { - String[] splits = path.split(":"); - return splits[1]; - } - else - { - return path; - } + return asset.getPath(); } public boolean isFile() { - return desc.isFile(); + return asset.isFile(); } public boolean isDirectory() { - return desc.isDirectory(); + return asset.isFolder(); } public boolean isDeleted() { - return desc.isDeleted(); + return asset.isDeleted(); } - + public boolean isLocked() + { + return asset.isLocked(); + } + + /* TODO review public int getVersion() { - return desc.getVersionID(); + return asset.getVersion(); } + */ /** * Submit this asset to staging diff --git a/source/java/org/alfresco/wcm/sandbox/script/Sandbox.java b/source/java/org/alfresco/wcm/sandbox/script/Sandbox.java index ef3642e7d4..c27b402bc0 100644 --- a/source/java/org/alfresco/wcm/sandbox/script/Sandbox.java +++ b/source/java/org/alfresco/wcm/sandbox/script/Sandbox.java @@ -31,6 +31,8 @@ import java.util.List; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.util.ISO8601DateFormat; +import org.alfresco.wcm.asset.AssetInfo; +import org.alfresco.wcm.asset.AssetService; import org.alfresco.wcm.sandbox.SandboxInfo; import org.alfresco.wcm.sandbox.SandboxConstants; import org.alfresco.wcm.sandbox.SandboxService; @@ -138,6 +140,7 @@ public class Sandbox implements Serializable getSandboxService().submitList(getSandboxRef(), items, submitLabel, submitComment); } + /** * Submit the specified files and directories modified contents of this sandbox */ @@ -260,28 +263,55 @@ public class Sandbox implements Serializable */ public Asset[] getModifiedAssets() { - List items = getSandboxService().listChangedAll(getSandboxRef(), true); + List items = getSandboxService().listChangedAll(getSandboxRef(), true); Asset[] ret = new Asset[items.size()]; int i = 0; - for(AVMNodeDescriptor item : items) + for(AssetInfo item : items) { ret[i++] = new Asset(this, item); } return ret; } + /** + * Get the specified asset (Either folder or file) + * @param path the full path e.g. /www/web_apps/ROOT/index.html + * @return the asset + */ + public Asset getAsset(String path) + { + AssetService as = getAssetService(); + AssetInfo item = as.getAsset(getSandboxRef(), path); + Asset newAsset = new Asset(this, item); + return newAsset; + } + + /** + * Get the specified asset with a path relative to the specified web app. + * @param path e.g. index.html + * @param webApp e.g. ROOT + * @return the asset + */ + public Asset getAssetWebApp(String webApp, String path) + { + AssetService as = getAssetService(); + AssetInfo item = as.getAssetWebApp(getSandboxRef(), webApp, path); + Asset newAsset = new Asset(this, item); + return newAsset; + } + /** * Get the modified assets within this sandbox * @return the list of changed assets */ public Asset[] getModifiedAssetsWebApp(String webApp) { - List items = getSandboxService().listChangedWebApp(getSandboxRef(), webApp, true); + List items = getSandboxService().listChangedWebApp(getSandboxRef(), webApp, true); Asset[] ret = new Asset[items.size()]; int i = 0; - for(AVMNodeDescriptor item : items) + for(AssetInfo item : items) { ret[i++] = new Asset(this, item); } @@ -305,4 +335,13 @@ public class Sandbox implements Serializable { return webproject.getWebProjects().getSandboxService(); } + + /** + * Get the asset service + * @return the asset service + */ + private AssetService getAssetService() + { + return webproject.getWebProjects().getAssetService(); + } } diff --git a/source/java/org/alfresco/wcm/util/WCMUtil.java b/source/java/org/alfresco/wcm/util/WCMUtil.java index 7ff0aee148..44ca9e465a 100644 --- a/source/java/org/alfresco/wcm/util/WCMUtil.java +++ b/source/java/org/alfresco/wcm/util/WCMUtil.java @@ -35,6 +35,7 @@ import org.alfresco.config.JNDIConstants; import org.alfresco.mbeans.VirtServerRegistry; import org.alfresco.model.WCMAppModel; import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.service.cmr.avm.AVMBadArgumentException; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -63,7 +64,7 @@ public class WCMUtil * * @return the sandbox store id */ - protected static String getSandboxStoreId(final String avmPath) + public static String getSandboxStoreId(final String avmPath) { final int i = avmPath.indexOf(AVM_STORE_SEPARATOR); if (i == -1) @@ -85,7 +86,7 @@ public class WCMUtil * * @return the web project store id */ - protected static String getWebProjectStoreId(final String storeName) + public static String getWebProjectStoreId(final String storeName) { final int index = storeName.indexOf(WCMUtil.STORE_SEPARATOR); return (index == -1 @@ -102,7 +103,7 @@ public class WCMUtil * * @return the web project store id. */ - protected static String getWebProjectStoreIdFromPath(final String avmPath) + public static String getWebProjectStoreIdFromPath(final String avmPath) { return getWebProjectStoreId(getSandboxStoreId(avmPath)); } @@ -143,7 +144,7 @@ public class WCMUtil * * @return true if the store is a user store, false otherwise. */ - protected static boolean isUserStore(String storeName) + public static boolean isUserStore(String storeName) { if (WCMUtil.isPreviewStore(storeName)) { @@ -159,7 +160,7 @@ public class WCMUtil * * @return true if the store is a main store, false otherwise. */ - protected static boolean isStagingStore(String storeName) + public static boolean isStagingStore(String storeName) { return ((storeName != null) && (storeName.indexOf(WCMUtil.STORE_SEPARATOR) == -1)); } @@ -397,7 +398,7 @@ public class WCMUtil * * @return root sandbox path for the specified store name */ - protected static String buildSandboxRootPath(final String storeName) + public static String buildSandboxRootPath(final String storeName) { ParameterCheck.mandatoryString("storeName", storeName); return storeName + AVM_STORE_SEPARATOR + JNDIConstants.DIR_DEFAULT_WWW_APPBASE; @@ -411,7 +412,7 @@ public class WCMUtil * * @return the root webapp path for the specified store and webapp name */ - protected static String buildStoreWebappPath(final String storeName, String webApp) + public static String buildStoreWebappPath(final String storeName, String webApp) { ParameterCheck.mandatoryString("webApp", webApp); return WCMUtil.buildSandboxRootPath(storeName) + '/' + webApp; @@ -522,7 +523,7 @@ public class WCMUtil * @param absoluteAVMPath an absolute path within the avm * @return the path without the store prefix. */ - protected static String getStoreRelativePath(final String absoluteAVMPath) + public static String getStoreRelativePath(final String absoluteAVMPath) { ParameterCheck.mandatoryString("absoluteAVMPath", absoluteAVMPath); return absoluteAVMPath.substring(absoluteAVMPath.indexOf(AVM_STORE_SEPARATOR) + 1); @@ -654,7 +655,7 @@ public class WCMUtil * @param path Path to match against * @param force True to force update of server even if path does not match */ - protected static void updateVServerWebapp(VirtServerRegistry vServerRegistry, String path, boolean force) + public static void updateVServerWebapp(VirtServerRegistry vServerRegistry, String path, boolean force) { if (force || VirtServerUtils.requiresUpdateNotification(path)) { @@ -714,18 +715,20 @@ public class WCMUtil } } - protected static String getWebProjectsPath() + public static String[] splitPath(String path) { - return "/"+SPACES_COMPANY_HOME_CHILDNAME+"/"+SPACES_WCM_CHILDNAME; + String[] storePath = path.split(AVM_STORE_SEPARATOR); + if (storePath.length != 2) + { + throw new AVMBadArgumentException("Invalid Path: " + path); + } + return storePath; } - private static final String SPACES_COMPANY_HOME_CHILDNAME = "app:company_home"; // should match repository property: spaces.company_home.childname - private static final String SPACES_WCM_CHILDNAME = "app:wcm"; // should match repository property: spaces.wcm.childname - // Component Separator. protected static final String STORE_SEPARATOR = "--"; - protected static final char AVM_STORE_SEPARATOR = ':'; + public static final String AVM_STORE_SEPARATOR = ":"; // names of the stores representing the layers for an AVM website //XXXarielb this should be private diff --git a/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java b/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java index dbe1dac551..a2b05014e4 100644 --- a/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java +++ b/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java @@ -53,8 +53,8 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthorityService; @@ -173,12 +173,12 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService if (wpStoreId.indexOf(WCMUtil.STORE_SEPARATOR) != -1) { - throw new AlfrescoRuntimeException("Unexpected store id '"+wpStoreId+"' - should not contain '"+WCMUtil.STORE_SEPARATOR+"'"); + throw new IllegalArgumentException("Unexpected store id '"+wpStoreId+"' - should not contain '"+WCMUtil.STORE_SEPARATOR+"'"); } - if (wpStoreId.indexOf(":") != -1) + if (wpStoreId.indexOf(WCMUtil.AVM_STORE_SEPARATOR) != -1) { - throw new AlfrescoRuntimeException("Unexpected store id '"+wpStoreId+"' - should not contain ':'"); + throw new IllegalArgumentException("Unexpected store id '"+wpStoreId+"' - should not contain '"+WCMUtil.AVM_STORE_SEPARATOR+"'"); } // create the website space in the correct parent folder @@ -409,7 +409,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService ResultSet resultSet = null; try { - resultSet = this.searchService.query(WEBPROJECT_STORE, SearchService.LANGUAGE_LUCENE, "PATH:\""+WCMUtil.getWebProjectsPath()+"\""); + resultSet = this.searchService.query(WEBPROJECT_STORE, SearchService.LANGUAGE_LUCENE, "PATH:\""+getWebProjectsPath()+"\""); if (resultSet.length() == 0) { // No root web projects folder exists @@ -874,16 +874,16 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService if (wpStoreId.indexOf(WCMUtil.STORE_SEPARATOR) != -1) { - throw new AlfrescoRuntimeException("Unexpected web project store id '"+wpStoreId+"' - should not contain '"+WCMUtil.STORE_SEPARATOR+"'"); + throw new IllegalArgumentException("Unexpected web project store id '"+wpStoreId+"' - should not contain '"+WCMUtil.STORE_SEPARATOR+"'"); } if (wpStoreId.indexOf(":") != -1) { - throw new AlfrescoRuntimeException("Unexpected web project store id '"+wpStoreId+"' - should not contain ':'"); + throw new IllegalArgumentException("Unexpected web project store id '"+wpStoreId+"' - should not contain ':'"); } // construct the query - String path = WCMUtil.getWebProjectsPath() + "/*"; + String path = getWebProjectsPath() + "/*"; String query = "PATH:\"/" + path + "\" AND @wca\\:avmstore:\"" + wpStoreId + "\""; NodeRef webProjectNode = null; @@ -1297,6 +1297,15 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService return users; } + private String getWebProjectsPath() + { + return "/"+SPACES_COMPANY_HOME_CHILDNAME+"/"+SPACES_WCM_CHILDNAME; + } + + private static final String SPACES_COMPANY_HOME_CHILDNAME = "app:company_home"; // should match repository property: spaces.company_home.childname + private static final String SPACES_WCM_CHILDNAME = "app:wcm"; // should match repository property: spaces.wcm.childname + + /** * Transaction listener - invoked after commit */ diff --git a/source/java/org/alfresco/wcm/webproject/WebProjectServiceImplTest.java b/source/java/org/alfresco/wcm/webproject/WebProjectServiceImplTest.java index 6705b0f107..7786d2ca34 100644 --- a/source/java/org/alfresco/wcm/webproject/WebProjectServiceImplTest.java +++ b/source/java/org/alfresco/wcm/webproject/WebProjectServiceImplTest.java @@ -295,7 +295,7 @@ public class WebProjectServiceImplTest extends TestCase wpInfo = wpService.createWebProject(dnsName, name, TEST_TITLE, TEST_DESCRIPTION, TEST_DEFAULT_WEBAPP, TEST_USE_AS_TEMPLATE, null); fail("Shouldn't be able to create web project with '--'"); } - catch (AlfrescoRuntimeException exception) + catch (IllegalArgumentException exception) { // Expected } @@ -309,7 +309,7 @@ public class WebProjectServiceImplTest extends TestCase wpInfo = wpService.createWebProject(dnsName, name, TEST_TITLE, TEST_DESCRIPTION, TEST_DEFAULT_WEBAPP, TEST_USE_AS_TEMPLATE, null); fail("Shouldn't be able to create web project with '--'"); } - catch (AlfrescoRuntimeException exception) + catch (IllegalArgumentException exception) { // Expected } diff --git a/source/java/org/alfresco/wcm/webproject/script/WebProjects.java b/source/java/org/alfresco/wcm/webproject/script/WebProjects.java index 09674f6fb5..e2736579c3 100644 --- a/source/java/org/alfresco/wcm/webproject/script/WebProjects.java +++ b/source/java/org/alfresco/wcm/webproject/script/WebProjects.java @@ -30,6 +30,7 @@ import org.alfresco.repo.jscript.BaseScopableProcessorExtension; import org.alfresco.repo.model.Repository; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.wcm.asset.AssetService; import org.alfresco.wcm.sandbox.SandboxService; import org.alfresco.wcm.webproject.WebProjectInfo; import org.alfresco.wcm.webproject.WebProjectService; @@ -51,6 +52,9 @@ public class WebProjects extends BaseScopableProcessorExtension /** The sandbox service */ private SandboxService sandboxService; + /** The asset service */ + private AssetService assetService; + /** * Sets the Service Registry * @@ -91,6 +95,21 @@ public class WebProjects extends BaseScopableProcessorExtension return this.sandboxService; } + /** + * Set the wcm asset service + * + * @param assetService the wcm asset service + */ + public void setAssetService(AssetService assetService) + { + this.assetService = assetService; + } + + public AssetService getAssetService() + { + return this.assetService; + } + /** * create web project * @param name