From d8b2e56aa3871783af021ca84f3079078d173c62 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Fri, 3 Mar 2006 17:39:32 +0000 Subject: [PATCH] . Addition of Email Templates folder (in Data Dictionary) to Bootstrap spaces.xml . New patch to apply Email Templates folder to older schemas git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2515 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/bootstrap/spaces.xml | 141 ++++----- config/alfresco/core-services-context.xml | 1 + .../messages/bootstrap-spaces.properties | 3 + .../messages/patch-service.properties | 6 +- .../model-specific-services-context.xml | 1 + .../alfresco/patch/patch-services-context.xml | 11 + config/alfresco/repository.properties | 1 + config/alfresco/version.properties | 2 +- .../patch/impl/EmailTemplatesFolderPatch.java | 272 ++++++++++++++++++ 9 files changed, 369 insertions(+), 69 deletions(-) create mode 100644 source/java/org/alfresco/repo/admin/patch/impl/EmailTemplatesFolderPatch.java diff --git a/config/alfresco/bootstrap/spaces.xml b/config/alfresco/bootstrap/spaces.xml index 18d37d6e33..0d2d5665c9 100644 --- a/config/alfresco/bootstrap/spaces.xml +++ b/config/alfresco/bootstrap/spaces.xml @@ -2,75 +2,82 @@ 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} - - - - - GROUP_EVERYONE - Contributor - - - - ${spaces.savedsearches.name} - space-icon-default - ${spaces.savedsearches.name} - ${spaces.savedsearches.description} - - - - - - - guest - Consumer - - + + + + 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} + + + + GROUP_EVERYONE - Consumer - - - - ${spaces.guest_home.name} - space-icon-default - ${spaces.guest_home.name} - ${spaces.guest_home.description} + Contributor + + + + ${spaces.savedsearches.name} + space-icon-default + ${spaces.savedsearches.name} + ${spaces.savedsearches.description} + + - - + + + + guest + Consumer + + + GROUP_EVERYONE + Consumer + + + + ${spaces.guest_home.name} + space-icon-default + ${spaces.guest_home.name} + ${spaces.guest_home.description} + + + diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 73ed20cf93..ca532b33d6 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -741,6 +741,7 @@ ${spaces.dictionary.childname} ${spaces.templates.childname} ${spaces.templates.content.childname} + ${spaces.templates.email.childname} ${spaces.savedsearches.childname} diff --git a/config/alfresco/messages/bootstrap-spaces.properties b/config/alfresco/messages/bootstrap-spaces.properties index 1feb9b1afa..13c73f403e 100644 --- a/config/alfresco/messages/bootstrap-spaces.properties +++ b/config/alfresco/messages/bootstrap-spaces.properties @@ -12,6 +12,9 @@ spaces.templates.description=Space templates spaces.templates.content.name=Presentation Templates spaces.templates.content.description=Presentation templates +spaces.templates.email.name=Email Templates +spaces.templates.email.description=Email templates + spaces.savedsearches.name=Saved Searches spaces.savedsearches.description=Saved Searches diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 4904d81e29..6c01ea98dd 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -42,4 +42,8 @@ patch.contentPermission.description=Update permission entries from 'cm:content' patch.contentPermission.result=Created the following permission reference names: {0}. \nUpdated {1} permission entries. patch.forumsIcons.description=Updates forums icon references -patch.forumsIcons.result=Updated {0} icon references \ No newline at end of file +patch.forumsIcons.result=Updated {0} icon references + +patch.emailTemplatesFolder.description=Ensures the existence of the 'Email Templates' folder. +patch.emailTemplatesFolder.result.exists=The email templates folder already exists: {0} +patch.emailTemplatesFolder.result.created=The email templates folder was successfully created: {0} diff --git a/config/alfresco/model-specific-services-context.xml b/config/alfresco/model-specific-services-context.xml index b55ab6cb26..1f788b0ea2 100644 --- a/config/alfresco/model-specific-services-context.xml +++ b/config/alfresco/model-specific-services-context.xml @@ -19,6 +19,7 @@ /${spaces.company_home.childname}/${spaces.dictionary.childname} /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.childname} /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname} + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 8587332e51..444506f106 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -296,5 +296,16 @@ + + patch.emailTemplatesFolder + patch.emailTemplatesFolder.description + 0 + 8 + 9 + + + + + diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index cd0f73d9d7..34350f7ce8 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -88,6 +88,7 @@ spaces.guest_home.childname=app:guest_home spaces.dictionary.childname=app:dictionary spaces.templates.childname=app:space_templates spaces.templates.content.childname=app:content_templates +spaces.templates.email.childname=app:email_templates spaces.savedsearches.childname=app:saved_searches # Folders for storing people diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index fff64d2a1a..e86b455a1f 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -15,4 +15,4 @@ version.edition=Community Network # Schema number -version.schema=8 +version.schema=9 diff --git a/source/java/org/alfresco/repo/admin/patch/impl/EmailTemplatesFolderPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/EmailTemplatesFolderPatch.java new file mode 100644 index 0000000000..2c169a2eda --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/EmailTemplatesFolderPatch.java @@ -0,0 +1,272 @@ +/* + * 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.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.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.springframework.context.MessageSource; + +/** + * Ensures that the email templates folder is present. + *

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

+ * This class should be replaced with a more generic ImporterPatch + * that can do conditional importing into given locations. + *

+ * JIRA: {@link http://www.alfresco.org/jira/browse/AR-342 AR-342} + * + * @author Kevin Roast + */ +public class EmailTemplatesFolderPatch extends AbstractPatch +{ + private static final String MSG_EXISTS = "patch.emailTemplatesFolder.result.exists"; + private static final String MSG_CREATED = "patch.emailTemplatesFolder.result.created"; + + public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname"; + public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname"; + public static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME = "spaces.templates.email.childname"; + private static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_NAME = "spaces.templates.email.name"; + private static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_DESCRIPTION = "spaces.templates.email.description"; + private static final String PROPERTY_ICON = "space-icon-default"; + + private ImporterBootstrap importerBootstrap; + private NamespaceService namespaceService; + private SearchService searchService; + private NodeService nodeService; + private MessageSource messageSource; + + protected NodeRef dictionaryNodeRef; + protected Properties configuration; + protected NodeRef emailTemplatesFolderNodeRef; + + public void setImporterBootstrap(ImporterBootstrap importerBootstrap) + { + this.importerBootstrap = importerBootstrap; + } + + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + 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 dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME); + if (dictionaryChildName == null || dictionaryChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present"); + } + String emailTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME); + if (emailTemplatesChildName == null || emailTemplatesChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME + "' is not present"); + } + + // build the search string to get the dictionary node + StringBuilder sb = new StringBuilder(128); + sb.append("/").append(companyHomeChildName) + .append("/").append(dictionaryChildName); + String xpath = sb.toString(); + + // get the dictionary node + 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.dictionaryNodeRef = nodeRefs.get(0); + + // Now we have the optional part. Check for the existence of the email templates folder + xpath = emailTemplatesChildName; + nodeRefs = searchService.selectNodes(dictionaryNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + + " dictionary node: " + dictionaryNodeRef + "\n" + + " xpath: " + xpath + "\n" + + " results: " + nodeRefs); + } + else if (nodeRefs.size() == 0) + { + // the node does not exist + this.emailTemplatesFolderNodeRef = null; + } + else + { + // we have the email templates folder noderef + this.emailTemplatesFolderNodeRef = nodeRefs.get(0); + } + } + + @Override + protected String applyInternal() throws Exception + { + // common properties must be set before we can continue + checkCommonProperties(); + if (messageSource == null) + { + throw new PatchException("'messageSource' property has not been set"); + } + + setUp(); + + // create the folder if needed - output a message to describe the result + String msg = null; + if (emailTemplatesFolderNodeRef == null) + { + createFolder(); + msg = I18NUtil.getMessage(MSG_CREATED, emailTemplatesFolderNodeRef); + } + else + { + msg = I18NUtil.getMessage(MSG_EXISTS, emailTemplatesFolderNodeRef); + } + + return msg; + } + + private void createFolder() + { + // get required properties + String emailTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME); + if (emailTemplatesChildName == null) + { + throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME + "' is not present"); + } + + String emailTemplatesName = messageSource.getMessage( + PROPERTY_EMAIL_TEMPLATES_FOLDER_NAME, + null, + I18NUtil.getLocale()); + if (emailTemplatesName == null || emailTemplatesName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_NAME + "' is not present"); + } + + String emailTemplatesDescription = messageSource.getMessage( + PROPERTY_EMAIL_TEMPLATES_FOLDER_DESCRIPTION, + null, + I18NUtil.getLocale()); + if (emailTemplatesDescription == null || emailTemplatesDescription.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_DESCRIPTION + "' is not present"); + } + + Map properties = new HashMap(7); + properties.put(ContentModel.PROP_NAME, emailTemplatesName); + properties.put(ContentModel.PROP_TITLE, emailTemplatesName); + properties.put(ContentModel.PROP_DESCRIPTION, emailTemplatesDescription); + properties.put(ContentModel.PROP_ICON, PROPERTY_ICON); + + // create the node + ChildAssociationRef childAssocRef = nodeService.createNode( + dictionaryNodeRef, + ContentModel.ASSOC_CONTAINS, + QName.resolveToQName(namespaceService, emailTemplatesChildName), + ContentModel.TYPE_FOLDER, + properties); + emailTemplatesFolderNodeRef = childAssocRef.getChildRef(); + + // add the required aspects + nodeService.addAspect(emailTemplatesFolderNodeRef, ContentModel.ASPECT_UIFACETS, null); + } +}