2 * Copyright (C) 2016 quix0r
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.jusercore.model.email_address;
19 import java.text.MessageFormat;
20 import java.util.GregorianCalendar;
21 import java.util.List;
22 import javax.annotation.PostConstruct;
24 import javax.ejb.EJBException;
25 import javax.ejb.Stateless;
26 import javax.faces.FacesException;
27 import javax.jms.Connection;
28 import javax.jms.JMSException;
29 import javax.jms.MessageProducer;
30 import javax.jms.ObjectMessage;
31 import javax.jms.Queue;
32 import javax.jms.QueueConnectionFactory;
33 import javax.jms.Session;
34 import javax.naming.Context;
35 import javax.naming.InitialContext;
36 import javax.naming.NamingException;
37 import javax.persistence.NoResultException;
38 import javax.persistence.Query;
39 import org.mxchange.jcoreee.database.BaseDatabaseBean;
40 import org.mxchange.jmailee.model.delivery.DeliverableEmail;
41 import org.mxchange.jmailee.model.delivery.Mailer;
42 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
43 import org.mxchange.jusercore.model.user.UserUtils;
46 * A session bean for changing email addresses
48 * @author Roland Haeder<roland@mxchange.org>
50 @Stateless (name = "email-change", mappedName = "ejb/stateless-addressbook-email-change", description = "A bean handling email changes")
51 public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implements EmailChangeSessionBeanRemote {
56 private static final long serialVersionUID = 182_698_165_971_548L;
61 private Connection connection;
66 private ObjectMessage message;
71 private MessageProducer messageProducer;
74 * Mailer message queue
81 private Session session;
87 private UserSessionBeanRemote userBean;
92 public AddressbookEmailChangeSessionBean () {
96 @SuppressWarnings ("unchecked")
97 public List<String> allQueuedAddressesAsList () {
99 this.getLoggerBeanLocal().logTrace("allQueuedAddressesAsList: CALLED!"); //NOI18N
102 Query query = this.getEntityManager().createNamedQuery("AllEmailAddressChanges", List.class); //NOI18N
105 List<String> emailAddresses = query.getResultList();
108 this.getLoggerBeanLocal().logTrace(MessageFormat.format("allQueuedAddressesAsList: emailAddresses.size()={0} - EXIT!", emailAddresses.size())); //NOI18N
111 return emailAddresses;
115 public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailChange) {
117 this.getLoggerBeanLocal().logTrace(MessageFormat.format("enqueueEmailAddressForChange: emailChange={0} - CALLED!", emailChange)); //NOI18N
119 // Email address change should be valid
120 if (null == emailChange) {
122 throw new NullPointerException("emailChange is null"); //NOI18N
123 } else if (emailChange.getEmailChangeUser() == null) {
125 throw new NullPointerException("emailChange.emailChangeUser is null"); //NOI18N
126 } else if (emailChange.getEmailChangeUser().getUserId() == null) {
128 throw new NullPointerException("emailChange.emailChangeUser.userId is null"); //NOI18N
129 } else if (emailChange.getEmailChangeUser().getUserId() < 1) {
131 throw new IllegalArgumentException(MessageFormat.format("emailChange.emailChangeUser.userId={0} is invalid.", emailChange.getEmailChangeUser().getUserId())); //NOI18N
132 } else if (!this.userBean.ifUserExists(emailChange.getEmailChangeUser())) {
133 // User does not exist
134 throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailChange.getEmailChangeId())); //NOI18N
135 } else if (emailChange.getEmailAddress().trim().isEmpty()) {
136 // Email address is empty
137 throw new IllegalArgumentException("emailChange.emaiLAddress is empty."); //NOI18N
138 } else if (this.isEmailAddressEnqueued(emailChange.getEmailAddress())) {
139 // Email address is already enqueued
140 throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailChange.getEmailAddress())); //NOI18N
143 // The email change is not (yet) there, add secure hash and "created" timestamp
144 emailChange.setEmailChangeCreated(new GregorianCalendar());
145 this.generateSecureHash(emailChange);
148 //this.getEntityManager().persist(emailChange);
150 // Get mailer instance
151 DeliverableEmail mailer = new Mailer();
153 // Send out email change
154 mailer.sendEmailChangeMail(this.messageProducer, this.message, emailChange);
158 * Initialization of this bean
161 public void init () {
163 // Get initial context
164 Context context = new InitialContext();
166 // Get factory from JMS resource
167 QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/addressbook-queue-factory"); //NOI18N
170 this.queue = (Queue) context.lookup("jms/addressbook-email-queue"); //NOI18N
173 this.connection = connectionFactory.createConnection();
175 // Init session instance
176 this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
178 // And message producer
179 this.messageProducer = this.session.createProducer(this.queue);
181 // Finally the message instance itself
182 this.message = this.session.createObjectMessage();
183 } catch (final NamingException | JMSException e) {
184 // Continued to throw
185 throw new FacesException(e);
190 public boolean isEmailAddressEnqueued (final String emailAddress) {
192 this.getLoggerBeanLocal().logTrace(MessageFormat.format("isEmailAddressEnqueued: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
194 // Create query instance
195 Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByEmail"); //NOI18N
197 // Add email address as parameter
198 query.setParameter("email", emailAddress); //NOI18N
200 // Initialize variable
201 boolean isFound = false;
205 // Try to get single result
206 ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
210 } catch (final NoResultException ex) {
212 this.getLoggerBeanLocal().logException(ex);
216 this.getLoggerBeanLocal().logTrace(MessageFormat.format("isEmailAddressEnqueued: isFound={0} - EXIT!", isFound)); //NOI18N
223 public void updateEmailAddress (final ChangeableEmailAddress emailAddress) {
225 this.getLoggerBeanLocal().logTrace(MessageFormat.format("updateEmailAddress: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
227 // Email address change should be valid
228 if (null == emailAddress) {
230 throw new NullPointerException("emailAddress is null"); //NOI18N
231 } else if (emailAddress.getEmailChangeId() == null) {
233 throw new NullPointerException("emailAddress.emailChangeId is null"); //NOI18N
234 } else if (emailAddress.getEmailChangeId() < 1) {
236 throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N
237 } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
238 // Email address is empty
239 throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
240 } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) {
241 // User does not exist
242 throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N
243 } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) {
244 // Email address is not enqueued
245 throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress())); //NOI18N
248 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
252 * Generates a secure, unique hash for given email address change. This
253 * requires to check if the hash is really not there.
255 * @param emailAddress Email address change
257 private void generateSecureHash (final ChangeableEmailAddress emailAddress) {
258 // Email address change should be valid
259 if (null == emailAddress) {
261 throw new NullPointerException("emailAddress is null"); //NOI18N
262 } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
263 // Email address is empty
264 throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
267 // Initialize loop with null
270 // Default is not used
271 boolean isUsed = true;
273 // Search for free hash
275 // Generate hash, there is already in UserUtils a nice method that can be used for this purpose.
276 hash = UserUtils.encryptPassword(String.format("%s:%s", emailAddress.getEmailAddress(), emailAddress.toString())); //NOI18N
278 // The hash *may* be unique, better test it
279 Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N
281 // Set hash as parameter
282 query.setParameter("hash", hash); //NOI18N
284 // Try to get single result
287 ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
288 } catch (final NoResultException ex) {
294 // hash should not be null and set
295 assert (hash != null) : "hash is null"; //NOI18N
296 assert (!hash.isEmpty()) : "hash is empty"; //NOI18N
298 // Set it in email change
299 emailAddress.setEmailChangeHash(hash);