2 * Copyright (C) 2016 Roland Haeder
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (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 Affero General Public License for more details.
14 * You should have received a copy of the GNU Affero 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.addressbook.mailer.model.delivery.AddressbookMailer;
40 import org.mxchange.addressbook.mailer.model.delivery.DeliverableAddressbookEmail;
41 import org.mxchange.jcoreee.database.BaseDatabaseBean;
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);
149 // Get mailer instance
150 DeliverableAddressbookEmail mailer = new AddressbookMailer();
152 // Send out email change
153 mailer.sendEmailChangeMail(this.messageProducer, this.message, emailChange);
157 * Initialization of this bean
160 public void init () {
162 // Get initial context
163 Context context = new InitialContext();
165 // Get factory from JMS resource
166 QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/addressbook-queue-factory"); //NOI18N
169 this.queue = (Queue) context.lookup("jms/addressbook-email-queue"); //NOI18N
172 this.connection = connectionFactory.createConnection();
174 // Init session instance
175 this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
177 // And message producer
178 this.messageProducer = this.session.createProducer(this.queue);
180 // Finally the message instance itself
181 this.message = this.session.createObjectMessage();
182 } catch (final NamingException | JMSException e) {
183 // Continued to throw
184 throw new FacesException(e);
189 public boolean isEmailAddressEnqueued (final String emailAddress) {
191 this.getLoggerBeanLocal().logTrace(MessageFormat.format("isEmailAddressEnqueued: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
193 // Create query instance
194 Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByEmail"); //NOI18N
196 // Add email address as parameter
197 query.setParameter("email", emailAddress); //NOI18N
199 // Initialize variable
200 boolean isFound = false;
204 // Try to get single result
205 ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
209 } catch (final NoResultException ex) {
211 this.getLoggerBeanLocal().logException(ex);
215 this.getLoggerBeanLocal().logTrace(MessageFormat.format("isEmailAddressEnqueued: isFound={0} - EXIT!", isFound)); //NOI18N
222 public void updateEmailAddress (final ChangeableEmailAddress emailAddress) {
224 this.getLoggerBeanLocal().logTrace(MessageFormat.format("updateEmailAddress: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
226 // Email address change should be valid
227 if (null == emailAddress) {
229 throw new NullPointerException("emailAddress is null"); //NOI18N
230 } else if (emailAddress.getEmailChangeId() == null) {
232 throw new NullPointerException("emailAddress.emailChangeId is null"); //NOI18N
233 } else if (emailAddress.getEmailChangeId() < 1) {
235 throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N
236 } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
237 // Email address is empty
238 throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
239 } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) {
240 // User does not exist
241 throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N
242 } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) {
243 // Email address is not enqueued
244 throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress())); //NOI18N
247 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
251 * Generates a secure, unique hash for given email address change. This
252 * requires to check if the hash is really not there.
254 * @param emailAddress Email address change
256 private void generateSecureHash (final ChangeableEmailAddress emailAddress) {
257 // Email address change should be valid
258 if (null == emailAddress) {
260 throw new NullPointerException("emailAddress is null"); //NOI18N
261 } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
262 // Email address is empty
263 throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
266 // Initialize loop with null
269 // Default is not used
270 boolean isUsed = true;
272 // Search for free hash
274 // Generate hash, there is already in UserUtils a nice method that can be used for this purpose.
275 hash = UserUtils.encryptPassword(String.format("%s:%s", emailAddress.getEmailAddress(), emailAddress.toString())); //NOI18N
277 // The hash *may* be unique, better test it
278 Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N
280 // Set hash as parameter
281 query.setParameter("hash", hash); //NOI18N
283 // Try to get single result
286 ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
287 } catch (final NoResultException ex) {
293 // hash should not be null and set
294 assert (hash != null) : "hash is null"; //NOI18N
295 assert (!hash.isEmpty()) : "hash is empty"; //NOI18N
297 // Set it in email change
298 emailAddress.setEmailChangeHash(hash);