Author: tchemit Date: 2012-03-07 17:44:51 +0100 (Wed, 07 Mar 2012) New Revision: 3166 Url: http://chorem.org/repositories/revision/pollen/3166 Log: reuse the siteUrl applicationUrl, safer than using url from request... add prevent rule notifier clean PollFeedService and EmailService and more... Added: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/SendMail.java Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/UserService.java branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties branches/pollen-1.2.6-struts2/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/log4j.properties branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/pollen-fake.properties Added: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -0,0 +1,66 @@ +/* + * #%L + * Pollen :: Services + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.bean; + +import org.chorem.pollen.business.persistence.Choice; +import org.chorem.pollen.business.persistence.ChoiceImpl; + +import java.util.Date; + +/** + * Extends the basic choice to keep the date (will be transformed to name) + * (during poll creation). + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class PollDateChoice extends ChoiceImpl { + + private static final long serialVersionUID = 1L; + + protected Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public void fromChoice(Choice choice) { + setName(choice.getName()); + setDescription(choice.getDescription()); + setTopiaId(choice.getTopiaId()); + setValidate(choice.isValidate()); + setPoll(choice.getPoll()); + setDate(new Date(Long.valueOf(choice.getName()))); + } + + public void toChoice(Choice choice) { + choice.setName(String.valueOf(getDate().getTime())); + choice.setDescription(getDescription()); + choice.setValidate(isValidate()); + } +} Property changes on: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -23,6 +23,7 @@ */ package org.chorem.pollen.bean; +import org.chorem.pollen.business.persistence.Choice; import org.chorem.pollen.business.persistence.ChoiceImpl; /** @@ -33,6 +34,7 @@ * @since 1.2.6 */ public class PollImageChoice extends ChoiceImpl { + private static final long serialVersionUID = 1L; protected String location; @@ -44,4 +46,18 @@ public void setLocation(String location) { this.location = location; } + + public void fromChoice(Choice choice) { + setName(choice.getName()); + setDescription(choice.getDescription()); + setTopiaId(choice.getTopiaId()); + setValidate(choice.isValidate()); + setPoll(choice.getPoll()); + } + + public void toChoice(Choice choice) { + choice.setName(getName()); + choice.setDescription(getDescription()); + choice.setValidate(isValidate()); + } } Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -48,16 +48,13 @@ protected Locale locale; - private final URL applicationURL; - public static PollenServiceContext newContext( PollenServiceContext serviceContext, TopiaContext transaction) { return newContext(serviceContext.getLocale(), transaction, serviceContext.getConfiguration(), - serviceContext.getServiceFactory(), - serviceContext.getApplicationURL() + serviceContext.getServiceFactory() ); } @@ -66,25 +63,21 @@ Locale locale, TopiaContext transaction, PollenConfiguration configuration, - PollenServiceFactory serviceFactory, - URL applicationURL) { + PollenServiceFactory serviceFactory) { return new DefaultPollenServiceContext(locale, transaction, configuration, - serviceFactory, - applicationURL); + serviceFactory); } protected DefaultPollenServiceContext(Locale locale, TopiaContext transaction, PollenConfiguration configuration, - PollenServiceFactory serviceFactory, - URL applicationURL) { + PollenServiceFactory serviceFactory) { this.locale = locale; this.transaction = transaction; this.configuration = configuration; this.serviceFactory = serviceFactory; - this.applicationURL = applicationURL; } @Override @@ -105,7 +98,7 @@ @Override public URL getApplicationURL() { - return applicationURL; + return getConfiguration().getApplicationUrl(); } @Override Added: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -0,0 +1,116 @@ +/* + * #%L + * Pollen :: Services + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.services; + +import com.google.common.base.Preconditions; +import org.chorem.pollen.PollenTechnicalException; +import org.chorem.pollen.business.persistence.Poll; +import org.chorem.pollen.business.persistence.PreventRule; +import org.chorem.pollen.services.impl.PollService; +import org.chorem.pollen.services.impl.PreventRuleService; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; + +import java.io.Closeable; +import java.io.IOException; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +/** + * This service run as a daemon seek to send some notification from running poll + * store in {@link PreventRule}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class PollenNotifierWorker implements Runnable, Closeable { + + /** Service context used to create other services. */ + protected final PollenServiceContext serviceContext; + + /** Timer gérant les threads. */ + private final Timer timer; + + /** Topia root context to pollen db. */ + private final TopiaContext rootContext; + + public PollenNotifierWorker(PollenServiceContext serviceContext, + TopiaContext rootContext) { + Preconditions.checkNotNull(serviceContext); + Preconditions.checkNotNull(rootContext); + Preconditions.checkState(!rootContext.isClosed()); + this.rootContext = rootContext; + this.serviceContext = serviceContext; + timer = new Timer(); + } + + @Override + public void run() { + + // starts it + timer.schedule(new TimerTask() { + + @Override + public void run() { + try { + TopiaContext transaction = rootContext.beginTransaction(); + try { + serviceContext.setTransaction(transaction); + + PollService pollService = + serviceContext.newService(PollService.class); + PreventRuleService preventRuleService = + serviceContext.newService(PreventRuleService.class); + + // Récupération des sondages en cours + List<Poll> polls = pollService.getRunningPolls(true); + + for (Poll poll : polls) { + + String pollVoteUrl = pollService.getPollVoteUrl(poll); + + preventRuleService.onPollToRemind(poll, pollVoteUrl); + + } + + } finally { + + serviceContext.setTransaction(null); + + transaction.closeContext(); + } + } catch (TopiaException e) { + throw new PollenTechnicalException("Topia problem", e); + } + } + }, 600000, 600000); + } + + @Override + public void close() throws IOException { + timer.cancel(); + } + +} Property changes on: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -24,70 +24,295 @@ package org.chorem.pollen.services.impl; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail; import org.chorem.pollen.PollenConfiguration; import org.chorem.pollen.PollenTechnicalException; +import org.chorem.pollen.business.persistence.PersonToList; +import org.chorem.pollen.business.persistence.Poll; +import org.chorem.pollen.business.persistence.PollAccount; +import org.chorem.pollen.business.persistence.UserAccount; +import org.chorem.pollen.business.persistence.VotingList; import org.chorem.pollen.services.PollenServiceSupport; +import org.nuiton.util.StringUtil; +import java.net.URL; +import java.util.List; +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; + public class EmailService extends PollenServiceSupport { /** Logger. */ private static final Log log = LogFactory.getLog(EmailService.class); - public void sendEmail(String to, - String subject, - String content) { + public void onUserCreated(UserAccount user) { + URL url = serviceContext.getApplicationURL(); + + if (url != null && StringUtil.isEmail(user.getEmail())) { + + Locale locale = getLocale(); + String subject = l_(locale, "pollen.email.userRegister.subject", + user.getLogin()); + String content = l_(locale, "pollen.email.userRegister.content", + user.getDisplayName(), + user.getLogin(), user.getPassword(), url); + + PollEmail pollEmail = createPollEmail(user.getEmail(), + subject, + content); + + sendEmail(pollEmail); + } + } + + public void onVoteAdded(Poll poll, String voteURL, String modifURL) { + + URL url = serviceContext.getApplicationURL(); + + if (url != null) { + + Locale locale = getLocale(); + + String pollTitle = poll.getTitle(); + + // Mail au créateur + + if (StringUtils.isNotEmpty(poll.getCreator().getEmail())) { + + String subject = l_(locale, "pollen.email.creatorEmail.subject", + pollTitle); + String content = l_(locale, "pollen.email.creatorEmail.content", + pollTitle, voteURL, modifURL); + + PollEmail pollEmail = createPollEmail( + poll.getCreator().getEmail(), subject, content); + + sendEmail(pollEmail); + } + + } + } + + public void onPollCreated(Poll poll, String voteURL, String modifURL) { + + URL url = serviceContext.getApplicationURL(); + + if (url != null) { + + Locale locale = getLocale(); + + String pollTitle = poll.getTitle(); + + // Mail au créateur + + if (StringUtils.isNotEmpty(poll.getCreator().getEmail())) { + + String subject = l_(locale, "pollen.email.creatorEmail.subject", + pollTitle); + String content = l_(locale, "pollen.email.creatorEmail.content", + pollTitle, voteURL, modifURL); + + PollEmail pollEmail = createPollEmail( + poll.getCreator().getEmail(), subject, content); + + sendEmail(pollEmail); + } + + // Mails à tous les votants + List<PollAccount> votingPollAccounts = + getVotingPollAccounts(poll, false); + + if (CollectionUtils.isNotEmpty(votingPollAccounts)) { + String subject = l_(locale, "pollen.email.votingEmail.subject", + pollTitle); + + List<PollEmail> emails = Lists.newArrayList(); + for (PollAccount account : votingPollAccounts) { + String accountVoteURL = + voteURL + ":" + account.getAccountId(); + + String content = + l_(locale, "pollen.email.votingEmail.content", + pollTitle, voteURL, accountVoteURL); + + PollEmail pollEmail = createPollEmail( + account.getEmail(), subject, content); + + emails.add(pollEmail); + } + + sendEmail(emails); + } + } + } + + public void onPollReminder(Poll poll, String voteURL) { + + URL url = serviceContext.getApplicationURL(); + + if (url != null) { + + Locale locale = getLocale(); + + String pollTitle = poll.getTitle(); + + // Mails aux votants qui n'ont toujours pas voté + List<PollAccount> votingPollAccounts = getVotingPollAccounts(poll, true); + + if (CollectionUtils.isNotEmpty(votingPollAccounts)) { + String subject = l_(locale, "pollen.email.reminderEmail.subject", + pollTitle); + + List<PollEmail> emails = Lists.newArrayList(); + for (PollAccount account : votingPollAccounts) { + String accountVoteURL = + voteURL + ":" + account.getAccountId(); + + String content = + l_(locale, "pollen.email.reminderEmail.content", + pollTitle, account.getVotingId(), accountVoteURL); + + PollEmail pollEmail = createPollEmail( + account.getEmail(), subject, content); + + emails.add(pollEmail); + } + sendEmail(emails); + } + } + } + + //TODO Move this to Poll + protected List<PollAccount> getVotingPollAccounts(Poll poll, + boolean keepOnlyIfNotHasVoted) { + List<PollAccount> result = Lists.newLinkedList(); + + if (!poll.isVotingListEmpty()) { + + for (VotingList votingList : poll.getVotingList()) { + + if (!votingList.isPollAccountPersonToListEmpty()) { + + for (PersonToList personToList : + votingList.getPollAccountPersonToList()) { + + if (!keepOnlyIfNotHasVoted || !personToList.isHasVoted()) { + + PollAccount account = personToList.getPollAccount(); + result.add(account); + } + + + } + } + } + } + return result; + } + + protected void sendEmail(Iterable<PollEmail> pollEmails) { + + //TODO tchemit If two much mails then use SendEmail thread... + for (PollEmail pollEmail : pollEmails) { + sendEmail(pollEmail); + } + +// // send mail preparation +// try { +// sendMailService.prepareMails(poll.getId(), mailList); +// sendMailService.wakeUp(); +// } catch (IOException ex) { +// if (log.isErrorEnabled()) { +// log.error("Can't prepare send mail on disk, mail won't be send !!!", ex); +// } +// } + + } + + protected void sendEmail(PollEmail pollEmail) { + + Preconditions.checkNotNull(pollEmail); + + String to = pollEmail.getTo(); Preconditions.checkNotNull(to); + + String subject = pollEmail.getSubject(); Preconditions.checkNotNull(subject); + + String content = pollEmail.getContent(); Preconditions.checkNotNull(content); try { // Create the SimpleEmail to send - SimpleEmail email = createSimpleEmail(to, subject, content); + SimpleEmail email = new SimpleEmail(); + + PollenConfiguration configuration = getConfiguration(); + + email.setHostName(configuration.getEmailHost()); + email.setSmtpPort(configuration.getEmailPort()); + email.setFrom(configuration.getEmailFrom()); + email.setCharset(configuration.getCharset()); + + email.addTo(to); + email.setSubject(subject); + email.setMsg(content); email.send(); if (log.isInfoEnabled()) { log.info("Mail sent to : " + to); - - if (log.isDebugEnabled()) { - log.debug("Email infos : " + - "\ndate: " + email.getSentDate() + - "\nhostname: " + email.getHostName() + - "\nport: " + email.getSmtpPort() + - "\nfrom: " + email.getFromAddress().toString()); - } } + if (log.isDebugEnabled()) { + log.debug("Email infos : " + + "\ndate: " + email.getSentDate() + + "\nhostname: " + email.getHostName() + + "\nport: " + email.getSmtpPort() + + "\nfrom: " + email.getFromAddress().toString()); + } } catch (EmailException eee) { throw new PollenTechnicalException( "could not send email to " + to, eee); } } - protected SimpleEmail createSimpleEmail( - String to, - String subject, - String content) throws EmailException { + public static PollEmail createPollEmail(String to, + String subject, + String content) { + return new PollEmail(to, subject, content); + } - Preconditions.checkNotNull(to); - Preconditions.checkNotNull(subject); - Preconditions.checkNotNull(content); + public static class PollEmail { - PollenConfiguration configuration = getConfiguration(); + protected String subject; - SimpleEmail result = new SimpleEmail(); - result.setHostName(configuration.getEmailHost()); - result.setSmtpPort(configuration.getEmailPort()); - result.setFrom(configuration.getEmailFrom()); - result.setCharset(configuration.getCharset()); + protected String content; - result.addTo(to); - result.setSubject(subject); - result.setMsg(content); - return result; + protected String to; + + + private PollEmail(String to, String subject, String content) { + this.subject = subject; + this.content = content; + this.to = to; + } + + public String getSubject() { + return subject; + } + + public String getContent() { + return content; + } + + public String getTo() { + return to; + } } - } Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -76,9 +76,15 @@ // add it to poll pollToUpdate.addComment(commentCreated); - // add a feed entry + commitTransaction("Could not create comment"); + + // feed notification + + PollService pollService = newService(PollService.class); + + String pollVoteUrl = pollService.getPollVoteUrl(poll); PollFeedService pollFeedService = newService(PollFeedService.class); - pollFeedService.addFeedEntryWhenCreateComment(commentCreated); + pollFeedService.onAddComment(commentCreated, pollVoteUrl); return commentCreated; } catch (TopiaException e) { Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -23,6 +23,7 @@ */ package org.chorem.pollen.services.impl; +import com.google.common.collect.Lists; import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndEntry; @@ -44,7 +45,6 @@ import java.io.File; import java.io.FileWriter; import java.io.Writer; -import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -81,25 +81,17 @@ return result; } - /** - * Création d'un flux. - * - * @param poll poll - * @param type type de flux (rss_2.0, atom_1.0) - */ - public void createFeed(Poll poll, String type) { - + public void onPollCreated(Poll poll, String pollVoteUrl) { File file = getFeedLocation(poll); String title = l_(getLocale(), "pollen.feed.pollTitle", poll.getTitle()); String description = l_(getLocale(), "pollen.feed.pollDescription", poll.getDescription()); - String link = getPollFeedLink(poll); try { SyndFeed feed = new SyndFeedImpl(); - feed.setFeedType(type); + feed.setFeedType("atom_1.0"); feed.setTitle(title); - feed.setLink(link); + feed.setLink(pollVoteUrl); feed.setDescription(description); Writer writer = new FileWriter(file); @@ -110,30 +102,102 @@ if (log.isDebugEnabled()) { log.debug("Feed created: " + file.getAbsolutePath()); } + + title = _("pollen.feed.createPollContent", + poll.getCreator().getVotingId()); + + String content = _("pollen.feed.createPollContent", + poll.getDescription()); + + addFeedEntry(poll, title, content, pollVoteUrl); } catch (Exception e) { throw new PollenTechnicalException("Could not create feed", e); } } + public void onAddComment(Comment comment, String pollVoteUrl) { + + //TODO Validate this is ok + String title = _("pollen.feed.addCommentTitle", + comment.getPollAccount().getVotingId()); + + String content = _("pollen.feed.addCommentContent", + comment.getText()); + + addFeedEntry(comment.getPoll(), title, content, pollVoteUrl); + } + + public void onAddVote(Vote vote, + boolean anonymousVote, + String pollResult + , String pollVoteUrl) { + + String userId; + if (anonymousVote) { + userId = _("pollen.common.anonymous"); + } else { + userId = vote.getPollAccount().getVotingId(); + + } + String title = _("pollen.feed.addVoteTitle", userId); + + String content = _("pollen.feed.addVoteContent", pollResult); + + addFeedEntry(vote.getPoll(), title, content, pollVoteUrl); + } + + public void onAddChoice(Choice choice, String pollVoteUrl) { + + String title = _("pollen.feed.addChoiceTitle", choice.getName()); + + String content = _("pollen.feed.addChoiceContent", + choice.getDescription()); + + addFeedEntry(choice.getPoll(), title, content, pollVoteUrl); + } + /** + * Delete the poll feed file. + * + * @param poll poll + */ + public void deleteFeed(Poll poll) { + + File feedLocation = getFeedLocation(poll); + if (feedLocation.exists()) { + boolean wasDeleted = feedLocation.delete(); + if (!wasDeleted) { + throw new PollenTechnicalException("Could not delete feed"); + } + if (log.isDebugEnabled()) { + log.debug("Feed deleted: " + feedLocation.getAbsolutePath()); + } + } + } + + /** * Ajout d'une entrée dans un flux. * - * @param poll poll - * @param title titre de l'entrée - * @param content contenu de l'entrée + * @param poll poll + * @param title titre de l'entrée + * @param content contenu de l'entrée + * @param pollVoteUrl poll vote url */ - public void feedFeed(Poll poll, String title, - String content) { + protected void addFeedEntry(Poll poll, + String title, + String content, + String pollVoteUrl) { + //TODO tchemitshould remove this, may migrates when going to version 2.0 + //TODO pass on all polls from database and creates the feed if not found. if (!isFeedExists(poll)) { - createFeed(poll, "atom_1.0"); + onPollCreated(poll, pollVoteUrl); } File file = getFeedLocation(poll); - String link = getPollFeedLink(poll); try { - List entries = new ArrayList(); + List entries = Lists.newArrayList(); SyndFeedInput input = new SyndFeedInput(); SyndFeed feed = input.build(new XmlReader(file)); entries.addAll(feed.getEntries()); @@ -142,7 +206,7 @@ SyndContent description; entry = new SyndEntryImpl(); entry.setTitle(title); - entry.setLink(link); + entry.setLink(pollVoteUrl); entry.setPublishedDate(new Date()); description = new SyndContentImpl(); description.setType("text/plain"); @@ -167,83 +231,4 @@ throw new PollenTechnicalException("Could not feed feed", e); } } - - /** - * Delete the poll feed file. - * - * @param poll poll - */ - public void deleteFeed(Poll poll) { - - File feedLocation = getFeedLocation(poll); - if (feedLocation.exists()) { - boolean wasDeleted = feedLocation.delete(); - if (!wasDeleted) { - throw new PollenTechnicalException("Could not delete feed"); - } - if (log.isDebugEnabled()) { - log.debug("Feed deleted: " + feedLocation.getAbsolutePath()); - } - } - } - - public void addFeedEntryWhenCreatePoll(Poll poll) { - - - String title = _("pollen.feed.createPollContent", - poll.getCreator().getVotingId()); - - String content = _("pollen.feed.createPollContent", - poll.getDescription()); - - feedFeed(poll, title, content); - } - - - public void addFeedEntryWhenCreateComment(Comment comment) { - - //TODO Validate this is ok - String title = _("pollen.feed.addCommentTitle", - comment.getPollAccount().getVotingId()); - - String content = _("pollen.feed.addCommentContent", - comment.getText()); - - feedFeed(comment.getPoll(), title, content); - } - - public void addFeedEntryWhenAddVote(Vote vote, - boolean anonymousVote, - String pollResult) { - - String userId; - if (anonymousVote) { - userId = _("pollen.common.anonymous"); - } else { - userId = vote.getPollAccount().getVotingId(); - - } - String title = _("pollen.feed.addVoteTitle", userId); - - String content = _("pollen.feed.addVoteContent", pollResult); - - feedFeed(vote.getPoll(), title, content); - } - - public void addFeedEntryWhenAddChoice(Choice choice) { - - String title = _("pollen.feed.addChoiceTitle", choice.getName()); - - String content = _("pollen.feed.addChoiceContent", - choice.getDescription()); - - feedFeed(choice.getPoll(), title, content); - } - - protected String getPollFeedLink(Poll poll) { - String link = - serviceContext.getApplicationURL() + - "/poll/vote?pollId=" + poll.getPollId(); - return link; - } } Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.chorem.pollen.PollenConfiguration; import org.chorem.pollen.PollenTechnicalException; +import org.chorem.pollen.bean.PollDateChoice; import org.chorem.pollen.bean.PollImageChoice; import org.chorem.pollen.business.persistence.Choice; import org.chorem.pollen.business.persistence.ChoiceDAO; @@ -49,6 +50,7 @@ import org.chorem.pollen.business.persistence.VotingList; import org.chorem.pollen.business.persistence.VotingListDAO; import org.chorem.pollen.common.ChoiceType; +import org.chorem.pollen.common.PollType; import org.chorem.pollen.services.PollenServiceSupport; import org.chorem.pollen.services.exceptions.PollChoiceNotFoundException; import org.chorem.pollen.services.exceptions.PollNotFoundException; @@ -72,6 +74,7 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.net.URL; import java.util.List; public class PollService extends PollenServiceSupport { @@ -79,6 +82,11 @@ /** Logger. */ private static final Log log = LogFactory.getLog(PollService.class); + + /** Représente l'action qui envoi un email de notification. */ + public static final String RULE_EMAIL_ACTION = "emailAction"; + + /** * Build a new Poll instance with given {@code user} as administrator * @@ -120,6 +128,12 @@ PollDAO pollDAO = getDAO(Poll.class); Poll result = create(pollDAO); + // check max number choice authorized (can not be more than + if (poll.getMaxChoiceNb() < 1 + || poll.getMaxChoiceNb() > poll.sizeChoice()) { + poll.setMaxChoiceNb(poll.sizeChoice()); + } + result.setAnonymous(poll.isAnonymous()); result.setAnonymousVoteAllowed(poll.isAnonymousVoteAllowed()); result.setBeginChoiceDate(poll.getBeginChoiceDate()); @@ -212,10 +226,8 @@ ChoiceDAO choiceDAO = getDAO(Choice.class); for (Choice choice : poll.getChoice()) { + Choice choiceCreated = create(choiceDAO); - choiceCreated.setDescription(choice.getDescription()); - choiceCreated.setName(choice.getName()); - choiceCreated.setValidate(choice.isValidate()); result.addChoice(choiceCreated); if (choiceType == ChoiceType.IMAGE) { @@ -223,21 +235,66 @@ // copy image where it belong and generate the thumb PollImageChoice imageChoice = (PollImageChoice) choice; - + imageChoice.toChoice(choiceCreated); try { saveImages(result, imageChoice); } catch (IOException e) { throw new PollenTechnicalException( "Could not create image choice", e); } + } else if (choiceType == ChoiceType.DATE) { + // date choice + PollDateChoice dateChoice = (PollDateChoice) choice; + dateChoice.toChoice(choiceCreated); + } else { + + // text choice + choiceCreated.setDescription(choice.getDescription()); + choiceCreated.setValidate(choice.isValidate()); + choiceCreated.setName(choice.getName()); } } } + commitTransaction("Could not create poll " + poll.getTitle()); + + String pollVoteUrl = getPollVoteUrl(poll); + + // email notification + EmailService emailService = newService(EmailService.class); + emailService.onPollCreated(poll, + pollVoteUrl, + getPollEditUrl(poll)); + + // feed notification + PollFeedService pollFeedService = newService(PollFeedService.class); + pollFeedService.onPollCreated(poll, pollVoteUrl); + return result; } + + public String getPollVoteUrl(Poll poll) { + URL applicationUrl = serviceContext.getApplicationURL(); + StringBuilder url = new StringBuilder(applicationUrl.toString()); + + url.append("/poll/votefor/").append(poll.getPollId()); + + if (poll.getPollType() != PollType.FREE) { + url.append(':').append(poll.getCreator().getAccountId()); + } + return url.toString(); + } + + public String getPollEditUrl(Poll poll) { + URL applicationUrl = serviceContext.getApplicationURL(); + StringBuilder url = new StringBuilder(applicationUrl.toString()); + + url.append("/poll/modification/").append(poll.getPollId()); + url.append(':').append(poll.getCreator().getAccountId()); + return url.toString(); + } /* private void addFeedEntry() { PollAccountDTO creator = servicePollAccount.findPollAccountById(poll.getCreatorId()); @@ -406,7 +463,50 @@ } catch (TopiaException e) { throw new PollenTechnicalException(e); } + } + public List<Poll> getRunningPolls(boolean withEndDate) { + + List<Poll> results; + try { + + PollDAO dao = getDAO(Poll.class); + + TopiaQuery query; + + if (withEndDate) { + + query = dao.createQuery("poll"). + addWhere("poll.endDate is not null and poll.endDate > current_timestamp()"). + addWhere("poll.beginDate is null or poll.beginDate < current_timestamp()"); + +// results = transaction +// .find("from " +// + Poll.class.getName() +// + " as poll where (poll.endDate is not null and poll.endDate > current_timestamp())" +// + " and (poll.beginDate is null or poll.beginDate < current_timestamp())"); + } else { + query = dao.createQuery("poll"). + addWhere("poll.endDate is null or poll.endDate > current_timestamp()"). + addWhere("poll.beginDate is null or poll.beginDate < current_timestamp()"); + +// results = transaction +// .find("from " +// + Poll.class.getName() +// + " as poll where (poll.endDate is null or poll.endDate > current_timestamp())" +// + " and (poll.beginDate is null or poll.beginDate < current_timestamp())"); + } + + results = dao.findAllByQuery(query); + + if (log.isDebugEnabled()) { + log.debug("Entities found: " + + ((results == null) ? "null" : results.size())); + } + return results; + } catch (TopiaException e) { + throw new PollenTechnicalException("Culd not obtain polls", e); + } } public Poll getPollByPollId(String pollId) { Added: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -0,0 +1,192 @@ +/* + * #%L + * Pollen :: Services + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.services.impl; + +import com.google.common.base.Preconditions; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.business.persistence.Poll; +import org.chorem.pollen.business.persistence.PreventRule; +import org.chorem.pollen.business.persistence.PreventRuleDAO; +import org.chorem.pollen.services.PollenServiceSupport; + +import java.util.Date; + +/** + * Manage prevent rules of a poll. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class PreventRuleService extends PollenServiceSupport { + + /** Logger. */ + private static final Log log = LogFactory.getLog(PreventRuleService.class); + + public PreventRule createAddVotePreventRule() { + PreventRuleDAO dao = getDAO(PreventRule.class); + PreventRule rule = newInstance(dao); + rule.setScope("vote"); + rule.setSensibility(1); + rule.setRepeated(true); + return rule; + } + + public PreventRule createRemindPreventRule(int sensibility) { + PreventRuleDAO dao = getDAO(PreventRule.class); + PreventRule rule = newInstance(dao); + rule.setScope("rappel"); + rule.setSensibility(sensibility); + rule.setRepeated(false); + return rule; + } + + public void onVoteAdded(Poll poll, String pollVoteUrl, String modifURL) { + + if (poll.getEndDate() != null) { + + for (PreventRule rule : poll.getPreventRule()) { + onVoteAdded(poll, + rule, + pollVoteUrl, + modifURL + ); + } + } + } + + public void onPollToRemind(Poll poll, String pollVoteUrl) { + + // Parcours des preventRules de chaque sondage + // envoi d'un email si endDate-nowDate <= preventRuleSensibility + if (poll.getEndDate() != null) { + + Date now = new Date(); + + // timeValue = endDate-nowDate + long timeValue = poll.getEndDate().getTime() - now.getTime(); + + if (log.isDebugEnabled()) { + log.debug("Now: " + now.getTime() + " End: " + + poll.getEndDate().getTime() + " timeValue: " + + timeValue + "(" + timeValue / 3600000 + "h)"); + } + + int hourBeforeEnd = (int) (timeValue / 3600000); + + for (PreventRule rule : poll.getPreventRule()) { + + onPollToRemind(poll, + rule, + pollVoteUrl, + hourBeforeEnd + ); + } + } + } + + protected void onVoteAdded(Poll poll, + PreventRule preventRule, + String pollVoteUrl, + String modifURL) { + + // send to creator a email to say hey a new vote was added! + + if (execute("vote", preventRule, 1)) { + + // ok can execute this task + + EmailService emailService = newService(EmailService.class); + + // let's send an email + emailService.onVoteAdded(poll, pollVoteUrl, modifURL); + + // and update prevent rule + commitTransaction("Could not update prevent rule"); + } + } + + protected void onPollToRemind(Poll poll, + PreventRule preventRule, + String pollVoteUrl, + int timeValue) { + + // send to all voting a email to say hey we need to vote + + if (execute("rappel", preventRule, timeValue)) { + + // ok can execute this task + + EmailService emailService = newService(EmailService.class); + + // let's send an email + emailService.onPollReminder(poll, pollVoteUrl); + + // and update prevent rule + commitTransaction("Could not update prevent rule"); + } + } + + protected boolean execute(String scope, + PreventRule preventRule, + Integer value) { + + Preconditions.checkNotNull(scope); + Preconditions.checkNotNull(value); + + // Si la règle n'est pas active, on ne fait rien + if (!preventRule.isActive()) { + log.debug("Règle non active"); + return false; + } + + // Si la règle est à exécution unique, on la désactive + if (preventRule.isOneTime()) { + log.debug("Règle à exécution unique : désactivation"); + preventRule.setActive(false); + } + + if (!scope.equals(preventRule.getScope())) { + + // pas bon scope + return false; + } + + // Si la règle est répétitive (exécution tous les n), on met à jour la valeur + if (preventRule.isRepeated() && preventRule.getSensibility() != 0) { + value = value % preventRule.getSensibility() + + preventRule.getSensibility(); + } + + if (value != preventRule.getSensibility()) { + + // pas la bonne valeur + return false; + } + + // ok on peut lancer la tâche + return true; + } + +} Property changes on: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/SendMail.java (from rev 3162, branches/pollen-1.2.6-struts2/pollen-ui/src/main/java/org/chorem/pollen/ui/utils/SendMail.java) =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/SendMail.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/SendMail.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -0,0 +1,316 @@ +/* + * #%L + * Pollen :: Services + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +/* *##% Pollen + * Copyright (C) 2009 CodeLutin + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. ##%*/ + +package org.chorem.pollen.services.impl; + +import au.com.bytecode.opencsv.CSVReader; +import au.com.bytecode.opencsv.CSVWriter; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.chorem.pollen.PollenConfiguration; +import org.nuiton.util.FileUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.List; + +/** + * Note tchemit : Not used at the moment, perharps later if needed. + * <p/> + * Mass mail management class. + * <p/> + * This class store email to send in a csv file, and send it (one per second) in + * a second time. + * This class can restart to send mail at application restart. + * <p/> + * For a mass mail sending to start, following files must be present: + * <ul> + * <li>xxx.emails : CSV file ("email", "subject", "body")</li> + * <li>xxx.index : next index to manage ( inited at 0)</li> + * </ul> + * + * @author chatellier + * @version $Revision$ + * <p/> + * Last update : $Date$ + * By : $Author$ + */ +public class SendMail extends Thread { + + /** logger. */ + private static final Logger log = LoggerFactory.getLogger(SendMail.class); + + public static final String EXTENSION_MAIL = ".mail"; + + public static final String EXTENSION_INDEX = ".index"; + + protected EmailService emailService; + + /** Pollen configuration. */ + protected PollenConfiguration configuration; + + /** Mail storage directory. */ + protected File mailStorageDirectory; + + public SendMail(EmailService emailService, + PollenConfiguration configuration) { + this.emailService = emailService; + this.configuration = configuration; + + // get email directory in configuration + // create it if not exists +// File filename = configuration.getEmailDirectory(); + mailStorageDirectory = configuration.getEmailDirectory(); +// +// if (!mailStorageDirectory.exists()) { +// if (mailStorageDirectory.mkdirs()) { +// if (log.isDebugEnabled()) { +// log.debug("Email storage directory created in : " + mailStorageDirectory.getAbsolutePath()); +// } +// } +// } + } + + /* + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + + // try to find existing files + while (true) { + try { + sendAllMails(); + + // bloque thread until next notify + sleep(); + } catch (Exception ex) { + if (log.isErrorEnabled()) { + log.error("Error during SendMail main loop", ex); + } + } + } + } + + protected synchronized void sleep() throws InterruptedException { + wait(); + } + + public synchronized void wakeUp() { + notifyAll(); + } + + /** + * Look for all xx.index file, and restart mail sending on + * non ending mass mail sending. + * <p/> + * After execution, delete mail and index file. + * + * @throws IOException if could not send emails + */ + protected void sendAllMails() throws IOException { + + // don't do for, allways take the first found + // a new one can be created when managing one other + List<File> indexFiles = null; + do { + + // filter is java valid : .*\\.index + indexFiles = FileUtil.find(mailStorageDirectory, ".*\\" + EXTENSION_INDEX, false); + + if (!indexFiles.isEmpty()) { + File indexFile = indexFiles.get(0); + // convert index content to int + String indexContent = FileUtils.readFileToString(indexFile, "UTF-8"); + int index = Integer.parseInt(indexContent); + + // get mail content file + File mailFile = new File(indexFile.getAbsolutePath().replaceAll(EXTENSION_INDEX + "$", EXTENSION_MAIL)); + + if (log.isDebugEnabled()) { + log.debug("Managing mail file : " + mailFile + " (from index " + indexContent + ")"); + } + + Reader indexFileReader = new BufferedReader(new FileReader(mailFile)); + CSVReader cvsReader = new CSVReader(indexFileReader); + + int currentIndex = 0; + String[] currentLine = cvsReader.readNext(); + while (currentLine != null) { + String receiver = currentLine[0]; + String subject = currentLine[1]; + String body = currentLine[2]; + + log.debug("Props = " + configuration.getProperties()); + + // index contains next index to treat so == is ok + if (currentIndex >= index) { + + EmailService.PollEmail pollEmail = + EmailService.createPollEmail( + receiver, + subject, + body + ); + emailService.sendEmail(pollEmail); + +// MailUtil.sendMail(configuration.getProperty("email_host"), +// Integer.parseInt(configuration.getProperty("email_port")), +// configuration.getProperty("email_from"), +// receiver, subject, body); + + // index contains next index to treat + FileUtils.writeStringToFile( + indexFile, + String.valueOf(currentIndex + 1)); + + // wait 2 secondes between each mail to not + // load smtp server + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + if (log.isErrorEnabled()) { + log.error("Can't wait between mail", ex); + } + } + } else { + if (log.isDebugEnabled()) { + log.debug("Mail to " + receiver + " already sent in a previous execution, skip."); + } + } + + currentIndex++; + currentLine = cvsReader.readNext(); + } + + // delete both index and mail file + mailFile.delete(); + indexFile.delete(); + } else { + if (log.isInfoEnabled()) { + log.info("No more index mail index file found, go to sleep a while :)"); + } + } + } while (!indexFiles.isEmpty()); + } + + /** + * Prepare mail list. + * <p/> + * TODO : improve configuration reading + * + * @param id + * @param mailData + * @throws IOException + */ + public void prepareMails(String id, + List<EmailService.PollEmail> mailData) throws IOException { + + Writer fileWriter = null; + CSVWriter cvsWriter = null; + try { + + // write CSV datas + File emailFile = new File(mailStorageDirectory, id + EXTENSION_MAIL); + fileWriter = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(emailFile))); + cvsWriter = new CSVWriter(fileWriter); + + for (EmailService.PollEmail singleMailData : mailData) { + String[] nextLine = new String[]{ + singleMailData.getTo(), + singleMailData.getSubject(), + singleMailData.getTo() + }; + cvsWriter.writeNext(nextLine); + } + + // write index (default to 0) + File indexFile = new File(mailStorageDirectory, id + EXTENSION_INDEX); + FileUtil.writeString(indexFile, "0"); + } finally { + if (cvsWriter != null) { + cvsWriter.close(); + } + IOUtils.closeQuietly(fileWriter); + } + + } + +// public void prepareMails(String id, List<Map<String, String>> mailData) throws IOException { +// +// Writer fileWriter = null; +// CSVWriter cvsWriter = null; +// try { +// +// // write CSV datas +// File emailFile = new File(mailStorageDirectory, id + EXTENSION_MAIL); +// fileWriter = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(emailFile))); +// cvsWriter = new CSVWriter(fileWriter); +// +// for (Map<String, String> singleMailData : mailData) { +// String[] nextLine = new String[] { +// singleMailData.get("receiver"), +// singleMailData.get("subject"), +// singleMailData.get("body") +// }; +// cvsWriter.writeNext(nextLine); +// } +// +// // write index (default to 0) +// File indexFile = new File(mailStorageDirectory, id + EXTENSION_INDEX); +// FileUtil.writeString(indexFile, "0"); +// } +// finally { +// if (cvsWriter != null) { +// cvsWriter.close(); +// } +// IOUtils.closeSilently(fileWriter); +// } +// +// } +} Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/UserService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/UserService.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/UserService.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -106,6 +106,7 @@ // let's generate the new password password = RandomStringUtils.randomAlphanumeric(8); + user.setPassword(password); } String encodedPassword = encodePassword(password); @@ -116,29 +117,35 @@ user.setTopiaId(userAccount.getTopiaId()); copyUserAccount(user, userAccount); + commitTransaction("Could not create user"); + } catch (TopiaException e) { throw new PollenTechnicalException(e); } - URL url = serviceContext.getApplicationURL(); + // send a email to user + EmailService emailService = newService(EmailService.class); + emailService.onUserCreated(user); - if (url != null && StringUtil.isEmail(user.getEmail())) { +// URL url = serviceContext.getApplicationURL(); +// +// if (url != null && StringUtil.isEmail(user.getEmail())) { +// +// Locale locale = getLocale(); +// String subject = l_(locale, "pollen.email.userRegister.subject", +// user.getLogin()); +// String content = l_(locale, "pollen.email.userRegister.content", +// user.getDisplayName(), +// user.getLogin(), password, url); +// +// EmailService emailService = newService(EmailService.class); +// +// emailService.sendEmail( +// user.getEmail(), +// subject, +// content); +// } - Locale locale = getLocale(); - String subject = l_(locale, "pollen.email.userRegister.subject", - user.getLogin()); - String content = l_(locale, "pollen.email.userRegister.content", - user.getDisplayName(), - user.getLogin(), password, url); - - EmailService emailService = newService(EmailService.class); - - emailService.sendEmail( - user.getEmail(), - subject, - content); - } - return userAccount; } Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties 2012-03-07 16:44:51 UTC (rev 3166) @@ -8,8 +8,16 @@ pollen.common.numberVote-blank-votes=Number of blank votes pollen.common.numberVote-total=Sum of numbers pollen.common.numberVote-total-votes=Total votes +pollen.email.creatorEmail.content=You had just created the new poll\: "%s".\nYou can access to this poll by following the links below.\n\nVote page\: \n%s\nEdit page\: \n%s +pollen.email.creatorEmail.subject=[Pollen] Poll creation (%s) +pollen.email.reminderEmail.content=You have not yet voted for the poll "%s".\nYou can still participate with the identifier %s by following this link\: \n%s +pollen.email.reminderEmail.subject=[Pollen] Reminder (%s) pollen.email.userRegister.content=Welcome %1$s. You had just created an account on the web application Pollen.\n\nLogin\: %2$s\nPassword\: %3$s\n\nYou can now manage your polls by logging on the website \: \n%4$s pollen.email.userRegister.subject=[Pollen] Confirmation of account creation %s +pollen.email.voteEmail.content=A vote has been submitted for the poll "%s". There are now %d votes for this poll.\nYou can access to this poll by following the links below.\n\nVote page\: \n%s\nEdit page\: \n%s +pollen.email.voteEmail.subject=[Pollen] Vote reporting (%s) +pollen.email.votingEmail.content=A new poll has been created\: "%s".\nYou can participate with the identifier %s by following this link\: \n%s +pollen.email.votingEmail.subject=[Pollen] Invitation to vote (%s) pollen.feed.addChoiceContent= pollen.feed.addChoiceTitle= pollen.feed.addCommentContent=%s Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties 2012-03-07 16:44:51 UTC (rev 3166) @@ -10,8 +10,16 @@ pollen.common.numberVote-total-votes=Nombre total de votes pollen.email.createPoll.content=Vous venez de créer le sondage "%1$s".\nVous pouvez y accéder en suivant les liens ci-dessous.\n\nPage de vote \: \n%2$s\nModération des votes \: \n%3$s\nPage de modification \: \n%4$s pollen.email.createPoll.subject=[Pollen] Création d'un sondage (%1$s) +pollen.email.creatorEmail.content=Vous venez de créer le sondage "%s".\nVous pouvez y accéder en suivant les liens ci-dessous.\n\nPage de vote \: \n%s\nPage de modification \: \n%s +pollen.email.creatorEmail.subject=[Pollen] Création d'un sondage (%s) +pollen.email.reminderEmail.content=Vous n'avez pas encore voté pour le sondage "%s".\nVous pouvez encore y participer avec l'identifiant %s à l'adresse suivante \: \n%s +pollen.email.reminderEmail.subject=[Pollen] Rappel (%s) pollen.email.userRegister.content=Bienvenue %1$s. Vous venez de créer un compte sur l'application de sondage en ligne Pollen.\n\nIdentifiant \: %2$s\nMot de passe \: %3$s\n\nVous pouvez dès maintenant gérer vos sondages en vous identifiant sur le site \: \n%4$s pollen.email.userRegister.subject=[Pollen] Confirmation de création du compte %s +pollen.email.voteEmail.content=Un vote vient d'être enregistré pour le sondage "%s". Ce sondage compte désormais %d votes.\nVous pouvez accéder à ce sondage en suivant les liens ci-dessous.\n\nPage de vote \: \n%s\nPage de modification \: \n%s +pollen.email.voteEmail.subject=[Pollen] Notification de vote (%s) +pollen.email.votingEmail.content=Un nouveau sondage a été créé \: "%s".\nVous pouvez y participer avec l'identifiant %s à l'adresse suivante \: \n%s +pollen.email.votingEmail.subject=[Pollen] Invitation au vote (%s) pollen.feed.addChoiceContent= pollen.feed.addChoiceTitle= pollen.feed.addCommentContent=%s Modified: branches/pollen-1.2.6-struts2/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java 2012-03-07 16:44:51 UTC (rev 3166) @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.chorem.pollen.PolleIOUtil; import org.chorem.pollen.PollenConfiguration; +import org.chorem.pollen.PollenConfigurationOption; import org.chorem.pollen.PollenTopiaRootContextFactory; import org.junit.rules.TestWatcher; import org.junit.runner.Description; @@ -39,9 +40,7 @@ import java.io.File; import java.net.URL; import java.util.Date; -import java.util.HashMap; import java.util.Locale; -import java.util.Map; import java.util.Properties; import java.util.UUID; Modified: branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/log4j.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/log4j.properties 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/log4j.properties 2012-03-07 16:44:51 UTC (rev 3166) @@ -21,17 +21,13 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ### -# Default to info level output; this is very handy if you eventually use Hibernate as well. -log4j.rootCategory=warn, A1 +log4j.rootCategory=WARN, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%d [%p] %c{2} %m%n +log4j.appender.A1.layout.ConversionPattern=%d [%p] %c %m%n -log4j.logger.org.chorem.pollen=debug - -log4j.logger.org.chorem.pollen.business.PollenContextImpl=warn -log4j.logger.org.chorem.pollen.business.services.SendMail=warn +log4j.logger.org.chorem.pollen=INFO Modified: branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/pollen-fake.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/pollen-fake.properties 2012-03-07 16:43:44 UTC (rev 3165) +++ branches/pollen-1.2.6-struts2/pollen-services/src/test/resources/pollen-fake.properties 2012-03-07 16:44:51 UTC (rev 3166) @@ -34,6 +34,7 @@ topia.service.migration.callback=org.chorem.pollen.entities.migration.PollenMigrationCallback topia.service.migration.showSql=true +siteUrl=http://meFake/pollen upImgDir=${testDirectory}/.pollen/uploadedImages feedDir=${testDirectory}/.pollen/feeds pollen.emails.directory=${testDirectory}/.pollen/emails