001/**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.service.impl;
017
018import java.text.MessageFormat;
019import java.util.Arrays;
020import java.util.HashSet;
021import java.util.Set;
022
023import org.apache.commons.lang.StringUtils;
024import org.apache.log4j.Logger;
025import org.kuali.rice.core.api.CoreApiServiceLocator;
026import org.kuali.rice.core.api.mail.MailMessage;
027import org.kuali.rice.core.api.mail.Mailer;
028import org.kuali.rice.kim.api.identity.Person;
029import org.kuali.rice.kim.api.services.KimApiServiceLocator;
030import org.kuali.rice.krad.service.KualiFeedbackService;
031import org.kuali.rice.krad.util.GlobalVariables;
032import org.kuali.rice.krad.util.KRADConstants;
033
034/**
035 * This class implements the KualiFeedbackService and contains logic
036 * to send a feedback email to the feedback email list with information from
037 * users.
038 */
039public class KualiFeedbackServiceImpl implements KualiFeedbackService {
040        
041        private static final Logger LOG = Logger.getLogger(KualiFeedbackServiceImpl.class);
042        
043        private static final String FEEDBACK_EMAIL_SUBJECT_PARAM = "feedback.email.subject";
044        private static final String FEEDBACK_EMAIL_BODY_PARAM = "feedback.email.body";
045
046        /**
047         * A Mailer for sending report.
048         */
049        private Mailer mailer;
050        /**
051         * An email template is used to construct an email to be sent by the mail service.
052         */
053        private MailMessage messageTemplate;
054
055        /**
056         * This mails the report using the mail service from the mail template.
057         * 
058         * @see org.kuali.rice.krad.service.KualiExceptionIncidentService#emailReport(String, String)
059         */
060        @Override
061        public void emailReport(String subject, String message) throws Exception {
062                if (LOG.isTraceEnabled()) {
063                        String lm=String.format("ENTRY %s;%s",
064                                        (subject==null)?"null":subject.toString(),
065                                                        (message==null)?"null":message.toString());
066                        LOG.trace(lm);
067                }
068
069                if (mailer == null) {
070                        String errorMessage = "mailer property of KualiExceptionIncidentServiceImpl is null";
071                        LOG.fatal(errorMessage);
072                        throw new IllegalStateException(errorMessage);
073                }
074
075                // Send mail
076                MailMessage msg = createMailMessage(subject, message);
077                mailer.sendEmail(msg);
078
079                if (LOG.isTraceEnabled()) {
080                        LOG.trace("EXIT");
081                }
082        }
083
084        @Override
085        public void sendFeedback(String documentId, String componentName, String description) throws Exception {
086                this.emailReport(this.createFeedbackReportSubject(), this.createFeedbackReportMessage(documentId, componentName, description));
087        }
088        
089        private String createFeedbackReportSubject() {
090                String env = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(KRADConstants.ENVIRONMENT_KEY);
091                String formatString = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(FEEDBACK_EMAIL_SUBJECT_PARAM);
092                String subject = MessageFormat.format(formatString, env);
093                return subject;
094        }
095
096        private String createFeedbackReportMessage(String documentId, String componentName, String description) {
097                documentId = (documentId == null) ? "" : documentId;
098                componentName = (componentName == null) ? "" : componentName;
099                description = (description == null) ? "" : description;
100                
101                String principalName = GlobalVariables.getUserSession().getLoggedInUserPrincipalName();
102                principalName = (principalName == null) ? "" : principalName;
103                
104                String formatString = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(FEEDBACK_EMAIL_BODY_PARAM);
105                String message = MessageFormat.format(formatString, documentId, principalName, componentName, description);
106                return message;
107        }
108
109        /**
110     * Creates an instance of MailMessage from the inputs using the given
111     * template.
112         *
113     * @param subject the subject line text
114     * @param message the body of the email message
115     * @return MailMessage
116     * @throws IllegalStateException if the <codeREPORT_MAIL_LIST</code> is not set
117     * or messageTemplate does not have ToAddresses already set.
118     */
119    @SuppressWarnings("unchecked")
120    protected MailMessage createMailMessage(String subject, String message)
121            throws Exception {
122                if (LOG.isTraceEnabled()) {
123            String lm=String.format("ENTRY %s%n%s",
124                    (subject==null) ? "null" : subject.toString(),
125                    (message==null) ? "null" : message.toString());
126            LOG.trace(lm);
127        }
128        
129        MailMessage messageTemplate = this.getMessageTemplate();
130        if (messageTemplate == null) {
131            throw new IllegalStateException(String.format(
132                    "%s.templateMessage is null or not set",
133                    this.getClass().getName()));
134        }
135        
136        // Copy input message reference for creating an instance of mail message
137        MailMessage msg=new MailMessage();
138        
139        msg.setFromAddress(this.getFromAddress());
140        msg.setToAddresses(this.getToAddresses());
141        msg.setBccAddresses(this.getBccAddresses());
142        msg.setCcAddresses(this.getCcAddresses());
143
144        // Set mail message subject
145        msg.setSubject((subject==null) ? "" : subject);
146
147        // Set mail message body
148        msg.setMessage((message==null) ? "" : message);
149        
150        if (LOG.isTraceEnabled()) {
151            String lm = String.format("EXIT %s", (msg==null) ? "null" : msg.toString());
152            LOG.trace(lm);
153        }
154
155        return msg;
156        }
157
158        protected String getFromAddress() {
159        // First check if message template already defines the mailing list
160        String email = this.getMessageTemplate().getFromAddress();
161
162        if (StringUtils.isBlank(email)) {
163            Person actualUser = GlobalVariables.getUserSession().getActualPerson();
164
165            if (StringUtils.isBlank(actualUser.getEmailAddress())) {
166                String em = "No email address available from the current user or messageTemplate does not have FromAddress already set.";
167                LOG.error(em);
168                throw new IllegalStateException(em);
169            } else {
170                return actualUser.getEmailAddress();
171            }
172        } else {
173            return email;
174        }
175        }
176        
177        protected Set<String> getToAddresses() {
178                // First check if message template already defines the mailing list
179        Set<String> emails = this.getMessageTemplate().getToAddresses();
180        if (emails == null || emails.isEmpty()) {
181                String mailingList = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(this.getToAddressesPropertyName());
182            if (StringUtils.isBlank(mailingList)) {
183                String em = REPORT_MAIL_LIST + " is not set or messageTemplate does not have ToAddresses already set.";
184                LOG.error(em);
185                throw new IllegalStateException(em);
186            } else {
187                return new HashSet<String>(Arrays.asList(StringUtils.split(mailingList,
188                                KRADConstants.FIELD_CONVERSIONS_SEPARATOR)));
189            }
190        } else {
191            return emails;
192        }
193        }
194        
195        protected String getToAddressesPropertyName() {
196                return REPORT_MAIL_LIST;
197        }
198        
199        protected Set<String> getCcAddresses() {
200                return this.getMessageTemplate().getCcAddresses();
201        }
202        
203        protected Set<String> getBccAddresses() {
204                return this.getMessageTemplate().getBccAddresses();
205        }
206
207        public Mailer getMailer() {
208                return mailer;
209        }
210
211        public final void setMailer(Mailer mailer) {
212                this.mailer = mailer;
213        }
214
215        public MailMessage getMessageTemplate() {
216                return messageTemplate;
217        }
218
219        public void setMessageTemplate(MailMessage messageTemplate) {
220                this.messageTemplate = messageTemplate;
221        }
222}