Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)

121917 jkaabimofrad: RA-778: Added support for QuickShare service to email users notifying them that a content has been shared with them.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@126436 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jamal Kaabi-Mofrad
2016-05-10 10:54:46 +00:00
parent 4e8926ccf3
commit aa9a557f4d
6 changed files with 873 additions and 57 deletions

View File

@@ -0,0 +1,2 @@
# QuickShare Service
quickshare.notifier.email.subject={0} {1} shared {2} with you

View File

@@ -51,7 +51,7 @@
</property>
</bean>
<!-- Calendar Service base bean -->
<!-- QuickShare Service base bean -->
<bean id="quickShareService" class="org.alfresco.repo.quickshare.QuickShareServiceImpl" init-method="init">
<property name="attributeService" ref="AttributeService"/>
<property name="dictionaryService" ref="dictionaryService"/>
@@ -64,6 +64,27 @@
<property name="thumbnailService" ref="ThumbnailService"/>
<property name="eventPublisher" ref="eventPublisher" />
<property name="behaviourFilter" ref="policyBehaviourFilter" />
<property name="actionService" ref="ActionService" />
<property name="preferenceService" ref="PreferenceService" />
<property name="defaultEmailSender" value="${system.quickshare.email.from.default}" />
<property name="templateRegistry" ref="quickShare.emailTemplates" />
</bean>
<bean id="quickShare.emailTemplates" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<!-- key=> template Id value=> template classpath -->
<entry key="default" value="alfresco/templates/quickshare-email-templates/quickshare-email.default.template.ftl" />
</map>
</property>
</bean>
<bean id="quickShareResourceBundles" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
<property name="resourceBundles">
<list>
<value>alfresco.messages.quickshare-service</value>
</list>
</property>
</bean>
</beans>

View File

@@ -958,9 +958,6 @@ download.cleaner.startDelayMins=60
download.cleaner.repeatIntervalMins=60
download.cleaner.maxAgeMins=60
# enable QuickShare - if false then the QuickShare-specific REST APIs will return 403 Forbidden
system.quickshare.enabled=true
#
# Download Service Limits, in bytes
#
@@ -977,6 +974,7 @@ authority.useBridgeTable=true
# enable QuickShare - if false then the QuickShare-specific REST APIs will return 403 Forbidden
system.quickshare.enabled=true
system.quickshare.email.from.default=noreply@alfresco.com
# Oubound Mail
mail.service.corePoolSize=8

View File

@@ -0,0 +1,452 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Alfresco</title>
<style type="text/css">
td {
font-family: 'Helvetica Neue', Arial, sans-serif;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
width: 100% ! important;
height: 100% !important;
color: #727174;
font-weight: 400;
font-size: 18px;
margin: 0;
}
h1 {
margin: 10px 0;
}
h2 {
color: #727174;
font-weight: 600;
font-size: 22px;
}
a {
color: #0c79bf;
text-decoration: underline;
}
a.linkone {
color: #0c79bf;
text-decoration: underline;
}
.appleLinks a {
color: #0c79bf;
}
.appleLinksWhite a {
color: #0c79bf;
}
.force-full-width {
width: 100% !important;
}
.body-padding {
padding: 0 75px
}
.force-width-80 {
width: 80% !important;
}
p {
Margin-bottom: 1em;
}
.button {
text-align: center;
font-size: 18px;
font-family: sans-serif;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
.button a {
color: #ffffff;
text-decoration: none;
}
img {
max-width: 600px;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
a img {
border: none;
}
table {
border-collapse: collapse;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
#outlook a {
padding: 0;
}
.ReadMsgBody {
width: 100%;
}
.ExternalClass {
width: 100%;
}
.backgroundTable {
margin: 0 auto;
padding: 0;
width: 100% !important;
}
table td {
border-collapse: collapse;
}
.ExternalClass * {
line-height: 115%;
}
.ExternalClass {
vertical-align: middle
}
/*]]>*/
</style>
<style type="text/css" media="screen">
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { {
@-ms-viewport {
width: 320px;
}
@viewport {
width: 320px;
}
}
</style>
<style type="text/css" media="screen">
@media screen {
* {
font-family: 'Helvetica Neue', 'Arial', 'sans-serif' !important;
}
.w280 {
width: 280px !important;
}
}
</style>
<style type="text/css" media="only screen and (max-width: 480px)">
@media only screen and (max-width: 480px) {
.full {
display: block;
width: 100%;
}
table[class*="w320"] {
width: 320px !important;
}
td[class*="w320"] {
width: 280px !important;
padding-left: 20px !important;
padding-right: 20px !important;
}
img[class*="w320"] {
width: 250px !important;
height: 67px !important;
}
td[class*="mobile-spacing"] {
padding-top: 10px !important;
padding-bottom: 10px !important;
}
*[class*="mobile-hide"] {
display: none !important;
}
*[class*="mobile-br"] {
font-size: 8px !important;
}
*[class*="mobile-brh"] {
font-size: 1px !important;
}
td[class*="mobile-w20"] {
width: 20px !important;
}
img[class*="mobile-w20"] {
width: 20px !important;
}
td[class*="mobile-center"] {
text-align: center !important;
}
table[class*="w100p"] {
width: 100% !important;
}
td[class*="activate-now"] {
padding-right: 0 !important;
padding-top: 20px !important;
}
td[class*="mobile-resize"] {
font-size: 22px !important;
padding-left: 15px !important;
}
}
</style>
</head>
<body offset="0" class="body" style="padding:0; margin:0; display:block; background:#f3f4f4; -webkit-text-size-adjust:none; " bgcolor="#EEEEEE">
<table align="center" cellpadding="0" cellspacing="0" width="100%" height="100%">
<tr>
<td align="center" valign="top" style="background-color:#f3f4f4; " width="100%">
<table cellspacing="0" cellpadding="0" width="600" class="w320">
<tr>
<td align="center" valign="top">
<!--Snippet Block-->
<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%">
<tr>
<td>
<table border="0" cellspacing="0" cellpadding="10" width="100%" align="center">
<tbody>
<tr>
<td align="left">
<table align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="right">
<div style="display:none;font-size:1px;color:#333333;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">
-
</div>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
<!--Header Block-->
<table bgcolor="#FFFFFF" border="0" cellspacing="0" cellpadding="0" align="center" width="100%"
style="border: 1px solid #dedee4;width:100%!important; min-width:100%;">
<tr style="width:100%;">
<td>
<table border="0" cellspacing="0" cellpadding="10" align="center" width="100%">
<tr>
<td align="left" valign="middle"><a style="color: #ffffff; text-decoration: none;" href=
"http://go.alfresco.com/a0100K050L0000KZjI2d00U" target="_blank"
><span style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px; color: #727174;"><img
style="border:none; display:block; border-collapse:collapse; outline:none; text-decoration:none;"
src="${url.context}/images/logo/Alfresco_Logo_gray.png" border="0"
alt="Alfresco" width="122" height="38"></span></a></td>
</tr>
</table>
</td>
<td align="right" bgcolor="#FFFFFF">
<table border="0" cellspacing="0" cellpadding="10" align="center" width="100%">
<tr>
<td align="right" valign="middle"><span
style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; font-weight:200; color: #727174;">Simple<span
style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; font-weight:400; color:
#727174;">+</span>Smart&nbsp;</span></td>
</tr>
</table>
</td>
</tr>
</table>
<!--Break-->
<table width="100%">
<tr>
<td height="10">
<div class="mobile-br">&nbsp;</div>
</td>
</tr>
</table>
<!--Body Block 1-->
<!--Banner Block-->
<table cellspacing="0" cellpadding="0" width="100%" style="border-left:solid 1px #dedee4; border-right:solid 1px #dedee4; ">
<tr>
<td style="border-collapse:collapse; ">
<table cellspacing="0" cellpadding="0" width="100%" style="background-color:#0c79bf; border:none; ">
<tr>
<td style="border-collapse:collapse; ">
<div class="mktEditable" id="Banner Image 1"><span
style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px; color: #ffffff;"><img
src="${url.context}/images/icons/Product_Banner_1.jpg" alt="Alfresco Products" style="width:100%; border:none;
display:block; border-collapse:collapse; outline:none; text-decoration:none;"></span></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!--Copy-->
<table cellspacing="0" cellpadding="0" align="center" bgcolor="#FFFFFF"
style="border-left:solid 1px #dedee4; border-right:solid 1px #dedee4; border-bottom:solid 1px #dedee4; " width="100%">
<tr align="center">
<td style="background-color:#ffffff; " align="center">
<table class="force-width-80" cellspacing="0" cellpadding="12" align="center" bgcolor="#FFFFFF" width="80%">
<tbody>
<tr>
<td align="left">
<!--Headline Text-->
<div class="mktEditable" id="Headline Text 1" align="left" style="vertical-align:middle; "><span
style="color: #727174; margin: 0px; font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 22px; font-weight: 600; text-align: left; text-decoration: none; vertical-align:
middle;"><p>${shared_node_name} shared with you</p></span></div>
<div class="mktEditable" id="Body Text 1" align="left">
<span style="color:#727174; font-family:Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:18px;font-weight:400; text-align:left; text-decoration:none; -webkit-text-size-adjust:none;">
<p>${sender_first_name} ${sender_last_name} has shared <a href="${shared_node_url}">${shared_node_name}</a> with you.</p>
<p>${sender_message}</p>
</span>
</div>
<!--Break-->
<table width="100%">
<tr>
<td height="5">
<div class="mobile-br">&nbsp;</div>
</td>
</tr>
</table>
<!--Button-->
<table style="margin:0 auto; " cellspacing="0" cellpadding="0" width="100%">
<tr>
<td style="text-align:center; margin:0 auto; ">
<div><!--[if mso]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="urn:schemas-microsoft-com:office:word"
style="height:45px;v-text-anchor:middle;width:220px;" stroke="f"
fillcolor="#47AA2">
<w:anchorlock/>
<center>
<![endif]-->
<div class="mktEditable" id="Button Text"><a href="${shared_node_url}" style="background-color:#47aa42; color:#ffffff; display:inline-block; font-family:Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:18px; font-weight:400; line-height:45px; text-align:center; text-decoration:none; width:220px;
-webkit-text-size-adjust:none;"
>View Online</a></div>
<!--[if mso]>
</center>
</v:rect>
<![endif]--></div>
</td>
</tr>
</table>
<!--Break-->
<table width="100%">
<tr>
<td height="5">
<div class="mobile-br">&nbsp;</div>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
<!--Break-->
<table width="100%">
<tr>
<td height="10">
<div class="mobile-br">&nbsp;</div>
</td>
</tr>
</table>
<!--Footer Block-->
<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%">
<tr>
<td align="center">
<table cellspacing="0" cellpadding="0" border="0" align="center">
<tr>
<td cellspacing="0" cellpadding="0" border="0" align="center"><a
style="color: #ffffff; text-decoration: none;"
href="http://go.alfresco.com/a0100K060L0000RZeI2o00U" target="_blank"><img
src="${url.context}/images/icons/Alfresco_Icon_Social_Twitter.png" width="23" height="23"
border="0"></a>&nbsp; <a style="color: #ffffff; text-decoration: none;"
href="http://go.alfresco.com/G6I0Zo100S0fL0UK0000020"
target="_blank"><img src="${url.context}/images/icons/Alfresco_Icon_Social_LinkedIn.png"
width="23" height="23" border="0"></a>&nbsp; <a
style="color:
#ffffff; text-decoration: none;" href="http://go.alfresco.com/TT2Lo00060000Ig10K00UZ0" target="_blank"><img
src="${url.context}/images/icons/Alfresco_Icon_Social_Facebook.png" width="23" height="23" border="0"></a>&nbsp; <a
style="color: #ffffff; text-decoration: none;"
href="http://go.alfresco.com/v00002oh0UKZL0U6I010000" target="_blank"><img
src="${url.context}/images/icons/Alfresco_Icon_Social_Google.png" width="23" height="23" border="0"></a></td>
<td cellspacing="0" cellpadding="0" border="0" align="center" width="10"></td>
<td cellspacing="0" cellpadding="0" border="0" align="center"><a style="color: #333333;"
href="http://go.alfresco.com/a0100K050L0000KZjI2d00U"
target="_blank"><span
style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #727174;"><img
src="${url.context}/images/logo/AlfrrescoGlobal_Logo_BW.png" border="0" alt="alfresco.com" width="92" height="29"><br></span></a>
</td>
</tr>
</table>
<a style="color: #0c79bf; text-decoration: underline;" href="http://{{my.Footer_ContactUs_URL}}"
target="_blank"><span
style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #0c79bf;">Contact Us</span></a> <span
style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial,
sans-serif; font-size: 10px; color: #b3b3b8;">© 2015 Alfresco Software, Inc. All Rights Reserved.</span><br>
<span style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #b3b3b8;">Bridge Ave, The Place Maidenhead SL6 1AF United Kingdom</span><br>
<span style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #b3b3b8;">1825 S Grant St, Suite 900 San Mateo, CA 94402 USA</span><br>
</td>
</tr>
</table>
<!--Break-->
<table width="100%">
<tr>
<td height="10">
<div class="mobile-br">&nbsp;</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!--Litmus Tracking-->
<table style="display: none;">
<tbody>
<tr>
<td style="width: 0px; display: none; overflow: hidden; max-height: 0px;">{{my.Litmus_Code}}</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@@ -20,16 +20,23 @@ package org.alfresco.repo.quickshare;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.events.types.ActivityEvent;
import org.alfresco.events.types.Event;
import org.alfresco.model.ContentModel;
import org.alfresco.model.QuickShareModel;
import org.alfresco.repo.Client;
import org.alfresco.repo.Client.ClientType;
import org.alfresco.repo.action.executer.MailActionExecuter;
import org.alfresco.repo.copy.CopyBehaviourCallback;
import org.alfresco.repo.copy.CopyDetails;
import org.alfresco.repo.copy.CopyServicePolicies;
@@ -47,8 +54,11 @@ import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.service.cmr.quickshare.InvalidSharedIdException;
import org.alfresco.service.cmr.quickshare.QuickShareDTO;
import org.alfresco.service.cmr.quickshare.QuickShareDisabledException;
@@ -66,11 +76,16 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.safehaus.uuid.UUID;
import org.safehaus.uuid.UUIDGenerator;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.util.StringUtils;
/**
* QuickShare Service implementation.
@@ -78,7 +93,7 @@ import org.safehaus.uuid.UUIDGenerator;
* In addition to the quick share service, this class also provides a BeforeDeleteNodePolicy and
* OnCopyNodePolicy for content with the QuickShare aspect.
*
* @author Alex Miller, janv
* @author Alex Miller, janv, Jamal Kaabi-Mofrad
*/
public class QuickShareServiceImpl implements QuickShareService, NodeServicePolicies.BeforeDeleteNodePolicy, CopyServicePolicies.OnCopyNodePolicy
{
@@ -86,8 +101,12 @@ public class QuickShareServiceImpl implements QuickShareService, NodeServicePoli
static final String ATTR_KEY_SHAREDIDS_ROOT = ".sharedIds";
private boolean enabled;
private static final String FTL_SHARED_NODE_URL = "shared_node_url";
private static final String FTL_SHARED_NODE_NAME = "shared_node_name";
private static final String FTL_SENDER_MESSAGE = "sender_message";
private static final String FTL_SENDER_FIRST_NAME = "sender_first_name";
private static final String FTL_SENDER_LAST_NAME = "sender_last_name";
private static final String DEFAULT_EMAIL_SUBJECT = "quickshare.notifier.email.subject";
private AttributeService attributeService;
private DictionaryService dictionaryService;
@@ -98,27 +117,14 @@ public class QuickShareServiceImpl implements QuickShareService, NodeServicePoli
private TenantService tenantService;
private ThumbnailService thumbnailService;
private EventPublisher eventPublisher;
private ActionService actionService;
private PreferenceService preferenceService;
/** Component to determine which behaviours are active and which not */
private BehaviourFilter behaviourFilter;
/**
* Spring configuration
*
* @param behaviourFilter the behaviourFilter to set
*/
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
{
this.behaviourFilter = behaviourFilter;
}
/**
* Enable or disable this service.
*/
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
private boolean enabled;
private String defaultEmailSender;
private Map<String, String> templateRegistry;
/**
* Set the attribute service
@@ -192,11 +198,81 @@ public class QuickShareServiceImpl implements QuickShareService, NodeServicePoli
this.eventPublisher = eventPublisher;
}
/**
* Set the actionService
*/
public void setActionService(ActionService actionService)
{
this.actionService = actionService;
}
/**
* Set the preferenceService
*/
public void setPreferenceService(PreferenceService preferenceService)
{
this.preferenceService = preferenceService;
}
/**
* Spring configuration
*
* @param behaviourFilter the behaviourFilter to set
*/
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
{
this.behaviourFilter = behaviourFilter;
}
/**
* Enable or disable this service.
*/
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
/**
* Set the default email sender
*/
public void setDefaultEmailSender(String defaultEmailSender)
{
this.defaultEmailSender = defaultEmailSender;
}
/**
* Set the templates
*/
public void setTemplateRegistry(Map<String, String> templateRegistry)
{
this.templateRegistry = templateRegistry;
}
private void checkMandatoryProperties()
{
PropertyCheck.mandatory(this, "attributeService", attributeService);
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "permissionService", permissionService);
PropertyCheck.mandatory(this, "personService", personService);
PropertyCheck.mandatory(this, "policyComponent", policyComponent);
PropertyCheck.mandatory(this, "tenantService", tenantService);
PropertyCheck.mandatory(this, "thumbnailService", thumbnailService);
PropertyCheck.mandatory(this, "eventPublisher", eventPublisher);
PropertyCheck.mandatory(this, "actionService", actionService);
PropertyCheck.mandatory(this, "preferenceService", preferenceService);
PropertyCheck.mandatory(this, "behaviourFilter", behaviourFilter);
PropertyCheck.mandatory(this, "defaultEmailSender", defaultEmailSender);
PropertyCheck.mandatory(this, "templateRegistry", templateRegistry);
}
/**
* The initialise method. Register our policies.
*/
public void init()
{
checkMandatoryProperties();
// Register interest in the beforeDeleteNode policy - note: currently for content only !!
policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
@@ -596,4 +672,263 @@ public class QuickShareServiceImpl implements QuickShareService, NodeServicePoli
}
@Override
public void sendEmailNotification(final QuickShareEmailRequest emailRequest)
{
ParameterCheck.mandatory("emailRequest", emailRequest);
emailRequest.validate();
if (!templateRegistry.containsKey(emailRequest.getTemplateId()))
{
throw new AlfrescoRuntimeException("Invalid template. Couldn't find a template with id:" + emailRequest.getTemplateId());
}
// Set the details of the person sending the email
final String authenticatedUser = AuthenticationUtil.getFullyAuthenticatedUser();
final NodeRef senderNodeRef = personService.getPerson(authenticatedUser, false);
final Map<QName, Serializable> senderProps = nodeService.getProperties(senderNodeRef);
final String senderFirstName = (String) senderProps.get(ContentModel.PROP_FIRSTNAME);
final String senderLastName = (String) senderProps.get(ContentModel.PROP_LASTNAME);
final String senderEmail = (String) senderProps.get(ContentModel.PROP_EMAIL);
final String senderFullName = ((senderFirstName != null ? senderFirstName + " " : "") + (senderLastName != null ? senderLastName : "")).trim();
// Set the default model information
Map<String, Serializable> templateModel = new HashMap<>(5);
templateModel.put(FTL_SENDER_FIRST_NAME, senderFirstName);
templateModel.put(FTL_SENDER_LAST_NAME, senderLastName);
templateModel.put(FTL_SHARED_NODE_URL, emailRequest.getSharedNodeURL());
templateModel.put(FTL_SHARED_NODE_NAME, emailRequest.getSharedNodeName());
templateModel.put(FTL_SENDER_MESSAGE, emailRequest.getSenderMessage());
// Email sender
// By default the current-user's email address will not be used to send this mail.
// However, current-user's first and lastname will be used as the personal name.
final String from = (!emailRequest.isSendFromDefaultEmail() && senderEmail != null) ? senderEmail : this.defaultEmailSender;
// Set the email details
Map<String, Serializable> actionParams = new HashMap<>();
actionParams.put(MailActionExecuter.PARAM_FROM, from);
actionParams.put(MailActionExecuter.PARAM_FROM_PERSONAL_NAME, senderFullName);
actionParams.put(MailActionExecuter.PARAM_SUBJECT, DEFAULT_EMAIL_SUBJECT);
actionParams.put(MailActionExecuter.PARAM_SUBJECT_PARAMS, new Object[] { senderFirstName, senderLastName, emailRequest.getSharedNodeName() });
actionParams.put(MailActionExecuter.PARAM_IGNORE_SEND_FAILURE, emailRequest.isIgnoreSendFailure());
// Pick the template
actionParams.put(MailActionExecuter.PARAM_TEMPLATE, templateRegistry.get(emailRequest.getTemplateId()));
actionParams.put(MailActionExecuter.PARAM_TEMPLATE_MODEL, (Serializable) templateModel);
actionParams.put(MailActionExecuter.PARAM_LOCALE, getDefaultIfNull(getEmailCreatorLocale(authenticatedUser), emailRequest.getLocale()));
for (String to : emailRequest.getToEmails())
{
Map<String, Serializable> params = new HashMap<>(actionParams);
params.put(MailActionExecuter.PARAM_TO, to);
Action mailAction = actionService.createAction(MailActionExecuter.NAME, params);
actionService.executeAction(mailAction, null, false, true);
}
}
private <T> T getDefaultIfNull(T defaultValue, T newValue)
{
return (newValue == null) ? defaultValue : newValue;
}
private Locale getEmailCreatorLocale(String userId)
{
String localeString = (String) preferenceService.getPreference(userId, "locale");
return I18NUtil.parseLocale(localeString);
}
/**
* Represents an email request to send a quick share link.
*/
public static class QuickShareEmailRequest
{
/**
* Whether to send an email from the default email address or use the current-user's email (if not null).
* The default is true.
*/
private boolean sendFromDefaultEmail = true;
/**
* Optional Locale for subject and body text
*/
private Locale locale;
/**
* The email addresses (1 or many) of the recipients.
*/
private Set<String> toEmails;
/**
* The template id. If not provided, a default template will be used.
*/
private String templateId = "default";
/**
* The shared content URL.
*/
private String sharedNodeURL;
/**
* The shared content name.
*/
private String sharedNodeName;
/**
* Optional message from the sender.
*/
private String senderMessage;
/**
* Whether to ignore throwing exception or not. The default is false.
*/
private boolean ignoreSendFailure = false;
public void validate()
{
ParameterCheck.mandatoryCollection("toEmails", toEmails);
ParameterCheck.mandatoryString("templateId", templateId);
ParameterCheck.mandatoryString("sharedNodeURL", sharedNodeURL);
ParameterCheck.mandatoryString("sharedNodeName", sharedNodeName);
ParameterCheck.mandatoryString("senderMessage", senderMessage);
}
/**
* {@link QuickShareEmailRequest#sendFromDefaultEmail}
*/
public boolean isSendFromDefaultEmail()
{
return sendFromDefaultEmail;
}
/**
* {@link QuickShareEmailRequest#sendFromDefaultEmail}
*/
public void setSendFromDefaultEmail(Boolean sendFromDefaultEmail)
{
if (sendFromDefaultEmail != null)
{
this.sendFromDefaultEmail = sendFromDefaultEmail;
}
}
/**
* {@link QuickShareEmailRequest#locale}
*/
public Locale getLocale()
{
return this.locale;
}
/**
* {@link QuickShareEmailRequest#locale}
*/
public void setLocale(Locale locale)
{
this.locale = locale;
}
/**
* {@link QuickShareEmailRequest#toEmails}
*/
public Set<String> getToEmails()
{
return this.toEmails;
}
/**
* {@link QuickShareEmailRequest#toEmails}
*/
public void setToEmails(Collection<String> toEmails)
{
if (toEmails != null)
{
this.toEmails = Collections.unmodifiableSet(new HashSet<>(toEmails));
}
}
/**
* {@link QuickShareEmailRequest#templateId}
*/
public String getTemplateId()
{
return templateId;
}
/**
* {@link QuickShareEmailRequest#templateId}
*/
public void setTemplateId(String templateId)
{
if (templateId != null)
{
this.templateId = templateId;
}
}
/**
* {@link QuickShareEmailRequest#sharedNodeURL}
*/
public String getSharedNodeURL()
{
return sharedNodeURL;
}
/**
* {@link QuickShareEmailRequest#sharedNodeURL}
*/
public void setSharedNodeURL(String sharedNodeURL)
{
this.sharedNodeURL = sharedNodeURL;
}
/**
* {@link QuickShareEmailRequest#sharedNodeName}
*/
public String getSharedNodeName()
{
return sharedNodeName;
}
/**
* {@link QuickShareEmailRequest#sharedNodeName}
*/
public void setSharedNodeName(String sharedNodeName)
{
this.sharedNodeName = sharedNodeName;
}
/**
* {@link QuickShareEmailRequest#senderMessage}
*/
public String getSenderMessage()
{
return senderMessage;
}
/**
* {@link QuickShareEmailRequest#senderMessage}
*/
public void setSenderMessage(String senderMessage)
{
this.senderMessage = senderMessage;
}
/**
* {@link QuickShareEmailRequest#ignoreSendFailure}
*/
public boolean isIgnoreSendFailure()
{
return ignoreSendFailure;
}
/**
* {@link QuickShareEmailRequest#ignoreSendFailure}
*/
public void setIgnoreSendFailure(Boolean ignoreSendFailure)
{
if (ignoreSendFailure != null)
{
this.ignoreSendFailure = ignoreSendFailure;
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
* Copyright (C) 2005-2016 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -20,6 +20,7 @@ package org.alfresco.service.cmr.quickshare;
import java.util.Map;
import org.alfresco.repo.quickshare.QuickShareServiceImpl.QuickShareEmailRequest;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.Pair;
@@ -77,4 +78,11 @@ public interface QuickShareService
* Determine if the current user has permission to read the shared content.
*/
public boolean canRead(String sharedId);
/**
* Notifies users by email that a content has been shared with them, and the details of it.
*
* @param emailRequest The email details including its template details
*/
public void sendEmailNotification(QuickShareEmailRequest emailRequest);
}