diff --git a/source/java/org/alfresco/web/action/evaluator/WCMContentManagerEvaluator.java b/source/java/org/alfresco/web/action/evaluator/WCMContentManagerEvaluator.java index 4dd3573044..12883ae5cc 100644 --- a/source/java/org/alfresco/web/action/evaluator/WCMContentManagerEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/WCMContentManagerEvaluator.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 @@ -26,12 +26,9 @@ package org.alfresco.web.action.evaluator; import javax.faces.context.FacesContext; -import org.alfresco.model.WCMAppModel; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.web.action.ActionEvaluator; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.wcm.SandboxFactory; /** * Evaluator to return true if the current user is a content manager for the current website. @@ -48,10 +45,7 @@ public class WCMContentManagerEvaluator extends BaseActionEvaluator public boolean evaluate(final Node node) { FacesContext facesContext = FacesContext.getCurrentInstance(); - NodeService nodeService = Repository.getServiceRegistry(facesContext).getNodeService(); - - String storeId = (String)nodeService.getProperty(node.getNodeRef(), WCMAppModel.PROP_AVMSTORE); - - return SandboxFactory.isContentManager(storeId); + WebProjectService webProjectService = Repository.getServiceRegistry(facesContext).getWebProjectService(); + return webProjectService.isContentManager(node.getNodeRef()); } } diff --git a/source/java/org/alfresco/web/bean/actions/handlers/CopyToWebProjectHandler.java b/source/java/org/alfresco/web/bean/actions/handlers/CopyToWebProjectHandler.java index 92d9622535..f4835b365a 100644 --- a/source/java/org/alfresco/web/bean/actions/handlers/CopyToWebProjectHandler.java +++ b/source/java/org/alfresco/web/bean/actions/handlers/CopyToWebProjectHandler.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 @@ -100,7 +100,7 @@ public class CopyToWebProjectHandler extends BaseActionHandler folder = avmPath.substring(avmPath.indexOf(AVMUtil.DIR_ROOT)+4); // get the destination web project name - NodeRef webProjectNode = AVMUtil.getWebProjectNodeFromPath(avmPath); + NodeRef webProjectNode = Repository.getServiceRegistry(context).getWebProjectService().findWebProjectNodeFromPath(avmPath); webProject = Repository.getNameForNode( Repository.getServiceRegistry(context).getNodeService(), webProjectNode); } diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 7c71e8c18d..5123764b3b 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -75,9 +75,10 @@ import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.workflow.WorkflowService; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.Pair; import org.alfresco.util.VirtServerUtils; +import org.alfresco.wcm.webproject.WebProjectInfo; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; @@ -87,7 +88,6 @@ import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.search.SearchContext; import org.alfresco.web.forms.FormInstanceData; import org.alfresco.web.forms.FormNotFoundException; @@ -220,6 +220,9 @@ public class AVMBrowseBean implements IContextListener /** The NavigationBean bean reference */ protected NavigationBean navigator; + /** WebProjectService bean reference */ + transient protected WebProjectService wpService; + /** AVM service bean reference */ transient protected AVMService avmService; @@ -255,6 +258,23 @@ public class AVMBrowseBean implements IContextListener // ------------------------------------------------------------------------------ // Bean property getters and setters + /** + * @param wpService The WebProjectService to set. + */ + public void setWebProjectService(WebProjectService wpService) + { + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); + } + return wpService; + } + /** * @param avmService The AVMService to set. */ @@ -493,8 +513,7 @@ public class AVMBrowseBean implements IContextListener summary.append(msg.getString(MSG_CREATED_BY)).append(": ") .append(store.getCreator()) .append("

"); - final int numUsers = nodeService.getChildAssocs( - webProject.getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL).size(); + final int numUsers = getWebProjectService().getWebUserCount(webProject.getNodeRef()); summary.append(MessageFormat.format(msg.getString(MSG_WORKING_USERS), numUsers)); } @@ -616,7 +635,15 @@ public class AVMBrowseBean implements IContextListener if (this.webapp == null) { // TODO - temporary, should only be called for WCM forms (not ECM forms) - this.webapp = this.getWebProject() != null ? this.getWebProject().getDefaultWebapp() : null; + Node wpNode = getWebsite(); + if (wpNode != null) + { + WebProjectInfo wpInfo = getWebProjectService().getWebProject(wpNode.getNodeRef()); + if (wpInfo != null) + { + this.webapp = wpInfo.getDefaultWebApp(); + } + } } return this.webapp; } @@ -1012,8 +1039,12 @@ public class AVMBrowseBean implements IContextListener */ public boolean getIsManagerRole() { - final User user = Application.getCurrentUser(FacesContext.getCurrentInstance()); - return this.getWebProject().isManager(user); + Node wpNode = getWebsite(); + if (wpNode != null) + { + return getWebProjectService().isContentManager(wpNode.getNodeRef()); + } + return false; } /** diff --git a/source/java/org/alfresco/web/bean/wcm/AVMUtil.java b/source/java/org/alfresco/web/bean/wcm/AVMUtil.java index 5c2bb2fc53..1dacb60605 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMUtil.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMUtil.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 @@ -25,7 +25,6 @@ package org.alfresco.web.bean.wcm; import java.text.MessageFormat; -import java.util.Map; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -36,36 +35,30 @@ import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigService; import org.alfresco.config.JNDIConstants; import org.alfresco.mbeans.VirtServerRegistry; -import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.sandbox.SandboxConstants; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMNotFoundException; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.VirtServerUtils; +import org.alfresco.wcm.util.WCMUtil; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.preview.PreviewURIService; import org.alfresco.web.bean.wcm.preview.VirtualisationServerPreviewURIService; import org.alfresco.web.config.ClientConfigElement; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.jsf.FacesContextUtils; - /** * Helper methods and constants related to AVM directories, paths and store name manipulation. * + * TODO refactor ... + * * @author Ariel Backenroth * @author Kevin Roast */ -public final class AVMUtil +public final class AVMUtil extends WCMUtil { ///////////////////////////////////////////////////////////////////////////// @@ -93,204 +86,64 @@ public final class AVMUtil ///////////////////////////////////////////////////////////////////////////// - /** - * Private constructor - */ - private AVMUtil() - { - } - - /** - * Extracts the store name from the avmpath - * - * @param avmPath an absolute avm path - * - * @return the store name - */ public static String getStoreName(final String avmPath) { - final int i = avmPath.indexOf(':'); - if (i == -1) - { - throw new IllegalArgumentException("path " + avmPath + " does not contain a store"); - } - 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(AVMUtil.STORE_SEPARATOR + AVMUtil.STORE_PREVIEW); - } - - /** - * Indicates whether the store name describes a workflow store. - * - * @param storeName the store name - * - * @return true if the store is a workflow store, false otherwise. - */ - public static boolean isWorkflowStore(String storeName) - { - if (AVMUtil.isPreviewStore(storeName)) - { - storeName = AVMUtil.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 (AVMUtil.isPreviewStore(storeName)) - { - storeName = AVMUtil.getCorrespondingMainStoreName(storeName); - } - return storeName.indexOf(AVMUtil.STORE_SEPARATOR) != -1; + return WCMUtil.getStoreName(avmPath); + } + + public static boolean isPreviewStore(final String storeName) + { + return WCMUtil.isPreviewStore(storeName); + } + + public static boolean isWorkflowStore(String storeName) + { + return WCMUtil.isWorkflowStore(storeName); + } + + public static boolean isUserStore(String storeName) + { + return WCMUtil.isUserStore(storeName); } - /** - * Indicates whether the store name describes a main store. - * - * @param storeName the store name - * - * @return true if the store is a main store, false otherwise. - */ public static boolean isMainStore(String storeName) { - return (storeName.indexOf(AVMUtil.STORE_SEPARATOR) == -1); + return WCMUtil.isMainStore(storeName); } - /** - * 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 (AVMUtil.isPreviewStore(storeName)) - { - storeName = AVMUtil.getCorrespondingMainStoreName(storeName); - } - final int index = storeName.indexOf(AVMUtil.STORE_SEPARATOR); - return (index == -1 - ? null - : storeName.substring(index + AVMUtil.STORE_SEPARATOR.length())); + return WCMUtil.getUserName(storeName); } - /** - * 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(AVMUtil.STORE_SEPARATOR); - return (index == -1 - ? storeName - : storeName.substring(0, index)); + return WCMUtil.getStoreId(storeName); } - /** - * 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 (!AVMUtil.isPreviewStore(storeName)) - { - throw new IllegalArgumentException("store " + storeName + " is not a preview store"); - } - return storeName.substring(0, - (storeName.length() - - (AVMUtil.STORE_SEPARATOR + AVMUtil.STORE_PREVIEW).length())); + return WCMUtil.getCorrespondingMainStoreName(storeName); } - /** - * 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 (AVMUtil.isPreviewStore(storeName)) - { - throw new IllegalArgumentException("store " + storeName + " is already a preview store"); - } - return storeName + AVMUtil.STORE_SEPARATOR + AVMUtil.STORE_PREVIEW; + return WCMUtil.getCorrespondingPreviewStoreName(storeName); } - /** - * Returns the corresponding path in the main store name if this is a path in - * a preview 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 = AVMUtil.getStoreName(avmPath); - storeName = AVMUtil.getCorrespondingMainStoreName(storeName); - return AVMUtil.getCorrespondingPath(avmPath, storeName); + return WCMUtil.getCorrespondingPathInMainStore(avmPath); } - /** - * 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 = AVMUtil.getStoreName(avmPath); - storeName = AVMUtil.getCorrespondingPreviewStoreName(storeName); - return AVMUtil.getCorrespondingPath(avmPath, storeName); + return WCMUtil.getCorrespondingPathInPreviewStore(avmPath); } - /** - * Returns the corresponding path in the store provided. - * - * @param avmPath an avm path - * @param otherStore the other store to return the corresponding path for - * - * @return the corresponding path within the supplied store - */ public static String getCorrespondingPath(final String avmPath, final String otherStore) { - return (otherStore + ':' + AVMUtil.getStoreRelativePath(avmPath)); + return WCMUtil.getCorrespondingPath(avmPath, otherStore); } /** @@ -371,146 +224,53 @@ public final class AVMUtil return pollFreq; } - /** - * Returns the main staging store name for the specified store id. - * - * @param storeId store id to build staging store name for - * - * @return main staging store name for the specified store id - */ public static String buildStagingStoreName(final String storeId) { - if (storeId == null || storeId.length() == 0) - { - throw new IllegalArgumentException("Store id is mandatory."); - } - return storeId; + return WCMUtil.buildStagingStoreName(storeId); } - /** - * Returns the preview store name for the specified store id. - * - * @param storeId store id to build preview store name for - * - * @return preview store name for the specified store id - */ public static String buildStagingPreviewStoreName(final String storeId) { - return (AVMUtil.buildStagingStoreName(storeId) + - AVMUtil.STORE_SEPARATOR + AVMUtil.STORE_PREVIEW); + return WCMUtil.buildStagingPreviewStoreName(storeId); } - /** - * Returns the main store name for a specific username. - * - * @param storeId store id to build user store name for - * @param username of the user to build store name for - * - * @return the main store for the specified user and store id - */ public static String buildUserMainStoreName(final String storeId, final String username) { - if (username == null || username.length() == 0) - { - throw new IllegalArgumentException("Username is mandatory."); - } - return (AVMUtil.buildStagingStoreName(storeId) + AVMUtil.STORE_SEPARATOR + - username); + return WCMUtil.buildUserMainStoreName(storeId, username); } - /** - * Returns the preview store name for a specific username. - * - * @param storeId store id to build user preview store name for - * @param username of the user to build preview store name for - * - * @return the preview store for the specified user and store id - */ public static String buildUserPreviewStoreName(final String storeId, final String username) { - return (AVMUtil.buildUserMainStoreName(storeId, username) + - AVMUtil.STORE_SEPARATOR + AVMUtil.STORE_PREVIEW); + return WCMUtil.buildUserPreviewStoreName(storeId, username); } - /** - * Returns the store name for a specific workflow Id. - * - * @param storeId store id to build workflow store name for - * @param workflowId of the user to build workflow store name for - * - * @return the store for the specified workflow and store ids - */ public static String buildWorkflowMainStoreName(final String storeId, final String workflowId) { - if (workflowId == null || workflowId.length() == 0) - { - throw new IllegalArgumentException("workflowId is mandatory."); - } - return (AVMUtil.buildStagingStoreName(storeId) + AVMUtil.STORE_SEPARATOR + - workflowId); + return WCMUtil.buildWorkflowMainStoreName(storeId, workflowId); } - /** - * Returns the preview store name for a specific workflow Id. - * - * @param storeId store id to build preview workflow store name for - * @param workflowId of the user to build preview workflow store name for - * - * @return the store for the specified preview workflow and store ids - */ public static String buildWorkflowPreviewStoreName(final String storeId, final String workflowId) { - return (AVMUtil.buildWorkflowMainStoreName(storeId, workflowId) + - AVMUtil.STORE_SEPARATOR + AVMUtil.STORE_PREVIEW); + return WCMUtil.buildWorkflowPreviewStoreName(storeId, workflowId); } - /** - * Returns the root path for the specified store name - * - * @param storeName store to build root path for - * - * @return root path for the specified store name - */ public static String buildStoreRootPath(final String storeName) { - if (storeName == null || storeName.length() == 0) - { - throw new IllegalArgumentException("Store name is mandatory."); - } - return storeName + ":/" + JNDIConstants.DIR_DEFAULT_WWW; + return WCMUtil.buildStoreRootPath(storeName); } - /** - * Returns the root path for the specified sandbox name - * - * @param storeName store to build root sandbox path for - * - * @return root sandbox path for the specified store name - */ public static String buildSandboxRootPath(final String storeName) { - return AVMUtil.buildStoreRootPath(storeName) + '/' + JNDIConstants.DIR_DEFAULT_APPBASE; + return WCMUtil.buildSandboxRootPath(storeName); } - /** - * Returns the root webapp path for the specified store and webapp name - * - * @param storeName store to build root webapp path for - * @param webapp webapp folder name - * - * @return the root webapp path for the specified store and webapp name - */ public static String buildStoreWebappPath(final String storeName, String webapp) { - if (webapp == null || webapp.length() == 0) - { - throw new IllegalArgumentException("Webapp name is mandatory."); - } - return AVMUtil.buildSandboxRootPath(storeName) + '/' + webapp; + return WCMUtil.buildStoreWebappPath(storeName, webapp); } public static String buildStoreUrl(String store) @@ -539,7 +299,7 @@ public final class AVMUtil return AVMUtil.buildWebappUrl(AVMUtil.getStoreName(avmPath), AVMUtil.getWebapp(avmPath)); } - + public static String buildWebappUrl(final String store, final String webapp) { if (webapp == null || webapp.length() == 0) @@ -581,30 +341,7 @@ public final class AVMUtil public static String buildAssetUrl(String assetPath, String domain, String port, String dns) { - if (domain == null || port == null || dns == null) - { - throw new IllegalArgumentException("Domain, port and dns name are mandatory."); - } - if (assetPath == null || assetPath.length() == 0) - { - throw new IllegalArgumentException("Asset path is mandatory."); - } - if (assetPath.startsWith('/' + JNDIConstants.DIR_DEFAULT_WWW + - '/' + JNDIConstants.DIR_DEFAULT_APPBASE)) - { - assetPath = assetPath.substring(('/' + JNDIConstants.DIR_DEFAULT_WWW + - '/' + JNDIConstants.DIR_DEFAULT_APPBASE).length()); - } - if (assetPath.startsWith('/' + DIR_ROOT)) - { - assetPath = assetPath.substring(('/' + DIR_ROOT).length()); - } - if (assetPath.length() == 0 || assetPath.charAt(0) != '/') - { - assetPath = '/' + assetPath; - } - - return MessageFormat.format(JNDIConstants.PREVIEW_ASSET_URL, dns, domain, port, assetPath); + return WCMUtil.buildAssetUrl(assetPath, domain, port, dns); } public static String getPreviewURI(final String storeId, final String assetPath) @@ -633,19 +370,10 @@ public final class AVMUtil public static String lookupStoreDNS(String store) { - if (store == null || store.length() == 0) - { - throw new IllegalArgumentException("Store name is mandatory."); - } - final ServiceRegistry serviceRegistry = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); final AVMService avmService = serviceRegistry.getAVMService(); - final Map props = - avmService.queryStorePropertyKey(store, QName.createQName(null, SandboxConstants.PROP_DNS + '%')); - return (props.size() == 1 - ? props.keySet().iterator().next().getLocalName().substring(SandboxConstants.PROP_DNS.length()) - : null); + return WCMUtil.lookupStoreDNS(avmService, store); } /** @@ -685,157 +413,34 @@ public final class AVMUtil 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; + return WCMUtil.getStoreRelativePath(absoluteAVMPath); } - - /** - * Returns a path relative to the webapp portion of the avm path. - * - * @param absoluteAVMPath an absolute path within the avm - * @return a relative path within the webapp. - */ + public static String getWebappRelativePath(final String absoluteAVMPath) { - final Matcher m = WEBAPP_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath); - return m.matches() && m.group(3).length() != 0 ? m.group(3) : "/"; + return WCMUtil.getWebappRelativePath(absoluteAVMPath); } - /** - * Returns the webapp within the path - * - * @param absoluteAVMPath the path from which to extract the webapp name - * - * @return an the webapp name contained within the path or null. - */ public static String getWebapp(final String absoluteAVMPath) { - final Matcher m = WEBAPP_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath); - return m.matches() && m.group(2).length() != 0 ? m.group(2) : null; + return WCMUtil.getWebapp(absoluteAVMPath); } - /** - * Returns the path portion up the webapp - * - * @param absoluteAVMPath the path from which to extract the webapp path - * - * @return an absolute avm path to the webapp contained within - * the path or null. - */ public static String getWebappPath(final String absoluteAVMPath) { - final Matcher m = WEBAPP_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath); - return m.matches() && m.group(1).length() != 0 ? m.group(1) : null; + return WCMUtil.getWebappPath(absoluteAVMPath); } - /** - * Returns a path relative to the sandbox porition of the avm path. - * - * @param absoluteAVMPath an absolute path within the avm - * @return a relative path within the sandbox. - */ public static String getSandboxRelativePath(final String absoluteAVMPath) { - final Matcher m = SANDBOX_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath); - return m.matches() && m.group(2).length() != 0 ? m.group(2) : "/"; + return WCMUtil.getSandboxRelativePath(absoluteAVMPath); } - /** - * Returns the path portion up the sandbox - * - * @param absoluteAVMPath the path from which to extract the sandbox path - * - * @return an absolute avm path to the sandbox contained within - * the path or null. - */ public static String getSandboxPath(final String absoluteAVMPath) { - final Matcher m = SANDBOX_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath); - return m.matches() && m.group(1).length() != 0 ? m.group(1) : null; - } - - /** - * Returns the NodeRef that represents the given avm path - * - * @param absoluteAVMPath The path from which to determine the Web Project - * @return The NodeRef representing the Web Project the path is from or null - * if it could not be determined - */ - public static NodeRef getWebProjectNodeFromPath(final String absoluteAVMPath) - { - String storeName = AVMUtil.getStoreName(absoluteAVMPath); - String storeId = AVMUtil.getStoreId(storeName); - return getWebProjectNodeFromStore(storeId); - } - - /** - * Returns the NodeRef that represents the given avm store - * - * @param storeName The store name from which to determine the Web Project - * @return The NodeRef representing the Web Project the store is from or null - * if it could not be determined - */ - public static NodeRef getWebProjectNodeFromStore(final String storeName) - { - // get services - FacesContext fc = FacesContext.getCurrentInstance(); - SearchService searchService = Repository.getServiceRegistry(fc).getSearchService(); - NodeService nodeService = Repository.getServiceRegistry(fc).getNodeService(); - - // construct the query - String path = Application.getRootPath(fc) + "/" + Application.getWebsitesFolderName(fc) + "/*"; - String query = "PATH:\"/" + path + "\" AND @wca\\:avmstore:\"" + storeName + "\""; - - NodeRef webProjectNode = null; - ResultSet results = null; - try - { - // execute the query - results = searchService.query(Repository.getStoreRef(), - SearchService.LANGUAGE_LUCENE, query); - - // WCM-810: - // the 'avmstore' property was not defined as an identifier in the model (before 2.2) - // which means it may get tokenised which in turn means that 'test' and 'test-site' - // would get returned by the query above even though it's an exact match query, - // we therefore need to go through the results and check names if there is more - // than one result although this shouldn't happen anymore as the - // AVMStorePropertyTokenisationPatch will have reindexed the wca:avmstore property - if (results.length() == 1) - { - webProjectNode = results.getNodeRef(0); - } - else if (results.length() > 1) - { - for (NodeRef node : results.getNodeRefs()) - { - String nodeStoreName = (String)nodeService.getProperty(node, - WCMAppModel.PROP_AVMSTORE); - if (nodeStoreName.equals(storeName)) - { - webProjectNode = node; - break; - } - } - } - } - finally - { - if (results != null) - { - results.close(); - } - } - - return webProjectNode; + return WCMUtil.getSandboxPath(absoluteAVMPath); } /** @@ -875,77 +480,20 @@ public final class AVMUtil avmService.createDirectory(sb[0], sb[1]); } } - - /** - * Update notification on the virtualisation server webapp as required for the specified path - * - * @param path Path to match against - * @param force True to force update of server even if path does not match - */ + public static void updateVServerWebapp(String path, boolean force) { - if (force || VirtServerUtils.requiresUpdateNotification(path)) - { - final int webappIndex = path.indexOf('/', - path.indexOf(JNDIConstants.DIR_DEFAULT_APPBASE) + - JNDIConstants.DIR_DEFAULT_APPBASE.length() + 1); - - if (webappIndex != -1) - { - path = path.substring(0, webappIndex); - } - final VirtServerRegistry vServerRegistry = AVMUtil.getVirtServerRegistry(); - vServerRegistry.updateWebapp(-1, path, true); - } + WCMUtil.updateVServerWebapp(getVirtServerRegistry(), path, force); } - - /** - * Removal notification on all the virtualisation server webapp as required by the specified path - * - * @param path Path to match against - * @param force True to force update of server even if path does not match - */ public static void removeAllVServerWebapps(String path, boolean force) { - if (force || VirtServerUtils.requiresUpdateNotification(path)) - { - final int webappIndex = path.indexOf('/', - path.indexOf(JNDIConstants.DIR_DEFAULT_APPBASE) + - JNDIConstants.DIR_DEFAULT_APPBASE.length() + 1); - - if (webappIndex != -1) - { - path = path.substring(0, webappIndex); - } - final VirtServerRegistry vServerRegistry = AVMUtil.getVirtServerRegistry(); - vServerRegistry.removeAllWebapps(-1, path, true); - } + WCMUtil.removeAllVServerWebapps(getVirtServerRegistry(), path, force); } - - - /** - * Removal notification on the virtualisation server webapp as required for the specified path - * - * @param path Path to match against - * @param force True to force update of server even if path does not match - */ public static void removeVServerWebapp(String path, boolean force) { - if (force || VirtServerUtils.requiresUpdateNotification(path)) - { - final int webappIndex = path.indexOf('/', - path.indexOf(JNDIConstants.DIR_DEFAULT_APPBASE) + - JNDIConstants.DIR_DEFAULT_APPBASE.length() + 1); - - if (webappIndex != -1) - { - path = path.substring(0, webappIndex); - } - final VirtServerRegistry vServerRegistry = AVMUtil.getVirtServerRegistry(); - vServerRegistry.removeWebapp(-1, path, true); - } + WCMUtil.removeVServerWebapp(getVirtServerRegistry(), path, force); } private static VirtServerRegistry getVirtServerRegistry() @@ -984,26 +532,14 @@ public final class AVMUtil } // Component Separator. - public static final String STORE_SEPARATOR = "--"; + public static final String STORE_SEPARATOR = WCMUtil.STORE_SEPARATOR; - // names of the stores representing the layers for an AVM website - //XXXarielb this should be private - public final static String STORE_WORKFLOW = "workflow"; - public final static String STORE_PREVIEW = "preview"; - - // servlet default webapp - // Note: this webapp is mapped to the URL path "" - public final static String DIR_ROOT = "ROOT"; - - public final static String SPACE_ICON_WEBSITE = "space-icon-website"; - - // web user role permissions - public final static String ROLE_CONTENT_MANAGER = "ContentManager"; - public final static String ROLE_CONTENT_PUBLISHER = "ContentPublisher"; + public static final String STORE_WORKFLOW = WCMUtil.STORE_WORKFLOW; + public static final String STORE_PREVIEW = WCMUtil.STORE_PREVIEW; // pattern for absolute AVM Path - private final static Pattern STORE_RELATIVE_PATH_PATTERN = - Pattern.compile("[^:]+:(.+)"); + //private final static Pattern STORE_RELATIVE_PATH_PATTERN = + // Pattern.compile("[^:]+:(.+)"); private final static Pattern WEBAPP_RELATIVE_PATH_PATTERN = Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW + diff --git a/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java b/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java index d7207c13ea..0074b25349 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.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 @@ -30,7 +30,13 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; import javax.faces.context.FacesContext; @@ -41,24 +47,25 @@ import org.alfresco.model.WCMWorkflowModel; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.security.authority.AuthorityDAO; import org.alfresco.repo.workflow.WorkflowModel; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.avm.*; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMNotFoundException; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.LayeringDescriptor; import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; 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.security.AuthorityService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.cmr.workflow.*; +import org.alfresco.service.cmr.workflow.WorkflowDefinition; +import org.alfresco.service.cmr.workflow.WorkflowPath; +import org.alfresco.service.cmr.workflow.WorkflowService; +import org.alfresco.service.cmr.workflow.WorkflowTask; +import org.alfresco.service.cmr.workflow.WorkflowTaskQuery; import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; +import org.alfresco.wcm.sandbox.SandboxInfo; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.workflow.WorkflowUtil; diff --git a/source/java/org/alfresco/web/bean/wcm/CreateLayeredFolderDialog.java b/source/java/org/alfresco/web/bean/wcm/CreateLayeredFolderDialog.java index e03da9cf18..ce8f9ef600 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateLayeredFolderDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateLayeredFolderDialog.java @@ -44,6 +44,8 @@ import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.wcm.webproject.WebProjectInfo; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.data.IDataContainer; @@ -67,6 +69,25 @@ public class CreateLayeredFolderDialog extends CreateFolderDialog protected String targetPath; protected List webProjects; + transient protected WebProjectService wpService; + + /** + * @param wpService The WebProjectService to set. + */ + public void setWebProjectService(WebProjectService wpService) + { + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); + } + return wpService; + } + // ------------------------------------------------------------------------------ // Dialog implementation @@ -147,39 +168,18 @@ public class CreateLayeredFolderDialog extends CreateFolderDialog // get the current web project dns name String thisStoreName = this.avmBrowseBean.getWebProject().getStagingStore(); - FacesContext fc = FacesContext.getCurrentInstance(); + List wpInfos = getWebProjectService().listWebProjects(); - // construct the query to retrieve the web projects - String path = Application.getRootPath(fc) + "/" + Application.getWebsitesFolderName(fc) + "/*"; - StringBuilder query = new StringBuilder(200); - query.append("PATH:\"/").append(path).append("\""); - query.append(" +TYPE:\"{").append(NamespaceService.WCMAPP_MODEL_1_0_URI).append("}webfolder\""); - - ResultSet results = null; - try + this.webProjects = new ArrayList(wpInfos.size()); + for (WebProjectInfo wpInfo : wpInfos) { - // execute the query - results = getSearchService().query(Repository.getStoreRef(), - SearchService.LANGUAGE_LUCENE, query.toString()); - this.webProjects = new ArrayList(results.length()); - for (ResultSetRow row : results) + String name = wpInfo.getName(); + String dns = wpInfo.getStoreId(); + + // don't add ourself to the list of projects + if (thisStoreName.equals(dns) == false) { - NodeRef ref = row.getNodeRef(); - String name = (String)getNodeService().getProperty(ref, ContentModel.PROP_NAME); - String dns = (String)getNodeService().getProperty(ref, WCMAppModel.PROP_AVMSTORE); - - // don't add ourself to the list of projects - if (thisStoreName.equals(dns) == false) - { - this.webProjects.add(new SelectItem(dns, name)); - } - } - } - finally - { - if (results != null) - { - results.close(); + this.webProjects.add(new SelectItem(dns, name)); } } diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java b/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java index 58a7283cee..03e3669434 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebappDialog.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 @@ -26,15 +26,9 @@ package org.alfresco.web.bean.wcm; import javax.faces.context.FacesContext; -import org.alfresco.model.ApplicationModel; -import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.wcm.webproject.WebProjectService; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; /** * Bean implementation for the AVM "Create Webapp Folder" dialog. @@ -48,7 +42,24 @@ public class CreateWebappDialog extends CreateFolderDialog private static final long serialVersionUID = -3883601909422422829L; - protected String path; + transient private WebProjectService wpService; + + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + public void setWebProjectService(WebProjectService wpService) + { + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); + } + return wpService; + } /** * @see org.alfresco.web.bean.dialog.BaseDialogBean#finishImpl(javax.faces.context.FacesContext, java.lang.String) @@ -56,49 +67,13 @@ public class CreateWebappDialog extends CreateFolderDialog @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { - final String stagingStore = this.avmBrowseBean.getStagingStore(); - - if (SandboxFactory.isContentManager(stagingStore)) + Node websiteNode = this.avmBrowseBean.getWebsite(); + + if (websiteNode != null) { - AuthenticationUtil.runAs(new RunAsWork(){ - - public Object doWork() throws Exception - { - final String parent = AVMUtil.buildSandboxRootPath( stagingStore ); - CreateWebappDialog.this.getAvmService().createDirectory(parent, CreateWebappDialog.this.name); - - CreateWebappDialog.this.path = AVMNodeConverter.ExtendAVMPath(parent, CreateWebappDialog.this.name); - CreateWebappDialog.this.getAvmService().addAspect(CreateWebappDialog.this.path, ApplicationModel.ASPECT_UIFACETS); - CreateWebappDialog.this.getAvmService().addAspect(CreateWebappDialog.this.path, WCMAppModel.ASPECT_WEBAPP); - if (CreateWebappDialog.this.description != null && CreateWebappDialog.this.description.length() != 0) - { - CreateWebappDialog.this.getAvmService().setNodeProperty(path, - ContentModel.PROP_DESCRIPTION, - new PropertyValue(DataTypeDefinition.TEXT, - CreateWebappDialog.this.description)); - } - - // Snapshot the store with the empty webapp - CreateWebappDialog.this.getAvmService().createSnapshot(stagingStore, null, null); - return null; - }}, AuthenticationUtil.getSystemUserName()); - + getWebProjectService().createWebApp(websiteNode.getNodeRef(), this.name, this.description); } - else - { - throw new AccessDeniedException("Only content managers may create new webapp folders"); - } - - return outcome; - } - - @Override - protected String doPostCommitProcessing(FacesContext context, String outcome) - { - // Tell the virtualization server about the new webapp. - // e.g.: this.path = "mysite:/www/avm_webapps/mywebapp" - AVMUtil.updateVServerWebapp(this.path, true); - + return outcome; } } diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index 717b9bc3a3..df94156bed 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.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 @@ -38,28 +38,21 @@ import javax.faces.model.DataModel; import javax.faces.model.ListDataModel; import javax.faces.model.SelectItem; -import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.locking.AVMLockingService; -import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowService; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.util.DNSNameMangler; import org.alfresco.util.ExpiringValueCache; +import org.alfresco.wcm.util.WCMUtil; +import org.alfresco.wcm.webproject.WebProjectInfo; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; @@ -110,26 +103,29 @@ public class CreateWebsiteWizard extends BaseWizardBean protected final static Log logger = LogFactory.getLog(CreateWebsiteWizard.class); protected boolean editMode = false; - protected String dnsName; + // TODO refactor to WebProjectInfo + protected String dnsName; protected String title; protected String name; protected String description; protected String webapp = WEBAPP_DEFAULT; protected String createFrom = null; + protected boolean isSource; + protected NodeRef wpNodeRef; + protected String[] sourceWebProject = null; protected ExpiringValueCache> webProjectsList; protected List webappsList; - protected boolean isSource; protected boolean showAllSourceProjects; protected String websiteDescriptionAttribute; - transient private AVMService avmService; transient private WorkflowService workflowService; transient private PersonService personService; - transient private AVMLockingService avmLockingService; transient private FormsService formsService; + transient private WebProjectService wpService; + /** set true when an option in the Create From screen is changed - this is used as an indicator to reload the wizard data model from the selected source web project */ private boolean createFromValueChanged; @@ -165,9 +161,6 @@ public class CreateWebsiteWizard extends BaseWizardBean protected boolean inAddDeployServerMode = false; protected String addDeployServerType = WCMAppModel.CONSTRAINT_FILEDEPLOY; - /** Data for virtualization server notification */ - private SandboxInfo sandboxInfo; - // ------------------------------------------------------------------------------ // Wizard implementation @@ -221,39 +214,25 @@ public class CreateWebsiteWizard extends BaseWizardBean // the Finish button can be pressed early in the steps - ensure the model is up-to-date updateModelOnCreateFromChange(); - // create the website space in the correct parent folder - final NodeRef websiteParent = WebProject.getWebsitesFolder(); + // if the user selected Create From existing web project we will branch from it + NodeRef sourceNodeRef = null; + if (CREATE_EXISTING.equals(this.createFrom) && + (this.sourceWebProject != null && this.sourceWebProject.length != 0)) + { + sourceNodeRef = new NodeRef(this.sourceWebProject[0]); + } - FileInfo fileInfo = this.getFileFolderService().create( - websiteParent, - this.name, - WCMAppModel.TYPE_AVMWEBFOLDER); - NodeRef nodeRef = fileInfo.getNodeRef(); + WebProjectInfo wpInfo = getWebProjectService().createWebProject(this.dnsName, this.name, this.title, this.description, this.webapp, this.isSource, sourceNodeRef); - if (logger.isDebugEnabled()) - logger.debug("Created website folder node with name: " + this.name); + String avmStore = wpInfo.getStoreId(); + NodeRef wpNodeRef = wpInfo.getNodeRef(); - // TODO: check that this dns is unique by querying existing store properties for a match - String avmStore = DNSNameMangler.MakeDNSName(this.dnsName); - - // apply the uifacets aspect - icon, title and description props - Map uiFacetsProps = new HashMap(4); - uiFacetsProps.put(ApplicationModel.PROP_ICON, AVMUtil.SPACE_ICON_WEBSITE); - uiFacetsProps.put(ContentModel.PROP_TITLE, this.title); - uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, this.description); - getNodeService().addAspect(nodeRef, ApplicationModel.ASPECT_UIFACETS, uiFacetsProps); - - // use as template source flag - getNodeService().setProperty(nodeRef, WCMAppModel.PROP_ISSOURCE, this.isSource); - - // set the default webapp name for the project - String webapp = (this.webapp != null && this.webapp.length() != 0) ? this.webapp : WEBAPP_DEFAULT; - getNodeService().setProperty(nodeRef, WCMAppModel.PROP_DEFAULTWEBAPP, webapp); + final NodeRef websiteParent = getWebProjectService().getWebProjectsRoot(); // call a delegate wizard bean to provide invite user functionality InviteWebsiteUsersWizard wiz = getInviteUsersWizard(); wiz.reset(); - wiz.setNode(new Node(nodeRef)); + wiz.setNode(new Node(wpNodeRef)); wiz.setAvmStore(avmStore); wiz.setStandalone(false); // the wizard is responsible for notifying the invited users, setting the appropriate @@ -261,68 +240,16 @@ public class CreateWebsiteWizard extends BaseWizardBean outcome = wiz.finish(); if (outcome != null) { - // if the user selected Create From existing web project we will branch from it - String branchStoreId = null; - if (CREATE_EXISTING.equals(this.createFrom) && - (this.sourceWebProject != null && this.sourceWebProject.length != 0)) - { - NodeRef sourceNodeRef = new NodeRef(this.sourceWebProject[0]); - branchStoreId = (String)getNodeService().getProperty(sourceNodeRef, WCMAppModel.PROP_AVMSTORE); - } - - // create the AVM staging store to represent the newly created location website - this.sandboxInfo = SandboxFactory.createStagingSandbox(avmStore, nodeRef, branchStoreId); - - // create the default webapp folder under the hidden system folders - if (branchStoreId == null) - { - String stagingStore = AVMUtil.buildStagingStoreName(avmStore); - String stagingStoreRoot = AVMUtil.buildSandboxRootPath(stagingStore); - getAvmService().createDirectory(stagingStoreRoot, webapp); - getAvmService().addAspect(AVMNodeConverter.ExtendAVMPath(stagingStoreRoot, webapp), - WCMAppModel.ASPECT_WEBAPP); - } - - // now the sandbox is created set the permissions masks for the store - SandboxFactory.setStagingPermissionMasks(avmStore); - - // set the property on the node to reference the root AVM store - getNodeService().setProperty(nodeRef, WCMAppModel.PROP_AVMSTORE, avmStore); - // persist the forms, templates, workflows, workflow defaults and deployment // config to the model for this web project - saveWebProjectModel(nodeRef); + saveWebProjectModel(wpNodeRef); // navigate to the Websites folder so we can see the newly created folder this.navigator.setCurrentNodeId(websiteParent.getId()); - // inform the locking service about this new instance - this.getAvmLockingService().addWebProject(avmStore); - outcome = AlfrescoNavigationHandler.CLOSE_WIZARD_OUTCOME; - - // Snapshot the store with the empty webapp - getAvmService().createSnapshot( avmStore, null, null); } - return outcome; - } - /** - * @see org.alfresco.web.bean.dialog.BaseDialogBean#doPostCommitProcessing(javax.faces.context.FacesContext, java.lang.String) - */ - @Override - protected String doPostCommitProcessing(FacesContext context, String outcome) - { - if (this.sandboxInfo != null) - { - // update the virtualisation server with the default ROOT webapp path - // performed after the main txn has committed successfully - String newStoreName = AVMUtil.buildStagingStoreName(sandboxInfo.getMainStoreName()); - - String path = AVMUtil.buildStoreWebappPath(newStoreName, WEBAPP_DEFAULT); - - AVMUtil.updateVServerWebapp(path, true); - } return outcome; } @@ -471,17 +398,14 @@ public class CreateWebsiteWizard extends BaseWizardBean // simple properties are optionally loaded if (loadProperties) { - Map props = getNodeService().getProperties(nodeRef); - this.name = (String)props.get(ContentModel.PROP_NAME); - this.title = (String)props.get(ContentModel.PROP_TITLE); - this.description = (String)props.get(ContentModel.PROP_DESCRIPTION); - this.dnsName = (String)props.get(WCMAppModel.PROP_AVMSTORE); - this.webapp = (String)props.get(WCMAppModel.PROP_DEFAULTWEBAPP); - Boolean isSource = (Boolean)props.get(WCMAppModel.PROP_ISSOURCE); - if (isSource != null) - { - this.isSource = isSource.booleanValue(); - } + WebProjectInfo wpInfo = getWebProjectService().getWebProject(nodeRef); + this.name = wpInfo.getName(); + this.title = wpInfo.getTitle(); + this.description = wpInfo.getDescription(); + this.dnsName = wpInfo.getStoreId(); + this.webapp = wpInfo.getDefaultWebApp(); + this.isSource = wpInfo.isTemplate(); + this.wpNodeRef = wpInfo.getNodeRef(); } if (loadUsers) @@ -490,13 +414,11 @@ public class CreateWebsiteWizard extends BaseWizardBean wiz.reset(); // load the users assigned to the web project - List userInfoRefs = getNodeService().getChildAssocs( - nodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) + Map userRoles = getWebProjectService().listWebUsers(nodeRef); + for (Map.Entry userRole : userRoles.entrySet()) { - NodeRef userRef = ref.getChildRef(); - String username = (String)getNodeService().getProperty(userRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)getNodeService().getProperty(userRef, WCMAppModel.PROP_WEBUSERROLE); + String username = userRole.getKey(); + String userrole = userRole.getValue(); wiz.addAuthorityWithRole(username, userrole); } } @@ -608,23 +530,6 @@ public class CreateWebsiteWizard extends BaseWizardBean // ------------------------------------------------------------------------------ // Service setters - /** - * @param avmService The AVMService to set. - */ - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - protected AVMService getAvmService() - { - if (avmService == null) - { - avmService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService(); - } - return avmService; - } - /** * @param workflowService The WorkflowService to set. */ @@ -658,23 +563,6 @@ public class CreateWebsiteWizard extends BaseWizardBean } return personService; } - - /** - * @param avmLockingService The AVMLockingService to set - */ - public void setAvmLockingService(AVMLockingService avmLockingService) - { - this.avmLockingService = avmLockingService; - } - - protected AVMLockingService getAvmLockingService() - { - if (avmLockingService == null) - { - avmLockingService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMLockingService(); - } - return avmLockingService; - } /** * @param formsService The FormsService to set. @@ -693,7 +581,22 @@ public class CreateWebsiteWizard extends BaseWizardBean return formsService; } - + /** + * @param wpService The WebProjectService to set. + */ + public void setWebProjectService(final WebProjectService wpService) + { + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = (WebProjectService) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "WebProjectService"); + } + return wpService; + } // ------------------------------------------------------------------------------ // Bean getters and setters @@ -714,6 +617,14 @@ public class CreateWebsiteWizard extends BaseWizardBean this.editMode = editMode; } + /** + * @return Returns the web project node ref. + */ + protected NodeRef getWebProjectNodeRef() + { + return wpNodeRef; + } + /** * @return Returns the name. */ @@ -837,7 +748,7 @@ public class CreateWebsiteWizard extends BaseWizardBean } else { - if (existingWebProject != null || existingWebProject.length != 0) + if (existingWebProject != null && existingWebProject.length != 0) { this.createFromValueChanged = true; } @@ -884,45 +795,22 @@ public class CreateWebsiteWizard extends BaseWizardBean List webProjects = this.webProjectsList.get(); if (webProjects == null) { - FacesContext fc = FacesContext.getCurrentInstance(); - - // construct the query to retrieve the web projects - String path = Application.getRootPath(fc) + "/" + Application.getWebsitesFolderName(fc) + "/*"; - StringBuilder query = new StringBuilder(200); - query.append("PATH:\"/").append(path).append("\""); - query.append(" +TYPE:\"{").append(NamespaceService.WCMAPP_MODEL_1_0_URI).append("}webfolder\""); - if (this.showAllSourceProjects == false) + List wps = getWebProjectService().listWebProjects(); + webProjects = new ArrayList(wps.size()); + for (WebProjectInfo wpInfo : wps) { - // only query for web project templates by default - query.append(" +@").append(Repository.escapeQName(WCMAppModel.PROP_ISSOURCE)).append(":true"); - } - - ResultSet results = null; - try - { - // execute the query - results = getSearchService().query(Repository.getStoreRef(), - SearchService.LANGUAGE_LUCENE, query.toString()); - webProjects = new ArrayList(results.length()); - for (ResultSetRow row : results) + if ((this.showAllSourceProjects == false) && (! wpInfo.isTemplate())) { - NodeRef ref = row.getNodeRef(); - String name = (String)getNodeService().getProperty(ref, ContentModel.PROP_NAME); - String desc = (String)getNodeService().getProperty(ref, ContentModel.PROP_DESCRIPTION); - UIListItem item = new UIListItem(); - item.setLabel(name); - item.setDescription(desc); - item.setValue(ref.toString()); - item.setImage(WebResources.IMAGE_WEBPROJECT_32); - webProjects.add(item); - } - } - finally - { - if (results != null) - { - results.close(); + // only query for web project templates by default + continue; } + + UIListItem item = new UIListItem(); + item.setLabel(wpInfo.getName()); + item.setDescription(wpInfo.getDescription()); + item.setValue(wpInfo.getNodeRef().toString()); + item.setImage(WebResources.IMAGE_WEBPROJECT_32); + webProjects.add(item); } this.webProjectsList.put(webProjects); @@ -1030,7 +918,7 @@ public class CreateWebsiteWizard extends BaseWizardBean if (foundCurrentUser == false) { buf.append(getInviteUsersWizard().buildLabelForUserAuthorityRole( - currentUser, AVMUtil.ROLE_CONTENT_MANAGER)); + currentUser, WCMUtil.ROLE_CONTENT_MANAGER)); } return buildSummary( @@ -1060,7 +948,7 @@ public class CreateWebsiteWizard extends BaseWizardBean } if (foundCurrentUser == false) { - result.add(new UserWrapper(currentUser, AVMUtil.ROLE_CONTENT_MANAGER)); + result.add(new UserWrapper(currentUser, WCMUtil.ROLE_CONTENT_MANAGER)); } return result; } diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java index b8ea6da842..fe188d1962 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.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 @@ -25,16 +25,12 @@ package org.alfresco.web.bean.wcm; import java.text.MessageFormat; -import java.util.List; import javax.faces.context.FacesContext; import org.alfresco.model.WCMAppModel; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.locking.AVMLockingService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.bean.dialog.BaseDialogBean; @@ -54,10 +50,8 @@ public class DeleteSandboxDialog extends BaseDialogBean private static final Log logger = LogFactory.getLog(DeleteSandboxDialog.class); - transient private AVMService avmService; protected AVMBrowseBean avmBrowseBean; - transient private AVMLockingService avmLockingService; - + transient private WebProjectService wpService; // ------------------------------------------------------------------------------ // Bean property getters and setters @@ -69,42 +63,21 @@ public class DeleteSandboxDialog extends BaseDialogBean { this.avmBrowseBean = avmBrowseBean; } + + public void setWebProjectService(WebProjectService wpService) + { + this.wpService = wpService; + } - /** - * @param avmService The avmService to set. - */ - public void setAvmService(AVMService avmService) + protected WebProjectService getWebProjectService() { - this.avmService = avmService; - } - - protected AVMService getAvmService() - { - if (avmService == null) + if (wpService == null) { - avmService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService(); + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); } - return avmService; + return wpService; } - /** - * @param avmLockingService The AVMLockingService to set - */ - public void setAvmLockingService(AVMLockingService avmLockingService) - { - this.avmLockingService = avmLockingService; - } - - protected AVMLockingService getAvmLockingService() - { - if (avmLockingService == null) - { - avmLockingService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMLockingService(); - } - return avmLockingService; - } - - // ------------------------------------------------------------------------------ // Dialog implementation @@ -112,76 +85,26 @@ public class DeleteSandboxDialog extends BaseDialogBean protected String finishImpl(FacesContext context, String outcome) throws Exception { - // the username for the sandbox to delete + // the username for the sandbox to delete (also uninvites from the web project) String username = this.avmBrowseBean.getUsername(); if (username != null) { Node website = this.avmBrowseBean.getWebsite(); - String storeRoot = (String)website.getProperties().get(WCMAppModel.PROP_AVMSTORE); - String mainStore = AVMUtil.buildUserMainStoreName(storeRoot, username); - - // remove the store reference from the website folder meta-data - List userInfoRefs = this.getNodeService().getChildAssocs( - website.getNodeRef(), - WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String user = (String)getNodeService().getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - - if (username.equals(user)) - { - // found the sandbox to remove - String path = AVMUtil.buildStoreWebappPath(mainStore, this.avmBrowseBean.getWebapp()); - - // Notify virtualisation server about removing this sandbox. - // - // Implementation note: - // - // Because the removal of virtual webapps in the - // virtualization server is recursive, it only - // needs to be given the name of the main store. - // - // This notification must occur *prior* to purging content - // within the AVM because the virtualization server must list - // the avm_webapps dir in each store to discover which - // virtual webapps must be unloaded. The virtualization - // server traverses the sandbox's stores in most-to-least - // dependent order, so clients don't have to worry about - // accessing a preview layer whose main layer has been torn - // out from under it. - AVMUtil.removeAllVServerWebapps(path, true); - - // TODO: Use the .sandbox-id. property to delete all sandboxes, - // rather than assume a sandbox always had a single preview - // layer attached. - - // purge the user main sandbox store from the system - this.getAvmService().purgeStore(mainStore); - // remove any locks this user may have - this.getAvmLockingService().removeStoreLocks(mainStore); - - // purge the user preview sandbox store from the system - String previewStore = AVMUtil.buildUserPreviewStoreName(storeRoot, username); - this.getAvmService().purgeStore(previewStore); - // remove any locks this user may have - this.getAvmLockingService().removeStoreLocks(previewStore); - - // remove the association to this web project user meta-data - this.getNodeService().removeChild(website.getNodeRef(), ref.getChildRef()); - - break; - } - } - + getWebProjectService().uninviteWebUser(website.getNodeRef(), username); + + String wpStoreId = getWebProjectService().getWebProject(website.getNodeRef()).getStoreId(); + String mainStore = AVMUtil.buildUserMainStoreName(wpStoreId, username); + // if the sandbox is allocated to a test server release it NodeRef testServer = DeploymentUtil.findAllocatedTestServer(mainStore); if (testServer != null) { getNodeService().setProperty(testServer, WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO, null); - + if (logger.isDebugEnabled()) + { logger.debug("Released test server from user sandbox: " + mainStore); + } } } diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java index 2aaddb61ca..62f6f70b41 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeleteWebsiteDialog.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 @@ -24,17 +24,9 @@ */ package org.alfresco.web.bean.wcm; -import java.util.List; - import javax.faces.context.FacesContext; -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.spaces.DeleteSpaceDialog; @@ -48,27 +40,23 @@ public class DeleteWebsiteDialog extends DeleteSpaceDialog { private static final long serialVersionUID = -3598950865168230942L; - transient private AVMService avmService; + transient private WebProjectService wpService; // ------------------------------------------------------------------------------ // Bean property getters and setters - /** - * @param avmService - * The AVMService to set. - */ - public void setAvmService(AVMService avmService) + public void setWebProjectService(WebProjectService wpService) { - this.avmService = avmService; + this.wpService = wpService; } - protected AVMService getAvmService() + protected WebProjectService getWebProjectService() { - if (avmService == null) - { - avmService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService(); - } - return avmService; + if (wpService == null) + { + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); + } + return wpService; } // ------------------------------------------------------------------------------ @@ -80,88 +68,14 @@ public class DeleteWebsiteDialog extends DeleteSpaceDialog @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { - Node websiteNode = this.browseBean.getActionSpace(); + Node websiteNode = this.browseBean.getActionSpace(); - if (websiteNode != null) - { - // delete all attached website sandboxes in reverse order to the layering - String storeRoot = (String) websiteNode.getProperties().get(WCMAppModel.PROP_AVMSTORE); - - if (storeRoot != null) - { - // Notifiy virtualization server about removing this website - // - // Implementation note: - // - // Because the removal of virtual webapps in the virtualization - // server is recursive, it only needs to be given the name of - // the main staging store. - // - // This notification must occur *prior* to purging content - // within the AVM because the virtualization server must list - // the avm_webapps dir in each store to discover which - // virtual webapps must be unloaded. The virtualization - // server traverses the sandbox's stores in most-to-least - // dependent order, so clients don't have to worry about - // accessing a preview layer whose main layer has been torn - // out from under it. - // - // It does not matter what webapp name we give here, so "/ROOT" - // is as sensible as anything else. It's all going away. - - String sandbox = AVMUtil.buildStagingStoreName(storeRoot); - String path = AVMUtil.buildStoreWebappPath(sandbox, "/ROOT"); - AVMUtil.removeAllVServerWebapps(path, true); - - // get the list of users who have a sandbox in the website - List userInfoRefs = getNodeService().getChildAssocs(websiteNode.getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - String username = (String) getNodeService().getProperty(ref.getChildRef(), WCMAppModel.PROP_WEBUSERNAME); - - // delete the preview store for this user - deleteStore(AVMUtil.buildUserPreviewStoreName(storeRoot, username)); - - // delete the main store for this user - deleteStore(AVMUtil.buildUserMainStoreName(storeRoot, username)); - } - - // remove the main staging and preview stores - deleteStore(AVMUtil.buildStagingPreviewStoreName(storeRoot)); - deleteStore(AVMUtil.buildStagingStoreName(storeRoot)); - } - } - - // use the super implementation to delete the node itself - return super.finishImpl(context, outcome); - } - - /** - * Delete a store, checking for its existance first. - * - * @param store - */ - private void deleteStore(final String store) - { - // check it exists before we try to remove it - if (this.getAvmService().getStore(store) != null) - { - if (SandboxFactory.isContentManager(store)) - { - AuthenticationUtil.runAs(new RunAsWork(){ - - public Object doWork() throws Exception - { - DeleteWebsiteDialog.this.getAvmService().purgeStore(store); - return null; - }}, AuthenticationUtil.getSystemUserName()); - - } - else - { - throw new AccessDeniedException("Only content managers may delete websites"); - } - } + if (websiteNode != null) + { + getWebProjectService().deleteWebProject(websiteNode.getNodeRef()); + } + + 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 12d47d7a39..1d50100916 100644 --- a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.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,10 +33,10 @@ import javax.faces.model.SelectItem; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.wcm.webproject.WebProjectInfo; import org.alfresco.web.app.AlfrescoNavigationHandler; /** @@ -89,15 +89,12 @@ public class EditWebsiteWizard extends CreateWebsiteWizard { if (this.webappsList == null) { - // get directory listing to show webapps that can be selected - Map dirs = this.getAvmService().getDirectoryListing( - -1, AVMUtil.buildSandboxRootPath(this.dnsName)); - // create list of webapps - this.webappsList = new ArrayList(dirs.size()); - for (String dirName : dirs.keySet()) + List webApps = getWebProjectService().listWebApps(getWebProjectNodeRef()); + this.webappsList = new ArrayList(webApps.size()); + for (String webAppName : webApps) { - this.webappsList.add(new SelectItem(dirName, dirName)); + this.webappsList.add(new SelectItem(webAppName, webAppName)); } } @@ -112,11 +109,16 @@ public class EditWebsiteWizard extends CreateWebsiteWizard { NodeRef nodeRef = this.browseBean.getActionSpace().getNodeRef(); + WebProjectInfo wpInfo = getWebProjectService().getWebProject(nodeRef); + // apply the name, title and description props - getNodeService().setProperty(nodeRef, ContentModel.PROP_NAME, this.name); - getNodeService().setProperty(nodeRef, ContentModel.PROP_TITLE, this.title); - getNodeService().setProperty(nodeRef, ContentModel.PROP_DESCRIPTION, this.description); - getNodeService().setProperty(nodeRef, WCMAppModel.PROP_ISSOURCE, this.isSource); + + wpInfo.setName(this.name); + wpInfo.setTitle(this.title); + wpInfo.setDescription(this.description); + wpInfo.setIsTemplate(this.isSource); + + getWebProjectService().updateWebProject(wpInfo); // clear the existing settings for forms, template, workflows and deployment - then // the existing methods can be used to apply the modified and previous settings from scratch diff --git a/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java b/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java index 8aa140b74c..cf4c7ef603 100644 --- a/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.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 @@ -24,26 +24,18 @@ */ package org.alfresco.web.bean.wcm; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Set; import javax.faces.context.FacesContext; import org.alfresco.model.WCMAppModel; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.AuthorityType; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.wcm.util.WCMUtil; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wizard.BaseInviteUsersWizard; import org.alfresco.web.ui.common.Utils; @@ -68,19 +60,21 @@ public class InviteWebsiteUsersWizard extends BaseInviteUsersWizard /** assume we are launching the wizard standalone */ private boolean standalone = true; - /** AVM Browse Bean reference */ - protected AVMBrowseBean avmBrowseBean; + transient private WebProjectService wpService; + - /** Data for virtualization server notification */ - private List sandboxInfoList; - - - /** - * @param avmBrowseBean The AVMBrowseBean to set. - */ - public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean) + public void setWebProjectService(WebProjectService wpService) { - this.avmBrowseBean = avmBrowseBean; + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); + } + return wpService; } /** @@ -114,205 +108,17 @@ public class InviteWebsiteUsersWizard extends BaseInviteUsersWizard { super.finishImpl(context, outcome); - // break the permissions inheritance on the node so that only assigned users can access it - NodeRef nodeRef = this.getNode().getNodeRef(); - this.getPermissionService().setInheritParentPermissions(nodeRef, false); - - // create a sandbox for each user appropriately with permissions based on role - // build a list of managers who will have full permissions on ALL staging areas - List managers = new ArrayList(4); - Set existingUsers = new HashSet(8); - if (isStandalone() == false) - { - // no website created yet - so we need to build the list of managers from the - // invited users and the power user who is executing the create web project wizard - boolean foundCurrentUser = false; - String currentUser = Application.getCurrentUser(context).getUserName(); - - for (UserGroupRole userRole : this.userGroupRoles) - { - for (String userAuth : findNestedUserAuthorities(userRole.getAuthority())) - { - if (currentUser.equals(userAuth)) - { - foundCurrentUser = true; - } - if (AVMUtil.ROLE_CONTENT_MANAGER.equals(userRole.getRole())) - { - managers.add(userAuth); - } - } - } - - if (foundCurrentUser == false) - { - this.userGroupRoles.add(new UserGroupRole(currentUser, AVMUtil.ROLE_CONTENT_MANAGER, null)); - managers.add(currentUser); - - // assign permissions explicitly for the current user - this.getPermissionService().setPermission( - nodeRef, - currentUser, - AVMUtil.ROLE_CONTENT_MANAGER, - true); - } - } - else - { - // website already exists - we are only adding to the existing sandboxes - // so retrieve the list of managers from the existing users and the selected invitees - for (UserGroupRole userRole : this.userGroupRoles) - { - for (String userAuth : findNestedUserAuthorities(userRole.getAuthority())) - { - if (AVMUtil.ROLE_CONTENT_MANAGER.equals(userRole.getRole())) - { - managers.add(userAuth); - } - } - } - - List userInfoRefs = this.getNodeService().getChildAssocs( - getNode().getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)getNodeService().getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)getNodeService().getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - if (AVMUtil.ROLE_CONTENT_MANAGER.equals(userrole) && - managers.contains(username) == false) - { - managers.add(username); - } - - // add each existing user to the exclude this - we cannot add them more than once! - existingUsers.add(username); - } - } - - // build the sandboxes now we have the manager list and complete user list - // and create an association to a node to represent each invited user - this.sandboxInfoList = new LinkedList(); - - boolean managersUpdateRequired = false; + Map selectedInvitees = new HashMap(this.userGroupRoles.size()); for (UserGroupRole userRole : this.userGroupRoles) { - for (String userAuth : findNestedUserAuthorities(userRole.getAuthority())) - { - // create the sandbox if the invited user does not already have one - if (existingUsers.contains(userAuth) == false) - { - SandboxInfo info = SandboxFactory.createUserSandbox( - getAvmStore(), managers, userAuth, userRole.getRole()); - - SandboxFactory.addStagingAreaUser(getAvmStore(), userAuth, userRole.getRole()); - - this.sandboxInfoList.add(info); - - // create an app:webuser instance for each authority and assoc to the website node - Map props = new HashMap(2, 1.0f); - props.put(WCMAppModel.PROP_WEBUSERNAME, userAuth); - props.put(WCMAppModel.PROP_WEBUSERROLE, userRole.getRole()); - this.getNodeService().createNode(getNode().getNodeRef(), - WCMAppModel.ASSOC_WEBUSER, - WCMAppModel.ASSOC_WEBUSER, - WCMAppModel.TYPE_WEBUSER, - props); - - // if this new user is a manager, we'll need to update the manager permissions applied - // to each existing user sandbox - to ensure that new managers have access to them - managersUpdateRequired |= (AVMUtil.ROLE_CONTENT_MANAGER.equals(userRole.getRole())); - } - } - } - - if (isStandalone() == true && managersUpdateRequired == true) - { - // walk existing sandboxes and reapply manager permissions to include any new manager users - List userInfoRefs = this.getNodeService().getChildAssocs( - getNode().getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)getNodeService().getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - if (existingUsers.contains(username)) - { - // only need to modify the sandboxes we haven't just created - SandboxFactory.updateSandboxManagers(getAvmStore(), managers, username); - } - } - SandboxFactory.updateStagingAreaManagers(getAvmStore(), getNode().getNodeRef(), managers); + selectedInvitees.put(userRole.getAuthority(), userRole.getRole()); } + getWebProjectService().inviteWebUsersGroups(this.getNode().getNodeRef(), selectedInvitees); + return outcome; } - - /** - * Handle notification to the virtualization server - * (this needs to occur after the sandbox is created in the main txn). - */ - @Override - protected String doPostCommitProcessing(FacesContext context, String outcome) - { - // reload virtualisation server for webapp in this web project - if (isStandalone()) - { - for (SandboxInfo sandboxInfo : this.sandboxInfoList) - { - String newlyInvitedStoreName = AVMUtil.buildStagingStoreName( - sandboxInfo.getMainStoreName()); - - String path = AVMUtil.buildStoreWebappPath( - newlyInvitedStoreName, this.avmBrowseBean.getWebapp()); - - AVMUtil.updateVServerWebapp(path, true); - } - } - return outcome; - } - - /** - * Find all nested user authorities contained with an authority - * - * @param authority The authority to search, USER authorities are returned immediately, GROUP authorites - * are recursively scanned for contained USER authorities. - * - * @return a Set of USER authorities - */ - private Set findNestedUserAuthorities(String authority) - { - Set users; - - AuthorityType authType = AuthorityType.getAuthorityType(authority); - if (authType.equals(AuthorityType.USER)) - { - users = new HashSet(1, 1.0f); - if (this.getPersonService().personExists(authority) == true) - { - users.add(authority); - } - } - else if (authType.equals(AuthorityType.GROUP)) - { - // walk each member of the group - users = this.getAuthorityService().getContainedAuthorities(AuthorityType.USER, authority, false); - for (String userAuth : users) - { - if (this.getPersonService().personExists(userAuth) == false) - { - users.remove(authType); - } - } - } - else - { - users = Collections.emptySet(); - } - - return users; - } - + /** * @return summary text for the wizard */ @@ -336,7 +142,7 @@ public class InviteWebsiteUsersWizard extends BaseInviteUsersWizard if (isStandalone() == false && foundCurrentUser == false) { buf.append(buildLabelForUserAuthorityRole( - currentUser, AVMUtil.ROLE_CONTENT_MANAGER)); + currentUser, WCMUtil.ROLE_CONTENT_MANAGER)); } return buildSummary( diff --git a/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.java b/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.java index c92039c215..4eabd75779 100644 --- a/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.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 @@ -35,7 +35,7 @@ import javax.transaction.UserTransaction; import org.alfresco.model.WCMModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.sandbox.SandboxConstants; +import org.alfresco.wcm.sandbox.SandboxConstants; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLockingService; @@ -269,7 +269,7 @@ public class ManageChangeRequestTaskDialog extends ManageTaskDialog String userStoreName = AVMUtil.getStoreName(userStoreAvmPath); String stagingStoreName = this.getAvmService().getStoreProperty(userStoreName, SandboxConstants.PROP_WEBSITE_NAME).getStringValue(); - NodeRef webProjectRef = AVMUtil.getWebProjectNodeFromStore(stagingStoreName); + NodeRef webProjectRef = getWebProjectService().findWebProjectNodeFromStore(stagingStoreName); // update the UI context to the web project this.browseBean.clickSpace(webProjectRef); diff --git a/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java b/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java index 607c8742bc..bcdc4ecbb2 100644 --- a/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.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 @@ -85,7 +85,7 @@ public class ManageReviewTaskDialog extends ManageTaskDialog // get the web project noderef for the workflow store String stagingStore = AVMUtil.getStoreId(this.store); - this.webProjectRef = AVMUtil.getWebProjectNodeFromStore(stagingStore); + this.webProjectRef = getWebProjectService().findWebProjectNodeFromStore(stagingStore); PropertyValue val = this.getAvmService().getStoreProperty(this.store, SandboxConstants.PROP_LINK_VALIDATION_REPORT); diff --git a/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java b/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java index 504ef6e865..3ee758dfd4 100644 --- a/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java @@ -47,10 +47,14 @@ import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.wcm.webproject.WebProjectInfo; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wizard.BaseWizardBean; +import org.alfresco.web.data.IDataContainer; +import org.alfresco.web.data.QuickSort; import org.alfresco.web.forms.Form; import org.alfresco.web.forms.FormInstanceData; import org.alfresco.web.forms.FormNotFoundException; @@ -80,6 +84,7 @@ public class RegenerateRenditionsWizard private final static Log LOGGER = LogFactory.getLog(RegenerateRenditionsWizard.class); + transient protected WebProjectService wpService; transient private AVMLockingService avmLockingService; transient private AVMService avmService; transient private AVMSyncService avmSyncService; @@ -235,16 +240,20 @@ public class RegenerateRenditionsWizard public List getWebProjectChoices() { - final List webProjects = WebProject.getWebProjects(); - final List result = new ArrayList(webProjects.size()); - for (final WebProject wp : webProjects) + List wpInfos = getWebProjectService().listWebProjects(); + List result = new ArrayList(wpInfos.size()); + + QuickSort sorter = new QuickSort((List)wpInfos, "name", true, IDataContainer.SORT_CASEINSENSITIVE); + sorter.sort(); + + for (WebProjectInfo wpInfo : wpInfos) { - final String s = wp.getTitle(); + String s = wpInfo.getTitle(); if (this.selectedWebProject == null) { - this.selectedWebProject = wp; + this.selectedWebProject = new WebProject(wpInfo.getNodeRef()); } - result.add(new SelectItem(wp.getNodeRef().toString(), s != null && s.length() != 0 ? s : wp.getName())); + result.add(new SelectItem(wpInfo.getNodeRef().toString(), s != null && s.length() != 0 ? s : wpInfo.getName())); } return result; } @@ -362,6 +371,23 @@ public class RegenerateRenditionsWizard // ------------------------------------------------------------------------------ // Service Injection + /** + * @param wpService The WebProjectService to set. + */ + public void setWebProjectService(WebProjectService wpService) + { + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWebProjectService(); + } + return wpService; + } + /** * @param avmService The AVMService to set. */ diff --git a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java deleted file mode 100644 index 62e9456e84..0000000000 --- a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright (C) 2005-2007 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.web.bean.wcm; - -import java.util.List; -import java.util.Map; - -import javax.faces.context.FacesContext; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.sandbox.SandboxConstants; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.util.DNSNameMangler; -import org.alfresco.util.GUID; -import org.alfresco.web.app.Application; -import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.repository.User; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Helper factory to create AVM sandbox structures. - * - * @author Kevin Roast - */ -public final class SandboxFactory -{ - private static Log logger = LogFactory.getLog(SandboxFactory.class); - - /** - * Private constructor - */ - private SandboxFactory() - { - } - - /** - * Create the staging sandbox for the named store. - * - * A staging sandbox is comprised of two stores, the first named 'storename-staging' with a - * preview store named 'storename-preview' layered over the staging store. - * - * Various store meta-data properties are set including: - * Identifier for store-types: .sandbox.staging.main and .sandbox.staging.preview - * Store-id: .sandbox-id. (unique across all stores in the sandbox) - * DNS: .dns. = - * Website Name: .website.name = website name - * - * @param storeId The store name to create the sandbox for. - * @param webProjectNodeRef The noderef for the webproject. - * @param branchStoreId The ID of the store to branch this staging store from. - */ - public static SandboxInfo createStagingSandbox(String storeId, - NodeRef webProjectNodeRef, - String branchStoreId) - { - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - AVMService avmService = services.getAVMService(); - PermissionService permissionService = services.getPermissionService(); - - // create the 'staging' store for the website - String stagingStoreName = AVMUtil.buildStagingStoreName(storeId); - avmService.createStore(stagingStoreName); - if (logger.isDebugEnabled()) - logger.debug("Created staging sandbox store: " + stagingStoreName); - - // we can either branch from an existing staging store or create a new structure - if (branchStoreId != null) - { - String branchStorePath = AVMUtil.buildStagingStoreName(branchStoreId) + ":/" + - JNDIConstants.DIR_DEFAULT_WWW; - avmService.createBranch(-1, branchStorePath, - stagingStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW); - } - else - { - // create the system directories 'www' and 'avm_webapps' - avmService.createDirectory(stagingStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW); - avmService.createDirectory(AVMUtil.buildStoreRootPath(stagingStoreName), - JNDIConstants.DIR_DEFAULT_APPBASE); - } - - - - // set staging area permissions - SandboxFactory.setStagingPermissions(storeId, webProjectNodeRef); - - // Add permissions for layers - - // tag the store with the store type - avmService.setStoreProperty(stagingStoreName, - SandboxConstants.PROP_SANDBOX_STAGING_MAIN, - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(stagingStoreName, - SandboxConstants.PROP_WEB_PROJECT_NODE_REF, - new PropertyValue(DataTypeDefinition.NODE_REF, webProjectNodeRef)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, stagingStoreName, storeId); - - // snapshot the store - avmService.createSnapshot(stagingStoreName, null, null); - - - - - - // create the 'preview' store for the website - String previewStoreName = AVMUtil.buildStagingPreviewStoreName(storeId); - avmService.createStore(previewStoreName); - if (logger.isDebugEnabled()) - logger.debug("Created staging preview sandbox store: " + previewStoreName + - " above " + stagingStoreName); - - // create a layered directory pointing to 'www' in the staging area - avmService.createLayeredDirectory(AVMUtil.buildStoreRootPath(stagingStoreName), - previewStoreName + ":/", - JNDIConstants.DIR_DEFAULT_WWW); - - - // apply READ permissions for all users - //dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(previewStoreName)); - //permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); - - // tag the store with the store type - avmService.setStoreProperty(previewStoreName, - SandboxConstants.PROP_SANDBOX_STAGING_PREVIEW, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, previewStoreName, storeId, "preview"); - - // The preview store depends on the main staging store (dist=1) - tagStoreBackgroundLayer(avmService,previewStoreName,stagingStoreName,1); - - // snapshot the store - avmService.createSnapshot(previewStoreName, null, null); - - - // tag all related stores to indicate that they are part of a single sandbox - final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); - avmService.setStoreProperty(stagingStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(previewStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - if (logger.isDebugEnabled()) - { - dumpStoreProperties(avmService, stagingStoreName); - dumpStoreProperties(avmService, previewStoreName); - } - - return new SandboxInfo( new String[] { stagingStoreName, previewStoreName } ); - } - - public static void setStagingPermissions(String storeId, - NodeRef webProjectNodeRef) - { - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - PermissionService permissionService = services.getPermissionService(); - NodeService nodeService = services.getNodeService(); - - String storeName = AVMUtil.buildStagingStoreName(storeId); - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(storeName)); - - // Apply sepcific user permissions as set on the web project - // All these will be masked out - List userInfoRefs = nodeService.getChildAssocs( - webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - permissionService.setPermission(dirRef, username, userrole, true); - } - } - - public static void setStagingPermissionMasks(String storeId) - { - FacesContext context = FacesContext.getCurrentInstance(); - ServiceRegistry services = Repository.getServiceRegistry(context); - PermissionService permissionService = services.getPermissionService(); - - String storeName = AVMUtil.buildStagingStoreName(storeId); - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(storeName)); - - // apply READ permissions for all users - permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); - - // Set store permission masks - String currentUser = Application.getCurrentUser(context).getUserName(); - permissionService.setPermission(dirRef.getStoreRef(), currentUser, PermissionService.CHANGE_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), currentUser, PermissionService.READ_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); - } - - public static void updateStagingAreaManagers(String storeId, - NodeRef webProjectNodeRef, final List managers) - { - // The stores have the mask set in updateSandboxManagers - String storeName = AVMUtil.buildStagingStoreName(storeId); - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - PermissionService permissionService = services.getPermissionService(); - - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(storeName)); - for (String manager : managers) - { - permissionService.setPermission(dirRef, manager, AVMUtil.ROLE_CONTENT_MANAGER, true); - - // give the manager change permissions permission in the staging area store - permissionService.setPermission(dirRef.getStoreRef(), manager, - PermissionService.CHANGE_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), manager, - PermissionService.READ_PERMISSIONS, true); - } - } - - public static boolean isContentManager(String storeId) - { - FacesContext context = FacesContext.getCurrentInstance(); - ServiceRegistry services = Repository.getServiceRegistry(context); - AVMService avmService = services.getAVMService(); - - String storeName = extractStagingAreaName(storeId); - PropertyValue pValue = avmService.getStoreProperty(storeName, SandboxConstants.PROP_WEB_PROJECT_NODE_REF); - - if (pValue != null) - { - NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); - - User currentUser = Application.getCurrentUser(context); - String currentUserRole = WebProject.getWebProjectUserRole(webProjectNodeRef, currentUser); - return AVMUtil.ROLE_CONTENT_MANAGER.equals(currentUserRole); - } - else - { - return false; - } - } - - private static String extractStagingAreaName(String name) - { - int index = name.indexOf("--"); - if (index == -1) - { - return name; - } - return name.substring(0, index); - } - - public static void addStagingAreaUser(String storeId, String authority, String role) - { - // The stores have the mask set in updateSandboxManagers - String storeName = AVMUtil.buildStagingStoreName(storeId); - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - PermissionService permissionService = services.getPermissionService(); - - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(storeName)); - permissionService.setPermission(dirRef, authority, role, true); - } - - /** - * 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 - * @return Summary information regarding the sandbox - */ - public static SandboxInfo createUserSandbox(String storeId, - List managers, - String username, - String role) - { - ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - AVMService avmService = services.getAVMService(); - PermissionService permissionService = services.getPermissionService(); - - // create the user 'main' store - String userStoreName = AVMUtil.buildUserMainStoreName(storeId, username); - String previewStoreName = AVMUtil.buildUserPreviewStoreName(storeId, username); - - if (avmService.getStore(userStoreName) != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("Not creating as store already exists: " + userStoreName); - } - return new SandboxInfo( new String[] { userStoreName, previewStoreName } ); - } - - avmService.createStore(userStoreName); - String stagingStoreName = AVMUtil.buildStagingStoreName(storeId); - if (logger.isDebugEnabled()) - logger.debug("Created user sandbox store: " + userStoreName + - " above staging store " + stagingStoreName); - - // create a layered directory pointing to 'www' in the staging area - avmService.createLayeredDirectory(AVMUtil.buildStoreRootPath(stagingStoreName), - userStoreName + ":/", - JNDIConstants.DIR_DEFAULT_WWW); - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(userStoreName)); - - // Apply access mask to the store (ACls are applie to the staging area) - - // apply the user role permissions to the sandbox - permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.ALL_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); - // apply the manager role permission for each manager in the web project - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, AVMUtil.ROLE_CONTENT_MANAGER, true); - } - - // tag the store with the store type - avmService.setStoreProperty(userStoreName, - SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the base name of the website so that corresponding - // staging areas can be found. - avmService.setStoreProperty(userStoreName, - SandboxConstants.PROP_WEBSITE_NAME, - new PropertyValue(DataTypeDefinition.TEXT, storeId)); - - // tag the store, oddly enough, with its own store name for querying. - avmService.setStoreProperty(userStoreName, - QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + userStoreName), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, userStoreName, storeId, username); - - // The user store depends on the main staging store (dist=1) - tagStoreBackgroundLayer(avmService,userStoreName,stagingStoreName,1); - - // snapshot the store - avmService.createSnapshot(userStoreName, null, null); - - // create the user 'preview' store - avmService.createStore(previewStoreName); - if (logger.isDebugEnabled()) - logger.debug("Created user preview sandbox store: " + previewStoreName + - " above " + userStoreName); - - // create a layered directory pointing to 'www' in the user 'main' store - avmService.createLayeredDirectory(AVMUtil.buildStoreRootPath(userStoreName), - previewStoreName + ":/", - JNDIConstants.DIR_DEFAULT_WWW); - dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(previewStoreName)); - - // Apply access mask to the store (ACls are applied to the staging area) - - // apply the user role permissions to the sandbox - permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.ALL_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); - // apply the manager role permission for each manager in the web project - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, AVMUtil.ROLE_CONTENT_MANAGER, true); - } - - // tag the store with the store type - avmService.setStoreProperty(previewStoreName, - SandboxConstants.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, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, previewStoreName, storeId, username, "preview"); - - // The preview user store depends on the main user store (dist=1) - tagStoreBackgroundLayer(avmService,previewStoreName, userStoreName,1); - - // The preview user store depends on the main staging store (dist=2) - tagStoreBackgroundLayer(avmService,previewStoreName, stagingStoreName,2); - - - // snapshot the store - avmService.createSnapshot(previewStoreName, null, null); - - - // tag all related stores to indicate that they are part of a single sandbox - QName sandboxIdProp = QName.createQName(null, SandboxConstants.PROP_SANDBOXID + GUID.generate()); - avmService.setStoreProperty(userStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(previewStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - if (logger.isDebugEnabled()) - { - dumpStoreProperties(avmService, userStoreName); - dumpStoreProperties(avmService, previewStoreName); - } - return new SandboxInfo( new String[] { userStoreName, previewStoreName } ); - } - - /** - * Create a workflow sandbox for the named store. - * - * Various store meta-data properties are set including: - * Identifier for store-types: .sandbox.workflow.main and .sandbox.workflow.preview - * Store-id: .sandbox-id. (unique across all stores in the sandbox) - * DNS: .dns. = - * Website Name: .website.name = website name - * - * @param storeId The id of the store to create a sandbox for - * @return Information about the sandbox - */ - public static SandboxInfo createWorkflowSandbox(final String storeId) - { - final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - final AVMService avmService = services.getAVMService(); - - final String stagingStoreName = AVMUtil.buildStagingStoreName(storeId); - - // create the workflow 'main' store - final String packageName = AVMUtil.STORE_WORKFLOW + "-" + GUID.generate(); - final String mainStoreName = - AVMUtil.buildWorkflowMainStoreName(storeId, packageName); - - avmService.createStore(mainStoreName); - if (logger.isDebugEnabled()) - logger.debug("Created workflow sandbox store: " + mainStoreName); - - // create a layered directory pointing to 'www' in the staging area - avmService.createLayeredDirectory(AVMUtil.buildStoreRootPath(stagingStoreName), - mainStoreName + ":/", - JNDIConstants.DIR_DEFAULT_WWW); - - // tag the store with the store type - avmService.setStoreProperty(mainStoreName, - SandboxConstants.PROP_SANDBOX_WORKFLOW_MAIN, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the base name of the website so that corresponding - // staging areas can be found. - avmService.setStoreProperty(mainStoreName, - SandboxConstants.PROP_WEBSITE_NAME, - new PropertyValue(DataTypeDefinition.TEXT, storeId)); - - // tag the store, oddly enough, with its own store name for querying. - avmService.setStoreProperty(mainStoreName, - QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + mainStoreName), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with the DNS name property - tagStoreDNSPath(avmService, mainStoreName, storeId, packageName); - - - // The main workflow store depends on the main staging store (dist=1) - tagStoreBackgroundLayer(avmService,mainStoreName, stagingStoreName ,1); - - // snapshot the store - avmService.createSnapshot(mainStoreName, null, null); - - // create the workflow 'preview' store - final String previewStoreName = - AVMUtil.buildWorkflowPreviewStoreName(storeId, packageName); - avmService.createStore(previewStoreName); - if (logger.isDebugEnabled()) - logger.debug("Created workflow sandbox preview store: " + previewStoreName); - - // create a layered directory pointing to 'www' in the workflow 'main' store - avmService.createLayeredDirectory(AVMUtil.buildStoreRootPath(mainStoreName), - previewStoreName + ":/", - JNDIConstants.DIR_DEFAULT_WWW); - - // tag the store with the store type - avmService.setStoreProperty(previewStoreName, - SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // tag the store with its own store name for querying. - avmService.setStoreProperty(previewStoreName, - QName.createQName(null, - SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName), - new PropertyValue(DataTypeDefinition.TEXT, null)); - - // 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) - tagStoreBackgroundLayer(avmService,previewStoreName, mainStoreName,1); - - // The preview workflow store depends on the main staging store (dist=2) - tagStoreBackgroundLayer(avmService,previewStoreName, stagingStoreName,2); - - - // snapshot the store - avmService.createSnapshot(previewStoreName, null, null); - - - // tag all related stores to indicate that they are part of a single sandbox - final QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); - avmService.setStoreProperty(mainStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - avmService.setStoreProperty(previewStoreName, - sandboxIdProp, - new PropertyValue(DataTypeDefinition.TEXT, null)); - - if (logger.isDebugEnabled()) - { - dumpStoreProperties(avmService, mainStoreName); - dumpStoreProperties(avmService, previewStoreName); - } - return new SandboxInfo( new String[] { mainStoreName, previewStoreName } ); - } - - /** - * Update the permissions for the list of sandbox managers applied to a user sandbox. - *

- * Ensures that all managers in the list have full WRITE access to the specified user stores. - * - * @param storeId The store id of the sandbox to update - * @param managers The list of authorities who have ContentManager role in the web project - * @param username Username of the user sandbox to update - */ - public static void updateSandboxManagers( - final String storeId, final List managers, final String username) - { - final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); - final PermissionService permissionService = services.getPermissionService(); - - final String userStoreName = AVMUtil.buildUserMainStoreName(storeId, username); - final String previewStoreName = AVMUtil.buildUserPreviewStoreName(storeId, username); - - // Apply masks to the stores - - // apply the manager role permission to the user main sandbox for each manager - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(userStoreName)); - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, AVMUtil.ROLE_CONTENT_MANAGER, true); - } - - // apply the manager role permission to the user preview sandbox for each manager - dirRef = AVMNodeConverter.ToNodeRef(-1, AVMUtil.buildStoreRootPath(previewStoreName)); - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, AVMUtil.ROLE_CONTENT_MANAGER, true); - } - } - - /** - * Tag a named store with a DNS path meta-data attribute. - * The DNS meta-data attribute is set to the system path 'store:/www/avm_webapps' - * - * @param store Name of the store to tag - */ - private static void tagStoreDNSPath(AVMService avmService, String store, String... components) - { - String path = AVMUtil.buildSandboxRootPath(store); - // DNS name mangle the property name - can only contain value DNS characters! - String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(components); - avmService.setStoreProperty(store, QName.createQName(null, dnsProp), - new PropertyValue(DataTypeDefinition.TEXT, path)); - } - - /** - * Tags a store with a property that indicates one of its - * backgroundStore layers, and the distance of that layer. - * This function must be called separately for each background - * store; for example the "mysite--alice--preview" store had - * as its immediate background "mysite--alice", which itself had - * as its background store "mysite", you'd make a sequence of - * calls like this: - * - *

-    *    tagStoreBackgroundLayer("mysite--alice",          "mysite",        1);
-    *    tagStoreBackgroundLayer("mysite--alice--preview", "mysite--alice", 1);
-    *    tagStoreBackgroundLayer("mysite--alice--preview", "mysite",        2);
-    *   
- * - * This make it easy for other parts of the system to determine - * which stores depend on others directly or indirectly (which is - * useful for reloading virtualized webapps). - * - * @param store Name of the store to tag - * @param backgroundStore Name of store's background store - * @param distance Distance from store. - * The backgroundStore 'mysite' is 1 away from the store 'mysite--alice' - * but 2 away from the store 'mysite--alice--preview'. - */ - private static void tagStoreBackgroundLayer(AVMService avmService, - String store, - String backgroundStore, - int distance) - { - String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + backgroundStore; - avmService.setStoreProperty(store, QName.createQName(null, prop_key), - new PropertyValue(DataTypeDefinition.INT, distance)); - } - - /** - * Debug helper method to dump the properties of a store - * - * @param store Store name to dump properties for - */ - private static void dumpStoreProperties(AVMService avmService, String store) - { - logger.debug("Store " + store); - Map props = avmService.getStoreProperties(store); - for (QName name : props.keySet()) - { - logger.debug(" " + name + ": " + props.get(name)); - } - } -} diff --git a/source/java/org/alfresco/web/bean/wcm/SandboxInfo.java b/source/java/org/alfresco/web/bean/wcm/SandboxInfo.java deleted file mode 100644 index 3991fbe4fa..0000000000 --- a/source/java/org/alfresco/web/bean/wcm/SandboxInfo.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2005-2007 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.web.bean.wcm; - -import java.io.Serializable; - -/** -* Provides information about a sandbox created by SandboxFactory. -*/ -public final class SandboxInfo implements Serializable -{ - private static final long serialVersionUID = 3615436375385857404L; - - String [] store_names_; - public SandboxInfo(String [] store_names) - { - store_names_ = store_names; - } - - /** - * A list of names of the stores within this sandbox. - * The "main" store should come first in this list; - * any other stores should appear in the order that - * they are overlaid on "main" (e.g.: any "preview" - * layers should come afterward, in "lowest first" order). - *

- * Note: all sandboxes must have a "main" layer. - */ - public String [] getStoreNames() { return store_names_; } - - /** - * The name of the "main" store within this sandbox. - */ - public String getMainStoreName() { return store_names_[0]; } -} diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index 608922ced1..e1f13619f8 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.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 @@ -69,6 +69,8 @@ import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.ISO8601DateFormat; import org.alfresco.util.NameMatcher; import org.alfresco.util.VirtServerUtils; +import org.alfresco.wcm.sandbox.SandboxFactory; +import org.alfresco.wcm.sandbox.SandboxInfo; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.app.servlet.FacesHelper; @@ -135,6 +137,7 @@ public class SubmitDialog extends BaseDialogBean transient private AVMSyncService avmSyncService; transient private AVMLockingService avmLockingService; transient private FormsService formsService; + transient private SandboxFactory sandboxFactory; transient private NameMatcher nameMatcher; @@ -258,6 +261,21 @@ public class SubmitDialog extends BaseDialogBean return formsService; } + // TODO - refactor ... push down into sandbox service (submit to workflow) + public void setSandboxFactory(final SandboxFactory sandboxFactory) + { + this.sandboxFactory = sandboxFactory; + } + + protected SandboxFactory getSandboxFactory() + { + if (sandboxFactory == null) + { + sandboxFactory = (SandboxFactory) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "SandboxFactory"); + } + return sandboxFactory; + } + /** * @see org.alfresco.web.bean.dialog.BaseDialogBean#init(java.util.Map) @@ -544,7 +562,7 @@ public class SubmitDialog extends BaseDialogBean if (this.workflowParams != null) { // Create workflow sandbox for workflow package - this.sandboxInfo = SandboxFactory.createWorkflowSandbox( + this.sandboxInfo = sandboxFactory.createWorkflowSandbox( this.avmBrowseBean.getStagingStore()); // create container for our avm workflow package diff --git a/source/java/org/alfresco/web/bean/wcm/WebProject.java b/source/java/org/alfresco/web/bean/wcm/WebProject.java index 946911d95e..ad4c7c61a2 100644 --- a/source/java/org/alfresco/web/bean/wcm/WebProject.java +++ b/source/java/org/alfresco/web/bean/wcm/WebProject.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,26 +33,18 @@ import java.util.Map; import javax.faces.context.FacesContext; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; -import org.alfresco.sandbox.SandboxConstants; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.web.app.Application; +import org.alfresco.wcm.sandbox.SandboxConstants; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.repository.User; import org.alfresco.web.data.IDataContainer; import org.alfresco.web.data.QuickSort; import org.alfresco.web.forms.Form; @@ -188,11 +180,9 @@ public class WebProject implements Serializable private final static Log LOGGER = LogFactory.getLog(WebProject.class); - private static NodeRef websitesFolder; private final NodeRef nodeRef; private String storeId = null; private Boolean hasWorkflow = null; - private Map userRoles = new HashMap(16, 1.0f); public WebProject(final NodeRef nodeRef) { @@ -238,10 +228,12 @@ public class WebProject implements Serializable * Returns the name of the web project. * * @return the name of the web project. + * @deprecated */ public String getName() { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); + // TODO refactor out ... + final NodeService nodeService = getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME); } @@ -249,10 +241,12 @@ public class WebProject implements Serializable * Returns the title of the web project. * * @return the title of the web project. + * @deprecated */ public String getTitle() { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); + // TODO refactor out ... + final NodeService nodeService = getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_TITLE); } @@ -260,10 +254,12 @@ public class WebProject implements Serializable * Returns the description of the web project. * * @return the description of the web project. + * @deprecated */ public String getDescription() { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); + // TODO refactor out ... + final NodeService nodeService = getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_DESCRIPTION); } @@ -271,12 +267,14 @@ public class WebProject implements Serializable * Returns the store id for this web project. * * @return the store id for this web project. + * @deprecated */ public String getStoreId() { + // TODO refactor out ... if (this.storeId == null) { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final NodeService nodeService = getServiceRegistry().getNodeService(); this.storeId = (String)nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_AVMSTORE); } return this.storeId; @@ -286,9 +284,11 @@ public class WebProject implements Serializable * Returns the staging store name. * * @return the staging store name. + * @deprecated */ public String getStagingStore() { + // TODO refactor out ... return AVMUtil.buildStagingStoreName(this.getStoreId()); } @@ -299,7 +299,7 @@ public class WebProject implements Serializable */ public List

getForms() { - final List forms = new ArrayList(this.getFormsImpl().values()); + final List forms = new ArrayList(this.getFormsImpl().values()); final QuickSort sorter = new QuickSort(forms, "name", true, IDataContainer.SORT_CASEINSENSITIVE); sorter.sort(); return Collections.unmodifiableList(forms); @@ -362,166 +362,6 @@ public class WebProject implements Serializable return this.hasWorkflow.booleanValue(); } - /** - * Returns true if the user is a manager of this web project. - * - * @param user the user - * @return true if the user is a manager, false otherwise. - * @exception NullPointerException if the user is null. - */ - public boolean isManager(final User user) - { - String userrole; - String username = user.getUserName(); - synchronized (userRoles) - { - userrole = userRoles.get(username); - if (userrole == null) - { - userrole = WebProject.getWebProjectUserRole(nodeRef, user); - userRoles.put(username, userrole); - } - } - return AVMUtil.ROLE_CONTENT_MANAGER.equals(userrole); - } - - /** - * @return the role of this user in the given Web Project, or null for no assigned role - */ - public static String getWebProjectUserRole(NodeRef webProjectRef, User user) - { - String userrole = null; - - long start = 0; - if (LOGGER.isDebugEnabled()) - { - start = System.currentTimeMillis(); - } - - if (user.isAdmin()) - { - // fake the Content Manager role for an admin user - userrole = AVMUtil.ROLE_CONTENT_MANAGER; - } - else - { - NodeService nodeService = WebProject.getServiceRegistry().getNodeService(); - - NodeRef roleRef = findUserRoleNodeRef(webProjectRef, user); - if (roleRef != null) - { - userrole = (String)nodeService.getProperty(roleRef, WCMAppModel.PROP_WEBUSERROLE); - } - else - { - LOGGER.warn("getWebProjectUserRole: user role not found for " + user); - } - } - - if (LOGGER.isDebugEnabled()) - { - LOGGER.debug("getWebProjectUserRole: " + user.getUserName() + " " + userrole + " in " + (System.currentTimeMillis()-start) + " ms"); - } - - return userrole; - } - - /** - * Perform a Lucene search to return a NodeRef to the node representing the the User Role - * within the given WebProject. - * - * @param webProjectRef Web Project to search against - * @param user User to test against - * - * @return NodeRef of the User Role node or null if none found - */ - public static NodeRef findUserRoleNodeRef(NodeRef webProjectRef, User user) - { - SearchService searchService = WebProject.getServiceRegistry().getSearchService(); - - StringBuilder query = new StringBuilder(128); - query.append("+PARENT:\"").append(webProjectRef).append("\" "); - query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" "); - query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\""); - query.append(user.getUserName()); - query.append("\""); - - ResultSet resultSet = searchService.query( - Repository.getStoreRef(), - SearchService.LANGUAGE_LUCENE, - query.toString()); - List nodes = resultSet.getNodeRefs(); - - return (nodes.size() == 1 ? nodes.get(0) : null); - } - - /** - * Returns the default webapp for this web project. - * - * @return the default webapp for this web project. - */ - public String getDefaultWebapp() - { - final ServiceRegistry serviceRegistry = this.getServiceRegistry(); - final NodeService nodeService = serviceRegistry.getNodeService(); - return (String) - nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_DEFAULTWEBAPP); - } - - /** - * Helper to get the ID of the 'Websites' system folder - * - * @return ID of the 'Websites' system folder - * - * @throws AlfrescoRuntimeException if unable to find the required folder - */ - public synchronized static NodeRef getWebsitesFolder() - { - if (WebProject.websitesFolder == null) - { - // get the template from the special Content Templates folder - final FacesContext fc = FacesContext.getCurrentInstance(); - final String xpath = Application.getRootPath(fc) + "/" + Application.getWebsitesFolderName(fc); - - final NodeRef rootNodeRef = WebProject.getServiceRegistry().getNodeService().getRootNode(Repository.getStoreRef()); - final NamespaceService resolver = Repository.getServiceRegistry(fc).getNamespaceService(); - final List results = WebProject.getServiceRegistry().getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false); - if (results.size() == 1) - { - WebProject.websitesFolder = new NodeRef(Repository.getStoreRef(), results.get(0).getId()); - } - else - { - throw new AlfrescoRuntimeException("Unable to find 'Websites' system folder at: " + xpath); - } - } - - return WebProject.websitesFolder; - } - - public static List getWebProjects() - { - final ServiceRegistry serviceRegistry = WebProject.getServiceRegistry(); - final SearchParameters sp = new SearchParameters(); - sp.addStore(Repository.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("+TYPE:\"" + WCMAppModel.TYPE_AVMWEBFOLDER + - "\" +PARENT:\"" + WebProject.getWebsitesFolder() + "\""); - if (LOGGER.isDebugEnabled()) - LOGGER.debug("running query [" + sp.getQuery() + "]"); - final ResultSet rs = serviceRegistry.getSearchService().query(sp); - if (LOGGER.isDebugEnabled()) - LOGGER.debug("received " + rs.length() + " results"); - final List result = new ArrayList(rs.length()); - for (ResultSetRow row : rs) - { - result.add(new WebProject(row.getNodeRef())); - } - QuickSort sorter = new QuickSort((List)result, "name", true, IDataContainer.SORT_CASEINSENSITIVE); - sorter.sort(); - return result; - } - private Map getFormsImpl() { final ServiceRegistry serviceRegistry = this.getServiceRegistry(); diff --git a/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java b/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java index 22004d5994..9eacffe7c2 100644 --- a/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java +++ b/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.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 @@ -38,16 +38,11 @@ import javax.transaction.UserTransaction; import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.template.AVMTemplateNode; 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.dictionary.TypeDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.workflow.WorkflowInstance; @@ -57,8 +52,8 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition; import org.alfresco.service.cmr.workflow.WorkflowTransition; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.Pair; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; @@ -89,6 +84,7 @@ public class ManageTaskDialog extends BaseDialogBean transient private WorkflowService workflowService; transient private AVMService avmService; transient private AVMSyncService avmSyncService; + transient private WebProjectService wpService; protected Node taskNode; transient private WorkflowTask task; transient private WorkflowInstance workflowInstance; @@ -799,6 +795,23 @@ public class ManageTaskDialog extends BaseDialogBean return avmSyncService; } + /** + * @param wpService The WebProjectService to set. + */ + public void setWebProjectService(final WebProjectService wpService) + { + this.wpService = wpService; + } + + protected WebProjectService getWebProjectService() + { + if (wpService == null) + { + wpService = (WebProjectService) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "WebProjectService"); + } + return wpService; + } + protected WorkflowTask getWorkflowTask() { if (task == null) diff --git a/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java b/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java index 11b35eed3a..6d444cfb31 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java @@ -52,7 +52,6 @@ import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMCompareUtils; -import org.alfresco.web.bean.wcm.AVMUtil; import org.alfresco.web.bean.wcm.DeploymentUtil; import org.alfresco.web.ui.common.ComponentConstants; import org.alfresco.web.ui.common.ConstantMethodBinding; @@ -233,7 +232,7 @@ public class UISandboxSnapshots extends SelfRenderingComponent // determine whether the deploy action should be shown boolean showDeployAction = false; - NodeRef webProjectRef = AVMUtil.getWebProjectNodeFromStore(sandbox); + NodeRef webProjectRef = Repository.getServiceRegistry(context).getWebProjectService().findWebProjectNodeFromStore(sandbox); List deployToServers = DeploymentUtil.findLiveServers(webProjectRef); if (deployToServers != null && deployToServers.size() > 0) { 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 9054ecb0f0..98f7c5d28a 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -52,13 +52,13 @@ 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.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.NameMatcher; +import org.alfresco.wcm.util.WCMUtil; +import org.alfresco.wcm.webproject.WebProjectService; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.app.servlet.FacesHelper; @@ -301,6 +301,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa ResourceBundle bundle = Application.getBundle(context); AVMService avmService = getAVMService(context); + WebProjectService wpService = getWebProjectService(context); NodeService nodeService = getNodeService(context); PermissionService permissionService = getPermissionService(context); AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, AVMBrowseBean.BEAN_NAME); @@ -321,19 +322,29 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa // find out the current user role in the web project User currentUser = Application.getCurrentUser(context); String currentUserName = currentUser.getUserName(); - String currentUserRole = WebProject.getWebProjectUserRole(websiteRef, currentUser); + String currentUserRole = wpService.getWebUserRole(websiteRef, currentUserName); // sort the user list alphabetically and insert the current user at the top of the list List userRoleWrappers; if (showAllSandboxes) { - List userInfoRefs = nodeService.getChildAssocs( - websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userInfoRefs); + // TODO refactor with new SandboxService + Map userRoles = null; + if (currentUserRole.equals(WCMUtil.ROLE_CONTENT_MANAGER)) + { + userRoles = wpService.listWebUsers(websiteRef); + } + else + { + userRoles = new HashMap(1); + userRoles.put(currentUserName, currentUserRole); + } + + userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userRoles); } else { - userRoleWrappers = buildCurrentUserRole(nodeService, websiteRef, currentUser); + userRoleWrappers = buildCurrentUserRole(wpService, websiteRef, currentUserName); } // determine whether the check links action should be shown @@ -619,16 +630,15 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa * is inserted at the top of the list if present. */ private static List buildSortedUserRoles( - NodeService nodeService, String currentUser, List userInfoRefs) + NodeService nodeService, String currentUser, Map userRoles) { // build a list of wrappers to hold the fields we need for each user and role UserRoleWrapper currentUserWrapper = null; List wrappers = new LinkedList(); - for (ChildAssociationRef ref : userInfoRefs) + for (Map.Entry userRole : userRoles.entrySet()) { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + String username = userRole.getKey(); + String userrole = userRole.getValue(); UserRoleWrapper wrapper = new UserRoleWrapper(username, userrole); @@ -660,18 +670,15 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa * Build a list containing one item representing the current user role for the website. */ private static List buildCurrentUserRole( - NodeService nodeService, NodeRef webProjectRef, User user) + WebProjectService wpService, NodeRef webProjectRef, String username) { // build a list of wrappers to hold the fields we need for each user and role List wrappers = new ArrayList(0); - NodeRef userInfoRef = WebProject.findUserRoleNodeRef(webProjectRef, user); - if (userInfoRef != null) + String userrole = wpService.getWebUserRole(webProjectRef, username); + if (userrole != null) { wrappers = new ArrayList(1); - - String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - + UserRoleWrapper wrapper = new UserRoleWrapper(username, userrole); wrapper.IsCurrentUser = true; wrappers.add(0, wrapper); @@ -1319,6 +1326,11 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa return menu; } + private WebProjectService getWebProjectService(FacesContext fc) + { + return (WebProjectService)FacesContextUtils.getRequiredWebApplicationContext(fc).getBean("WebProjectService"); + } + private AVMService getAVMService(FacesContext fc) { return (AVMService)FacesContextUtils.getRequiredWebApplicationContext(fc).getBean("AVMLockingAwareService"); diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index d50e46bd8f..7bf6355cc2 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -3139,6 +3139,10 @@ browseBean #{BrowseBean} + + webProjectService + #{WebProjectService} + avmService #{AVMLockingAwareService} @@ -3302,10 +3306,6 @@ searchService #{SearchService} - - avmService - #{AVMLockingAwareService} - workflowService #{WorkflowService} @@ -3314,14 +3314,14 @@ personService #{PersonService} - - avmLockingService - #{AVMLockingService} - formsService #{FormsService} + + webProjectService + #{WebProjectService} + @@ -3351,10 +3351,6 @@ searchService #{SearchService} - - avmService - #{AVMLockingAwareService} - workflowService #{WorkflowService} @@ -3446,8 +3442,8 @@ #{AuthorityService} - avmBrowseBean - #{AVMBrowseBean} + webProjectService + #{WebProjectService} @@ -3458,6 +3454,10 @@ AVMBrowseBean org.alfresco.web.bean.wcm.AVMBrowseBean session + + webProjectService + #{WebProjectService} + avmService #{AVMLockingAwareService} @@ -3676,14 +3676,6 @@ DeleteSandboxDialog org.alfresco.web.bean.wcm.DeleteSandboxDialog session - - avmService - #{AVMLockingAwareService} - - - avmLockingService - #{AVMLockingService} - avmBrowseBean #{AVMBrowseBean} @@ -3692,6 +3684,10 @@ nodeService #{NodeService} + + webProjectService + #{WebProjectService} + @@ -3743,6 +3739,10 @@ CreateLayeredFolderDialog org.alfresco.web.bean.wcm.CreateLayeredFolderDialog session + + webProjectService + #{WebProjectService} + avmService #{AVMLockingAwareService} @@ -3764,10 +3764,6 @@ CreateWebappDialog org.alfresco.web.bean.wcm.CreateWebappDialog session - - avmService - #{AVMLockingAwareService} - avmBrowseBean #{AVMBrowseBean} @@ -3776,6 +3772,10 @@ nodeService #{NodeService} + + webProjectService + #{WebProjectService} + @@ -3948,8 +3948,8 @@ org.alfresco.web.bean.wcm.DeleteWebsiteDialog session - avmService - #{AVMLockingAwareService} + webProjectService + #{WebProjectService} navigator