From c396a5f453115a6a3b7474c418574843d1e4cb85 Mon Sep 17 00:00:00 2001 From: Andrew Hind Date: Thu, 11 Jan 2007 12:09:53 +0000 Subject: [PATCH] Create "user Homes" folder in bootstrap and patch existing git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4791 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/bootstrap/spaces.xml | 257 +++++++++--------- config/alfresco/import-export-context.xml | 1 + .../messages/bootstrap-spaces.properties | 3 + .../messages/patch-service.properties | 6 +- .../alfresco/patch/patch-services-context.xml | 15 + config/alfresco/repository.properties | 1 + config/alfresco/version.properties | 2 +- .../patch/impl/UserHomesFolderPatch.java | 243 +++++++++++++++++ 8 files changed, 404 insertions(+), 124 deletions(-) create mode 100644 source/java/org/alfresco/repo/admin/patch/impl/UserHomesFolderPatch.java diff --git a/config/alfresco/bootstrap/spaces.xml b/config/alfresco/bootstrap/spaces.xml index a62a1d619a..c64ea36853 100644 --- a/config/alfresco/bootstrap/spaces.xml +++ b/config/alfresco/bootstrap/spaces.xml @@ -1,123 +1,136 @@ - - - - - - GROUP_EVERYONE - Consumer - - - - ${spaces.company_home.name} - space-icon-default - ${spaces.company_home.name} - ${spaces.company_home.description} - - - - ${spaces.dictionary.name} - space-icon-default - ${spaces.dictionary.name} - ${spaces.dictionary.description} - - - - ${spaces.templates.name} - space-icon-default - ${spaces.templates.name} - ${spaces.templates.description} - - - - ${spaces.templates.content.name} - space-icon-default - ${spaces.templates.content.name} - ${spaces.templates.content.description} - - - - ${spaces.templates.email.name} - space-icon-default - ${spaces.templates.email.name} - ${spaces.templates.email.description} - - - - - guest - Consumer - - - - ${spaces.templates.rss.name} - space-icon-default - ${spaces.templates.rss.name} - ${spaces.templates.rss.description} - - - - - GROUP_EVERYONE - Contributor - - - - ${spaces.savedsearches.name} - space-icon-default - ${spaces.savedsearches.name} - ${spaces.savedsearches.description} - - - - ${spaces.scripts.name} - space-icon-default - ${spaces.scripts.name} - ${spaces.scripts.description} - - - - ${spaces.content_forms.name} - space-icon-default - ${spaces.content_forms.name} - ${spaces.content_forms.description} - - - - - - - guest - Consumer - - - GROUP_EVERYONE - Consumer - - - - ${spaces.guest_home.name} - space-icon-default - ${spaces.guest_home.name} - ${spaces.guest_home.description} - - - - - GROUP_EVERYONE - Consumer - - - - ${spaces.wcm.name} - space-icon-default - ${spaces.wcm.name} - ${spaces.wcm.description} - - - - - + xmlns:cm="http://www.alfresco.org/model/content/1.0" + xmlns:app="http://www.alfresco.org/model/application/1.0"> + + + + + + GROUP_EVERYONE + Consumer + + + + ${spaces.company_home.name} + space-icon-default + ${spaces.company_home.name} + ${spaces.company_home.description} + + + + ${spaces.dictionary.name} + space-icon-default + ${spaces.dictionary.name} + ${spaces.dictionary.description} + + + + ${spaces.templates.name} + space-icon-default + ${spaces.templates.name} + ${spaces.templates.description} + + + + ${spaces.templates.content.name} + space-icon-default + ${spaces.templates.content.name} + ${spaces.templates.content.description} + + + + ${spaces.templates.email.name} + space-icon-default + ${spaces.templates.email.name} + ${spaces.templates.email.description} + + + + + guest + Consumer + + + + ${spaces.templates.rss.name} + space-icon-default + ${spaces.templates.rss.name} + ${spaces.templates.rss.description} + + + + + GROUP_EVERYONE + Contributor + + + + ${spaces.savedsearches.name} + space-icon-default + ${spaces.savedsearches.name} + ${spaces.savedsearches.description} + + + + ${spaces.scripts.name} + space-icon-default + ${spaces.scripts.name} + ${spaces.scripts.description} + + + + ${spaces.content_forms.name} + space-icon-default + ${spaces.content_forms.name} + ${spaces.content_forms.description} + + + + + + + guest + Consumer + + + GROUP_EVERYONE + Consumer + + + + ${spaces.guest_home.name} + space-icon-default + ${spaces.guest_home.name} + ${spaces.guest_home.description} + + + + ${spaces.user_homes.name} + space-icon-default + ${spaces.user_homes.name} + ${spaces.user_homes.description} + + + + + GROUP_EVERYONE + Consumer + + + + ${spaces.wcm.name} + space-icon-default + ${spaces.wcm.name} + ${spaces.wcm.description} + + + + + \ No newline at end of file diff --git a/config/alfresco/import-export-context.xml b/config/alfresco/import-export-context.xml index 7dacdad59a..8b4ee3da39 100644 --- a/config/alfresco/import-export-context.xml +++ b/config/alfresco/import-export-context.xml @@ -309,6 +309,7 @@ ${spaces.scripts.childname} ${spaces.wcm.childname} ${spaces.content_forms.childname} + ${spaces.user_homes.childname} diff --git a/config/alfresco/messages/bootstrap-spaces.properties b/config/alfresco/messages/bootstrap-spaces.properties index 378e4062d7..39166b11fb 100644 --- a/config/alfresco/messages/bootstrap-spaces.properties +++ b/config/alfresco/messages/bootstrap-spaces.properties @@ -32,3 +32,6 @@ spaces.wcm.description=Web Content Management Spaces spaces.content_forms.name=Web Forms spaces.content_forms.description=Web Content Forms + +spaces.user_homes.name=User Homes +spaces.user_homes.description=User Homes diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index b37e7addfd..6aa12a4784 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -110,4 +110,8 @@ patch.systemDescriptorContent.result=Added the version properties content to the patch.systemDescriptorContent.err.no_version_properties=The version.properties resource could not be found. patch.systemDescriptorContent.err.no_descriptor=The system descriptor could not be found. -patch.multilingualBootstrap.description=Bootstraps the node that will hold the multilingual containers. \ No newline at end of file +patch.multilingualBootstrap.description=Bootstraps the node that will hold the multilingual containers. + +patch.userHomesFolder.description=Ensures the existence of the 'User Homes' folder. +patch.userHomesFolder.result.exists=The user homes folder already exists: {0} +patch.userHomesFolder.result.created=The user homes folder was successfully created: {0} diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index cfaabf94c9..4fb01c6d7f 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -537,5 +537,20 @@ + + + patch.userHomesFolder + patch.userHomesFolder.description + 0 + 30 + 31 + + + + + + + + diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index ed4459e811..ac671dd5ee 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -114,6 +114,7 @@ spaces.savedsearches.childname=app:saved_searches spaces.scripts.childname=app:scripts spaces.wcm.childname=app:wcm spaces.content_forms.childname=app:wcm_forms +spaces.user_homes.childname=app:user_homes # Folders for storing people system.system_container.childname=sys:system diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 7caed947b5..68235d0958 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=30 +version.schema=31 diff --git a/source/java/org/alfresco/repo/admin/patch/impl/UserHomesFolderPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/UserHomesFolderPatch.java new file mode 100644 index 0000000000..c220e6cd4b --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/UserHomesFolderPatch.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.admin.patch.impl; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.alfresco.i18n.I18NUtil; +import org.alfresco.model.ApplicationModel; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.importer.ImporterBootstrap; +import org.alfresco.service.cmr.admin.PatchException; +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.namespace.QName; +import org.springframework.context.MessageSource; + +/** + * Ensures that the User Homes folder is present beneath company home. + * It inherits permissions from company home. + *

+ * This uses the bootstrap importer to get the paths to look for. If not present, + * the required structures are created. + *

+ * + * @author Andy Hind + */ +public class UserHomesFolderPatch extends AbstractPatch +{ + private static final String MSG_EXISTS = "patch.userHomesFolder.result.exists"; + private static final String MSG_CREATED = "patch.userHomesFolder.result.created"; + + public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname"; + public static final String PROPERTY_USER_HOMES_FOLDER_CHILDNAME = "spaces.user_homes.childname"; + private static final String PROPERTY_USER_HOMES_FOLDER_NAME = "spaces.user_homes.name"; + private static final String PROPERTY_USER_HOMES_FOLDER_DESCRIPTION = "spaces.user_homes.description"; + private static final String PROPERTY_ICON = "space-icon-default"; + + private ImporterBootstrap importerBootstrap; + private MessageSource messageSource; + + protected NodeRef companyHomeNodeRef; + protected Properties configuration; + protected NodeRef userHomesFolderNodeRef; + + public void setImporterBootstrap(ImporterBootstrap importerBootstrap) + { + this.importerBootstrap = importerBootstrap; + } + + public void setMessageSource(MessageSource messageSource) + { + this.messageSource = messageSource; + } + + /** + * Ensure that required common properties have been set + */ + protected void checkCommonProperties() throws Exception + { + if (importerBootstrap == null) + { + throw new PatchException("'importerBootstrap' property has not been set"); + } + else if (namespaceService == null) + { + throw new PatchException("'namespaceService' property has not been set"); + } + else if (searchService == null) + { + throw new PatchException("'searchService' property has not been set"); + } + else if (nodeService == null) + { + throw new PatchException("'nodeService' property has not been set"); + } + } + + /** + * Extracts pertinent references and properties that are common to execution + * of this and derived patches. + */ + protected void setUp() throws Exception + { + // get the node store that we must work against + StoreRef storeRef = importerBootstrap.getStoreRef(); + if (storeRef == null) + { + throw new PatchException("Bootstrap store has not been set"); + } + NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef); + + this.configuration = importerBootstrap.getConfiguration(); + // get the association names that form the path + String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME); + if (companyHomeChildName == null || companyHomeChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present"); + } + + String userHomesChildName = configuration.getProperty(PROPERTY_USER_HOMES_FOLDER_CHILDNAME); + if (userHomesChildName == null || userHomesChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_USER_HOMES_FOLDER_CHILDNAME + "' is not present"); + } + + // build the search string to get the company home node + StringBuilder sb = new StringBuilder(512); + sb.append("/").append(companyHomeChildName); + String xpath = sb.toString(); + // get the company home + List nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() == 0) + { + throw new PatchException("XPath didn't return any results: \n" + + " root: " + storeRootNodeRef + "\n" + + " xpath: " + xpath); + } + else if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + + " root: " + storeRootNodeRef + "\n" + + " xpath: " + xpath + "\n" + + " results: " + nodeRefs); + } + this.companyHomeNodeRef = nodeRefs.get(0); + + // Now we have the optional part. Check for the existence of the user homes folder + xpath = userHomesChildName; + nodeRefs = searchService.selectNodes(companyHomeNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + + " company home node: " + companyHomeNodeRef + "\n" + + " xpath: " + xpath + "\n" + + " results: " + nodeRefs); + } + else if (nodeRefs.size() == 0) + { + // the node does not exist + this.userHomesFolderNodeRef = null; + } + else + { + // we have the user homes folder noderef + this.userHomesFolderNodeRef = nodeRefs.get(0); + } + } + + @Override + protected String applyInternal() throws Exception + { + // properties must be set + checkCommonProperties(); + if (messageSource == null) + { + throw new PatchException("'messageSource' property has not been set"); + } + + // get useful values + setUp(); + + String msg = null; + if (userHomesFolderNodeRef == null) + { + // create it + createFolder(); + msg = I18NUtil.getMessage(MSG_CREATED, userHomesFolderNodeRef); + } + else + { + // it already exists + msg = I18NUtil.getMessage(MSG_EXISTS, userHomesFolderNodeRef); + } + // done + return msg; + } + + private void createFolder() + { + // get required properties + String userHomesChildName = configuration.getProperty(PROPERTY_USER_HOMES_FOLDER_CHILDNAME); + if (userHomesChildName == null) + { + throw new PatchException("Bootstrap property '" + PROPERTY_USER_HOMES_FOLDER_CHILDNAME + "' is not present"); + } + + String userHomesName = messageSource.getMessage( + PROPERTY_USER_HOMES_FOLDER_NAME, + null, + I18NUtil.getLocale()); + if (userHomesName == null || userHomesName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_USER_HOMES_FOLDER_NAME + "' is not present"); + } + + String userHomesDescription = messageSource.getMessage( + PROPERTY_USER_HOMES_FOLDER_DESCRIPTION, + null, + I18NUtil.getLocale()); + if (userHomesDescription == null || userHomesDescription.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_USER_HOMES_FOLDER_DESCRIPTION + "' is not present"); + } + + Map properties = new HashMap(7); + properties.put(ContentModel.PROP_NAME, userHomesName); + properties.put(ContentModel.PROP_TITLE, userHomesName); + properties.put(ContentModel.PROP_DESCRIPTION, userHomesDescription); + properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON); + // create the node + ChildAssociationRef childAssocRef = nodeService.createNode( + companyHomeNodeRef, + ContentModel.ASSOC_CONTAINS, + QName.resolveToQName(namespaceService, userHomesChildName), + ContentModel.TYPE_FOLDER, + properties); + userHomesFolderNodeRef = childAssocRef.getChildRef(); + // add the required aspects + nodeService.addAspect(userHomesFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null); + + // done + } +}