/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Cyclos 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package nl.strohalm.cyclos.utils.sms;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nl.strohalm.cyclos.entities.access.Channel;
import nl.strohalm.cyclos.entities.customization.fields.MemberCustomField;
import nl.strohalm.cyclos.entities.members.Element;
import nl.strohalm.cyclos.entities.members.Member;
import nl.strohalm.cyclos.entities.settings.LocalSettings;
import nl.strohalm.cyclos.entities.settings.MessageSettings;
import nl.strohalm.cyclos.entities.settings.events.LocalSettingsChangeListener;
import nl.strohalm.cyclos.entities.settings.events.LocalSettingsEvent;
import nl.strohalm.cyclos.services.access.ChannelServiceLocal;
import nl.strohalm.cyclos.services.alerts.ErrorLogServiceLocal;
import nl.strohalm.cyclos.services.customization.MemberCustomFieldServiceLocal;
import nl.strohalm.cyclos.services.elements.ElementServiceLocal;
import nl.strohalm.cyclos.services.settings.SettingsServiceLocal;
import nl.strohalm.cyclos.services.sms.SmsMailingServiceLocal;
import nl.strohalm.cyclos.utils.CustomFieldHelper;
import nl.strohalm.cyclos.utils.MessageProcessingHelper;
import nl.strohalm.cyclos.webservices.external.ExternalWebServiceHelper;
import nl.strohalm.cyclos.webservices.external.sms.SendSmsSenderParameters;
import nl.strohalm.cyclos.webservices.external.sms.SmsSenderWebService;
import nl.strohalm.cyclos.webservices.model.MemberVO;
import nl.strohalm.cyclos.webservices.utils.MemberHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* Send SMS using a Web Service, whose URL is set in the local settings
* @author Jefferson Magno
*/
public class SmsSenderImpl implements SmsSender, LocalSettingsChangeListener, BeanFactoryAware {
private static class VoidSender implements SmsSenderWebService {
@Override
public boolean send(final String cyclosId, final SendSmsSenderParameters params) {
return false;
}
}
private boolean initialized;
private BeanFactory beanFactory;
private SmsSenderWebService smsWebService;
private ElementServiceLocal elementService;
private ErrorLogServiceLocal errorLogService;
private MemberCustomFieldServiceLocal memberCustomFieldService;
private MemberHelper memberHelper;
private SettingsServiceLocal settingsService;
private ChannelServiceLocal channelService;
private SmsMailingServiceLocal smsMailingService;
private CustomFieldHelper customFieldHelper;
@Override
public void onLocalSettingsUpdate(final LocalSettingsEvent event) {
smsWebService = null;
}
@Override
public boolean send(Member member, String text, final String traceData) {
maybeInitialize();
Channel smsChannel = channelService.getSmsChannel();
if (smsChannel == null) {
IllegalStateException e = new IllegalStateException("No channel was set on Local Settings as SMS channel");
logError(member, text, e);
return false;
}
MemberCustomField smsCustomField = settingsService.getSmsCustomField();
if (smsCustomField == null) {
IllegalStateException e = new IllegalStateException("No custom field was set on Local Settings as SMS field");
logError(member, text, e);
return false;
}
Set<MemberCustomField> requiredCustomFields = smsChannel.getPrincipalCustomFields();
requiredCustomFields.add(smsCustomField);
final LocalSettings localSettings = settingsService.getLocalSettings();
final String cyclosId = localSettings.getCyclosId();
member = elementService.load(member.getId(), Element.Relationships.GROUP);
final List<MemberCustomField> memberCustomFields = memberCustomFieldService.list();
List<MemberCustomField> customFields = customFieldHelper.onlyForGroup(memberCustomFields, member.getMemberGroup());
customFields = customFieldHelper.onlyBasic(memberCustomFields);
final MemberVO memberVO = memberHelper.toVO(member, customFields, requiredCustomFields, false);
final MessageSettings messageSettings = settingsService.getMessageSettings();
String prefix = messageSettings.getSmsMessagePrefix();
final Map<String, String> variables = smsMailingService.getSmsTextVariables(null, member, false);
prefix = StringUtils.trimToEmpty(MessageProcessingHelper.processVariables(prefix, variables));
text = StringUtils.trimToEmpty(MessageProcessingHelper.processVariables(text, variables));
text = StringUtils.trimToEmpty(prefix + " " + text);
try {
SendSmsSenderParameters params = new SendSmsSenderParameters();
params.setMember(memberVO);
params.setText(text);
params.setTraceData(traceData);
return getSmsWebService().send(cyclosId, params);
} catch (final Exception e) {
logError(member, text, e);
return false;
}
}
@Override
public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void setChannelServiceLocal(final ChannelServiceLocal channelService) {
this.channelService = channelService;
}
public void setCustomFieldHelper(final CustomFieldHelper customFieldHelper) {
this.customFieldHelper = customFieldHelper;
}
public void setSmsMailingServiceLocal(final SmsMailingServiceLocal smsMailingService) {
this.smsMailingService = smsMailingService;
}
private SmsSenderWebService getSmsWebService() throws IOException {
if (smsWebService == null) {
final String url = settingsService.getLocalSettings().getSendSmsWebServiceUrl();
if (StringUtils.isEmpty(url)) {
smsWebService = new VoidSender();
} else {
// Create the proxy
smsWebService = ExternalWebServiceHelper.proxyFor(SmsSenderWebService.class, url);
}
}
return smsWebService;
}
private void logError(final Member member, final String sms, final Exception e) {
final Map<String, String> params = new HashMap<String, String>();
params.put("username", member.getUsername());
params.put("name", member.getName());
params.put("sms", sms);
errorLogService.insert(e, settingsService.getLocalSettings().getSendSmsWebServiceUrl(), params);
}
private synchronized void maybeInitialize() {
// As the standard setter injection was causing problems with other beans, for recursive injection,
// which caused unproxied instances to be injected, the setter injection is no longer used here
if (!initialized) {
settingsService = beanFactory.getBean(SettingsServiceLocal.class);
settingsService.addListener(this);
memberCustomFieldService = beanFactory.getBean(MemberCustomFieldServiceLocal.class);
elementService = beanFactory.getBean(ElementServiceLocal.class);
memberHelper = beanFactory.getBean(MemberHelper.class);
errorLogService = beanFactory.getBean(ErrorLogServiceLocal.class);
initialized = true;
}
}
}