diff --git a/config/alfresco/web-client-config-workflow-actions.xml b/config/alfresco/web-client-config-workflow-actions.xml index 9e2b743244..fba4dd9352 100644 --- a/config/alfresco/web-client-config-workflow-actions.xml +++ b/config/alfresco/web-client-config-workflow-actions.xml @@ -162,6 +162,10 @@ + + + + @@ -174,10 +178,24 @@ + + + + + + + + + + + + + + @@ -191,6 +209,16 @@ + + + + + + + + + + diff --git a/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java b/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java index 007bc3da1c..82340670df 100644 --- a/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java @@ -18,12 +18,14 @@ package org.alfresco.web.action.evaluator; import javax.faces.context.FacesContext; +import org.alfresco.util.Pair; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.wf.AVMSubmittedAspect; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.web.action.ActionEvaluator; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.wcm.AVMConstants; /** * UI Action Evaluator - return true if the node is not part of an in-progress WCM workflow. @@ -35,10 +37,14 @@ public class WCMWorkflowEvaluator implements ActionEvaluator /** * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) */ - public boolean evaluate(Node node) + public boolean evaluate(final Node node) { - AVMService avm = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService(); - String path = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()).getSecond(); - return !avm.hasAspect(-1, path, AVMSubmittedAspect.ASPECT); + final FacesContext facesContext = FacesContext.getCurrentInstance(); + final AVMService avmService = + Repository.getServiceRegistry(facesContext).getAVMService(); + final Pair p = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()); + final String path = p.getSecond(); + return (!avmService.hasAspect(p.getFirst(), path, AVMSubmittedAspect.ASPECT) || + AVMConstants.isWorkflowStore(AVMConstants.getStoreName(path))); } } diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 354ca3d2ac..f3d6361b61 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -241,7 +241,7 @@ public class AVMBrowseBean implements IContextListener { // count user stores int users = avmService.queryStoresPropertyKeys(QName.createQName(null, - AVMConstants.PROP_SANDBOX_STORE_PREFIX + storeRoot + "-%" + AVMConstants.STORE_MAIN)).size(); + AVMConstants.PROP_SANDBOX_STORE_PREFIX + storeRoot + "-%")).size() / 2; summary.append(msg.getString(MSG_CREATED_ON)).append(": ") .append(Utils.getDateFormat(fc).format(new Date(store.getCreateDate()))) .append("

"); @@ -263,7 +263,7 @@ public class AVMBrowseBean implements IContextListener public String getStagingStore() { String storeRoot = (String)getWebsite().getProperties().get(WCMAppModel.PROP_AVMSTORE); - return AVMConstants.buildAVMStagingStoreName(storeRoot); + return AVMConstants.buildStagingStoreName(storeRoot); } /** @@ -271,7 +271,7 @@ public class AVMBrowseBean implements IContextListener */ public String getStagingPreviewUrl() { - return AVMConstants.buildAVMWebappUrl(getStagingStore(), getWebapp()); + return AVMConstants.buildWebappUrl(getStagingStore(), getWebapp()); } /** @@ -279,7 +279,7 @@ public class AVMBrowseBean implements IContextListener */ public String getSandboxPreviewUrl() { - return AVMConstants.buildAVMWebappUrl(getSandbox(), getWebapp()); + return AVMConstants.buildWebappUrl(getSandbox(), getWebapp()); } /** @@ -387,7 +387,7 @@ public class AVMBrowseBean implements IContextListener */ public List getWebapps() { - String path = AVMConstants.buildAVMStoreRootPath(getStagingStore()); + String path = AVMConstants.buildSandboxRootPath(getStagingStore()); Map folders = this.avmService.getDirectoryListing(-1, path); List webapps = new ArrayList(folders.size()); for (AVMNodeDescriptor node : folders.values()) @@ -496,7 +496,7 @@ public class AVMBrowseBean implements IContextListener { if (this.currentPath == null) { - this.currentPath = AVMConstants.buildAVMStoreWebappPath(getSandbox(), getWebapp()); + this.currentPath = AVMConstants.buildStoreWebappPath(getSandbox(), getWebapp()); } return this.currentPath; } @@ -623,7 +623,7 @@ public class AVMBrowseBean implements IContextListener tx.begin(); String dns = AVMConstants.lookupStoreDNS(getSandbox()); - int rootPathIndex = AVMConstants.buildAVMStoreRootPath(getSandbox()).length(); + int rootPathIndex = AVMConstants.buildSandboxRootPath(getSandbox()).length(); Map nodes = this.avmService.getDirectoryListing(-1, getCurrentPath()); this.files = new ArrayList(nodes.size()); @@ -655,7 +655,7 @@ public class AVMBrowseBean implements IContextListener // common properties String assetPath = path.substring(rootPathIndex); - String previewUrl = AVMConstants.buildAVMAssetUrl(assetPath, wcmDomain, wcmPort, dns); + String previewUrl = AVMConstants.buildAssetUrl(assetPath, wcmDomain, wcmPort, dns); node.getProperties().put("previewUrl", previewUrl); } @@ -747,7 +747,7 @@ public class AVMBrowseBean implements IContextListener else { // get the staging store from the current website node - setSandbox(AVMConstants.buildAVMStagingStoreName( + setSandbox(AVMConstants.buildStagingStoreName( (String)getWebsite().getProperties().get(WCMAppModel.PROP_AVMSTORE))); } @@ -777,33 +777,39 @@ public class AVMBrowseBean implements IContextListener setupContentAction(path, true); } - /*package*/ void setupContentAction(String path, boolean refresh) + /*package*/ void setupContentAction(final String path, final boolean refresh) { - if (path != null && path.length() != 0) + if (logger.isDebugEnabled()) + logger.debug("Setup content action for path: " + path); + + if (path == null && path.length() == 0) { - if (logger.isDebugEnabled()) - logger.debug("Setup content action for path: " + path); - - // calculate username and store name from specified path - String[] parts = path.split("[-:]"); - String storename = parts[0]; - String username = parts[2]; - if (username.equals(AVMConstants.STORE_STAGING.substring(1))) - { - setupSandboxActionImpl(null, null, false); - } - else - { - setupSandboxActionImpl(AVMConstants.buildAVMUserMainStoreName(storename, username), username, false); - } - - // setup the action node - AVMNodeDescriptor node = avmService.lookup(-1, path, true); - setAVMActionNodeDescriptor(node); + setAvmActionNode(null); } else { - setAvmActionNode(null); + // calculate username and store name from specified path + String storeName = AVMConstants.getStoreName(path); + final String storeId = AVMConstants.getStoreId(storeName); + final String username = AVMConstants.getUserName(storeName); + final boolean preview = AVMConstants.isPreviewStore(storeName); + if (username == null) + { + storeName = (preview + ? AVMConstants.buildStagingPreviewStoreName(storeId) + : AVMConstants.buildStagingStoreName(storeId)); + setupSandboxActionImpl(storeName, null, false); + } + else + { + storeName = (preview + ? AVMConstants.buildUserPreviewStoreName(storeId, username) + : AVMConstants.buildUserMainStoreName(storeId, username)); + setupSandboxActionImpl(storeName, username, false); + } + + // setup the action node + setAVMActionNodeDescriptor(avmService.lookup(-1, path, true)); } // update UI state ready for return after dialog close @@ -1028,7 +1034,7 @@ public class AVMBrowseBean implements IContextListener @Override public String toString() { - if (AVMConstants.buildAVMStoreRootPath(getSandbox()).equals(path)) + if (AVMConstants.buildSandboxRootPath(getSandbox()).equals(path)) { // don't display the 'root' webapps path as this will confuse users // instead display which sandbox we are in diff --git a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java index ceccd7e045..1619a7fccf 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java @@ -25,12 +25,14 @@ import javax.faces.context.FacesContext; import org.alfresco.mbeans.VirtServerRegistry; import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ParameterCheck; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.config.ClientConfigElement; +import org.springframework.web.context.WebApplicationContext; import org.springframework.web.jsf.FacesContextUtils; /** @@ -70,74 +72,235 @@ public final class AVMConstants private AVMConstants() { } - - public static String buildAVMStagingStoreName(String store) + + /** + * Extracts the store name from the avmpath + * + * @param avmPath an absolute avm pth + * @return the store name + */ + public static String getStoreName(final String avmPath) { - if (store == null || store.length() == 0) + final int i = avmPath.indexOf(':'); + if (i == -1) { - throw new IllegalArgumentException("Store name is mandatory."); + throw new IllegalArgumentException("path " + avmPath + " does not contain a store"); } - return store + AVMConstants.STORE_STAGING; + return avmPath.substring(0, i); + } + + /** + * Indicates whether the store name describes a preview store. + * + * @param storeName the store name + * @return true if the store is a preview store, false otherwise. + */ + public static boolean isPreviewStore(final String storeName) + { + return storeName.endsWith(AVMConstants.STORE_SEPARATOR + AVMConstants.STORE_PREVIEW); + } + + public static boolean isWorkflowStore(String storeName) + { + if (AVMConstants.isPreviewStore(storeName)) + { + storeName = AVMConstants.getCorrespondingMainStoreName(storeName); + } + + return storeName.indexOf(STORE_SEPARATOR + STORE_WORKFLOW) != -1; + } + + /** + * Indicates whether the store name describes a user store. + * + * @param storeName the store name + * @return true if the store is a user store, false otherwise. + */ + public static boolean isUserStore(String storeName) + { + if (AVMConstants.isPreviewStore(storeName)) + { + storeName = AVMConstants.getCorrespondingMainStoreName(storeName); + } + return storeName.indexOf(AVMConstants.STORE_SEPARATOR) != -1; + } + + /** + * Extracts the username from the store name. + * + * @param storeName the store name + * @return the username associated or null if this is a staging store. + */ + public static String getUserName(String storeName) + { + if (AVMConstants.isPreviewStore(storeName)) + { + storeName = AVMConstants.getCorrespondingMainStoreName(storeName); + } + final int index = storeName.indexOf(AVMConstants.STORE_SEPARATOR); + return (index == -1 + ? null + : storeName.substring(index + AVMConstants.STORE_SEPARATOR.length())); + } + + /** + * Extracts the store id from the store name. + * + * @param storeName the store name. + * @return the store id. + */ + public static String getStoreId(final String storeName) + { + final int index = storeName.indexOf(AVMConstants.STORE_SEPARATOR); + return (index == -1 + ? storeName + : storeName.substring(0, index)); + } + + /** + * Returns the corresponding main store name if this is a preview store name. + * + * @param storeName the preview store name. + * @return the corresponding main store name. + * @exception IllegalArgumentException if this is not a preview store name. + */ + public static String getCorrespondingMainStoreName(final String storeName) + { + if (!AVMConstants.isPreviewStore(storeName)) + { + throw new IllegalArgumentException("store " + storeName + " is not a preview store"); + } + return storeName.substring(0, + (storeName.length() - + (AVMConstants.STORE_SEPARATOR + AVMConstants.STORE_PREVIEW).length())); + } + + /** + * Returns the corresponding preview store name if this is a main store name. + * + * @param storeName the main store name. + * @return the corresponding preview store name. + * @exception IllegalArgumentException if this is not a main store name. + */ + public static String getCorrespondingPreviewStoreName(final String storeName) + { + if (AVMConstants.isPreviewStore(storeName)) + { + throw new IllegalArgumentException("store " + storeName + " is already a preview store"); + } + return storeName + AVMConstants.STORE_SEPARATOR + AVMConstants.STORE_PREVIEW; + } + + /** + * Returns the corresponding path in the preview store name if this is a path in + * a main store. + * + * @param avmPath an avm path within the main store. + * @return the corresponding path within the preview store. + * @exception IllegalArgumentException if this is not a path within the preview store. + */ + public static String getCorrespondingPathInMainStore(final String avmPath) + { + String storeName = AVMConstants.getStoreName(avmPath); + storeName = AVMConstants.getCorrespondingMainStoreName(storeName); + return AVMConstants.getCorrespondingPath(avmPath, storeName); + } + + /** + * Returns the corresponding path in the preview store name if this is a path in + * a main store. + * + * @param avmPath an avm path within the main store. + * @return the corresponding path within the preview store. + * @exception IllegalArgumentException if this is not a path within the preview store. + */ + public static String getCorrespondingPathInPreviewStore(final String avmPath) + { + String storeName = AVMConstants.getStoreName(avmPath); + storeName = AVMConstants.getCorrespondingPreviewStoreName(storeName); + return AVMConstants.getCorrespondingPath(avmPath, storeName); + } + + public static String getCorrespondingPath(final String avmPath, final String otherStore) + { + return (otherStore + ':' + AVMConstants.getStoreRelativePath(avmPath)); } - public static String buildAVMStagingPreviewStoreName(String store) + public static String buildStagingStoreName(final String storeId) { - if (store == null || store.length() == 0) + if (storeId == null || storeId.length() == 0) { - throw new IllegalArgumentException("Store name is mandatory."); + throw new IllegalArgumentException("Store id is mandatory."); } - return store + AVMConstants.STORE_PREVIEW; + return storeId; } - public static String buildAVMUserMainStoreName(String store, String username) + public static String buildStagingPreviewStoreName(final String storeId) + { + return (AVMConstants.buildStagingStoreName(storeId) + + AVMConstants.STORE_SEPARATOR + AVMConstants.STORE_PREVIEW); + } + + public static String buildUserMainStoreName(final String storeId, + final String username) { - if (store == null || store.length() == 0) - { - throw new IllegalArgumentException("Store name is mandatory."); - } if (username == null || username.length() == 0) { throw new IllegalArgumentException("Username is mandatory."); } - return store + STORE_SEPARATOR + username + AVMConstants.STORE_MAIN; + return (AVMConstants.buildStagingStoreName(storeId) + AVMConstants.STORE_SEPARATOR + + username); } - public static String buildAVMUserPreviewStoreName(String store, String username) + public static String buildUserPreviewStoreName(final String storeId, + final String username) { - if (store == null || store.length() == 0) + return (AVMConstants.buildUserMainStoreName(storeId, username) + + AVMConstants.STORE_SEPARATOR + AVMConstants.STORE_PREVIEW); + } + + public static String buildWorkflowMainStoreName(final String storeId, + final String workflowId) + { + if (workflowId == null || workflowId.length() == 0) + { + throw new IllegalArgumentException("workflowId is mandatory."); + } + return (AVMConstants.buildStagingStoreName(storeId) + AVMConstants.STORE_SEPARATOR + + workflowId); + } + + public static String buildWorkflowPreviewStoreName(final String storeId, + final String workflowId) + { + return (AVMConstants.buildWorkflowMainStoreName(storeId, workflowId) + + AVMConstants.STORE_SEPARATOR + AVMConstants.STORE_PREVIEW); + } + + public static String buildStoreRootPath(final String storeName) + { + if (storeName == null || storeName.length() == 0) { throw new IllegalArgumentException("Store name is mandatory."); } - if (username == null || username.length() == 0) - { - throw new IllegalArgumentException("Username is mandatory."); - } - return store + STORE_SEPARATOR + username + AVMConstants.STORE_PREVIEW; + return storeName + ":/" + DIR_APPBASE; + } + + public static String buildSandboxRootPath(final String storeName) + { + return AVMConstants.buildStoreRootPath(storeName) + '/' + DIR_WEBAPPS; } - public static String buildAVMStoreRootPath(String store) + public static String buildStoreWebappPath(final String storeName, String webapp) { - if (store == null || store.length() == 0) - { - throw new IllegalArgumentException("Store name is mandatory."); - } - return store + ":/" + DIR_APPBASE + '/' + DIR_WEBAPPS; - } - - public static String buildAVMStoreWebappPath(String store, String webapp) - { - if (store == null || store.length() == 0) - { - throw new IllegalArgumentException("Store name is mandatory."); - } if (webapp == null || webapp.length() == 0) { throw new IllegalArgumentException("Webapp name is mandatory."); } - return store + ":/" + DIR_APPBASE + '/' + DIR_WEBAPPS + '/' + webapp; + return AVMConstants.buildSandboxRootPath(storeName) + '/' + webapp; } - public static String buildAVMStoreUrl(String store) + public static String buildStoreUrl(String store) { if (store == null || store.length() == 0) { @@ -148,26 +311,25 @@ public final class AVMConstants store = store.substring(0, store.indexOf(':')); } ClientConfigElement config = Application.getClientConfig(FacesContext.getCurrentInstance()); - return MessageFormat.format(PREVIEW_SANDBOX_URL, lookupStoreDNS(store), config.getWCMDomain(), config.getWCMPort()); + return MessageFormat.format(PREVIEW_SANDBOX_URL, + lookupStoreDNS(store), + config.getWCMDomain(), + config.getWCMPort()); } - public static String buildAVMWebappUrl(String store, String webapp) + public static String buildWebappUrl(final String store, + final String webapp) { if (webapp == null || webapp.length() == 0) { throw new IllegalArgumentException("Webapp name is mandatory."); } - if (!webapp.equals(DIR_ROOT)) - { - return buildAVMStoreUrl(store) + '/' + webapp; - } - else - { - return buildAVMStoreUrl(store); - } + return (webapp.equals(DIR_ROOT) + ? buildStoreUrl(store) + : buildStoreUrl(store) + '/' + webapp); } - public static String buildAVMAssetUrl(final String avmPath) + public static String buildAssetUrl(final String avmPath) { if (avmPath == null || avmPath.length() == 0) { @@ -178,10 +340,10 @@ public final class AVMConstants { throw new IllegalArgumentException("expected exactly one ':' in " + avmPath); } - return AVMConstants.buildAVMAssetUrl(s[0], s[1]); + return AVMConstants.buildAssetUrl(s[0], s[1]); } - public static String buildAVMAssetUrl(String store, String assetPath) + public static String buildAssetUrl(String store, String assetPath) { if (store == null || store.length() == 0) { @@ -192,10 +354,10 @@ public final class AVMConstants throw new IllegalArgumentException("Asset path is mandatory."); } ClientConfigElement config = Application.getClientConfig(FacesContext.getCurrentInstance()); - return buildAVMAssetUrl(assetPath, config.getWCMDomain(), config.getWCMPort(), lookupStoreDNS(store)); + return buildAssetUrl(assetPath, config.getWCMDomain(), config.getWCMPort(), lookupStoreDNS(store)); } - public static String buildAVMAssetUrl(String assetPath, String domain, String port, String dns) + public static String buildAssetUrl(String assetPath, String domain, String port, String dns) { if (domain == null || port == null || dns == null) { @@ -228,16 +390,14 @@ public final class AVMConstants throw new IllegalArgumentException("Store name is mandatory."); } - String dns = null; - - AVMService avmService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService(); - Map props = avmService.queryStorePropertyKey(store, QName.createQName(null, PROP_DNS + '%')); - if (props.size() == 1) - { - dns = props.keySet().iterator().next().getLocalName().substring(PROP_DNS.length()); - } - - return dns; + final ServiceRegistry serviceRegistry = + Repository.getServiceRegistry(FacesContext.getCurrentInstance()); + final AVMService avmService = serviceRegistry.getAVMService(); + final Map props = + avmService.queryStorePropertyKey(store, QName.createQName(null, PROP_DNS + '%')); + return (props.size() == 1 + ? props.keySet().iterator().next().getLocalName().substring(PROP_DNS.length()) + : null); } /** @@ -251,9 +411,9 @@ public final class AVMConstants * * @return an absolute path within the avm using the paths provided. */ - public static String buildAVMPath(final String parentAVMPath, - final String path, - final PathRelation relation) + public static String buildPath(final String parentAVMPath, + final String path, + final PathRelation relation) { String parent = parentAVMPath; if (path == null || path.length() == 0 || @@ -278,6 +438,18 @@ public final class AVMConstants return parent + path; } + /** + * Returns a path relative to the store portion of the avm path. + * + * @param absoluteAVMPath an absolute path within the avm + * @return the path without the store prefix. + */ + public static String getStoreRelativePath(final String absoluteAVMPath) + { + final Matcher m = STORE_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath); + return m.matches() && m.group(1).length() != 0 ? m.group(1) : null; + } + /** * Returns a path relative to the webapp portion of the avm path. * @@ -368,8 +540,7 @@ public final class AVMConstants { if (force || requiresVServerUpdate(path)) { - VirtServerRegistry vServerRegistry = (VirtServerRegistry)FacesContextUtils.getRequiredWebApplicationContext( - FacesContext.getCurrentInstance()).getBean(BEAN_VIRT_SERVER_REGISTRY); + VirtServerRegistry vServerRegistry = AVMConstants.getVirtServerRegistry(); int webappIndex = path.indexOf('/', path.indexOf(DIR_WEBAPPS) + DIR_WEBAPPS.length() + 1); if (webappIndex != -1) { @@ -389,8 +560,8 @@ public final class AVMConstants { if (force || requiresVServerUpdate(path)) { - VirtServerRegistry vServerRegistry = (VirtServerRegistry)FacesContextUtils.getRequiredWebApplicationContext( - FacesContext.getCurrentInstance()).getBean(BEAN_VIRT_SERVER_REGISTRY); + VirtServerRegistry vServerRegistry = AVMConstants.getVirtServerRegistry(); + int webappIndex = path.indexOf('/', path.indexOf(DIR_WEBAPPS) + DIR_WEBAPPS.length() + 1); if (webappIndex != -1) { @@ -400,13 +571,20 @@ public final class AVMConstants } } + private static VirtServerRegistry getVirtServerRegistry() + { + final FacesContext fc = FacesContext.getCurrentInstance(); + final WebApplicationContext ac = FacesContextUtils.getRequiredWebApplicationContext(fc); + return (VirtServerRegistry)ac.getBean(BEAN_VIRT_SERVER_REGISTRY); + } + // Component Separator. private static final String STORE_SEPARATOR = "--"; // names of the stores representing the layers for an AVM website - public final static String STORE_STAGING = STORE_SEPARATOR + "staging"; - public final static String STORE_MAIN = STORE_SEPARATOR + "main"; - public final static String STORE_PREVIEW = STORE_SEPARATOR + "preview"; + //XXXarielb this should be private + public final static String STORE_WORKFLOW = "workflow"; + private final static String STORE_PREVIEW = "preview"; // system directories at the top level of an AVM website // @@ -426,6 +604,8 @@ public final class AVMConstants public final static String PROP_SANDBOX_STAGING_PREVIEW = ".sandbox.staging.preview"; public final static String PROP_SANDBOX_AUTHOR_MAIN = ".sandbox.author.main"; public final static String PROP_SANDBOX_AUTHOR_PREVIEW = ".sandbox.author.preview"; + public final static String PROP_SANDBOX_WORKFLOW_MAIN = ".sandbox.workflow.main"; + public final static String PROP_SANDBOX_WORKFLOW_PREVIEW = ".sandbox.workflow.preview"; public final static String PROP_DNS = ".dns."; public final static String PROP_WEBSITE_NAME = ".website.name"; public final static String PROP_SANDBOX_STORE_PREFIX = ".sandbox.store."; @@ -439,6 +619,8 @@ public final class AVMConstants private final static String PREVIEW_ASSET_URL = "http://{0}.www--sandbox.{1}:{2}{3}"; // pattern for absolute AVM Path + private final static Pattern STORE_RELATIVE_PATH_PATTERN = + Pattern.compile("[^:]+:(.+)"); private final static Pattern WEBAPP_RELATIVE_PATH_PATTERN = Pattern.compile("([^:]+:/" + AVMConstants.DIR_APPBASE + "/" + AVMConstants.DIR_WEBAPPS + "/([^/]+))(.*)"); diff --git a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java index 9b42d4ae18..a2d0fdb672 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java @@ -309,9 +309,9 @@ public class AVMEditBean if (this.nodeService.hasAspect(avmRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { // reset the preview layer - String path = this.avmBrowseBean.getCurrentPath(); - path = path.replaceFirst(AVMConstants.STORE_MAIN, AVMConstants.STORE_PREVIEW); - path = path.split(":")[0] + ":/" + AVMConstants.DIR_APPBASE; + String storeName = AVMConstants.getStoreName(this.avmBrowseBean.getCurrentPath()); + storeName = AVMConstants.getCorrespondingPreviewStoreName(storeName); + final String path = AVMConstants.buildStoreRootPath(storeName); if (LOGGER.isDebugEnabled()) LOGGER.debug("reseting layer " + path); this.avmSyncService.resetLayer(path); @@ -417,8 +417,7 @@ public class AVMEditBean { final String path = AVMNodeConverter.ToAVMVersionPath(uploadedFile).getSecond(); diffList.add(new AVMDifference(-1, path, - -1, path.replaceFirst(AVMConstants.STORE_PREVIEW, - AVMConstants.STORE_MAIN), + -1, AVMConstants.getCorrespondingPathInMainStore(path), AVMDifference.NEWER)); } this.avmSyncService.update(diffList, null, true, true, true, true, null, null); diff --git a/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java b/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java index 33460aed2e..02b5623df5 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java @@ -22,18 +22,28 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import javax.faces.context.FacesContext; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.WCMAppModel; +import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.avm.wf.AVMSubmittedAspect; import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.workflow.WorkflowPath; +import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.namespace.QName; import org.alfresco.util.GUID; import org.alfresco.web.bean.repository.Repository; @@ -42,6 +52,7 @@ import org.alfresco.web.bean.workflow.WorkflowUtil; /** * AVM Specific workflow related helper methods. * + * @author Ariel Backenroth * @author Kevin Roast */ public class AVMWorkflowUtil extends WorkflowUtil @@ -50,45 +61,39 @@ public class AVMWorkflowUtil extends WorkflowUtil private static final String WCM_WORKFLOW_MODEL_1_0_URI = "http://www.alfresco.org/model/wcmworkflow/1.0"; public static final QName PROP_FROM_PATH = QName.createQName(WCM_WORKFLOW_MODEL_1_0_URI, "fromPath"); public static final QName PROP_LABEL = QName.createQName(WCM_WORKFLOW_MODEL_1_0_URI, "label"); - - private static final String STORE_WORKFLOW_SYSTEM = "workflow-system"; - private static final String FOLDER_PACKAGES = "packages"; - - /** - * Return the AVM workflow package root folder path - creating the default - * store and root folder if required. - * - * @param avmService AVMService to use - * - * @return AVM Root package path - */ - public static String getAVMPackageRoot(AVMService avmService) + + public static NodeRef createWorkflowPackage(final List srcPaths, + final String storeId, + final WorkflowPath path, + final AVMSubmittedAspect avmSubmittedAspect, + final AVMSyncService avmSyncService, + final AVMService avmService, + final WorkflowService workflowService, + final NodeService nodeService) { - String packagesRoot = STORE_WORKFLOW_SYSTEM + ":/" + FOLDER_PACKAGES; - AVMNodeDescriptor packagesDesc = avmService.lookup(-1, packagesRoot); - if (packagesDesc == null) + // create package paths (layered to user sandbox area as target) + final String packageName = SandboxFactory.createWorkflowSandbox(storeId); + final String workflowMainStoreName = + AVMConstants.buildWorkflowMainStoreName(storeId, packageName); + final String packagesPath = AVMConstants.buildStoreRootPath(workflowMainStoreName); + + final List diffs = new ArrayList(srcPaths.size()); + for (final String srcPath : srcPaths) { - avmService.createStore(STORE_WORKFLOW_SYSTEM); - avmService.createDirectory(STORE_WORKFLOW_SYSTEM + ":/", FOLDER_PACKAGES); + diffs.add(new AVMDifference(-1, srcPath, + -1, AVMConstants.getCorrespondingPath(srcPath, workflowMainStoreName), + AVMDifference.NEWER)); + avmSubmittedAspect.markSubmitted(-1, srcPath, path.instance.id); } - return packagesRoot; - } - - /** - * Create an AVM layered workflow package against the specified sandbox path. - * - * @param avmService AVMService to use - * @param sandboxPath The sandbox path to layer the package over - * - * @return Path to the layered package. - */ - public static String createAVMLayeredPackage(AVMService avmService, String sandboxPath) - { - String packagesRoot = getAVMPackageRoot(avmService); - String packageName = GUID.generate(); - avmService.createLayeredDirectory(sandboxPath, packagesRoot, packageName); - - return packagesRoot + "/" + packageName; + + // write changes to layer so files are marked as modified + avmSyncService.update(diffs, null, true, true, false, false, null, null); + + // convert package to workflow package + final AVMNodeDescriptor packageDesc = avmService.lookup(-1, packagesPath); + final NodeRef packageNodeRef = workflowService.createPackage(AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath())); + nodeService.setProperty(packageNodeRef, WorkflowModel.PROP_IS_SYSTEM_PACKAGE, true); + return packageNodeRef; } /** diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index 1353122936..d87ceab150 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -185,9 +185,9 @@ public class CreateWebContentWizard extends BaseContentWizard } // reset the preview layer - String path = this.avmBrowseBean.getCurrentPath(); - path = path.replaceFirst(AVMConstants.STORE_MAIN, AVMConstants.STORE_PREVIEW); - path = path.split(":")[0] + ":/" + AVMConstants.DIR_APPBASE; + String storeName = AVMConstants.getStoreName(this.avmBrowseBean.getCurrentPath()); + storeName = AVMConstants.getCorrespondingPreviewStoreName(storeName); + final String path = AVMConstants.buildStoreRootPath(storeName); if (LOGGER.isDebugEnabled()) LOGGER.debug("reseting layer " + path); this.avmSyncService.resetLayer(path); @@ -273,15 +273,13 @@ public class CreateWebContentWizard extends BaseContentWizard final List diffList = new ArrayList(1 + this.renditions.size() + uploadedFiles.length); diffList.add(new AVMDifference(-1, this.createdPath, - -1, this.createdPath.replaceFirst(AVMConstants.STORE_PREVIEW, - AVMConstants.STORE_MAIN), + -1, AVMConstants.getCorrespondingPathInMainStore(this.createdPath), AVMDifference.NEWER)); for (Rendition rendition : this.renditions) { final String path = AVMNodeConverter.ToAVMVersionPath(rendition.getNodeRef()).getSecond(); diffList.add(new AVMDifference(-1, path, - -1, path.replaceFirst(AVMConstants.STORE_PREVIEW, - AVMConstants.STORE_MAIN), + -1, AVMConstants.getCorrespondingPathInMainStore(path), AVMDifference.NEWER)); } @@ -289,8 +287,7 @@ public class CreateWebContentWizard extends BaseContentWizard { final String path = AVMNodeConverter.ToAVMVersionPath(uploadedFile).getSecond(); diffList.add(new AVMDifference(-1, path, - -1, path.replaceFirst(AVMConstants.STORE_PREVIEW, - AVMConstants.STORE_MAIN), + -1, AVMConstants.getCorrespondingPathInMainStore(path), AVMDifference.NEWER)); } @@ -298,14 +295,13 @@ public class CreateWebContentWizard extends BaseContentWizard { for (AVMDifference diff : diffList) { - LOGGER.debug("updating " + AVMConstants.STORE_MAIN + " with " + diff.getSourcePath()); + LOGGER.debug("updating main store with " + diff.getSourcePath()); } } this.avmSyncService.update(diffList, null, true, true, true, true, null, null); // reset all paths and structures to the main store - this.createdPath = this.createdPath.replaceFirst(AVMConstants.STORE_PREVIEW, - AVMConstants.STORE_MAIN); + this.createdPath = AVMConstants.getCorrespondingPathInMainStore(this.createdPath); LOGGER.debug("reset path " + this.createdPath + " to main store"); @@ -379,65 +375,42 @@ public class CreateWebContentWizard extends BaseContentWizard { if (LOGGER.isDebugEnabled()) LOGGER.debug("creating workflow package"); - // create package paths (layered to user sandbox area as target) - String stagingPath = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getStagingStore()); - String packagesPath = AVMWorkflowUtil.createAVMLayeredPackage(this.avmService, stagingPath); - LOGGER.debug("created layered package " + packagesPath + - " above " + stagingPath); - - List diffs = new ArrayList(8); + final String storeId = this.avmBrowseBean.getStagingStore(); + final List srcPaths = new ArrayList(); // construct diffs for selected items for submission - String webapp = this.avmBrowseBean.getWebapp(); - String sandboxPath = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getSandbox()); + final String sandboxName = this.avmBrowseBean.getSandbox(); if (form) { // collect diffs for form data instance and all renditions for (Rendition rendition : this.getRenditions()) { - String renditionPath = AVMNodeConverter.ToAVMVersionPath(rendition.getNodeRef()).getSecond(); - int webappIndex = renditionPath.indexOf('/' + webapp); - renditionPath = renditionPath.substring(webappIndex); - String srcPath = sandboxPath + renditionPath; - String destPath = packagesPath + renditionPath; - AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER); - diffs.add(diff); - avmSubmittedAspect.markSubmitted(-1, srcPath, path.instance.id); + final String renditionPath = AVMNodeConverter.ToAVMVersionPath(rendition.getNodeRef()).getSecond(); + srcPaths.add(AVMConstants.getCorrespondingPath(renditionPath, sandboxName)); } - String instancePath = AVMNodeConverter.ToAVMVersionPath(this.formInstanceData.getNodeRef()).getSecond(); - int webappIndex = instancePath.indexOf('/' + webapp); - instancePath = instancePath.substring(webappIndex); - String srcPath = sandboxPath + instancePath; - String destPath = packagesPath + instancePath; - AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER); - diffs.add(diff); - avmSubmittedAspect.markSubmitted(-1, srcPath, path.instance.id); + final String instancePath = AVMNodeConverter.ToAVMVersionPath(this.formInstanceData.getNodeRef()).getSecond(); + srcPaths.add(AVMConstants.getCorrespondingPath(instancePath, sandboxName)); } else { // diff for txt or html content - int webappIndex = this.createdPath.indexOf('/' + webapp); - String itemPath = this.createdPath.substring(webappIndex); - String srcPath = sandboxPath + itemPath; - String destPath = packagesPath + itemPath; - AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER); - diffs.add(diff); - avmSubmittedAspect.markSubmitted(-1, srcPath, path.instance.id); + srcPaths.add(AVMConstants.getCorrespondingPath(this.createdPath, sandboxName)); } - - // write changes to layer so files are marked as modified - this.avmSyncService.update(diffs, null, true, true, false, false, null, null); - - // convert package to workflow package - AVMNodeDescriptor packageDesc = this.avmService.lookup(-1, packagesPath); - NodeRef packageNodeRef = this.workflowService.createPackage( - AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath())); - this.nodeService.setProperty(packageNodeRef, WorkflowModel.PROP_IS_SYSTEM_PACKAGE, true); + + final NodeRef packageNodeRef = + AVMWorkflowUtil.createWorkflowPackage(srcPaths, + storeId, + path, + avmSubmittedAspect, + this.avmSyncService, + this.avmService, + this.workflowService, + this.nodeService); + parameters.put(WorkflowModel.ASSOC_PACKAGE, packageNodeRef); // TODO: capture label and comment? parameters.put(AVMWorkflowUtil.PROP_LABEL, form ? this.formInstanceData.getName() : this.fileName); - parameters.put(AVMWorkflowUtil.PROP_FROM_PATH, AVMConstants.buildAVMStoreRootPath( - this.avmBrowseBean.getSandbox())); + parameters.put(AVMWorkflowUtil.PROP_FROM_PATH, AVMConstants.buildStoreRootPath(sandboxName)); // update start task with submit parameters this.workflowService.updateTask(startTask.id, parameters, null, null); @@ -488,7 +461,7 @@ public class CreateWebContentWizard extends BaseContentWizard LOGGER.debug("saving file content to " + fileName); String path = this.avmBrowseBean.getCurrentPath(); - path = path.replaceFirst(AVMConstants.STORE_MAIN, AVMConstants.STORE_PREVIEW); + path = AVMConstants.getCorrespondingPathInPreviewStore(path); if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null) { path = this.getForm().getOutputPathForFormInstanceData(this.instanceDataDocument, diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java b/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java index b140d016c8..4ca4ffebb1 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java @@ -41,7 +41,7 @@ public class CreateWebappDialog extends CreateFolderDialog @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { - final String parent = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getStagingStore()); + final String parent = AVMConstants.buildSandboxRootPath(this.avmBrowseBean.getStagingStore()); this.avmService.createDirectory(parent, this.name); final String path = AVMNodeConverter.ExtendAVMPath(parent, this.name); diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index dbf8040b5e..4a549b0cde 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java @@ -187,8 +187,8 @@ public class CreateWebsiteWizard extends BaseWizardBean SandboxFactory.createStagingSandbox(avmStore, wiz.getManagers()); // create the default webapp folder under the hidden system folders - final String stagingStore = AVMConstants.buildAVMStagingStoreName(avmStore); - final String stagingStoreRoot = AVMConstants.buildAVMStoreRootPath(stagingStore); + final String stagingStore = AVMConstants.buildStagingStoreName(avmStore); + final String stagingStoreRoot = AVMConstants.buildSandboxRootPath(stagingStore); this.avmService.createDirectory(stagingStoreRoot, webapp); this.avmService.addAspect(AVMNodeConverter.ExtendAVMPath(stagingStoreRoot, webapp), diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java index cac226e2ec..3993cf3a1d 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java @@ -78,18 +78,18 @@ public class DeleteSandboxDialog extends BaseDialogBean // TODO: would it be better to use the .sandbox-id. property to delete all sandboxes? // purge the user main sandbox store from the system - String sandbox = AVMConstants.buildAVMUserMainStoreName(storeRoot, username); + String sandbox = AVMConstants.buildUserMainStoreName(storeRoot, username); this.avmService.purgeStore(sandbox); // purge the user preview sandbox store from the system - sandbox = AVMConstants.buildAVMUserPreviewStoreName(storeRoot, username); + sandbox = AVMConstants.buildUserPreviewStoreName(storeRoot, username); this.avmService.purgeStore(sandbox); // remove the association to this web project user meta-data this.nodeService.removeChild(website.getNodeRef(), ref.getChildRef()); // update virtualisation server for the sandbox removal - String path = AVMConstants.buildAVMStoreWebappPath(sandbox, this.avmBrowseBean.getWebapp()); + String path = AVMConstants.buildStoreWebappPath(sandbox, this.avmBrowseBean.getWebapp()); AVMConstants.removeVServerWebapp(path, true); break; diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java index 19d21cfe00..7f5536681c 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java @@ -57,15 +57,15 @@ public class DeleteWebsiteDialog extends DeleteSpaceDialog String username = (String)nodeService.getProperty(ref.getChildRef(), WCMAppModel.PROP_WEBUSERNAME); // delete the preview store for this user - deleteStore(AVMConstants.buildAVMUserPreviewStoreName(storeRoot, username)); + deleteStore(AVMConstants.buildUserPreviewStoreName(storeRoot, username)); // delete the main store for this user - deleteStore(AVMConstants.buildAVMUserMainStoreName(storeRoot, username)); + deleteStore(AVMConstants.buildUserMainStoreName(storeRoot, username)); } // remove the main staging and preview stores - deleteStore(AVMConstants.buildAVMStagingPreviewStoreName(storeRoot)); - deleteStore(AVMConstants.buildAVMStagingStoreName(storeRoot)); + deleteStore(AVMConstants.buildStagingPreviewStoreName(storeRoot)); + deleteStore(AVMConstants.buildStagingStoreName(storeRoot)); // use the super implementation to delete the node itself return super.finishImpl(context, outcome); diff --git a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java index 2bca48c840..f793487c24 100644 --- a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java @@ -180,11 +180,11 @@ public class EditWebsiteWizard extends CreateWebsiteWizard // change/create the root webapp name for the website if (this.webapp != null && this.webapp.length() != 0) { - String stagingStore = AVMConstants.buildAVMStagingStoreName(this.dnsName); - String webappPath = AVMConstants.buildAVMStoreWebappPath(stagingStore, this.webapp); + String stagingStore = AVMConstants.buildStagingStoreName(this.dnsName); + String webappPath = AVMConstants.buildStoreWebappPath(stagingStore, this.webapp); if (this.avmService.lookup(-1, webappPath) == null) { - this.avmService.createDirectory(AVMConstants.buildAVMStoreRootPath(stagingStore), this.webapp); + this.avmService.createDirectory(AVMConstants.buildSandboxRootPath(stagingStore), this.webapp); } this.nodeService.setProperty(nodeRef, WCMAppModel.PROP_DEFAULTWEBAPP, this.webapp); } diff --git a/source/java/org/alfresco/web/bean/wcm/FileDetailsBean.java b/source/java/org/alfresco/web/bean/wcm/FileDetailsBean.java index f298a6bb95..f8ae75c3ab 100644 --- a/source/java/org/alfresco/web/bean/wcm/FileDetailsBean.java +++ b/source/java/org/alfresco/web/bean/wcm/FileDetailsBean.java @@ -73,7 +73,7 @@ public class FileDetailsBean extends AVMDetailsBean */ public String getPreviewUrl() { - return AVMConstants.buildAVMAssetUrl(getAvmNode().getPath()); + return AVMConstants.buildAssetUrl(getAvmNode().getPath()); } /** diff --git a/source/java/org/alfresco/web/bean/wcm/FolderDetailsBean.java b/source/java/org/alfresco/web/bean/wcm/FolderDetailsBean.java index cdbd8a27f1..bbe09b525c 100644 --- a/source/java/org/alfresco/web/bean/wcm/FolderDetailsBean.java +++ b/source/java/org/alfresco/web/bean/wcm/FolderDetailsBean.java @@ -53,7 +53,7 @@ public class FolderDetailsBean extends AVMDetailsBean */ public String getPreviewUrl() { - return AVMConstants.buildAVMAssetUrl(getAvmNode().getPath()); + return AVMConstants.buildAssetUrl(getAvmNode().getPath()); } /** diff --git a/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java b/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java index 2f80c2d6a0..8b4744a72e 100644 --- a/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java @@ -215,11 +215,11 @@ public class ImportWebsiteDialog String webapp = this.avmBrowseBean.getWebapp(); if (storeRoot != null && webapp != null) { - String store = AVMConstants.buildAVMStagingStoreName(storeRoot); + String store = AVMConstants.buildStagingStoreName(storeRoot); if (this.avmService.getStore(store) != null) { // get the path to the root webapp import area of the store - String rootPath = AVMConstants.buildAVMStoreWebappPath(store, webapp); + String rootPath = AVMConstants.buildStoreWebappPath(store, webapp); // convert the AVM path to a NodeRef so we can use the NodeService to perform import NodeRef importRef = AVMNodeConverter.ToNodeRef(-1, rootPath); diff --git a/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java b/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java index 28e07c0c23..f7a8d257b3 100644 --- a/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ package org.alfresco.web.bean.wcm; import java.io.Serializable; @@ -166,8 +182,8 @@ public class InviteWebsiteUsersWizard extends InviteUsersWizard // reload virtualisation server for the web project if (isStandalone()) { - String stagingStore = AVMConstants.buildAVMStagingStoreName(getAvmStore()); - String path = AVMConstants.buildAVMStoreWebappPath(stagingStore, this.avmBrowseBean.getWebapp()); + String stagingStore = AVMConstants.buildStagingStoreName(getAvmStore()); + String path = AVMConstants.buildStoreWebappPath(stagingStore, this.avmBrowseBean.getWebapp()); AVMConstants.updateVServerWebapp(path, true); } diff --git a/source/java/org/alfresco/web/bean/wcm/RevertAllDialog.java b/source/java/org/alfresco/web/bean/wcm/RevertAllDialog.java index 7c40a1f685..bffa4b6f4d 100644 --- a/source/java/org/alfresco/web/bean/wcm/RevertAllDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/RevertAllDialog.java @@ -93,8 +93,8 @@ public class RevertAllDialog extends BaseDialogBean protected String finishImpl(FacesContext context, String outcome) throws Exception { String webapp = this.avmBrowseBean.getWebapp(); - String userStore = AVMConstants.buildAVMStoreWebappPath(this.avmBrowseBean.getSandbox(), webapp); - String stagingStore = AVMConstants.buildAVMStoreWebappPath(this.avmBrowseBean.getStagingStore(), webapp); + String userStore = AVMConstants.buildStoreWebappPath(this.avmBrowseBean.getSandbox(), webapp); + String stagingStore = AVMConstants.buildStoreWebappPath(this.avmBrowseBean.getStagingStore(), webapp); // calcluate the list of differences between the user store and the staging area List diffs = this.avmSyncService.compare( diff --git a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java index c11742f46e..ddf1074cb1 100644 --- a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java +++ b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java @@ -64,88 +64,214 @@ public final class SandboxFactory * DNS: .dns. = * Website Name: .website.name = website name * - * @param name The store name to create the sandbox for + * @param storeId The store name to create the sandbox for * @param managers The list of authorities who have ContentManager role in the website */ - public static void createStagingSandbox(String name, List managers) + public static void createStagingSandbox(final String storeId, final List managers) { - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - AVMService avmService = services.getAVMService(); - PermissionService permissionService = services.getPermissionService(); + final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); + final AVMService avmService = services.getAVMService(); + final PermissionService permissionService = services.getPermissionService(); // create the 'staging' store for the website - String stagingStore = AVMConstants.buildAVMStagingStoreName(name); - avmService.createStore(stagingStore); + final String stagingStoreName = AVMConstants.buildStagingStoreName(storeId); + avmService.createStore(stagingStoreName); if (logger.isDebugEnabled()) - logger.debug("Created staging sandbox store: " + stagingStore); + logger.debug("Created staging sandbox store: " + stagingStoreName); // create the system directories 'appBase' and 'avm_webapps' - String path = stagingStore + ":/"; - //this.fileFolderService.create(AVMNodeConverter.ToNodeRef(-1, path), AVMConstants.DIR_APPBASE, ContentModel.TYPE_AVM_PLAIN_FOLDER); - avmService.createDirectory(path, AVMConstants.DIR_APPBASE); - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, path + '/' + AVMConstants.DIR_APPBASE); + avmService.createDirectory(stagingStoreName + ":/", AVMConstants.DIR_APPBASE); + NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildStoreRootPath(stagingStoreName)); for (String manager : managers) { permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); } - path += AVMConstants.DIR_APPBASE; - //this.fileFolderService.create(AVMNodeConverter.ToNodeRef(-1, path), AVMConstants.DIR_WEBAPPS, ContentModel.TYPE_AVM_PLAIN_FOLDER); - avmService.createDirectory(path, AVMConstants.DIR_WEBAPPS); + avmService.createDirectory(AVMConstants.buildStoreRootPath(stagingStoreName), + AVMConstants.DIR_WEBAPPS); // tag the store with the store type - avmService.setStoreProperty(stagingStore, - QName.createQName(null, AVMConstants.PROP_SANDBOX_STAGING_MAIN), - new PropertyValue(DataTypeDefinition.TEXT, null)); + avmService.setStoreProperty(stagingStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_STAGING_MAIN), + new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the DNS name property - tagStoreDNSPath(avmService, stagingStore, name, "staging"); + tagStoreDNSPath(avmService, stagingStoreName, storeId); // snapshot the store - avmService.createSnapshot(stagingStore, null, null); + avmService.createSnapshot(stagingStoreName, null, null); // create the 'preview' store for the website - String previewStore = AVMConstants.buildAVMStagingPreviewStoreName(name); - avmService.createStore(previewStore); + final String previewStoreName = AVMConstants.buildStagingPreviewStoreName(storeId); + avmService.createStore(previewStoreName); if (logger.isDebugEnabled()) - logger.debug("Created staging sandbox store: " + previewStore); + logger.debug("Created staging preview sandbox store: " + previewStoreName + + " above " + stagingStoreName); // create a layered directory pointing to 'appBase' in the staging area - path = previewStore + ":/"; - String targetPath = name + AVMConstants.STORE_STAGING + ":/" + AVMConstants.DIR_APPBASE; - //this.fileFolderService.create(AVMNodeConverter.ToNodeRef(-1, path), AVMConstants.DIR_APPBASE, ContentModel.TYPE_AVM_PLAIN_FOLDER); - avmService.createLayeredDirectory(targetPath, path, AVMConstants.DIR_APPBASE); - dirRef = AVMNodeConverter.ToNodeRef(-1, path + '/' + AVMConstants.DIR_APPBASE); + + avmService.createLayeredDirectory(AVMConstants.buildStoreRootPath(stagingStoreName), + previewStoreName + ":/", + AVMConstants.DIR_APPBASE); + dirRef = AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildStoreRootPath(previewStoreName)); for (String manager : managers) { permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); } // tag the store with the store type - avmService.setStoreProperty(previewStore, - QName.createQName(null, AVMConstants.PROP_SANDBOX_STAGING_PREVIEW), - new PropertyValue(DataTypeDefinition.TEXT, null)); + avmService.setStoreProperty(previewStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_STAGING_PREVIEW), + new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the DNS name property - tagStoreDNSPath(avmService, previewStore, name, "preview"); + tagStoreDNSPath(avmService, previewStoreName, storeId, "preview"); // snapshot the store - avmService.createSnapshot(previewStore, null, null); + avmService.createSnapshot(previewStoreName, null, null); // tag all related stores to indicate that they are part of a single sandbox String sandboxIdProp = AVMConstants.PROP_SANDBOXID + GUID.generate(); - avmService.setStoreProperty(stagingStore, - QName.createQName(null, sandboxIdProp), - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(previewStore, - QName.createQName(null, sandboxIdProp), - new PropertyValue(DataTypeDefinition.TEXT, null)); + avmService.setStoreProperty(stagingStoreName, + QName.createQName(null, sandboxIdProp), + new PropertyValue(DataTypeDefinition.TEXT, null)); + avmService.setStoreProperty(previewStoreName, + QName.createQName(null, sandboxIdProp), + new PropertyValue(DataTypeDefinition.TEXT, null)); if (logger.isDebugEnabled()) { - dumpStoreProperties(avmService, stagingStore); - dumpStoreProperties(avmService, previewStore); + dumpStoreProperties(avmService, stagingStoreName); + dumpStoreProperties(avmService, previewStoreName); + } + } + + /** + * Create a user sandbox for the named store. + * + * A user sandbox is comprised of two stores, the first + * named 'storename---username' layered over the staging store with a preview store + * named 'storename--username--preview' layered over the main store. + * + * Various store meta-data properties are set including: + * Identifier for store-types: .sandbox.author.main and .sandbox.author.preview + * Store-id: .sandbox-id. (unique across all stores in the sandbox) + * DNS: .dns. = + * Website Name: .website.name = website name + * + * @param storeId The store id to create the sandbox for + * @param managers The list of authorities who have ContentManager role in the website + * @param username Username of the user to create the sandbox for + * @param role Role permission for the user + */ + public static void createUserSandbox(final String storeId, + final List managers, + final String username, + final String role) + { + final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); + final AVMService avmService = services.getAVMService(); + final PermissionService permissionService = services.getPermissionService(); + + // create the user 'main' store + final String userStoreName = AVMConstants.buildUserMainStoreName(storeId, username); + if (avmService.getStore(userStoreName) != null) + { + if (logger.isDebugEnabled()) + { + logger.debug("Not creating as store already exists: " + userStoreName); + } + return; + } + + avmService.createStore(userStoreName); + final String stagingStoreName = AVMConstants.buildStagingStoreName(storeId); + if (logger.isDebugEnabled()) + logger.debug("Created user sandbox store: " + userStoreName + + " above staging store " + stagingStoreName); + + // create a layered directory pointing to 'appBase' in the staging area + avmService.createLayeredDirectory(AVMConstants.buildStoreRootPath(stagingStoreName), + userStoreName + ":/", + AVMConstants.DIR_APPBASE); + NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildStoreRootPath(userStoreName)); + permissionService.setPermission(dirRef, username, role, true); + for (String manager : managers) + { + permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); + } + + // tag the store with the store type + avmService.setStoreProperty(userStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_AUTHOR_MAIN), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with the base name of the website so that corresponding + // staging areas can be found. + avmService.setStoreProperty(userStoreName, + QName.createQName(null, AVMConstants.PROP_WEBSITE_NAME), + new PropertyValue(DataTypeDefinition.TEXT, storeId)); + + // tag the store, oddly enough, with its own store name for querying. + // when will the madness end. + avmService.setStoreProperty(userStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_STORE_PREFIX + userStoreName), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with the DNS name property + tagStoreDNSPath(avmService, userStoreName, storeId, username); + + // snapshot the store + avmService.createSnapshot(userStoreName, null, null); + + + // create the user 'preview' store + String previewStoreName = AVMConstants.buildUserPreviewStoreName(storeId, username); + avmService.createStore(previewStoreName); + if (logger.isDebugEnabled()) + logger.debug("Created user preview sandbox store: " + previewStoreName + + " above " + userStoreName); + + // create a layered directory pointing to 'appBase' in the user 'main' store + avmService.createLayeredDirectory(AVMConstants.buildStoreRootPath(userStoreName), + previewStoreName + ":/", + AVMConstants.DIR_APPBASE); + dirRef = AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildStoreRootPath(previewStoreName)); + permissionService.setPermission(dirRef, username, role, true); + for (String manager : managers) + { + permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); + } + + // tag the store with the store type + avmService.setStoreProperty(previewStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_AUTHOR_PREVIEW), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with its own store name for querying. + avmService.setStoreProperty(previewStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with the DNS name property + tagStoreDNSPath(avmService, previewStoreName, storeId, username, "preview"); + + // snapshot the store + avmService.createSnapshot(previewStoreName, null, null); + + + // tag all related stores to indicate that they are part of a single sandbox + String sandboxIdProp = AVMConstants.PROP_SANDBOXID + GUID.generate(); + avmService.setStoreProperty(userStoreName, QName.createQName(null, sandboxIdProp), + new PropertyValue(DataTypeDefinition.TEXT, null)); + avmService.setStoreProperty(previewStoreName, QName.createQName(null, sandboxIdProp), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + if (logger.isDebugEnabled()) + { + dumpStoreProperties(avmService, userStoreName); + dumpStoreProperties(avmService, previewStoreName); } } @@ -167,106 +293,106 @@ public final class SandboxFactory * @param username Username of the user to create the sandbox for * @param role Role permission for the user */ - public static void createUserSandbox(String name, List managers, String username, String role) + public static String createWorkflowSandbox(final String storeId) { - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - AVMService avmService = services.getAVMService(); - PermissionService permissionService = services.getPermissionService(); + final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); + final AVMService avmService = services.getAVMService(); + final PermissionService permissionService = services.getPermissionService(); + final String stagingStoreName = AVMConstants.buildStagingStoreName(storeId); + // create the user 'main' store - String userStore = AVMConstants.buildAVMUserMainStoreName(name, username); - if (avmService.getStore(userStore) == null) + final String packageName = AVMConstants.STORE_WORKFLOW + "-" + GUID.generate(); + final String workflowMainStoreName = + AVMConstants.buildWorkflowMainStoreName(storeId, packageName); + + avmService.createStore(workflowMainStoreName); + if (logger.isDebugEnabled()) + logger.debug("Created workflow sandbox store: " + workflowMainStoreName); + + // create a layered directory pointing to 'appBase' in the staging area + avmService.createLayeredDirectory(AVMConstants.buildStoreRootPath(stagingStoreName), + workflowMainStoreName + ":/", + AVMConstants.DIR_APPBASE); +// NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, path + '/' + AVMConstants.DIR_APPBASE); +// permissionService.setPermission(dirRef, username, role, true); +// for (String manager : managers) +// { +// permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); +// } + + // tag the store with the store type + avmService.setStoreProperty(workflowMainStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_WORKFLOW_MAIN), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with the base name of the website so that corresponding + // staging areas can be found. + avmService.setStoreProperty(workflowMainStoreName, + QName.createQName(null, AVMConstants.PROP_WEBSITE_NAME), + new PropertyValue(DataTypeDefinition.TEXT, storeId)); + + // tag the store, oddly enough, with its own store name for querying. + // when will the madness end. + avmService.setStoreProperty(workflowMainStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_STORE_PREFIX + workflowMainStoreName), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with the DNS name property + tagStoreDNSPath(avmService, workflowMainStoreName, storeId, packageName); + + // snapshot the store + avmService.createSnapshot(workflowMainStoreName, null, null); + + // create the user 'preview' store + final String workflowPreviewStoreName = + AVMConstants.buildWorkflowPreviewStoreName(storeId, packageName); + avmService.createStore(workflowPreviewStoreName); + if (logger.isDebugEnabled()) + logger.debug("Created user sandbox preview store: " + workflowPreviewStoreName); + + // create a layered directory pointing to 'appBase' in the user 'main' store + avmService.createLayeredDirectory(AVMConstants.buildStoreRootPath(workflowMainStoreName), + workflowPreviewStoreName + ":/", + AVMConstants.DIR_APPBASE); +// dirRef = AVMNodeConverter.ToNodeRef(-1, path + '/' + AVMConstants.DIR_APPBASE); +// permissionService.setPermission(dirRef, username, role, true); +// for (String manager : managers) +// { +// permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); +// } + + // tag the store with the store type + avmService.setStoreProperty(workflowPreviewStoreName, + QName.createQName(null, AVMConstants.PROP_SANDBOX_WORKFLOW_PREVIEW), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with its own store name for querying. + avmService.setStoreProperty(workflowPreviewStoreName, + QName.createQName(null, + AVMConstants.PROP_SANDBOX_STORE_PREFIX + workflowPreviewStoreName), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + // tag the store with the DNS name property + tagStoreDNSPath(avmService, workflowPreviewStoreName, storeId, packageName, "preview"); + + // snapshot the store + avmService.createSnapshot(workflowPreviewStoreName, null, null); + + + // tag all related stores to indicate that they are part of a single sandbox + String sandboxIdProp = AVMConstants.PROP_SANDBOXID + GUID.generate(); + avmService.setStoreProperty(workflowMainStoreName, QName.createQName(null, sandboxIdProp), + new PropertyValue(DataTypeDefinition.TEXT, null)); + avmService.setStoreProperty(workflowPreviewStoreName, QName.createQName(null, sandboxIdProp), + new PropertyValue(DataTypeDefinition.TEXT, null)); + + if (logger.isDebugEnabled()) { - avmService.createStore(userStore); - if (logger.isDebugEnabled()) - logger.debug("Created user sandbox store: " + userStore); - - // create a layered directory pointing to 'appBase' in the staging area - String path = userStore + ":/"; - String targetPath = name + AVMConstants.STORE_STAGING + ":/" + AVMConstants.DIR_APPBASE; - avmService.createLayeredDirectory(targetPath, path, AVMConstants.DIR_APPBASE); - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, path + '/' + AVMConstants.DIR_APPBASE); - permissionService.setPermission(dirRef, username, role, true); - for (String manager : managers) - { - permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); - } - - // tag the store with the store type - avmService.setStoreProperty(userStore, - QName.createQName(null, AVMConstants.PROP_SANDBOX_AUTHOR_MAIN), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the base name of the website so that corresponding - // staging areas can be found. - avmService.setStoreProperty(userStore, - QName.createQName(null, AVMConstants.PROP_WEBSITE_NAME), - new PropertyValue(DataTypeDefinition.TEXT, name)); - - // tag the store, oddly enough, with its own store name for querying. - // when will the madness end. - avmService.setStoreProperty(userStore, - QName.createQName(null, AVMConstants.PROP_SANDBOX_STORE_PREFIX + userStore), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, userStore, name, username); - - // snapshot the store - avmService.createSnapshot(userStore, null, null); - - - // create the user 'preview' store - String previewStore = AVMConstants.buildAVMUserPreviewStoreName(name, username); - avmService.createStore(previewStore); - if (logger.isDebugEnabled()) - logger.debug("Created user sandbox store: " + previewStore); - - // create a layered directory pointing to 'appBase' in the user 'main' store - path = previewStore + ":/"; - targetPath = userStore + ":/" + AVMConstants.DIR_APPBASE; - avmService.createLayeredDirectory(targetPath, path, AVMConstants.DIR_APPBASE); - dirRef = AVMNodeConverter.ToNodeRef(-1, path + '/' + AVMConstants.DIR_APPBASE); - permissionService.setPermission(dirRef, username, role, true); - for (String manager : managers) - { - permissionService.setPermission(dirRef, manager, ROLE_CONTENT_MANAGER, true); - } - - // tag the store with the store type - avmService.setStoreProperty(previewStore, - QName.createQName(null, AVMConstants.PROP_SANDBOX_AUTHOR_PREVIEW), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with its own store name for querying. - avmService.setStoreProperty(previewStore, - QName.createQName(null, AVMConstants.PROP_SANDBOX_STORE_PREFIX + previewStore), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, previewStore, name, username, "preview"); - - // snapshot the store - avmService.createSnapshot(previewStore, null, null); - - - // tag all related stores to indicate that they are part of a single sandbox - String sandboxIdProp = AVMConstants.PROP_SANDBOXID + GUID.generate(); - avmService.setStoreProperty(userStore, QName.createQName(null, sandboxIdProp), - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(previewStore, QName.createQName(null, sandboxIdProp), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - if (logger.isDebugEnabled()) - { - dumpStoreProperties(avmService, userStore); - dumpStoreProperties(avmService, previewStore); - } - } - else if (logger.isDebugEnabled()) - { - logger.debug("Not creating as store already exists: " + userStore); + dumpStoreProperties(avmService, workflowMainStoreName); + dumpStoreProperties(avmService, workflowPreviewStoreName); } + return packageName; } /** @@ -277,7 +403,7 @@ public final class SandboxFactory */ private static void tagStoreDNSPath(AVMService avmService, String store, String... components) { - String path = AVMConstants.buildAVMStoreRootPath(store); + String path = AVMConstants.buildSandboxRootPath(store); // DNS name mangle the property name - can only contain value DNS characters! String dnsProp = AVMConstants.PROP_DNS + DNSNameMangler.MakeDNSName(components); avmService.setStoreProperty(store, QName.createQName(null, dnsProp), @@ -291,6 +417,7 @@ public final class SandboxFactory */ private static void dumpStoreProperties(AVMService avmService, String store) { + logger.debug("Store " + store); Map props = avmService.getStoreProperties(store); for (QName name : props.keySet()) { diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index 2e7532d0d8..6c4a13d03a 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -219,13 +219,27 @@ public class SubmitDialog extends BaseDialogBean if (startTask.state == WorkflowTaskState.IN_PROGRESS) { // create container for our avm workflow package - NodeRef workflowPackage = createWorkflowPackage(path.instance.id); + final List items = this.getSubmitItems(); + final List srcPaths = new ArrayList(items.size()); + for (ItemWrapper wrapper : items) + { + srcPaths.add(wrapper.getDescriptor().getPath()); + } + final NodeRef workflowPackage = + AVMWorkflowUtil.createWorkflowPackage(srcPaths, + this.avmBrowseBean.getStagingStore(), + path, + avmSubmittedAspect, + this.avmSyncService, + this.avmService, + this.workflowService, + this.nodeService); params.put(WorkflowModel.ASSOC_PACKAGE, workflowPackage); // add submission parameters params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, getComment()); params.put(AVMWorkflowUtil.PROP_LABEL, getLabel()); - params.put(AVMWorkflowUtil.PROP_FROM_PATH, AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getSandbox())); + params.put(AVMWorkflowUtil.PROP_FROM_PATH, AVMConstants.buildSandboxRootPath(this.avmBrowseBean.getSandbox())); // update start task with submit parameters this.workflowService.updateTask(startTask.id, params, null, null); @@ -249,8 +263,8 @@ public class SubmitDialog extends BaseDialogBean List items = getSubmitItems(); // construct diffs for selected items for submission - String sandboxPath = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getSandbox()); - String stagingPath = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getStagingStore()); + String sandboxPath = AVMConstants.buildSandboxRootPath(this.avmBrowseBean.getSandbox()); + String stagingPath = AVMConstants.buildSandboxRootPath(this.avmBrowseBean.getStagingStore()); List diffs = new ArrayList(items.size()); for (ItemWrapper wrapper : items) { @@ -457,8 +471,8 @@ public class SubmitDialog extends BaseDialogBean if (this.avmBrowseBean.getAllItemsAction()) { String webapp = this.avmBrowseBean.getWebapp(); - String userStore = AVMConstants.buildAVMStoreWebappPath(this.avmBrowseBean.getSandbox(), webapp); - String stagingStore = AVMConstants.buildAVMStoreWebappPath(this.avmBrowseBean.getStagingStore(), webapp); + String userStore = AVMConstants.buildStoreWebappPath(this.avmBrowseBean.getSandbox(), webapp); + String stagingStore = AVMConstants.buildStoreWebappPath(this.avmBrowseBean.getStagingStore(), webapp); List diffs = this.avmSyncService.compare(-1, userStore, -1, stagingStore, nameMatcher); selected = new ArrayList(diffs.size()); for (AVMDifference diff : diffs) @@ -571,46 +585,6 @@ public class SubmitDialog extends BaseDialogBean } } - /** - * Construct a workflow package as a layered directory over the staging sandbox. The items for - * submission are pushed into the layer and the package constructed around it. - * - * @param workflowInstanceId workflow instance id - * @return Reference to the package - */ - private NodeRef createWorkflowPackage(String workflowInstanceId) - { - List items = getSubmitItems(); - - // create package paths (layered to staging area as target) - String stagingPath = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getStagingStore()); - String packagesPath = AVMWorkflowUtil.createAVMLayeredPackage(this.avmService, stagingPath); - - // construct diffs for selected items for submission - // mark selected items for submission - String sandboxPath = AVMConstants.buildAVMStoreRootPath(this.avmBrowseBean.getSandbox()); - List diffs = new ArrayList(this.submitItems.size()); - for (ItemWrapper wrapper : this.submitItems) - { - String srcPath = sandboxPath + wrapper.getPath(); - String destPath = packagesPath + wrapper.getPath(); - AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER); - diffs.add(diff); - avmSubmittedAspect.markSubmitted(-1, srcPath, workflowInstanceId); - } - - // write changes to layer so files are marked as modified - this.avmSyncService.update(diffs, null, true, true, false, false, null, null); - - // convert package to workflow package - AVMNodeDescriptor packageDesc = this.avmService.lookup(-1, packagesPath); - NodeRef packageNodeRef = this.workflowService.createPackage( - AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath())); - this.nodeService.setProperty(packageNodeRef, WorkflowModel.PROP_IS_SYSTEM_PACKAGE, true); - - return packageNodeRef; - } - /** * Action method to setup a workflow for dialog context for the current row */ @@ -761,15 +735,12 @@ public class SubmitDialog extends BaseDialogBean public String getName() { - if (descriptor.isDeleted() == false) + String result = descriptor.getName(); + if (descriptor.isDeleted()) { - return descriptor.getName(); - } - else - { - return descriptor.getName() + " [" + - Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETED_ITEM) + "]"; + result += " [" + Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETED_ITEM) + "]"; } + return result; } public String getModifiedDate() @@ -801,16 +772,16 @@ public class SubmitDialog extends BaseDialogBean AVMNodeConverter.ToNodeRef(-1, descriptor.getPath()), descriptor.getName()); } + public AVMNodeDescriptor getDescriptor() + { + return this.descriptor; + } + public String getIcon() { - if (descriptor.isFile() || descriptor.isDeletedFile()) - { - return Utils.getFileTypeImage(descriptor.getName(), true); - } - else - { - return SPACE_ICON; - } + return (descriptor.isFile() || descriptor.isDeletedFile() + ? Utils.getFileTypeImage(descriptor.getName(), true) + : SPACE_ICON); } @Override diff --git a/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java b/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java index d2eb3c5503..892d4ab010 100644 --- a/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java +++ b/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java @@ -542,7 +542,6 @@ public class ManageTaskDialog extends BaseDialogBean final NodeRef stagingNodeRef = (NodeRef) this.nodeService.getProperty(this.workflowPackage, WCMModel.PROP_AVM_DIR_INDIRECTION); - final String fromAvmPath = (String)this.task.properties.get(AVMWorkflowUtil.PROP_FROM_PATH); final String stagingAvmPath = AVMNodeConverter.ToAVMVersionPath(stagingNodeRef).getSecond(); final String packageAvmPath = AVMNodeConverter.ToAVMVersionPath(this.workflowPackage).getSecond(); LOGGER.debug("comparing " + packageAvmPath + @@ -712,9 +711,9 @@ public class ManageTaskDialog extends BaseDialogBean return result; } }; - node.remove("path"); - node.addPropertyResolver("path", resolverPath); - node.addPropertyResolver("displayPath", resolverPath); +// node.remove("path"); +// node.addPropertyResolver("path", resolverPath); +// node.addPropertyResolver("displayPath", resolverPath); LOGGER.debug("created mapnode " + node); diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java index e0c2a69a44..473cddb49e 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -126,9 +126,9 @@ class FormImpl String result = templateService.processTemplateString(null, outputPathPattern, new SimpleHash(root)); - result = AVMConstants.buildAVMPath(parentAVMPath, - result, - AVMConstants.PathRelation.SANDBOX_RELATIVE); + result = AVMConstants.buildPath(parentAVMPath, + result, + AVMConstants.PathRelation.SANDBOX_RELATIVE); LOGGER.debug("processed pattern " + outputPathPattern + " as " + result); return result; } diff --git a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java index 52861b264f..c868edb01c 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -96,7 +96,7 @@ public class FormInstanceDataImpl public String getUrl() { - return AVMConstants.buildAVMAssetUrl(this.getPath()); + return AVMConstants.buildAssetUrl(this.getPath()); } public List getRenditions() diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java index 5c3b4e8b59..df3e798e67 100644 --- a/source/java/org/alfresco/web/forms/FormsService.java +++ b/source/java/org/alfresco/web/forms/FormsService.java @@ -378,7 +378,7 @@ public final class FormsService final String renditionAvmPath) { final HashMap parameters = new HashMap(); - parameters.put("avm_sandbox_url", AVMConstants.buildAVMStoreUrl(formInstanceDataAvmPath)); + parameters.put("avm_sandbox_url", AVMConstants.buildStoreUrl(formInstanceDataAvmPath)); parameters.put("form_instance_data_file_name", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[1]); parameters.put("rendition_file_name", AVMNodeConverter.SplitBase(renditionAvmPath)[1]); parameters.put("parent_path", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[0]); diff --git a/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java b/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java index e9859e9e0c..d3d1b65e8e 100644 --- a/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java +++ b/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java @@ -99,9 +99,9 @@ public class FreeMarkerRenderingEngine { final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions(); final String path = - AVMConstants.buildAVMPath(parameters.get("parent_path"), - (String)args.get(0), - AVMConstants.PathRelation.WEBAPP_RELATIVE); + AVMConstants.buildPath(parameters.get("parent_path"), + (String)args.get(0), + AVMConstants.PathRelation.WEBAPP_RELATIVE); final Document d = ef.parseXMLDocument(path); return d != null ? d.getDocumentElement() : null; } @@ -121,9 +121,9 @@ public class FreeMarkerRenderingEngine { final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions(); final String path = - AVMConstants.buildAVMPath(parameters.get("parent_path"), - args.size() == 1 ? "" : (String)args.get(1), - AVMConstants.PathRelation.WEBAPP_RELATIVE); + AVMConstants.buildPath(parameters.get("parent_path"), + args.size() == 1 ? "" : (String)args.get(1), + AVMConstants.PathRelation.WEBAPP_RELATIVE); final Map resultMap = ef.parseXMLDocuments((String)args.get(0), path); LOGGER.debug("received " + resultMap.size() + " documents in " + path); @@ -168,9 +168,9 @@ public class FreeMarkerRenderingEngine { try { - return AVMConstants.buildAVMPath(parameters.get("parent_path"), - (String)args.get(0), - AVMConstants.PathRelation.WEBAPP_RELATIVE); + return AVMConstants.buildPath(parameters.get("parent_path"), + (String)args.get(0), + AVMConstants.PathRelation.WEBAPP_RELATIVE); } catch (Exception e) { diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java index f776403f37..c890515466 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java +++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java @@ -177,9 +177,9 @@ public class RenderingEngineTemplateImpl outputPathPattern, new SimpleHash(root)); final String parentAVMPath = AVMNodeConverter.SplitBase(formInstanceDataAVMPath)[0]; - result = AVMConstants.buildAVMPath(parentAVMPath, - result, - AVMConstants.PathRelation.SANDBOX_RELATIVE); + result = AVMConstants.buildPath(parentAVMPath, + result, + AVMConstants.PathRelation.SANDBOX_RELATIVE); LOGGER.debug("processed pattern " + outputPathPattern + " as " + result); return result; } diff --git a/source/java/org/alfresco/web/forms/RenditionImpl.java b/source/java/org/alfresco/web/forms/RenditionImpl.java index b2ba98e7b0..60fd2fae65 100644 --- a/source/java/org/alfresco/web/forms/RenditionImpl.java +++ b/source/java/org/alfresco/web/forms/RenditionImpl.java @@ -120,7 +120,7 @@ public class RenditionImpl public String getUrl() { - return AVMConstants.buildAVMAssetUrl(this.getPath()); + return AVMConstants.buildAssetUrl(this.getPath()); } public String getFileTypeImage() diff --git a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java index 947eb8f342..4145da051c 100644 --- a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java +++ b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java @@ -79,9 +79,9 @@ public class XSLTRenderingEngine throws TransformerException { final XObject o = ec.getVariableOrParam(new QName(ALFRESCO_NS, ALFRESCO_NS_PREFIX, "parent_path")); - return o == null ? null : AVMConstants.buildAVMPath(o.toString(), - path, - AVMConstants.PathRelation.WEBAPP_RELATIVE); + return o == null ? null : AVMConstants.buildPath(o.toString(), + path, + AVMConstants.PathRelation.WEBAPP_RELATIVE); } /** diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java index 7ba0b9cb00..8a26cc2e68 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java @@ -432,11 +432,10 @@ public class XFormsBean else { final String previewStorePath = - this.avmBrowseBean.getCurrentPath().replaceFirst(AVMConstants.STORE_MAIN, - AVMConstants.STORE_PREVIEW); - currentPath = AVMConstants.buildAVMPath(previewStorePath, - currentPath, - AVMConstants.PathRelation.WEBAPP_RELATIVE); + AVMConstants.getCorrespondingPathInPreviewStore(this.avmBrowseBean.getCurrentPath()); + currentPath = AVMConstants.buildPath(previewStorePath, + currentPath, + AVMConstants.PathRelation.WEBAPP_RELATIVE); } LOGGER.debug(this + ".getFilePickerData(" + currentPath + ")"); @@ -518,11 +517,10 @@ public class XFormsBean else if (item.isFormField() && item.getFieldName().equals("currentPath")) { final String previewStorePath = - this.avmBrowseBean.getCurrentPath().replaceFirst(AVMConstants.STORE_MAIN, - AVMConstants.STORE_PREVIEW); - currentPath = AVMConstants.buildAVMPath(previewStorePath, - item.getString(), - AVMConstants.PathRelation.WEBAPP_RELATIVE); + AVMConstants.getCorrespondingPathInPreviewStore(this.avmBrowseBean.getCurrentPath()); + currentPath = AVMConstants.buildPath(previewStorePath, + item.getString(), + AVMConstants.PathRelation.WEBAPP_RELATIVE); LOGGER.debug("currentPath is " + currentPath); } else @@ -629,8 +627,8 @@ public class XFormsBean { String uri = includeEl.getAttribute("schemaLocation"); final String baseURI = (uri.charAt(0) == '/' - ? AVMConstants.buildAVMStoreUrl(cwdAvmPath) - : AVMConstants.buildAVMAssetUrl(cwdAvmPath)); + ? AVMConstants.buildStoreUrl(cwdAvmPath) + : AVMConstants.buildAssetUrl(cwdAvmPath)); LOGGER.debug("rewriting " + uri + " as " + (baseURI + uri)); includeEl.setAttribute("schemaLocation", baseURI + uri); diff --git a/source/java/org/alfresco/web/ui/common/renderer/BaseRenderer.java b/source/java/org/alfresco/web/ui/common/renderer/BaseRenderer.java index 18ce65b249..4a55ea39db 100644 --- a/source/java/org/alfresco/web/ui/common/renderer/BaseRenderer.java +++ b/source/java/org/alfresco/web/ui/common/renderer/BaseRenderer.java @@ -18,7 +18,7 @@ package org.alfresco.web.ui.common.renderer; import java.io.IOException; import java.util.HashMap; -import java.util.Iterator; +import java.util.List; import java.util.Map; import javax.faces.component.UIComponent; @@ -81,26 +81,33 @@ public abstract class BaseRenderer extends Renderer * * @param component to find UIParameter child values for * - * @return a Map of name/value pairs or null if none found + * @return a Map of name/value pairs or null if none found */ - protected static Map getParameterComponents(UIComponent component) + protected static Map getParameterComponents(final UIComponent component) { - Map params = null; - - if (component.getChildCount() != 0) + if (component.getChildCount() == 0) { - params = new HashMap(component.getChildCount(), 1.0f); - for (Iterator i=component.getChildren().iterator(); i.hasNext(); /**/) + return null; + } + + final Map params = new HashMap(component.getChildCount(), 1.0f); + for (UIComponent child : (List)component.getChildren()) + { + if (child instanceof UIParameter) { - UIComponent child = (UIComponent)i.next(); - if (child instanceof UIParameter) + final UIParameter param = (UIParameter)child; + if (param.getValue() == null || param.getValue() instanceof String) { - UIParameter param = (UIParameter)child; params.put(param.getName(), (String)param.getValue()); } + else + { + throw new ClassCastException("value of parameter " + param.getName() + + " is a " + param.getValue().getClass().getName() + + ". Expected a " + String.class.getName()); + } } } - return params; } } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index f430358e5c..ee4296d2c4 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -293,7 +293,7 @@ public class UIUserSandboxes extends SelfRenderingComponent this.rowToUserLookup.put(username, index); // build the name of the main store for this user - String mainStore = AVMConstants.buildAVMUserMainStoreName(storeRoot, username); + String mainStore = AVMConstants.buildUserMainStoreName(storeRoot, username); // check it exists before we render the view if (avmService.getStore(mainStore) != null) @@ -302,7 +302,7 @@ public class UIUserSandboxes extends SelfRenderingComponent if (logger.isDebugEnabled()) logger.debug("Checking user permissions for store: " + mainStore); if (permissionService.hasPermission( - AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildAVMStoreRootPath(mainStore)), + AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildSandboxRootPath(mainStore)), PermissionService.READ) == AccessStatus.ALLOWED) { if (logger.isDebugEnabled()) @@ -334,7 +334,7 @@ public class UIUserSandboxes extends SelfRenderingComponent out.write(")"); // direct actions for a sandbox - String websiteUrl = AVMConstants.buildAVMWebappUrl(mainStore, getWebapp()); + String websiteUrl = AVMConstants.buildWebappUrl(mainStore, getWebapp()); Map requestMap = context.getExternalContext().getRequestMap(); requestMap.put(REQUEST_PREVIEW_REF, websiteUrl); Utils.encodeRecursive(context, aquireAction( @@ -480,14 +480,14 @@ public class UIUserSandboxes extends SelfRenderingComponent ResourceBundle bundle = Application.getBundle(fc); // build the paths to the stores to compare - filter by current webapp - String userStore = AVMConstants.buildAVMUserMainStoreName(storeRoot, username); - String userStorePath = AVMConstants.buildAVMStoreWebappPath(userStore, getWebapp()); - String stagingStore = AVMConstants.buildAVMStagingStoreName(storeRoot); - String stagingStorePath = AVMConstants.buildAVMStoreWebappPath(stagingStore, getWebapp()); + String userStore = AVMConstants.buildUserMainStoreName(storeRoot, username); + String userStorePath = AVMConstants.buildStoreWebappPath(userStore, getWebapp()); + String stagingStore = AVMConstants.buildStagingStoreName(storeRoot); + String stagingStorePath = AVMConstants.buildStoreWebappPath(stagingStore, getWebapp()); // info we need to calculate preview paths for assets String dns = AVMConstants.lookupStoreDNS(userStore); - int rootPathIndex = AVMConstants.buildAVMStoreRootPath(userStore).length(); + int rootPathIndex = AVMConstants.buildSandboxRootPath(userStore).length(); ClientConfigElement config = Application.getClientConfig(fc); // get the UIActions component responsible for rendering context related user actions @@ -603,7 +603,7 @@ public class UIUserSandboxes extends SelfRenderingComponent // build node context required for actions AVMNode avmNode = new AVMNode(node); String assetPath = sourcePath.substring(rootPathIndex); - String previewUrl = AVMConstants.buildAVMAssetUrl( + String previewUrl = AVMConstants.buildAssetUrl( assetPath, config.getWCMDomain(), config.getWCMPort(), dns); avmNode.getProperties().put("previewUrl", previewUrl); @@ -704,7 +704,7 @@ public class UIUserSandboxes extends SelfRenderingComponent { NodeService nodeService = getNodeService(fc); Map requestMap = fc.getExternalContext().getRequestMap(); - String userStorePrefix = AVMConstants.buildAVMUserMainStoreName(storeRoot, username); + String userStorePrefix = AVMConstants.buildUserMainStoreName(storeRoot, username); // only need to collect the list of forms once per render // TODO: execute permission evaluations on a per user basis against each form? diff --git a/source/web/WEB-INF/faces-config-navigation.xml b/source/web/WEB-INF/faces-config-navigation.xml index 31c804edd9..7e3f9f498f 100644 --- a/source/web/WEB-INF/faces-config-navigation.xml +++ b/source/web/WEB-INF/faces-config-navigation.xml @@ -892,10 +892,6 @@ browseSandbox /jsp/wcm/browse-sandbox.jsp - - - - /jsp/wcm/* importContent /jsp/wcm/import-content-dialog.jsp @@ -924,10 +920,6 @@ updateAvmFile /jsp/wcm/update-file.jsp - - cancel - /jsp/wcm/browse-sandbox.jsp - showFileDetails /jsp/wcm/file-details.jsp @@ -937,5 +929,11 @@ /jsp/wcm/folder-details.jsp - + + /jsp/wcm/* + + cancel + /jsp/wcm/browse-sandbox.jsp + + diff --git a/source/web/jsp/workflow/manage-task-dialog.jsp b/source/web/jsp/workflow/manage-task-dialog.jsp index e8170a429b..67174e6be9 100644 --- a/source/web/jsp/workflow/manage-task-dialog.jsp +++ b/source/web/jsp/workflow/manage-task-dialog.jsp @@ -62,6 +62,8 @@ <%-- Path column --%> +<%-- +XXXarielb need to uncomment this once i figure out how to deal with paths... @@ -69,7 +71,7 @@ - +--%> <%-- Created Date column --%>