diff --git a/config/alfresco/bootstrap/imapSpacesTemplates.acp b/config/alfresco/bootstrap/imapSpacesTemplates.acp new file mode 100644 index 0000000000..13153c04a0 Binary files /dev/null and b/config/alfresco/bootstrap/imapSpacesTemplates.acp differ diff --git a/config/alfresco/import-export-context.xml b/config/alfresco/import-export-context.xml index fe7e53e40f..5b40577104 100644 --- a/config/alfresco/import-export-context.xml +++ b/config/alfresco/import-export-context.xml @@ -651,11 +651,11 @@ alfresco/messages/bootstrap-spaces - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.imapConfig.childname}/${spaces.imap_templates.childname} - alfresco/bootstrap/imapSpacesLocales.acp + alfresco/bootstrap/imapSpacesTemplates.acp alfresco/messages/bootstrap-spaces diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 4c25b11f7e..6141b06c23 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -185,6 +185,9 @@ patch.webscripts.description=Adds Web Scripts to Data Dictionary. patch.webscripts2.description=Adds Web Scripts (second set) to Data Dictionary. patch.webscripts3.description=Update Web Scripts ReadMe. patch.webscriptsExtension.description=Adds Web Scripts Extension to Data Dictionary. +patch.imap.messages.share.description=Adds email template for txt files to the Imap Configs/Templates +patch.imap.clear.old.messages.description=Remove old IMAP message templates +patch.imap.clear.old.messages.description.cleared=Old IMAP message templates no more exists in repo patch.AVMLayeredSnapshot.description=Set indirectionVersion on Layered Nodes. patch.AVMLayeredSnapshot.result=Layered Node indirectionVersions set. diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index a467261b60..e7a8e2365e 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -2798,4 +2798,62 @@ + + patch.imap.messages.share + patch.imap.messages.share.description + 0 + 4202 + 4203 + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.imapConfig.childname}/${spaces.imap_templates.childname} + alfresco/templates/imap/share_messages.xml + + + + + + patch.imap.clear.old.messages + patch.imap.clear.old.messages.description + 0 + 4202 + 4203 + + + + + + + patch.imap.clear.old.messages + patch.imap.clear.old.messages.description + 0 + 5000 + 5001 + + + + + + + patch.imapSpacesLocaleTemplates + patch.imapSpacesLocaleTemplates.description + 0 + 5000 + 5001 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.imapConfig.childname}/${spaces.imap_templates.childname} + alfresco/bootstrap/imapSpacesTemplates.acp + alfresco/messages/bootstrap-spaces + + + + diff --git a/config/alfresco/templates/imap/share_messages.xml b/config/alfresco/templates/imap/share_messages.xml new file mode 100644 index 0000000000..52dbafd4e2 --- /dev/null +++ b/config/alfresco/templates/imap/share_messages.xml @@ -0,0 +1,67 @@ + + + + + + + + + + true + Email template used to generate the "multipart/alternative" IMAP message body ("text/plain" part) for documents in Sites. + contentUrl=classpath:alfresco/templates/imap/imap_message_text_plain_share.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_ + emailbody-share-textplain.ftl + + emailbody-share-textplain.ftl + + + + + + + + + + + true + Email template used to generate the "multipart/alternative" IMAP message body ("text/html" part) for documents in Sites + contentUrl=classpath:alfresco/templates/imap/imap_message_text_html_share.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_ + emailbody-share-texthtml.ftl + + emailbody-share-texthtml.ftl + + + + + + + + + + + true + Email template used to generate the "multipart/alternative" IMAP message body ("text/plain" part) for documents in Alfresco + contentUrl=classpath:alfresco/templates/imap/imap_message_text_plain_alfresco.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_ + emailbody-alfresco-textplain.ftl + + emailbody-alfresco-textplain.ftl + + + + + + + + + + + true + Email template used to generate the "multipart/alternative" IMAP message body ("text/html" part) for documents in Alfresco + contentUrl=classpath:alfresco/templates/imap/imap_message_text_html_alfresco.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_ + emailbody-alfresco-texthtml.ftl + + emailbody-alfresco-texthtml.ftl + + + + \ No newline at end of file diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 4af5a9f6a4..644ba66be7 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=5000 +version.schema=5001 diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ClearOldImapMessgesPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/ClearOldImapMessgesPatch.java new file mode 100644 index 0000000000..ec85a34738 --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/ClearOldImapMessgesPatch.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.admin.patch.impl; + +import java.util.List; +import java.util.Properties; + +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.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.springframework.extensions.surf.util.I18NUtil; + +public class ClearOldImapMessgesPatch extends AbstractPatch +{ + private static final String MSG_REMOVED = "patch.imap.clear.old.messages.description.cleared"; + + private static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname"; + private static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname"; + private static final String PROPERTY_SCRIPTS_CHILDNAME = "spaces.scripts.childname"; + private static final String PROPERTY_IMAP_CONFIG_CHILDNAME = "spaces.imapConfig.childname"; + private static final String PROPERTY_IMAP_TEMPLATES_CHILDNAME = "spaces.imap_templates.childname"; + + private ImporterBootstrap importerBootstrap; + protected Properties configuration; + private NodeRef imapTemplatesFolderNodeRef; + + public void setImporterBootstrap(ImporterBootstrap importerBootstrap) + { + this.importerBootstrap = importerBootstrap; + } + + 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 scriptsChildName = configuration.getProperty(PROPERTY_SCRIPTS_CHILDNAME); + if (scriptsChildName == null || scriptsChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_SCRIPTS_CHILDNAME + "' is not present"); + } + + String imapConfigChildName = configuration.getProperty(PROPERTY_IMAP_CONFIG_CHILDNAME); + if (imapConfigChildName == null || imapConfigChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_IMAP_CONFIG_CHILDNAME + "' is not present"); + } + + String imapTemplatesChildName = configuration.getProperty(PROPERTY_IMAP_TEMPLATES_CHILDNAME); + if (imapConfigChildName == null || imapConfigChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_IMAP_CONFIG_CHILDNAME + "' is not present"); + } + + // build the search string to get the company home node + StringBuilder sb = new StringBuilder(256); + sb.append("/").append(companyHomeChildName); + sb.append("/").append(dictionaryChildName); + sb.append("/").append(imapConfigChildName); + sb.append("/").append(imapTemplatesChildName); + + String xpath = sb.toString(); + List nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + " root: " + storeRootNodeRef + "\n" + " xpath: " + xpath + "\n" + " results: " + nodeRefs); + } + else if (nodeRefs.size() == 0) + { + this.imapTemplatesFolderNodeRef = null; + } + else + { + this.imapTemplatesFolderNodeRef = nodeRefs.get(0); + } + + } + + @Override + protected String applyInternal() throws Exception + { + setUp(); + if (imapTemplatesFolderNodeRef != null) + { + NodeRef oldTextPlain = nodeService.getChildByName(imapTemplatesFolderNodeRef, ContentModel.ASSOC_CONTAINS, "emailbody-textplain.ftl"); + NodeRef oldTextHTML = nodeService.getChildByName(imapTemplatesFolderNodeRef, ContentModel.ASSOC_CONTAINS, "emailbody-texthtml.ftl"); + + if (oldTextPlain != null) + { + nodeService.deleteNode(oldTextPlain); + } + if (oldTextHTML != null) + { + nodeService.deleteNode(oldTextHTML); + } + } + + return I18NUtil.getMessage(MSG_REMOVED); + } + +} diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ClearOldImapTemplatesPatch2.java b/source/java/org/alfresco/repo/admin/patch/impl/ClearOldImapTemplatesPatch2.java new file mode 100644 index 0000000000..f7064d45bb --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/ClearOldImapTemplatesPatch2.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.admin.patch.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +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.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.springframework.extensions.surf.util.I18NUtil; + +public class ClearOldImapTemplatesPatch2 extends AbstractPatch +{ + private static final String MSG_REMOVED = "patch.imap.clear.old.messages.description.cleared"; + + private static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname"; + private static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname"; + private static final String PROPERTY_SCRIPTS_CHILDNAME = "spaces.scripts.childname"; + private static final String PROPERTY_IMAP_CONFIG_CHILDNAME = "spaces.imapConfig.childname"; + private static final String PROPERTY_IMAP_TEMPLATES_CHILDNAME = "spaces.imap_templates.childname"; + + private ImporterBootstrap importerBootstrap; + protected Properties configuration; + private NodeRef imapTemplatesFolderNodeRef; + + public void setImporterBootstrap(ImporterBootstrap importerBootstrap) + { + this.importerBootstrap = importerBootstrap; + } + + 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 scriptsChildName = configuration.getProperty(PROPERTY_SCRIPTS_CHILDNAME); + if (scriptsChildName == null || scriptsChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_SCRIPTS_CHILDNAME + "' is not present"); + } + + String imapConfigChildName = configuration.getProperty(PROPERTY_IMAP_CONFIG_CHILDNAME); + if (imapConfigChildName == null || imapConfigChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_IMAP_CONFIG_CHILDNAME + "' is not present"); + } + + String imapTemplatesChildName = configuration.getProperty(PROPERTY_IMAP_TEMPLATES_CHILDNAME); + if (imapConfigChildName == null || imapConfigChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_IMAP_CONFIG_CHILDNAME + "' is not present"); + } + + // build the search string to get the company home node + StringBuilder sb = new StringBuilder(256); + sb.append("/").append(companyHomeChildName); + sb.append("/").append(dictionaryChildName); + sb.append("/").append(imapConfigChildName); + sb.append("/").append(imapTemplatesChildName); + + String xpath = sb.toString(); + List nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + " root: " + storeRootNodeRef + "\n" + " xpath: " + xpath + "\n" + " results: " + nodeRefs); + } + else if (nodeRefs.size() == 0) + { + this.imapTemplatesFolderNodeRef = null; + } + else + { + this.imapTemplatesFolderNodeRef = nodeRefs.get(0); + } + + } + + @Override + protected String applyInternal() throws Exception + { + setUp(); + if (imapTemplatesFolderNodeRef != null) + { + List templatesToDelete = new ArrayList(); + + templatesToDelete.add("emailbody-textplain.ftl"); + templatesToDelete.add("emailbody-textplain_de.ftl"); + templatesToDelete.add("emailbody-textplain_it.ftl"); + templatesToDelete.add("emailbody-textplain_fr.ftl"); + templatesToDelete.add("emailbody-textplain_ja.ftl"); + templatesToDelete.add("emailbody-textplain_es.ftl"); + + templatesToDelete.add("emailbody-texthtml.ftl"); + templatesToDelete.add("emailbody-texthtml_de.ftl"); + templatesToDelete.add("emailbody-texthtml_it.ftl"); + templatesToDelete.add("emailbody-texthtml_fr.ftl"); + templatesToDelete.add("emailbody-texthtml_ja.ftl"); + templatesToDelete.add("emailbody-texthtml_es.ftl"); + + for(String template : templatesToDelete) + { + NodeRef nodeRef = nodeService.getChildByName(imapTemplatesFolderNodeRef, ContentModel.ASSOC_CONTAINS, template); + if(nodeRef != null) + { + nodeService.deleteNode(nodeRef); + } + + } + } + + return I18NUtil.getMessage(MSG_REMOVED); + } + +} diff --git a/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java b/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java index 318e77f9b0..ac36a190ed 100644 --- a/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java +++ b/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java @@ -37,14 +37,16 @@ import javax.mail.internet.MimeMessage; import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.model.ContentModel; -import org.alfresco.repo.imap.ImapService.EmailBodyType; +import org.alfresco.repo.imap.ImapService.EmailBodyFormat; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.site.SiteModel; import org.alfresco.repo.template.TemplateNode; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -68,6 +70,7 @@ public abstract class AbstractMimeMessage extends MimeMessage protected ImapService imapService; protected FileInfo messageFileInfo; protected MimeMessage wrappedMessage; + protected boolean isMessageInSitesLibrary; protected AbstractMimeMessage(Session session) { @@ -88,6 +91,7 @@ public abstract class AbstractMimeMessage extends MimeMessage this.serviceRegistry = serviceRegistry; this.imapService = serviceRegistry.getImapService(); this.messageFileInfo = fileInfo; + this.isMessageInSitesLibrary = imapService.isNodeInSitesLibrary(messageFileInfo.getNodeRef()); RetryingTransactionHelper txHelper = serviceRegistry.getTransactionService().getRetryingTransactionHelper(); txHelper.setMaxRetries(MAX_RETRIES); txHelper.setReadOnly(false); @@ -214,10 +218,10 @@ public abstract class AbstractMimeMessage extends MimeMessage * Returns the text representing email body for ContentModel node. * * @param nodeRef NodeRef of the target content. - * @param type The type of the returned body. May be the one of {@link EmailBodyType}. + * @param type The type of the returned body. May be the one of {@link EmailBodyFormat}. * @return Text representing email body for ContentModel node. */ - public String getEmailBodyText(EmailBodyType type) + public String getEmailBodyText(EmailBodyFormat type) { return serviceRegistry.getTemplateService().processTemplate( imapService.getDefaultEmailBodyTemplate(type), @@ -278,9 +282,46 @@ public abstract class AbstractMimeMessage extends MimeMessage model.put("date", new Date()); model.put("contextUrl", new String(imapService.getWebApplicationContextUrl())); model.put("alfTicket", new String(serviceRegistry.getAuthenticationService().getCurrentTicket())); + if (isMessageInSitesLibrary) + { + String pathFromSites = getPathFromSites(parent); + StringBuilder parsedPath = new StringBuilder(); + String[] pathParts = pathFromSites.split("/"); + if (pathParts.length > 2) + { + parsedPath.append(pathParts[0]).append("/").append(pathParts[1]); + parsedPath.append("?filter=path|"); + for (int i = 2; i < pathParts.length; i++) + { + parsedPath.append("/").append(pathParts[i]); + } + + } + else + { + parsedPath.append(pathFromSites); + } + model.put("shareContextUrl", new String(imapService.getShareApplicationContextUrl())); + model.put("parentPathFromSites", parsedPath.toString()); + } return model; } + private String getPathFromSites(NodeRef ref) + { + NodeService nodeService = serviceRegistry.getNodeService(); + String name = ((String) nodeService.getProperty(ref, ContentModel.PROP_NAME)).toLowerCase(); + if (nodeService.getType(ref).equals(SiteModel.TYPE_SITE)) + { + return name; + } + else + { + NodeRef parent = nodeService.getPrimaryParent(ref).getParentRef(); + return getPathFromSites(parent) + "/" + name; + } + } + protected void updateMessageID() throws MessagingException { setHeader("Message-ID", this.messageFileInfo.getNodeRef().getId()); diff --git a/source/java/org/alfresco/repo/imap/AlfrescoImapConst.java b/source/java/org/alfresco/repo/imap/AlfrescoImapConst.java index a41d223d54..0afe148ed0 100644 --- a/source/java/org/alfresco/repo/imap/AlfrescoImapConst.java +++ b/source/java/org/alfresco/repo/imap/AlfrescoImapConst.java @@ -58,8 +58,12 @@ public interface AlfrescoImapConst public static final String USER_SEPARATOR = ";"; // Default content model email message templates - public static final String CLASSPATH_TEXT_PLAIN_TEMPLATE = "/alfresco/templates/imap/imap_message_text_plain.ftl"; - public static final String CLASSPATH_TEXT_HTML_TEMPLATE = "/alfresco/templates/imap/imap_message_text_html.ftl"; + public static final String CLASSPATH_ALFRESCO_TEXT_PLAIN_TEMPLATE = "/alfresco/templates/imap/emailbody_textplain_alfresco.ftl"; + public static final String CLASSPATH_SHARE_TEXT_PLAIN_TEMPLATE = "/alfresco/templates/imap/emailbody_textplain_share.ftl"; + + public static final String CLASSPATH_ALFRESCO_TEXT_HTML_TEMPLATE = "/alfresco/templates/imap/emailbody_texthtml_alfresco.ftl"; + public static final String CLASSPATH_SHARE_TEXT_HTML_TEMPLATE = "/alfresco/templates/imap/emailbody_texthtml_share.ftl"; + public static final String DICTIONARY_TEMPLATE_PREFIX = "emailbody"; public static final String PREF_IMAP_FAVOURITE_SITES = "org.alfresco.share.sites.imapFavourites"; diff --git a/source/java/org/alfresco/repo/imap/ContentModelMessage.java b/source/java/org/alfresco/repo/imap/ContentModelMessage.java index ff49be33a4..33a911eb4d 100644 --- a/source/java/org/alfresco/repo/imap/ContentModelMessage.java +++ b/source/java/org/alfresco/repo/imap/ContentModelMessage.java @@ -32,7 +32,7 @@ import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import org.alfresco.model.ContentModel; -import org.alfresco.repo.imap.ImapService.EmailBodyType; +import org.alfresco.repo.imap.ImapService.EmailBodyFormat; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.namespace.QName; @@ -98,10 +98,20 @@ public class ContentModelMessage extends AbstractMimeMessage // Cite MOB-395: "email agent will be used to select an appropriate template" - we are not able to // detect an email agent so we use a default template for all messages. // See AlfrescoImapConst to see the possible templates to use. - String bodyTxt = getEmailBodyText(EmailBodyType.TEXT_PLAIN); - rootMultipart.addBodyPart(getTextBodyPart(bodyTxt, EmailBodyType.TEXT_PLAIN.getSubtype(), EmailBodyType.TEXT_PLAIN.getMimeType())); - String bodyHtml = getEmailBodyText(EmailBodyType.TEXT_HTML); - rootMultipart.addBodyPart(getTextBodyPart(bodyHtml, EmailBodyType.TEXT_HTML.getSubtype(), EmailBodyType.TEXT_HTML.getMimeType())); + if (isMessageInSitesLibrary) + { + String bodyTxt = getEmailBodyText(EmailBodyFormat.SHARE_TEXT_PLAIN); + rootMultipart.addBodyPart(getTextBodyPart(bodyTxt, EmailBodyFormat.SHARE_TEXT_PLAIN.getSubtype(), EmailBodyFormat.SHARE_TEXT_PLAIN.getMimeType())); + String bodyHtml = getEmailBodyText(EmailBodyFormat.SHARE_TEXT_HTML); + rootMultipart.addBodyPart(getTextBodyPart(bodyHtml, EmailBodyFormat.SHARE_TEXT_HTML.getSubtype(), EmailBodyFormat.SHARE_TEXT_HTML.getMimeType())); + } + else + { + String bodyTxt = getEmailBodyText(EmailBodyFormat.ALFRESCO_TEXT_PLAIN); + rootMultipart.addBodyPart(getTextBodyPart(bodyTxt, EmailBodyFormat.ALFRESCO_TEXT_PLAIN.getSubtype(), EmailBodyFormat.ALFRESCO_TEXT_PLAIN.getMimeType())); + String bodyHtml = getEmailBodyText(EmailBodyFormat.ALFRESCO_TEXT_HTML); + rootMultipart.addBodyPart(getTextBodyPart(bodyHtml, EmailBodyFormat.ALFRESCO_TEXT_HTML.getSubtype(), EmailBodyFormat.ALFRESCO_TEXT_HTML.getMimeType())); + } return rootMultipart; } diff --git a/source/java/org/alfresco/repo/imap/ImapService.java b/source/java/org/alfresco/repo/imap/ImapService.java index da0b8b72eb..dbc9b3f8f7 100644 --- a/source/java/org/alfresco/repo/imap/ImapService.java +++ b/source/java/org/alfresco/repo/imap/ImapService.java @@ -35,37 +35,45 @@ public interface ImapService { /** - * Helper enumeration to handle email body type text/html and text/plain + * Helper enumeration to handle email body format text/html and text/plain for Alfresco/Share webapp */ - public static enum EmailBodyType + public static enum EmailBodyFormat { - TEXT_PLAIN(AlfrescoImapConst.CLASSPATH_TEXT_PLAIN_TEMPLATE), - TEXT_HTML(AlfrescoImapConst.CLASSPATH_TEXT_HTML_TEMPLATE); + ALFRESCO_TEXT_PLAIN(AlfrescoImapConst.CLASSPATH_ALFRESCO_TEXT_PLAIN_TEMPLATE), + SHARE_TEXT_PLAIN(AlfrescoImapConst.CLASSPATH_SHARE_TEXT_PLAIN_TEMPLATE), - EmailBodyType(String templatePath) + ALFRESCO_TEXT_HTML(AlfrescoImapConst.CLASSPATH_ALFRESCO_TEXT_HTML_TEMPLATE), + SHARE_TEXT_HTML(AlfrescoImapConst.CLASSPATH_SHARE_TEXT_HTML_TEMPLATE); + + EmailBodyFormat(String templatePath) { this.templatePath = templatePath; } public String getSubtype() { - return name().toLowerCase().substring(5); + return name().toLowerCase().substring(name().indexOf("_") + 1 + "TEXT".length()); } public String getTypeSubtype() { - return name().toLowerCase().replaceAll("_", ""); + return name().toLowerCase().substring(name().indexOf("_") + 1).replaceAll("_", ""); } public String getMimeType() { - return name().toLowerCase().replaceAll("_", "/"); + return name().toLowerCase().substring(name().indexOf("_") + 1).replaceAll("_", "/"); } - public String getClasspathTempltePath() + public String getClasspathTemplatePath() { return this.templatePath; } + public String getWebApp() + { + return name().toLowerCase().substring(0, name().indexOf("_")); + } + private String templatePath; } @@ -228,6 +236,11 @@ public interface ImapService */ public String getWebApplicationContextUrl(); + /** + * @return Web application context url for share (e.g. http://localhost:8080/share) + */ + public String getShareApplicationContextUrl(); + /** * Returns a template for email body. It is either classpath path or NodeRef.toString(). * This method trying to find a template on the path in the repository first @@ -238,5 +251,14 @@ public interface ImapService * @param Type one of the possible body types text/html and text/plain * @return */ - public String getDefaultEmailBodyTemplate(EmailBodyType type); + public String getDefaultEmailBodyTemplate(EmailBodyFormat type); + + /** + * Determine if provided node belongs to Sites. + * + * @param nodeRef nodeRef + * @return true if provided node belongs to sites. + */ + public boolean isNodeInSitesLibrary(NodeRef nodeRef); + } diff --git a/source/java/org/alfresco/repo/imap/ImapServiceImpl.java b/source/java/org/alfresco/repo/imap/ImapServiceImpl.java index 0084fd942b..a64d3dacc0 100644 --- a/source/java/org/alfresco/repo/imap/ImapServiceImpl.java +++ b/source/java/org/alfresco/repo/imap/ImapServiceImpl.java @@ -127,7 +127,7 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol private String repositoryTemplatePath; private boolean extractAttachmentsEnabled = true; - private Map defaultBodyTemplates; + private Map defaultBodyTemplates; private final static Map qNameToFlag; private final static Map flagToQname; @@ -271,6 +271,11 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol return sysAdminParams.getAlfrescoProtocol() + "://" + sysAdminParams.getAlfrescoHost() + ":" + sysAdminParams.getAlfrescoPort() + "/" + sysAdminParams.getAlfrescoContext(); } + public String getShareApplicationContextUrl() + { + return sysAdminParams.getShareProtocol() + "://" + sysAdminParams.getShareHost() + ":" + sysAdminParams.getSharePort() + "/" + sysAdminParams.getShareContext(); + } + public String getRepositoryTemplatePath() { return repositoryTemplatePath; @@ -1915,21 +1920,23 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol return extractAttachmentsEnabled && !ignoreExtractionFolders.contains(nodeRef); } - public String getDefaultEmailBodyTemplate(EmailBodyType type) + public String getDefaultEmailBodyTemplate(EmailBodyFormat type) { if (defaultBodyTemplates == null) { - defaultBodyTemplates = new HashMap(2); + defaultBodyTemplates = new HashMap(4); - for (EmailBodyType onetype : EmailBodyType.values()) + for (EmailBodyFormat onetype : EmailBodyFormat.values()) { - String result = onetype.getClasspathTempltePath(); + String result = onetype.getClasspathTemplatePath(); try { // This query uses cm:name to find the template node(s). // For the case where the templates are renamed, it would be better to use a QName path-based query. - final StringBuilder templateName = new StringBuilder(DICTIONARY_TEMPLATE_PREFIX).append("-").append(onetype.getTypeSubtype()).append(".ftl"); + + final StringBuilder templateName = new StringBuilder(DICTIONARY_TEMPLATE_PREFIX).append("_").append(onetype.getTypeSubtype()).append("_").append(onetype.getWebApp()).append(".ftl"); + final String repositoryTemplatePath = getRepositoryTemplatePath(); int indexOfStoreDelim = repositoryTemplatePath.indexOf(StoreRef.URI_FILLER); if (indexOfStoreDelim == -1) @@ -1953,7 +1960,11 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol ResultSet resultSet = serviceRegistry.getSearchService().query(storeRef, "xpath", query); if (resultSet == null || resultSet.length() == 0) { - throw new IllegalArgumentException(String.format("[getDefaultEmailBodyTemplate] IMAP message template '%1$s' does not exist in the path '%2$s'.", templateName, repositoryTemplatePath)); + if(logger.isDebugEnabled()) + { + logger.debug("template not found:" + templateName); + } + throw new AlfrescoRuntimeException(String.format("[getDefaultEmailBodyTemplate] IMAP message template '%1$s' does not exist in the path '%2$s'.", templateName, repositoryTemplatePath)); } final NodeRef defaultLocaleTemplate = resultSet.getNodeRef(0); @@ -1963,7 +1974,7 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol resultSet.close(); } - // We are catching all exceptions. E.g. search service can possibly trow an exceptions on malformed queries. + // We are catching all exceptions. E.g. search service can possibly throw an exceptions on malformed queries. catch (Exception e) { logger.error("[getDefaultEmailBodyTemplate]", e); @@ -2153,5 +2164,33 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol } - + /** + * Return true if provided nodeRef is in Sites/.../documentlibrary + */ + public boolean isNodeInSitesLibrary(NodeRef nodeRef) + { + boolean isInDocLibrary = false; + NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); + while (parent != null && !nodeService.getType(parent).equals(SiteModel.TYPE_SITE)) + { + String parentName = (String) nodeService.getProperty(parent, ContentModel.PROP_NAME); + if (parentName.equalsIgnoreCase("documentlibrary")) + { + isInDocLibrary = true; + } + nodeRef = parent; + if (nodeService.getPrimaryParent(nodeRef) != null) + { + parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); + } + } + if (parent == null) + { + return false; + } + else + { + return nodeService.getType(parent).equals(SiteModel.TYPE_SITE) && isInDocLibrary; + } + } }