From 23466ea678246dfa35baf1f91502baab6c4d18d7 Mon Sep 17 00:00:00 2001 From: Roland Haeder Date: Mon, 15 Feb 2016 18:19:46 +0100 Subject: [PATCH] More imports from addressbook-war --- lib/addressbook-lib.jar | Bin 0 -> 51640 bytes lib/jcontacts-core.jar | Bin 0 -> 21053 bytes lib/jcore-logger-lib.jar | Bin 0 -> 2533 bytes lib/jcore.jar | Bin 0 -> 13656 bytes lib/jphone-core.jar | Bin 0 -> 25391 bytes lib/juser-core.jar | Bin 0 -> 29575 bytes lib/juser-lib.jar | Bin 0 -> 4033 bytes nbproject/build-impl.xml | 14 + nbproject/faces-config.NavData | 0 nbproject/genfiles.properties | 10 +- nbproject/project.properties | 21 + nbproject/project.xml | 28 + .../AddressbookWebSessionBean.java | 419 +++++++++ .../AddressbookWebSessionController.java | 211 +++++ .../country/CountryWebApplicationBean.java | 82 ++ .../CountryWebApplicationController.java | 36 + .../gender/GenderWebApplicationBean.java | 59 ++ .../GenderWebApplicationController.java | 43 + .../beans/login/UserLoginWebSessionBean.java | 187 ++++ .../login/UserLoginWebSessionController.java | 84 ++ .../profile/UserProfileWebRequestBean.java | 155 ++++ .../UserProfileWebRequestController.java | 67 ++ .../ProfileModeWebApplicationBean.java | 48 + .../ProfileModeWebApplicationController.java | 35 + .../register/UserRegisterWebSessionBean.java | 137 +++ .../UserRegisterWebSessionController.java | 35 + .../beans/shares/SharesWebSessionBean.java | 333 +++++++ .../shares/SharesWebSessionController.java | 112 +++ .../SmsProviderWebApplicationBean.java | 82 ++ .../SmsProviderWebApplicationController.java | 36 + .../beans/user/UserWebSessionBean.java | 866 ++++++++++++++++++ .../beans/user/UserWebSessionController.java | 481 ++++++++++ .../converter/country/CountryConverter.java | 137 +++ .../smsprovider/SmsProviderConverter.java | 138 +++ .../converter/user/UserConverter.java | 132 +++ web/WEB-INF/beans.xml | 6 + web/WEB-INF/faces-config.xml | 176 ++++ web/WEB-INF/glassfish-web.xml | 11 + 38 files changed, 4176 insertions(+), 5 deletions(-) create mode 100644 lib/addressbook-lib.jar create mode 100644 lib/jcontacts-core.jar create mode 100644 lib/jcore-logger-lib.jar create mode 100644 lib/jcore.jar create mode 100644 lib/jphone-core.jar create mode 100644 lib/juser-core.jar create mode 100644 lib/juser-lib.jar create mode 100644 nbproject/faces-config.NavData create mode 100644 src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java create mode 100644 src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java create mode 100644 src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java create mode 100644 src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java create mode 100644 src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java create mode 100644 src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java create mode 100644 src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java create mode 100644 src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java create mode 100644 src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java create mode 100644 src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java create mode 100644 src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java create mode 100644 src/java/org/mxchange/addressbook/converter/country/CountryConverter.java create mode 100644 src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java create mode 100644 src/java/org/mxchange/addressbook/converter/user/UserConverter.java create mode 100644 web/WEB-INF/beans.xml create mode 100644 web/WEB-INF/faces-config.xml create mode 100644 web/WEB-INF/glassfish-web.xml diff --git a/lib/addressbook-lib.jar b/lib/addressbook-lib.jar new file mode 100644 index 0000000000000000000000000000000000000000..a8382ba7879a4c436264e18b5fa74f027cb5c495 GIT binary patch literal 51640 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 literal 0 HcmV?d00001 diff --git a/lib/jcore-logger-lib.jar b/lib/jcore-logger-lib.jar new file mode 100644 index 0000000000000000000000000000000000000000..a3fd54ebfe1d379768b5bdfc365d4e7a31ddd118 GIT binary patch literal 2533 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 I9O2Oa0;_hN5dZ)H literal 0 HcmV?d00001 diff --git a/lib/juser-core.jar b/lib/juser-core.jar new file mode 100644 index 0000000000000000000000000000000000000000..8769dc941f2dabd69877256e0387c5812e3c76fb GIT binary patch literal 29575 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 literal 0 HcmV?d00001 diff --git a/lib/juser-lib.jar b/lib/juser-lib.jar new file mode 100644 index 0000000000000000000000000000000000000000..dd83e969106c6a459a91bd808c218fb6b1093bc8 GIT binary patch literal 4033 zcmcIn&2Jl35TEBb*~X2NG;#V7gb1w^C8}%(5EMuYxM@tI_)BqHBrehO`o(!+y&HDd zA%#;e9QYTI;LLo@7kN}t{at=*8Aa^-@KVOznR&__E~h z5hHpnEPBv$gsoe4oYL#jN?ofhj2L^jl2i?=Bh46qw|b`Abh+De81R(}ZM?s&!CvW>>2hh}s+DQa>_-3P`f8M(+AhysvbWA4 zvw5tGLrOzOgESJzbcmgg&5TS^=;@o55|GI+0H@tnlF6kNtPDVPE(B@-wyJy(f`XK`%qJ2N5>IM8nXQ z4D6Kcr$J!+lx6TR8D=oJ(NII#KQ@&86PWFo{rHaZAMkpat{w;IH%kogm@pG&!uV&q zf4zx(qVrx76MC4tUUf;z{6!6}X>eVG8w_6KhEWyWmarSWmLc`ino7As)pTXmtEa`D zD~)0Wn;%xw$)@a>*fngdcX!VS+#R(ae1uTbXkFPoH8`~=4TJ6j&R9D z4ReEBVz7LU7eUEyy0$bs>$Ki^R2|F*r9Lh92yY7uGQwfl=2ukIypB<^Ph!b zy+Ps?usr}8V*4Vk=xicfkl|5nEmRKA*c+YEL;NAG1l+%_7s%M z4#?5-G$5<+Ity34>l|H?b@SeD4i-+ica^xuQn|6{F&`!In1#PfboD2BHS`Cn=Z*cO zK*zI_+xY9N4txZ}8K<#a9c26uyrr@gr$N0{9i;IO-VPPII8_?k)j_I@ETkF?hH)S? z#s?tvXb_b_aZtDVNM7W>OM+6c`RX7Ce@_DJj|Q>vzS)QL7CD21%TT<7pbao4 zyvFcnKp*niNj(WKX@pfD1!05XIV&)@JD%Wx9~3GxsG+$yYs7? X_vzEv9;cZT2h1t>4g2PwG;hLx4AEcx literal 0 HcmV?d00001 diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml index 33e72bea..24dd9409 100644 --- a/nbproject/build-impl.xml +++ b/nbproject/build-impl.xml @@ -1030,15 +1030,29 @@ exists or setup the property manually. For example like this: + + + + + + + + + + + + + + diff --git a/nbproject/faces-config.NavData b/nbproject/faces-config.NavData new file mode 100644 index 00000000..e69de29b diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties index 1b2bbeaf..0e8b1adf 100644 --- a/nbproject/genfiles.properties +++ b/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=4018faed +build.xml.data.CRC32=1ae43834 build.xml.script.CRC32=fae72669 -build.xml.stylesheet.CRC32=651128d4@1.68.1.1 +build.xml.stylesheet.CRC32=651128d4@1.75.1.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=4018faed -nbproject/build-impl.xml.script.CRC32=73413a39 -nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.68.1.1 +nbproject/build-impl.xml.data.CRC32=1ae43834 +nbproject/build-impl.xml.script.CRC32=6df6af1f +nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.75.1.1 diff --git a/nbproject/project.properties b/nbproject/project.properties index f3da35a9..7f70d9ae 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -35,8 +35,15 @@ dist.javadoc.dir=${dist.dir}/javadoc dist.war=${dist.dir}/${war.name} endorsed.classpath= excludes= +file.reference.addressbook-lib.jar=lib/addressbook-lib.jar +file.reference.jcontacts-core.jar=lib/jcontacts-core.jar +file.reference.jcore-logger-lib.jar=lib/jcore-logger-lib.jar +file.reference.jcore.jar=lib/jcore.jar file.reference.jcountry-core.jar=lib/jcountry-core.jar file.reference.jcountry-lib.jar=lib/jcountry-lib.jar +file.reference.jphone-core.jar=lib/jphone-core.jar +file.reference.juser-core.jar=lib/juser-core.jar +file.reference.juser-lib.jar=lib/juser-lib.jar includes=** j2ee.compile.on.save=true j2ee.copy.static.files.on.save=true @@ -51,8 +58,15 @@ j2ee.platform.wsit.classpath= j2ee.server.type=gfv3ee6 jar.compress=false javac.classpath=\ + ${file.reference.addressbook-lib.jar}:\ + ${file.reference.jcontacts-core.jar}:\ + ${file.reference.jcore.jar}:\ + ${file.reference.jcore-logger-lib.jar}:\ ${file.reference.jcountry-core.jar}:\ ${file.reference.jcountry-lib.jar}:\ + ${file.reference.jphone-core.jar}:\ + ${file.reference.juser-core.jar}:\ + ${file.reference.juser-lib.jar}:\ ${reference.jjobs-lib.jar} # Space-separated list of extra javac options javac.compilerargs=-Xlint:unchecked -Xlint:deprecation @@ -93,8 +107,15 @@ run.test.classpath=\ # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value): runmain.jvmargs= source.encoding=UTF-8 +source.reference.addressbook-lib.jar=../addressbook-lib/src/ +source.reference.jcontacts-core.jar=../jcontacts-core/src/ +source.reference.jcore-logger-lib.jar=../jcore-logger-lib/src/ +source.reference.jcore.jar=../jcore/src/ source.reference.jcountry-core.jar=../jcountry-core/src/ source.reference.jcountry-lib.jar=../jcountry-lib/src/ +source.reference.jphone-core.jar=../jphone-core/src/ +source.reference.juser-core.jar=../juser-core/src/ +source.reference.juser-lib.jar=../juser-lib/src/ source.root=src src.dir=${source.root}/java test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml index acf850f8..499bdc69 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -6,6 +6,22 @@ jjobs-war 1.6.5 + + ${file.reference.addressbook-lib.jar} + WEB-INF/lib + + + ${file.reference.jcontacts-core.jar} + WEB-INF/lib + + + ${file.reference.jcore.jar} + WEB-INF/lib + + + ${file.reference.jcore-logger-lib.jar} + WEB-INF/lib + ${file.reference.jcountry-core.jar} WEB-INF/lib @@ -14,6 +30,18 @@ ${file.reference.jcountry-lib.jar} WEB-INF/lib + + ${file.reference.jphone-core.jar} + WEB-INF/lib + + + ${file.reference.juser-core.jar} + WEB-INF/lib + + + ${file.reference.juser-lib.jar} + WEB-INF/lib + ${reference.jjobs-lib.jar} WEB-INF/lib diff --git a/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java new file mode 100644 index 00000000..d01fbbef --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.addressbook; + +import java.text.MessageFormat; +import java.util.Calendar; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import javax.annotation.PostConstruct; +import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Observes; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Inject; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.login.UserLoginWebSessionController; +import org.mxchange.addressbook.events.addressbook.AddressbookLoadedEvent; +import org.mxchange.addressbook.exceptions.AddressbookNameAlreadyUsedException; +import org.mxchange.addressbook.model.addressbook.Addressbook; +import org.mxchange.addressbook.model.addressbook.AddressbookSessionBeanRemote; +import org.mxchange.addressbook.model.addressbook.UserAddressbook; +import org.mxchange.addressbook.model.addressbook.entry.AddressbookEntry; +import org.mxchange.jusercore.events.login.UserLoggedInEvent; +import org.mxchange.jusercore.model.user.User; + +/** + * An address book bean (controller) + *

+ * @author Roland Haeder + */ +@Named ("addressbookController") +@SessionScoped +public class AddressbookWebSessionBean implements AddressbookWebSessionController { + + /** + * Map for count of user's shared addresses + */ + private static ConcurrentMap countSharesList; + + /** + * Serial number + */ + private static final long serialVersionUID = 185_781_756_712_969L; + + /** + * Address book instance + */ + private Addressbook addressbook; + + /** + * Remote address book bean + */ + private AddressbookSessionBeanRemote addressbookBean; + + /** + * When this address book has been created + */ + private Calendar addressbookCreated; + + /** + * Address book id number (from URL for example) + */ + private Long addressbookId; + + /** + * Name of the address book + */ + private String addressbookName; + + /** + * Who owns this address book + */ + private User addressbookUser; + + /** + * Login controller + */ + @Inject + private UserLoginWebSessionController loginController; + + /** + * A list of all user's address books + */ + private List usersAddressbooks; + + /** + * Default constructor + */ + public AddressbookWebSessionBean () { + // Try it + try { + // Get initial context + Context context = new InitialContext(); + + // Try to lookup + this.addressbookBean = (AddressbookSessionBeanRemote) context.lookup("ejb/stateless-addressbook"); //NOI18N + } catch (final NamingException e) { + // Throw again + throw new FaceletException(e); + } + + // Init list + AddressbookWebSessionBean.countSharesList = new ConcurrentHashMap<>(0); + } + + @Override + public String addAddressbook () { + // Is this name already used? + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } else if (this.getAddressbookName() == null) { + // Address book name is null + throw new NullPointerException("addressbookName is null"); //NOI18N + } else if (this.getAddressbookName().isEmpty()) { + // Address book name is empty + throw new IllegalStateException("addressbookName is empty."); //NOI18N + } else if (this.isAddressbookNameUsed(this.getAddressbookName())) { + // Already used by this user + throw new FaceletException(MessageFormat.format("Address book name {0} already used.", this.getAddressbookName())); //NOI18N + } + + // Create address book instance with name + Addressbook book = new UserAddressbook(this.getAddressbookName(), this.loginController.getLoggedInUser(), new GregorianCalendar()); + + try { + // Register this address book + Addressbook updatedAddressbook = this.addressbookBean.createAddressbook(book); + + // Remove name + this.setAddressbookName(null); + + // Add address book entry to list + this.usersAddressbooks.add(updatedAddressbook); + + // All fine + return "login_own_addressbooks"; //NOI18N + } catch (final AddressbookNameAlreadyUsedException ex) { + // Throw again as cause + throw new FaceletException(ex); + } + } + + @Override + public void afterAddressbookLoadedEvent (final @Observes AddressbookLoadedEvent event) { + // event should not be null + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getAddressbook() == null) { + // Throw NPE again + throw new NullPointerException("event.addressbook is null"); //NOI18N + } else if (event.getAddressbook().getAddressbookId() == null) { + // And again a NPE + throw new NullPointerException("event.addressbook.addressbookId is null"); //NOI18N + } else if (event.getAddressbook().getAddressbookId() < 1) { + // Invalid id number + throw new IllegalArgumentException(MessageFormat.format("Address book instance {0} has invalid id number: {1}", event.getAddressbook(), event.getAddressbook().getAddressbookId())); //NOI18N + } else if (event.getAddressbook().getAddressbookUser() == null) { + // One more NPE ... + throw new NullPointerException("event.addressbook.addressbookUser is null"); //NOI18N + } + + // Get address book instance + Addressbook book = event.getAddressbook(); + + // Set address book data + this.setAddressbookId(book.getAddressbookId()); + this.setAddressbookName(book.getAddressbookName()); + this.setAddressbookUser(book.getAddressbookUser()); + this.setAddressbookCreated(book.getAddressbookCreated()); + + // And instance ... + this.setAddressbook(book); + } + + @Override + public void afterLoginEvent (final @Observes UserLoggedInEvent event) { + // Is the user logged in? + if (null == event) { + // Is null + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getUser() == null) { + // user is null + throw new NullPointerException("event.user is null"); //NOI18N + } else if (!event.getUser().equals(this.loginController.getLoggedInUser())) { + // Not matching + throw new IllegalStateException("event.user and loginController.loggedInUser don't match."); //NOI18N + } else if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + // Init user's address book list + this.initAddressbookList(); + } + + @Override + public List allAddressbooks () { + // Is the user logged in? + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + return Collections.unmodifiableList(this.usersAddressbooks); + } + + @Override + public List allEntries (final Addressbook addressbook) { + // Is the user logged in? + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + // Ask the bean + return this.addressbookBean.allEntries(addressbook); + } + + @Override + public int allEntriesSize (final Addressbook addressbook) { + // Ask the bean + return this.allEntries(addressbook).size(); + } + + @Override + public List allUsersNotSharing () { + // Is the user logged in? + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + // Call EJB + return this.addressbookBean.allUsersNotSharing(this.loginController.getLoggedInUser(), this.getAddressbook()); + } + + @Override + public Integer countAllUserSharedAddressbooks (final User user) { + // Is there cache? + if (AddressbookWebSessionBean.countSharesList.containsKey(user)) { + // Return it instead + return AddressbookWebSessionBean.countSharesList.get(user); + } + + // Call EJB ("expensive") + Integer count = this.addressbookBean.countAllUserSharedAddressbooks(user); + + // Add to list + AddressbookWebSessionBean.countSharesList.put(user, count); + + // Return it + return count; + } + + @Override + public Addressbook getAddressbook () { + return this.addressbook; + } + + @Override + public void setAddressbook (final Addressbook addressbook) { + this.addressbook = addressbook; + } + + @Override + public Calendar getAddressbookCreated () { + return this.addressbookCreated; + } + + @Override + public void setAddressbookCreated (final Calendar addressbookCreated) { + this.addressbookCreated = addressbookCreated; + } + + @Override + public Long getAddressbookId () { + return this.addressbookId; + } + + @Override + public void setAddressbookId (final Long addressbookId) { + this.addressbookId = addressbookId; + } + + @Override + public String getAddressbookName () { + return this.addressbookName; + } + + @Override + public void setAddressbookName (final String addressbookName) { + this.addressbookName = addressbookName; + } + + @Override + public User getAddressbookUser () { + return this.addressbookUser; + } + + @Override + public void setAddressbookUser (final User addressbookUser) { + this.addressbookUser = addressbookUser; + } + + @Override + public boolean hasCreatedAddressbooks () { + // Is the user logged in? + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + // Check if the list is filled + return (!this.usersAddressbooks.isEmpty()); + } + + @PostConstruct + public void init () { + // Init list + this.usersAddressbooks = new LinkedList<>(); + + // Is the user logged-in? + if (this.loginController.isUserLoggedIn()) { + // Initialize list + this.initAddressbookList(); + } + + // TODO Initialize list from bean with just one call + //this.addressbookBean.getUserCountMap() + } + + @Override + public boolean isAddressbookNameUsed (final String addressbookName) { + // Is it zero size? + if (null == addressbookName) { + // Is null + throw new NullPointerException("addressbookName is null"); //NOI18N + } else if (this.usersAddressbooks.isEmpty()) { + // Not found! + return false; + } + + // Default is not found + boolean isFound = false; + + // Check all entries + for (final Addressbook book : this.usersAddressbooks) { + // Is the name same? + if (book.getAddressbookName().equals(addressbookName)) { + // Found a match + isFound = true; + break; + } + } + + // Return status + return isFound; + } + + @Override + public boolean isOtherAddressbook () { + // Just call the other method and invert it + return (!this.isOwnAddressbook()); + } + + @Override + public boolean isOwnAddressbook () { + // Is the user logged in? + if (!this.loginController.isUserLoggedIn()) { + // No, then no own address book + throw new IllegalStateException("isOwnAddressbook() has been invoked for a guest account"); //NOI18N + } + + // Is same user? + return Objects.equals(this.getAddressbookUser(), this.loginController.getLoggedInUser()); + } + + @Override + public boolean isAddressbookLoaded () { + return ((this.getAddressbookId() instanceof Long) + && (this.getAddressbookName() instanceof String) + && (!this.getAddressbookName().isEmpty()) + && (this.getAddressbookUser() instanceof User)); + } + + /** + * Initializes the user user's address book list + */ + private void initAddressbookList () { + // Get user instance + User user = this.loginController.getLoggedInUser(); + + // Fill list with entries + this.usersAddressbooks = this.addressbookBean.getUsersAddressbookList(user); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java b/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java new file mode 100644 index 00000000..af97a86b --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.addressbook; + +import java.io.Serializable; +import java.util.Calendar; +import java.util.List; +import org.mxchange.addressbook.events.addressbook.AddressbookLoadedEvent; +import org.mxchange.addressbook.model.addressbook.Addressbook; +import org.mxchange.addressbook.model.addressbook.entry.AddressbookEntry; +import org.mxchange.jusercore.events.login.UserLoggedInEvent; +import org.mxchange.jusercore.model.user.User; + +/** + * An interface for address book beans + *

+ * @author Roland Haeder + */ +public interface AddressbookWebSessionController extends Serializable { + + /** + * Checks whether the user has created addressbooks. For this method to work + * it is vital that the user is logged into his/her account. + *

+ * @return Whether the user has created at least one addressbook + */ + boolean hasCreatedAddressbooks (); + + /** + * Creates a new address book with a name and redirects to proper target. + * For this method to work it is vital that the user is logged into his/her + * account. + *

+ * @return Target to redirect to + */ + String addAddressbook (); + + /** + * Getter for address book name + *

+ * @return Address book name + */ + String getAddressbookName (); + + /** + * Setter for address book name + *

+ * @param addressbookName Address book name + */ + void setAddressbookName (final String addressbookName); + + /** + * Checks if the given address book name is already used by the user. + *

+ * @param addressbookName Address book name to check + *

+ * @return Whether the name has already been used by the user + */ + boolean isAddressbookNameUsed (final String addressbookName); + + /** + * Returns all address books with this user + *

+ * @return A list of all address books by this user + */ + List allAddressbooks (); + + /** + * Returns a list of all address book entries for given address book + *

+ * @param addressbook Address book instance + *

+ * @return List of all entries + */ + List allEntries (final Addressbook addressbook); + + /** + * Size of all entries in given address book + *

+ * @param addressbook Address book instance + *

+ * @return Size of the entries in address book + */ + int allEntriesSize (final Addressbook addressbook); + + /** + * Getter for address book id number + *

+ * @return Address book id number + */ + Long getAddressbookId (); + + /** + * Setter for address book id number + *

+ * @param addressbookId Address book id number + */ + void setAddressbookId (final Long addressbookId); + + /** + * Getter for address book user (owner) + *

+ * @return Address book user (owner) + */ + User getAddressbookUser (); + + /** + * Setter for address book user (owner) + *

+ * @param addressbookUser Address book user (owner) + */ + void setAddressbookUser (final User addressbookUser); + + /** + * Getter for when the address book has been created + *

+ * @return When the address book has been created + */ + Calendar getAddressbookCreated (); + + /** + * Setter for when the address book has been created + *

+ * @param addressbookCreated When the address book has been created + */ + void setAddressbookCreated (final Calendar addressbookCreated); + + /** + * This method is called when an address book has been successfully loaded + * from JPA. + *

+ * @param event Event with address book instance + */ + void afterAddressbookLoadedEvent (final AddressbookLoadedEvent event); + + /** + * Count all shared address books by given user id + *

+ * @param user User instance to look for + *

+ * @return Count of user's shared address books + */ + Integer countAllUserSharedAddressbooks (final User user); + + /** + * This method is called when a user has successfully logged in his/her + * account. + *

+ * @param event + */ + void afterLoginEvent (final UserLoggedInEvent event); + + /** + * Checks if the user is logged in and if so if it matches the current + * address book owner. + *

+ * @return Whether the owner matches currently logged-in user + */ + boolean isOwnAddressbook (); + + /** + * Checks if the owner of the current address book is NOT matching the + * logged-in user. + *

+ * @return Whether the user does NOT match + */ + boolean isOtherAddressbook (); + + /** + * Getter for address book instance + *

+ * @return Address book instance + */ + Addressbook getAddressbook (); + + /** + * Setter for address book instance + *

+ * @param addressbook Address book instance + */ + void setAddressbook (final Addressbook addressbook); + + /** + * Retrieves a list of all users this user is not sharing this address book + * with. + *

+ * @return List of not sharing users + */ + List allUsersNotSharing (); + + /** + * Checks wether an address book has been loaded by checking the id number. + *

+ * @return Whether the address book is loaded + */ + boolean isAddressbookLoaded (); +} diff --git a/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java new file mode 100644 index 00000000..b994cd84 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java @@ -0,0 +1,82 @@ +package org.mxchange.addressbook.beans.country; + +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +import java.util.Collections; +import java.util.List; +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote; +import org.mxchange.jcountry.data.Country; + +/** + * A country bean + *

+ * @author Roland Haeder + */ +@Named ("country") +@ApplicationScoped +public class CountryWebApplicationBean implements CountryWebApplicationController { + + /** + * Serial number + */ + private static final long serialVersionUID = 176_985_298_681_742_960L; + + /** + * Remote country EJB + */ + private AddressbookCountrySingletonBeanRemote countryBean; + + /** + * List of all countries + */ + private List countryList; + + /** + * Default constructor + */ + public CountryWebApplicationBean () { + // Try this + try { + // Get initial context + Context context = new InitialContext(); + + // Try to lookup the bean + this.countryBean = (AddressbookCountrySingletonBeanRemote) context.lookup("ejb/addressbook-singleton-country"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw + throw new FaceletException(ex); + } + } + + @Override + public List allCountries () { + // Return "cached" version + return Collections.unmodifiableList(this.countryList); + } + + @PostConstruct + public void init () { + this.countryList = this.countryBean.allCountries(); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java new file mode 100644 index 00000000..bc70b9ce --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java @@ -0,0 +1,36 @@ +package org.mxchange.addressbook.beans.country; + +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +import java.io.Serializable; +import java.util.List; +import org.mxchange.jcountry.data.Country; + +/** + * An interface for country beans + *

+ * @author Roland Haeder + */ +public interface CountryWebApplicationController extends Serializable { + + /** + * A list of all countries + *

+ * @return All countries + */ + List allCountries (); +} diff --git a/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java new file mode 100644 index 00000000..1738fcf1 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.gender; + +import java.util.List; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Named; +import org.mxchange.jcontacts.contact.gender.Gender; +import org.mxchange.jcontacts.contact.gender.GenderUtils; + +/** + * A gender bean + *

+ * @author Roland Haeder + */ +@Named ("gender") +@ApplicationScoped +public class GenderWebApplicationBean implements GenderWebApplicationController { + + /** + * Serial number + */ + private static final long serialVersionUID = 835_482_364_189L; + + /** + * Default constructor + */ + public GenderWebApplicationBean () { + } + + @Override + public Gender[] getAllGenders () { + // Return it + return Gender.values(); + } + + @Override + public List getSelectableGenders () { + // Init array + List genders = GenderUtils.selectableGenders(); + + // Return it + return genders; + } +} diff --git a/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java new file mode 100644 index 00000000..9f24dbfd --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.gender; + +import java.io.Serializable; +import java.util.List; +import org.mxchange.jcontacts.contact.gender.Gender; + +/** + * An interface for data beans + *

+ * @author Roland Haeder + */ +public interface GenderWebApplicationController extends Serializable { + + /** + * Getter for all genders as array + *

+ * @return All genders as array + */ + Gender[] getAllGenders (); + + /** + * Getter for only selectable genders as array, UNKNOWN is not selectable + *

+ * @return All genders as array + */ + List getSelectableGenders (); +} diff --git a/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java new file mode 100644 index 00000000..d8932a74 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.login; + +import java.util.Objects; +import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Event; +import javax.enterprise.inject.Any; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Inject; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.user.UserWebSessionController; +import org.mxchange.jusercore.container.login.LoginContainer; +import org.mxchange.jusercore.container.login.UserLoginContainer; +import org.mxchange.jusercore.events.login.UserLoggedInEvent; +import org.mxchange.jusercore.events.login.UserLoginEvent; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.exceptions.UserPasswordMismatchException; +import org.mxchange.jusercore.exceptions.UserStatusLockedException; +import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException; +import org.mxchange.jusercore.model.login.UserLoginSessionBeanRemote; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; +import org.mxchange.jusercore.model.user.status.UserAccountStatus; + +/** + * A web bean for user registration + *

+ * @author Roland Haeder + */ +@Named ("loginController") +@SessionScoped +public class UserLoginWebSessionBean implements UserLoginWebSessionController { + + /** + * Serial number + */ + private static final long serialVersionUID = 47_828_986_719_691_592L; + + /** + * Logged-in user instance + */ + private User loggedInUser; + + /** + * Reemote register session bean + */ + private UserLoginSessionBeanRemote loginBean; + + /** + * Event fired when user has logged in + */ + @Inject + @Any + private Event loginEvent; + + /** + * Template type for pages that might be displayed in guest area and login + * area. Default is guest area. + */ + private String templateType = "guest"; //NOI18N + + /** + * User controller + */ + @Inject + private UserWebSessionController userController; + + /** + * Flag whether the user has logged-in, set only from inside + */ + private boolean userLoggedIn; + + /** + * Default constructor + */ + public UserLoginWebSessionBean () { + try { + // Get initial context + Context context = new InitialContext(); + + // Try to lookup + this.loginBean = (UserLoginSessionBeanRemote) context.lookup("ejb/stateless-login"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw + throw new FaceletException(ex); + } + } + + @Override + public String doLogin () { + // Get user instance + User user = this.userController.createUserInstance(); + + // Create login container + LoginContainer container = new UserLoginContainer(user, this.userController.getUserPassword()); + + try { + // Call bean + User confirmedUser = this.loginBean.validateUserAccountStatus(container); + + // All fine here so set it here + this.setLoggedInUser(confirmedUser); + + // Set template to "login" + this.setTemplateType("login"); //NOI18N + + // Fire event away. Keep this last before return statement. + this.loginEvent.fire(new UserLoginEvent(confirmedUser)); + + // All fine + return "login"; //NOI18N + } catch (final UserNotFoundException | UserStatusLockedException | UserStatusUnconfirmedException | UserPasswordMismatchException ex) { + // Throw again + throw new FaceletException(ex); + } + } + + @Override + public User getLoggedInUser () { + return this.loggedInUser; + } + + @Override + public void setLoggedInUser (final User loggedInUser) { + this.loggedInUser = loggedInUser; + } + + @Override + public String getTemplateType () { + return this.templateType; + } + + @Override + public void setTemplateType (final String templateType) { + this.templateType = templateType; + } + + @Override + public boolean isGuest () { + return (!this.isUserLoggedIn()); + } + + @Override + public boolean isUserLoggedIn () { + // Trace message + // NOISY: System.out.println(MessageFormat.format("UserLoginWebSessionBean:isUserLoggedIn: this.loggedInUser={0},this.templateType={1} - CALLED!", this.getLoggedInUser(), this.getTemplateType())); + + // Compare instance + this.userLoggedIn = ((this.getLoggedInUser() instanceof User) && (Objects.equals(this.getLoggedInUser().getUserAccountStatus(), UserAccountStatus.CONFIRMED))); + + // Trace message + // NOISY: System.out.println(MessageFormat.format("UserLoginWebSessionBean:isUserLoggedIn: this.userLoggedIn={0} - EXIT!", this.userLoggedIn)); + + // Return it + return this.userLoggedIn; + } + + @Override + public boolean isInvisible () { + // Check on login + if (!this.isUserLoggedIn()) { + // Not logged in! + throw new IllegalStateException("isInvisible() has been invoked for a guest."); //NOI18N + } + + // Check logged-in first, then invisibility + return this.getLoggedInUser().getUserProfileMode().equals(ProfileMode.INVISIBLE); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java b/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java new file mode 100644 index 00000000..31d9b212 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.login; + +import java.io.Serializable; +import org.mxchange.jusercore.model.user.User; + +/** + * An interface for registration web controllers + *

+ * @author Roland Haeder + */ +public interface UserLoginWebSessionController extends Serializable { + + /** + * Getter for template type + *

+ * @return Template type + */ + String getTemplateType (); + + /** + * Setter for template type + *

+ * @param templateType Template type + */ + void setTemplateType (final String templateType); + + /** + * Logins the user, if the account is found, confirmed and unlocked. + *

+ * @return Redirect target + */ + String doLogin (); + + /** + * Getter for logged-in user instance + *

+ * @return Logged-in user instance + */ + User getLoggedInUser (); + + /** + * Setter for logged-in user instance + *

+ * @param loggedInUser Logged-in user instance + */ + void setLoggedInUser (final User loggedInUser); + + /** + * Checks whether the user is logged-in + *

+ * @return Whether the user is logged-in + */ + boolean isUserLoggedIn (); + + /** + * Is this truly a guest? + *

+ * @return Whether the user is truly a guest + */ + boolean isGuest (); + + /** + * Whether the currently logged-in user is invisible + *

+ * @return Whether the currently logged-in user is invisible + */ + boolean isInvisible (); +} diff --git a/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java b/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java new file mode 100644 index 00000000..c10dff0c --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.profile; + +import java.text.MessageFormat; +import javax.enterprise.context.RequestScoped; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Inject; +import javax.inject.Named; +import org.mxchange.addressbook.beans.login.UserLoginWebSessionController; +import org.mxchange.addressbook.beans.user.UserWebSessionController; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; + +/** + * A web request bean for user profiles + *

+ * @author Roland Haeder + */ +@Named (value = "profileController") +@RequestScoped +public class UserProfileWebRequestBean implements UserProfileWebRequestController { + + /** + * Serial number + */ + private static final long serialVersionUID = 187_687_145_286_710L; + + /** + * Login controller + */ + @Inject + private UserLoginWebSessionController loginController; + + /** + * User instance + */ + private User user; + + /** + * User controller + */ + @Inject + private UserWebSessionController userController; + + @Override + public User getUser () { + return this.user; + } + + @Override + public void setUser (final User user) { + this.user = user; + } + + @Override + public boolean isProfileLinkVisible () { + // Check on user + if (this.getUser() == null) { + /* + * Not set, means wrong invocation of this method as the user + * instance needs to be set first. + */ + throw new NullPointerException("this.user is null"); //NOI18N + } else if (this.getUser().getUserId() == null) { + /* + * If the id number is not set it means that the user instance has + * not been persisted and the JPA has not been flushed. Or a + * "virgin" instance (e.g. from registration) has been used. + */ + throw new NullPointerException("this.user.userId is null"); //NOI18N + } else if (this.getUser().getUserId() < 1) { + /* + * The id number is set invalid for an unknown reason. + */ + throw new IllegalArgumentException(MessageFormat.format("this.user.userId={0} is invalid", this.getUser().getUserId())); //NOI18N + } else if (this.getUser().getUserProfileMode() == null) { + /* + * Possibly an out-dated user profile is being used. This should not + * happen. + */ + throw new NullPointerException("this.user.userProfileMode is null"); //NOI18N + } + + // Get profile mode from user instance (safe now) + ProfileMode profileMode = this.getUser().getUserProfileMode(); + + // Check all conditions (except for admin) + // TODO: Add admin role somehow? + return ((profileMode.equals(ProfileMode.PUBLIC)) || + (this.loginController.isUserLoggedIn()) && (profileMode.equals(ProfileMode.MEMBERS))); + } + + @Override + public boolean isProfileLinkVisibleById (final Long userId) { + // Init user instance + User u = null; + + try { + // Try to get it + u = this.userController.lookupUserById(userId); + } catch (final UserNotFoundException ex) { + // Throw again + throw new FaceletException(ex); + } + + // Set it here + this.setUser(u); + + // Is it null? + if (null == u) { + // Not found, not visible. + return false; + } + + // Ask other method + return this.isProfileLinkVisible(); + } + + @Override + public boolean isProfileLinkVisibleByUser (final User user) { + // Is it correctly set? + if (null == user) { + // Throw NPE + throw new NullPointerException("user is null"); + } else if (user.getUserId() == null) { + // Throw NPE again + throw new NullPointerException("user.userId is null"); + } else if (user.getUserId() < 1) { + // Invalid user id set + throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid.", user.getUserId())); + } + + // Set user here + this.setUser(user); + + // Ask other method + return this.isProfileLinkVisible(); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java b/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java new file mode 100644 index 00000000..e7306887 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.profile; + +import java.io.Serializable; +import org.mxchange.jusercore.model.user.User; + +/** + * A bean interface for user profiles + *

+ * @author Roland Haeder + */ +public interface UserProfileWebRequestController extends Serializable { + + /** + * Checks if the current user profile link is visible + *

+ * @return Whether the profile link is visible + */ + boolean isProfileLinkVisible (); + + /** + * Checks if the user profile link is visible + *

+ * @param userId User id + *

+ * @return Whether the profile link is visible + */ + boolean isProfileLinkVisibleById (final Long userId); + + /** + * Checks if given user's profile is visible + *

+ * @param user User instance to check + *

+ * @return Whether the user's profile is visible + */ + boolean isProfileLinkVisibleByUser (final User user); + + /** + * Getter for user instance + *

+ * @return User instance + */ + User getUser (); + + /** + * Setter for user instance + *

+ * @param user User instance + */ + void setUser (final User user); +} diff --git a/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java new file mode 100644 index 00000000..fb45a7b1 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.profilemode; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Named; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; + +/** + * A profile mode bean + *

+ * @author Roland Haeder + */ +@Named ("profileMode") +@ApplicationScoped +public class ProfileModeWebApplicationBean implements ProfileModeWebApplicationController { + + /** + * Serial number + */ + private static final long serialVersionUID = 835_482_364_189L; + + /** + * Default constructor + */ + public ProfileModeWebApplicationBean () { + } + + @Override + public ProfileMode[] getAllProfileModes () { + // Return it + return ProfileMode.values(); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java new file mode 100644 index 00000000..74e512fa --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.profilemode; + +import java.io.Serializable; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; + +/** + * An interface for data beans + *

+ * @author Roland Haeder + */ +public interface ProfileModeWebApplicationController extends Serializable { + + /** + * Getter for all genders as array + *

+ * @return All genders as array + */ + ProfileMode[] getAllProfileModes (); +} diff --git a/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java new file mode 100644 index 00000000..c4ce4892 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.register; + +import java.text.MessageFormat; +import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Event; +import javax.enterprise.inject.Any; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Inject; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.user.UserWebSessionController; +import org.mxchange.jusercore.events.registration.RegisteredUserEvent; +import org.mxchange.jusercore.events.registration.UserRegisteredEvent; +import org.mxchange.jusercore.exceptions.DataRepeatMismatchException; +import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException; +import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException; +import org.mxchange.jusercore.model.register.UserRegistrationSessionBeanRemote; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.UserUtils; +import org.mxchange.jusercore.model.user.status.UserAccountStatus; + +/** + * A web bean for user registration + *

+ * @author Roland Haeder + */ +@Named ("registerController") +@SessionScoped +public class UserRegisterWebSessionBean implements UserRegisterWebSessionController { + + /** + * Serial number + */ + private static final long serialVersionUID = 47_828_986_719_691_592L; + + /** + * Reemote register session bean + */ + private UserRegistrationSessionBeanRemote registerBean; + + /** + * An en event fireable when a new user has registered + */ + @Inject + @Any + private Event registeredEvent; + + /** + * User controller + */ + @Inject + private UserWebSessionController userController; + + /** + * Default constructor + */ + public UserRegisterWebSessionBean () { + try { + // Get initial context + Context context = new InitialContext(); + + // Try to lookup + this.registerBean = (UserRegistrationSessionBeanRemote) context.lookup("ejb/stateless-register"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw + throw new FaceletException(ex); + } + } + + @Override + public String doRegister () { + // Get user instance + User user = this.userController.createUserInstance(); + + // Is the user already used? + if (null == user) { + // user must be set + throw new NullPointerException("user is null"); //NOI18N + } else if (!this.userController.isRequiredPersonalDataSet()) { + // Not all required fields are set + throw new FaceletException("Not all required fields are set."); //NOI18N + } else if (this.userController.isUserNameRegistered(user)) { + // User name is already used + throw new FaceletException(new UserNameAlreadyRegisteredException(user)); + } else if (this.userController.isEmailAddressRegistered(user)) { + // Email address has already been taken + throw new FaceletException(new EmailAddressAlreadyRegisteredException(user)); + } else if (!this.userController.isSameEmailAddressEntered()) { + // Not same email address entered + throw new FaceletException(new DataRepeatMismatchException(MessageFormat.format("Email addresses not matching: {0} != {1}", this.userController.getEmailAddress(), this.userController.getEmailAddressRepeat()))); //NOI18N + } else if (!this.userController.isSamePasswordEntered()) { + // Not same password entered + throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N + } + + // Encrypt password + String encryptedPassword = UserUtils.encryptPassword(this.userController.getUserPassword()); + + // Set it here + user.setUserEncryptedPassword(encryptedPassword); + + // For debugging/programming only: + user.setUserAccountStatus(UserAccountStatus.CONFIRMED); + + try { + // Call bean + User registeredUser = this.registerBean.registerUser(user); + + // Fire event + this.registeredEvent.fire(new RegisteredUserEvent(registeredUser)); + + // All fine, redirect to proper page + return "register_done"; //NOI18N + } catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) { + // Continue to throw + throw new FaceletException(ex); + } + } +} diff --git a/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java b/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java new file mode 100644 index 00000000..6a9923b9 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.register; + +import java.io.Serializable; + +/** + * An interface for registration web controllers + *

+ * @author Roland Haeder + */ +public interface UserRegisterWebSessionController extends Serializable { + + /** + * Registers the user, if not found. Otherwise this method should throw an + * exception. + *

+ * @return Redirection target + */ + String doRegister (); +} diff --git a/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java new file mode 100644 index 00000000..30760580 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.shares; + +import java.text.MessageFormat; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import javax.annotation.PostConstruct; +import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Event; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Any; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Inject; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.login.UserLoginWebSessionController; +import org.mxchange.addressbook.events.sharing.AddressbookSharingEvent; +import org.mxchange.addressbook.events.sharing.StartedAddressbookSharingEvent; +import org.mxchange.addressbook.events.sharing.type.SharingType; +import org.mxchange.addressbook.exceptions.UserAlreadySharingAddressbookException; +import org.mxchange.addressbook.model.addressbook.Addressbook; +import org.mxchange.addressbook.model.addressbook.shared.ShareableAddressbook; +import org.mxchange.addressbook.model.shared.SharedAddressbooksSessionBeanRemote; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; + +/** + * A bean for sharing address books with other users + *

+ * @author Roland Haeder + */ +@Named (value = "shareController") +@SessionScoped +public class SharesWebSessionBean implements SharesWebSessionController { + + /** + * Serial number + */ + private static final long serialVersionUID = 19_868_976_871_976_780L; + + /** + * Cached flag whether the user is sharing address books + */ + private Boolean isUserSharing = null; + + /** + * Login controller injection + */ + @Inject + private UserLoginWebSessionController loginController; + + /** + * Share instance + */ + private ShareableAddressbook share; + + /** + * Remote bean for sharing address books + */ + private SharedAddressbooksSessionBeanRemote shareBean; + + /** + * A list of all user's shared (with others) address books + */ + private List sharedAddressbooks; + + /** + * User id of sharee + */ + private Long shareeUserId; + + /** + * An event triggered when address book sharing starts or ends + */ + @Inject + @Any + private Event sharingEvent; + + /** + * Default constructor + */ + public SharesWebSessionBean () { + // Try it + try { + // Get initial context + Context context = new InitialContext(); + + // Look up bean + this.shareBean = (SharedAddressbooksSessionBeanRemote) context.lookup("ejb/stateless-share"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw + throw new FaceletException(ex); + } + } + + @Override + public void afterAdressbookShareEnded (final @Observes AddressbookSharingEvent event) { + // Validate parameter + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getSharingType() == null) { + // Throw NPE + throw new NullPointerException("event.sharingType is null"); //NOI18N + } else if (event.getSharingType() != SharingType.ENDED) { + // Wrong event + return; + } + + // Validate event + this.validateEvent(event); + + // Add it to list + this.sharedAddressbooks.remove(event.getShareableAddressbook()); + } + + @Override + public void afterAdressbookShareStarted (final @Observes AddressbookSharingEvent event) { + // Validate parameter + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getSharingType() == null) { + // Throw NPE + throw new NullPointerException("event.sharingType is null"); //NOI18N + } else if (event.getSharingType() != SharingType.STARTED) { + // Wrong event + return; + } + + // Validate event + this.validateEvent(event); + + // Add it to list + this.sharedAddressbooks.add(event.getShareableAddressbook()); + } + + @Override + public List allShares () { + // Is the user logged in? + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + return Collections.unmodifiableList(this.sharedAddressbooks); + } + + @Override + public ShareableAddressbook getShare () { + return this.share; + } + + @Override + public void setShare (final ShareableAddressbook share) { + this.share = share; + } + + @Override + public Long getShareeUserId () { + return this.shareeUserId; + } + + @Override + public void setShareeUserId (final Long shareeUserId) { + this.shareeUserId = shareeUserId; + } + + @PostConstruct + public void init () { + // Check conditions + if (!this.loginController.isUserLoggedIn()) { + // No, then throw exception + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } + + // Init share list + this.sharedAddressbooks = this.shareBean.allSharedAddressbooks(this.loginController.getLoggedInUser()); + } + + @Override + public boolean isShareeUserIdEmpty () { + return (!this.isShareeUserIdSet()); + } + + @Override + public boolean isShareeUserIdSet () { + return ((this.getShareeUserId() instanceof Long) && (this.getShareeUserId() > 0)); + } + + @Override + public boolean isSharingAddressbooks () { + // Only to be called for logged-in users + if (!this.loginController.isUserLoggedIn()) { + // Not logged in + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } else if (this.isUserSharing instanceof Boolean) { + // Return cached value + return this.isUserSharing; + } + + // Call the proper bean + this.isUserSharing = this.shareBean.isUserSharingAddressbooks(this.loginController.getLoggedInUser()); + + // Return it + return this.isUserSharing; + } + + @Override + public String startSharing (final User user, final Addressbook addressbook) { + // Check conditions + if (!this.loginController.isUserLoggedIn()) { + // No, then throw exception + throw new FaceletException("This method can only be called as logged-in user."); //NOI18N + } else if (null == user) { + // Throw NPE + throw new NullPointerException("user is null"); //NOI18N + } else if (user.getUserId() == null) { + // Throw NPE again + throw new NullPointerException("user.userId is null"); //NOI18N + } else if (user.getUserId() < 1) { + // Invalid id number + throw new IllegalStateException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N + } else if (Objects.equals(user, this.loginController.getLoggedInUser())) { + // Sharing with yourself! + throw new IllegalStateException("User tries to share with himself."); //NOI18N + } else if (null == addressbook) { + // Throw NPE again + throw new NullPointerException("addressbook is null"); //NOI18N + } else if (addressbook.getAddressbookId() == null) { + // Throw NPE again + throw new NullPointerException("addressbook.addressbookId is null"); //NOI18N + } else if (addressbook.getAddressbookId() < 1) { + // Invalid id number + throw new IllegalArgumentException(MessageFormat.format("addressbook.addressbookId={0} is invalid.", addressbook.getAddressbookId())); //NOI18N + } else if (!Objects.equals(addressbook.getAddressbookUser(), this.loginController.getLoggedInUser())) { + // Not the same user! + throw new IllegalStateException(MessageFormat.format("Address book id {0} owner id {1} mismatching logged-in user id {2}", addressbook.getAddressbookId(), addressbook.getAddressbookUser().getUserId(), this.loginController.getLoggedInUser().getUserId())); //NOI18N + } else if (this.loginController.getLoggedInUser().getUserProfileMode() == ProfileMode.INVISIBLE) { + // User is invisible + throw new FaceletException(MessageFormat.format("user {0} is invisible and cannot start sharing address books.", this.loginController.getLoggedInUser().getUserId())); //NOI18N + } else if (user.getUserProfileMode() == ProfileMode.INVISIBLE) { + // User is invisible + throw new FaceletException(MessageFormat.format("user {0} is invisible and cannot be selected for sharing.", user.getUserId())); //NOI18N + } + + try { + // Init sharing + ShareableAddressbook shared = this.shareBean.startSharing(user, addressbook); + + // TODO Set it here + this.setShare(shared); + + /// Trigger event + this.sharingEvent.fire(new StartedAddressbookSharingEvent(shared)); + } catch (final UserAlreadySharingAddressbookException ex) { + // Throw again + throw new FaceletException(ex); + } + + // TODO Unfinished + return null; + } + + /** + * Validates given event for all values and throws exceptions + *

+ * @param event Event to validate + */ + private void validateEvent (final AddressbookSharingEvent event) { + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getSharingType() == null) { + // Throw NPE + throw new NullPointerException("event.sharingType is null"); //NOI18N + } else if (event.getShareableAddressbook() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareId() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareId is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareId() < 1) { + // Throw NPE again + throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareId={0} is invalid", event.getShareableAddressbook().getShareId())); //NOI18N + } else if (event.getShareableAddressbook().getShareAddressbook() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareAddressbook is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareAddressbook().getAddressbookId() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareAddressbook.addressbookId is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareAddressbook().getAddressbookId() < 1) { + // Throw NPE again + throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareAddressbook.addressbookId={0} is invalid", event.getShareableAddressbook().getShareAddressbook().getAddressbookId())); //NOI18N + } else if (event.getShareableAddressbook().getShareUserOwner() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareUserOwner is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareUserOwner().getUserId() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareUserOwner.userId is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareUserOwner().getUserId() < 1) { + // Throw NPE again + throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareUserOwner.userId={0} is invalid", event.getShareableAddressbook().getShareUserOwner().getUserId())); //NOI18N + } else if (event.getShareableAddressbook().getShareUserSharee() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareUserSharee is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareUserSharee().getUserId() == null) { + // Throw NPE again + throw new NullPointerException("event.shareableAddressbook.shareUserSharee.userId is null"); //NOI18N + } else if (event.getShareableAddressbook().getShareUserSharee().getUserId() < 1) { + // Throw NPE again + throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareUserSharee.userId={0} is invalid", event.getShareableAddressbook().getShareUserOwner().getUserId())); //NOI18N + } + } +} diff --git a/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java b/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java new file mode 100644 index 00000000..1be32834 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.shares; + +import java.io.Serializable; +import java.util.List; +import org.mxchange.addressbook.events.sharing.AddressbookSharingEvent; +import org.mxchange.addressbook.model.addressbook.Addressbook; +import org.mxchange.addressbook.model.addressbook.shared.ShareableAddressbook; +import org.mxchange.jusercore.model.user.User; + +/** + * Controller interface sharing address books + *

+ * @author Roland Haeder + */ +public interface SharesWebSessionController extends Serializable { + + /** + * Observer method for ended sharing events + *

+ * @param event Event instance + */ + void afterAdressbookShareEnded (final AddressbookSharingEvent event); + + /** + * Observer method for started sharing events + *

+ * @param event Event instance + */ + void afterAdressbookShareStarted (final AddressbookSharingEvent event); + + /** + * Returns a list of all address books the user is sharing with others. + *

+ * @return List of all shared address books + */ + List allShares (); + + /** + * Getter for share instance + *

+ * @return Share instance + */ + ShareableAddressbook getShare (); + + /** + * Setter for share instance + *

+ * @param share Share instance + */ + void setShare (final ShareableAddressbook share); + + /** + * Getter for sharee's user id + *

+ * @return Sharee's user id + */ + Long getShareeUserId (); + + /** + * Setter for sharee's user id + *

+ * @param shareeUserId Sharee's user id + */ + void setShareeUserId (final Long shareeUserId); + + /** + * Checks if the sharee's user id is empty. + *

+ * @return Whether the sharee's user id is empty. + */ + boolean isShareeUserIdEmpty (); + + /** + * Checks whether the sharee's user id is set + *

+ * @return Whether the sharee's user id is set + */ + boolean isShareeUserIdSet (); + + /** + * Checks wether the current user is sharing address books with others + *

+ * @return Whether the current user is sharing address books + */ + boolean isSharingAddressbooks (); + + /** + * Starts an address book share between currently logged-in user and + * assigned user for current address book. + *

+ * @param user User instance + * @param addressbook Address book instance + * @return Redirect target + */ + String startSharing (final User user, final Addressbook addressbook); +} diff --git a/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java new file mode 100644 index 00000000..aa64620c --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java @@ -0,0 +1,82 @@ +package org.mxchange.addressbook.beans.smsprovider; + +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +import java.util.Collections; +import java.util.List; +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote; +import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider; + +/** + * A SMS provider bean + *

+ * @author Roland Haeder + */ +@Named ("cellphone") +@ApplicationScoped +public class SmsProviderWebApplicationBean implements SmsProviderWebApplicationController { + + /** + * Serial number + */ + private static final long serialVersionUID = 176_985_298_681_742_960L; + + /** + * Remote country EJB + */ + private AddressbookSmsProviderSingletonBeanRemote cellphoneBean; + + /** + * List of all countries + */ + private List cellphoneList; + + /** + * Default constructor + */ + public SmsProviderWebApplicationBean () { + // Try this + try { + // Get initial context + Context context = new InitialContext(); + + // Try to lookup the bean + this.cellphoneBean = (AddressbookSmsProviderSingletonBeanRemote) context.lookup("ejb/addressbook-singleton-smsprovider"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw + throw new FaceletException(ex); + } + } + + @Override + public List allSmsProvider () { + // Return "cached" version + return Collections.unmodifiableList(this.cellphoneList); + } + + @PostConstruct + public void init () { + this.cellphoneList = this.cellphoneBean.allSmsProvider(); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java new file mode 100644 index 00000000..917ddcbd --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java @@ -0,0 +1,36 @@ +package org.mxchange.addressbook.beans.smsprovider; + +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +import java.io.Serializable; +import java.util.List; +import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider; + +/** + * An interface for country beans + *

+ * @author Roland Haeder + */ +public interface SmsProviderWebApplicationController extends Serializable { + + /** + * A list of all countries + *

+ * @return All countries + */ + List allSmsProvider (); +} diff --git a/src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java new file mode 100644 index 00000000..cc31bdc1 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java @@ -0,0 +1,866 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.user; + +import java.text.MessageFormat; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import javax.annotation.PostConstruct; +import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Observes; +import javax.faces.view.facelets.FaceletException; +import javax.inject.Inject; +import javax.inject.Named; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.login.UserLoginWebSessionController; +import org.mxchange.jcontacts.contact.Contact; +import org.mxchange.jcontacts.contact.UserContact; +import org.mxchange.jcontacts.contact.gender.Gender; +import org.mxchange.jcountry.data.Country; +import org.mxchange.jphone.phonenumbers.cellphone.CellphoneNumber; +import org.mxchange.jphone.phonenumbers.cellphone.DialableCellphoneNumber; +import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber; +import org.mxchange.jphone.phonenumbers.fax.FaxNumber; +import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber; +import org.mxchange.jphone.phonenumbers.landline.LandLineNumber; +import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider; +import org.mxchange.jusercore.events.login.UserLoggedInEvent; +import org.mxchange.jusercore.events.registration.UserRegisteredEvent; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.model.user.LoginUser; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.UserSessionBeanRemote; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; + +/** + * A user bean (controller) + *

+ * @author Roland Haeder + */ +@Named ("userController") +@SessionScoped +public class UserWebSessionBean implements UserWebSessionController { + + /** + * Serial number + */ + private static final long serialVersionUID = 542_145_347_916L; + + /////////////////////// Properties ///////////////////// + /** + * Birth day + */ + private Date birthday; + + /** + * Cellphone number's carrier + */ + private SmsProvider cellphoneCarrier; + + /** + * Cellphone number + */ + private Long cellphoneNumber; + + /** + * City + */ + private String city; + + /** + * Optional comments + */ + private String comment; + + /** + * Country instance + */ + private Country country; + + /** + * Email address + */ + private String emailAddress; + + /** + * Email address list + */ + private List emailAddressList; + + /** + * Email address repeated + */ + private String emailAddressRepeat; + + /** + * Family name + */ + private String familyName; + + /** + * Fax number's area code + */ + private Integer faxAreaCode; + + /** + * Country instance for fax number + */ + private Country faxCountry; + + /** + * Fax number + */ + private Long faxNumber; + + /** + * First name + */ + private String firstName; + + /** + * Gender instance + */ + private Gender gender; + + /** + * House number + */ + private Short houseNumber; + + /** + * Phone number area code + */ + private Integer phoneAreaCode; + + /** + * Country instance for phone number + */ + private Country phoneCountry; + + /** + * Phone number + */ + private Long phoneNumber; + + /** + * Street + */ + private String street; + + /** + * Remote user bean + */ + private final UserSessionBeanRemote userBean; + + /** + * User id + */ + private Long userId; + + /** + * User name + */ + private String userName; + + /** + * User name list + */ + private List userNameList; + + /** + * User password (unencrypted from web form) + */ + private String userPassword; + + /** + * User password repeated (unencrypted from web form) + */ + private String userPasswordRepeat; + + /** + * Whether the user wants a public profile + */ + private ProfileMode userProfileMode; + + /** + * ZIP code + */ + private Integer zipCode; + + /** + * A list of all public user profiles + */ + private List visibleUserList; + + /** + * Login bean (controller) + */ + @Inject + private UserLoginWebSessionController loginController; + + /** + * Default constructor + */ + public UserWebSessionBean () { + // Set gender to UNKNOWN + this.gender = Gender.UNKNOWN; + + // Try it + try { + // Get initial context + Context context = new InitialContext(); + + // Try to lookup + this.userBean = (UserSessionBeanRemote) context.lookup("ejb/stateless-user"); //NOI18N + } catch (final NamingException e) { + // Throw again + throw new FaceletException(e); + } + } + + @Override + public void afterUserLogin (final @Observes UserLoggedInEvent event) { + // Trace message + System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: event={0} - CALLED!", event)); //NOI18N + + // event should not be null + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getUser() == null) { + // Throw NPE again + throw new NullPointerException("event.user is null"); //NOI18N + } else if (event.getUser().getUserId() == null) { + // userId is null + throw new NullPointerException("event.user.userId is null"); //NOI18N + } else if (event.getUser().getUserId() < 1) { + // Not avalid id + throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUser(), event.getUser().getUserId())); //NOI18N + } + + // Re-initialize list + this.visibleUserList = this.userBean.allMemberPublicVisibleUsers(); + + // Trace message + System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: this.visibleUserList.size()={0} - EXIT!", this.visibleUserList.size())); //NOI18N + } + + @Override + public void afterRegistrationEvent (final @Observes UserRegisteredEvent event) { + // Trace message + System.out.println(MessageFormat.format("UserWebBean:afterRegistration: event={0} - CALLED!", event)); //NOI18N + + // event should not be null + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getUser() == null) { + // Throw NPE again + throw new NullPointerException("event.user is null"); //NOI18N + } else if (event.getUser().getUserId() == null) { + // userId is null + throw new NullPointerException("event.user.userId is null"); //NOI18N + } else if (event.getUser().getUserId() < 1) { + // Not avalid id + throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUser(), event.getUser().getUserId())); //NOI18N + } + + // Get user instance + User registeredUser = event.getUser(); + + // Debug message + System.out.println(MessageFormat.format("UserWebBean:afterRegistration: registeredUser={0}", registeredUser)); //NOI18N + + // Copy all data from registered->user + this.copyUser(registeredUser); + + // Add user name and email address + this.addUserNameEmailAddress(registeredUser); + + // Clear all data + this.clearData(); + + // Set user id again + this.setUserId(registeredUser.getUserId()); + + // Is the account public? + if (registeredUser.getUserProfileMode().equals(ProfileMode.PUBLIC)) { + // Also add it to this list + this.visibleUserList.add(registeredUser); + } + + // Trace message + System.out.println("UserWebBean:afterRegistration: EXIT!"); //NOI18N + } + + @Override + public List allVisibleUsers () { + // Return it + return Collections.unmodifiableList(this.visibleUserList); + } + + @Override + public User createUserInstance () { + // User message + //this.getLogger().logTrace("createUserInstance: CALLED!"); + + // Required personal data must be set + assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N + + // Create new user instance + User user = new LoginUser(); + user.setUserName(this.getUserName()); + user.setUserProfileMode(this.getUserProfileMode()); + user.setUserCreated(new GregorianCalendar()); + + // Generate phone number + DialableLandLineNumber phone = new LandLineNumber(this.getPhoneCountry(), this.getPhoneAreaCode(), this.getPhoneNumber(), new GregorianCalendar()); + DialableCellphoneNumber cellphone = new CellphoneNumber(this.getCellphoneCarrier(), this.getCellphoneNumber(), new GregorianCalendar()); + DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber(), new GregorianCalendar()); + + // Create new contact + Contact contact = new UserContact(this.getGender(), this.getFirstName(), this.getFamilyName()); + contact.setContactStreet(this.getStreet()); + contact.setContactHouseNumber(this.getHouseNumber()); + contact.setContactZipCode(this.getZipCode()); + contact.setContactCity(this.getCity()); + contact.setContactCountry(this.getCountry()); + contact.setContactEmailAddress(this.getEmailAddress()); + + // Don't set null or wrong references + if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneCountry() instanceof Country) && (this.getPhoneAreaCode() != null) && (this.getPhoneNumber() != null) && (this.getPhoneAreaCode() > 0) && (this.getPhoneNumber() > 0)) { + // Now the number must be given + if (phone.getPhoneAreaCode() == null) { + // Is null + throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N + } else if (phone.getPhoneAreaCode() < 1) { + // Abort here + throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N + } else if (phone.getPhoneNumber() == null) { + // Is null + throw new NullPointerException("phone.phoneNumber is null"); //NOI18N + } else if (phone.getPhoneNumber() < 1) { + // Abort here + throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N + } + + // Set phone number + contact.setContactPhoneNumber(phone); + } + + // Don't set null or wrong references + if ((fax instanceof DialableFaxNumber) && (fax.getPhoneCountry() instanceof Country) && (this.getFaxAreaCode() != null) && (this.getFaxNumber() != null) && (this.getFaxAreaCode() > 0) && (this.getFaxNumber() > 0)) { + // Now the number must be given + if (fax.getPhoneAreaCode() == null) { + // Is null + throw new NullPointerException("fax.phoneAreaCode is null"); //NOI18N + } else if (fax.getPhoneAreaCode() < 1) { + // Abort here + throw new IllegalArgumentException("fax.phoneAreaCode is zero or below."); //NOI18N + } else if (fax.getPhoneNumber() == null) { + // Is null + throw new NullPointerException("fax.phoneNumber is null"); //NOI18N + } else if (fax.getPhoneNumber() < 1) { + // Abort here + throw new IllegalArgumentException("fax.phoneNumber is zero or below."); //NOI18N + } + + // Set fax number + contact.setContactFaxNumber(fax); + } + + // Is the provider set? + if ((cellphone instanceof DialableCellphoneNumber) && (this.getCellphoneCarrier() instanceof SmsProvider) && (this.getCellphoneNumber() != null) && (this.getCellphoneNumber() > 0)) { + // Is the number set? + if (cellphone.getPhoneNumber() == null) { + // Is null + throw new NullPointerException("cellphone.phoneNumber is null"); //NOI18N + } else if (cellphone.getPhoneNumber() < 1) { + // Abort here + throw new IllegalArgumentException("cellphone.phoneNumber is zero or below."); //NOI18N + } + + // Set cellphone number + contact.setContactCellphoneNumber(cellphone); + } + + contact.setContactBirthday(this.getBirthday()); + contact.setContactComment(this.getComment()); + + // Created timestamp and ownContact + contact.setContactCreated(new GregorianCalendar()); + contact.setContactOwnContact(Boolean.TRUE); + + // Set contact in user + user.setUserContact(contact); + + // Trace message + //this.getLogger().logTrace(MessageFormat.format("createUserInstance: user={0} - EXIT!", user)); + // Return it + return user; + } + + @Override + public Date getBirthday () { + return this.birthday; + } + + @Override + public void setBirthday (final Date birthday) { + this.birthday = birthday; + } + + @Override + public SmsProvider getCellphoneCarrier () { + return this.cellphoneCarrier; + } + + @Override + public void setCellphoneCarrier (final SmsProvider cellphoneCarrier) { + this.cellphoneCarrier = cellphoneCarrier; + } + + @Override + public Long getCellphoneNumber () { + return this.cellphoneNumber; + } + + @Override + public void setCellphoneNumber (Long cellphoneNumber) { + this.cellphoneNumber = cellphoneNumber; + } + + @Override + public String getCity () { + return this.city; + } + + @Override + public void setCity (final String city) { + this.city = city; + } + + @Override + public String getComment () { + return this.comment; + } + + @Override + public void setComment (final String comment) { + this.comment = comment; + } + + @Override + public Country getCountry () { + return this.country; + } + + @Override + public void setCountry (final Country country) { + this.country = country; + } + + @Override + public String getEmailAddress () { + return this.emailAddress; + } + + @Override + public void setEmailAddress (final String emailAddress) { + this.emailAddress = emailAddress; + } + + @Override + public String getEmailAddressRepeat () { + return this.emailAddressRepeat; + } + + @Override + public void setEmailAddressRepeat (final String emailAddressRepeat) { + this.emailAddressRepeat = emailAddressRepeat; + } + + @Override + public String getFamilyName () { + return this.familyName; + } + + @Override + public void setFamilyName (final String familyName) { + this.familyName = familyName; + } + + @Override + public Integer getFaxAreaCode () { + return this.faxAreaCode; + } + + @Override + public void setFaxAreaCode (final Integer faxAreaCode) { + this.faxAreaCode = faxAreaCode; + } + + @Override + public Country getFaxCountry () { + return this.faxCountry; + } + + @Override + public void setFaxCountry (final Country faxCountry) { + this.faxCountry = faxCountry; + } + + @Override + public Long getFaxNumber () { + return this.faxNumber; + } + + @Override + public void setFaxNumber (final Long faxNumber) { + this.faxNumber = faxNumber; + } + + @Override + public String getFirstName () { + return this.firstName; + } + + @Override + public void setFirstName (final String firstName) { + this.firstName = firstName; + } + + @Override + public Gender getGender () { + return this.gender; + } + + @Override + public void setGender (final Gender gender) { + this.gender = gender; + } + + @Override + public Short getHouseNumber () { + return this.houseNumber; + } + + @Override + public void setHouseNumber (final Short houseNumber) { + this.houseNumber = houseNumber; + } + + @Override + public Integer getPhoneAreaCode () { + return this.phoneAreaCode; + } + + @Override + public void setPhoneAreaCode (final Integer phoneAreaCode) { + this.phoneAreaCode = phoneAreaCode; + } + + @Override + public Country getPhoneCountry () { + return this.phoneCountry; + } + + @Override + public void setPhoneCountry (final Country phoneCountry) { + this.phoneCountry = phoneCountry; + } + + @Override + public Long getPhoneNumber () { + return this.phoneNumber; + } + + @Override + public void setPhoneNumber (final Long phoneNumber) { + this.phoneNumber = phoneNumber; + } + + @Override + public String getStreet () { + return this.street; + } + + @Override + public void setStreet (final String street) { + this.street = street; + } + + @Override + public Long getUserId () { + return this.userId; + } + + @Override + public void setUserId (final Long userId) { + this.userId = userId; + } + + @Override + public String getUserName () { + return this.userName; + } + + @Override + public void setUserName (final String userName) { + this.userName = userName; + } + + @Override + public String getUserPassword () { + return this.userPassword; + } + + @Override + public void setUserPassword (final String userPassword) { + this.userPassword = userPassword; + } + + @Override + public String getUserPasswordRepeat () { + return this.userPasswordRepeat; + } + + @Override + public void setUserPasswordRepeat (final String userPasswordRepeat) { + this.userPasswordRepeat = userPasswordRepeat; + } + + @Override + public ProfileMode getUserProfileMode () { + return this.userProfileMode; + } + + @Override + public void setUserProfileMode (final ProfileMode userProfileMode) { + this.userProfileMode = userProfileMode; + } + + @Override + public Integer getZipCode () { + return this.zipCode; + } + + @Override + public void setZipCode (final Integer zipCode) { + this.zipCode = zipCode; + } + + @PostConstruct + public void init () { + // Get full user name list for reducing EJB calls + this.userNameList = this.userBean.getUserNameList(); + + // Get full email address list for reducing EJB calls + this.emailAddressList = this.userBean.getEmailAddressList(); + + // Is the user logged-in? + if (this.loginController.isUserLoggedIn()) { + // Is logged-in, so load also users visible to memebers + this.visibleUserList = this.userBean.allMemberPublicVisibleUsers(); + } else { + // Initialize user list + this.visibleUserList = this.userBean.allPublicUsers(); + } + } + + @Override + public boolean isEmailAddressRegistered (final User user) { + return ((this.emailAddressList instanceof List) && (this.emailAddressList.contains(user.getUserContact().getContactEmailAddress()))); + } + + @Override + public boolean isRequiredPersonalDataSet () { + return ((this.getUserName() != null) && + (this.getUserProfileMode() != null) && + (this.getGender() != null) && + (this.getFirstName() != null) && + (this.getFamilyName() != null) && + (this.getStreet() != null) && + (this.getHouseNumber() != null) && + (this.getZipCode() != null) && + (this.getCity() != null) && + (this.getEmailAddress() != null) && + (this.getEmailAddressRepeat() != null) && + (this.getUserPassword() != null) && + (this.getUserPasswordRepeat() != null)); + } + + @Override + public boolean isSameEmailAddressEntered () { + return (Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat())); + } + + @Override + public boolean isSamePasswordEntered () { + return (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())); + } + + @Override + public boolean isUserNameRegistered (final User user) { + return ((this.userNameList instanceof List) && (this.userNameList.contains(user.getUserName()))); + } + + @Override + public boolean isVisibleUserFound () { + return ((this.visibleUserList instanceof List) && (this.visibleUserList.size() > 0)); + } + + @Override + public User lookupUserById (final Long userId) throws UserNotFoundException { + // Init variable + User user = null; + + // Try to lookup it in visible user list + for (final Iterator iterator = this.visibleUserList.iterator(); iterator.hasNext();) { + // Get next user + User next = iterator.next(); + + // Is the user id found? + if (Objects.equals(next.getUserId(), userId)) { + // Copy to other variable + user = next; + break; + } + } + + // Is it still null? + if (null == user) { + // Not visible for the current user + throw new UserNotFoundException(userId); + } + + // Return it + return user; + } + + /** + * Adds user's name and email address to bean's internal list. It also + * updates the public user list if the user has decided to ha } + *

+ * @param user User instance + */ + private void addUserNameEmailAddress (final User user) { + // Make sure the entry is not added yet + if (this.userNameList.contains(user.getUserName())) { + // Abort here + throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N + } else if (this.emailAddressList.contains(user.getUserContact().getContactEmailAddress())) { + // Already added + throw new IllegalArgumentException(MessageFormat.format("Email address {0} already added.", user.getUserContact().getContactEmailAddress())); //NOI18N + } + + // Add user name + this.userNameList.add(user.getUserName()); + + // Add email addres + this.emailAddressList.add(user.getUserContact().getContactEmailAddress()); + } + + /** + * Clears all data in this bean + */ + private void clearData () { + // Clear all data + // - personal data + this.setUserId(null); + this.setGender(Gender.UNKNOWN); + this.setUserProfileMode(null); + this.setFirstName(null); + this.setFamilyName(null); + this.setStreet(null); + this.setHouseNumber(null); + this.setZipCode(null); + this.setCity(null); + this.setCountry(null); + + // - contact data + this.setEmailAddress(null); + this.setEmailAddressRepeat(null); + this.setPhoneAreaCode(null); + this.setCellphoneCarrier(null); + this.setFaxAreaCode(null); + + // - other data + this.setBirthday(null); + this.setComment(null); + this.setUserName(null); + this.setUserPassword(null); + this.setUserPasswordRepeat(null); + } + + /** + * Copies given user into the controller + *

+ * @param user User instance + */ + private void copyUser (final User user) { + // Copy all fields: + // - base data + this.setUserId(user.getUserId()); + this.setUserProfileMode(user.getUserProfileMode()); + this.setGender(user.getUserContact().getContactGender()); + this.setFirstName(user.getUserContact().getContactFirstName()); + this.setFamilyName(user.getUserContact().getContactFamilyName()); + this.setStreet(user.getUserContact().getContactStreet()); + this.setHouseNumber(user.getUserContact().getContactHouseNumber()); + this.setZipCode(user.getUserContact().getContactZipCode()); + this.setCity(user.getUserContact().getContactCity()); + this.setCountry(user.getUserContact().getContactCountry()); + + // Get cellphone, phone and fax instance + DialableCellphoneNumber cellphone = user.getUserContact().getContactCellphoneNumber(); + DialableFaxNumber fax = user.getUserContact().getContactFaxNumber(); + DialableLandLineNumber phone = user.getUserContact().getContactPhoneNumber(); + + // - contact data + if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneAreaCode() > 0)) { + this.setPhoneCountry(phone.getPhoneCountry()); + this.setPhoneAreaCode(phone.getPhoneAreaCode()); + this.setPhoneNumber(phone.getPhoneNumber()); + } + if ((cellphone instanceof DialableCellphoneNumber) && (cellphone.getCellphoneProvider() instanceof SmsProvider)) { + this.setCellphoneCarrier(cellphone.getCellphoneProvider()); + this.setCellphoneNumber(cellphone.getPhoneNumber()); + } + if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) { + this.setFaxCountry(fax.getPhoneCountry()); + this.setFaxAreaCode(fax.getPhoneAreaCode()); + this.setFaxNumber(fax.getPhoneNumber()); + } + this.setEmailAddress(user.getUserContact().getContactEmailAddress()); + + // -- other data + this.setBirthday(user.getUserContact().getContactBirthday()); + this.setComment(user.getUserContact().getContactComment()); + } + + @Override + public boolean isUserIdEmpty () { + return ((this.getUserId() == null) || (this.getUserId() == 0)); + } +} diff --git a/src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java b/src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java new file mode 100644 index 00000000..ac221cd8 --- /dev/null +++ b/src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java @@ -0,0 +1,481 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.beans.user; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import org.mxchange.jcontacts.contact.gender.Gender; +import org.mxchange.jcountry.data.Country; +import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider; +import org.mxchange.jusercore.events.login.UserLoggedInEvent; +import org.mxchange.jusercore.events.registration.UserRegisteredEvent; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; + +/** + * An interface for user beans + *

+ * @author Roland Haeder + */ +public interface UserWebSessionController extends Serializable { + + /** + * Tries to lookup user by given id number. If the user is not found or the + * account status is not CONFIRMED proper exceptions are thrown. + *

+ * @param userId User id + *

+ * @return User instance + *

+ * @throws UserNotFoundException If the user is not found + */ + User lookupUserById (final Long userId) throws UserNotFoundException; + + /** + * Event observer for new user registrations + *

+ * @param event User registration event + */ + void afterRegistrationEvent (final UserRegisteredEvent event); + + /** + * Event observer for logged-in user + *

+ * @param event Event instance + */ + void afterUserLogin (final UserLoggedInEvent event); + + /** + * All public user profiles + *

+ * @return A list of all public user profiles + */ + List allVisibleUsers (); + + /** + * Creates an instance from all properties + *

+ * @return A user instance + */ + User createUserInstance (); + + /** + * Getter for birth day + *

+ * @return Birth day + */ + Date getBirthday (); + + /** + * Setter for birth day + *

+ * @param birthday Birth day + */ + void setBirthday (final Date birthday); + + /** + * Getter for ellphone number's carrier + *

+ * @return Cellphone number's carrier + */ + SmsProvider getCellphoneCarrier (); + + /** + * Setter for cellphone number's carrier prefix + *

+ * @param cellphoneCarrier Cellphone number's carrier prefix + */ + void setCellphoneCarrier (final SmsProvider cellphoneCarrier); + + /** + * Getter for ellphone number + *

+ * @return Cellphone number + */ + Long getCellphoneNumber (); + + /** + * Setter for ellphone number + *

+ * @param cellphoneNumber Cellphone number + */ + void setCellphoneNumber (final Long cellphoneNumber); + + /** + * City + *

+ * @return the city + */ + String getCity (); + + /** + * City + *

+ * @param city the city to set + */ + void setCity (final String city); + + /** + * Getter for comments + *

+ * @return Comments + */ + String getComment (); + + /** + * Setter for comment + *

+ * @param comment Comments + */ + void setComment (final String comment); + + /** + * Getter for country instance + *

+ * @return Country instance + */ + Country getCountry (); + + /** + * Setter for country instance + *

+ * @param country Country instance + */ + void setCountry (final Country country); + + /** + * Getter for email address + *

+ * @return Email address + */ + String getEmailAddress (); + + /** + * Setter for email address + *

+ * @param emailAddress Email address + */ + void setEmailAddress (final String emailAddress); + + /** + * Getter for email address, repeated + *

+ * @return the emailAddress, repeated + */ + String getEmailAddressRepeat (); + + /** + * Setter for email address repeated + *

+ * @param emailAddressRepeat the emailAddress to set + */ + void setEmailAddressRepeat (final String emailAddressRepeat); + + /** + * Family name + *

+ * @return the familyName + */ + String getFamilyName (); + + /** + * Family name + *

+ * @param familyName the familyName to set + */ + void setFamilyName (final String familyName); + + /** + * Getter for fax number's area code + *

+ * @return Fax number's area code + */ + Integer getFaxAreaCode (); + + /** + * Setter for fax number's area code + *

+ * @param faxAreaCode Fax number's area code + */ + void setFaxAreaCode (final Integer faxAreaCode); + + /** + * Getter for fax's country instance + *

+ * @return Fax' country instance + */ + Country getFaxCountry (); + + /** + * Setter for fax's country instance + *

+ * @param faxCountry Fax' country instance + */ + void setFaxCountry (final Country faxCountry); + + /** + * Getter for fax number + *

+ * @return Fax number + */ + Long getFaxNumber (); + + /** + * Setter for fax number + *

+ * @param faxNumber Fax number + */ + void setFaxNumber (final Long faxNumber); + + /** + * First name + *

+ * @return the first name + */ + String getFirstName (); + + /** + * First name + *

+ * @param firstName the first name to set + */ + void setFirstName (final String firstName); + + /** + * Gender of the contact + *

+ * @return the gender + */ + Gender getGender (); + + /** + * Gender of the contact + *

+ * @param gender the gender to set + */ + void setGender (final Gender gender); + + /** + * House number + *

+ * @return the houseNumber + */ + Short getHouseNumber (); + + /** + * House number + *

+ * @param houseNumber the houseNumber to set + */ + void setHouseNumber (final Short houseNumber); + + /** + * Getter for phone number's area code + *

+ * @return Phone number's area code + */ + Integer getPhoneAreaCode (); + + /** + * Setter for phone number's area code + *

+ * @param phoneAreaCode Phone number's area code + */ + void setPhoneAreaCode (final Integer phoneAreaCode); + + /** + * Getter for phone number's country instance + *

+ * @return Phone number's country instance + */ + Country getPhoneCountry (); + + /** + * Setter for phone number's country instance + *

+ * @param phoneCountry Phone number's country instance + */ + void setPhoneCountry (final Country phoneCountry); + + /** + * Getter for phone number + *

+ * @return Phone number + */ + Long getPhoneNumber (); + + /** + * Setter for phone number + *

+ * @param phoneNumber Phone number + */ + void setPhoneNumber (final Long phoneNumber); + + /** + * Street + *

+ * @return the street + */ + String getStreet (); + + /** + * Street + *

+ * @param street the street to set + */ + void setStreet (final String street); + + /** + * Getter for user id + *

+ * @return User id + */ + Long getUserId (); + + /** + * Setter for user id + *

+ * @param userId User id + */ + void setUserId (final Long userId); + + /** + * Getter for user name + *

+ * @return User name + */ + String getUserName (); + + /** + * Setter for user name + *

+ * @param userName User name + */ + void setUserName (final String userName); + + /** + * Getter for unencrypted user password + *

+ * @return Unencrypted user password + */ + String getUserPassword (); + + /** + * Setter for unencrypted user password + *

+ * @param userPassword Unencrypted user password + */ + void setUserPassword (final String userPassword); + + /** + * Getter for unencrypted user password repeated + *

+ * @return Unencrypted user password repeated + */ + String getUserPasswordRepeat (); + + /** + * Setter for unencrypted user password repeated + *

+ * @param userPasswordRepeat Unencrypted user password repeated + */ + void setUserPasswordRepeat (final String userPasswordRepeat); + + /** + * Getter for user profile mode + *

+ * @return User profile mode + */ + ProfileMode getUserProfileMode (); + + /** + * Setter for user profile mode + *

+ * @param userProfileMode User profile mode + */ + void setUserProfileMode (final ProfileMode userProfileMode); + + /** + * ZIP code + *

+ * @return the zipCode + */ + Integer getZipCode (); + + /** + * ZIP code + *

+ * @param zipCode the zipCode to set + */ + void setZipCode (final Integer zipCode); + + /** + * Checks whether user instance's email address is used + *

+ * @param user User instance's email address to check + *

+ * @return Whether it is already used + */ + boolean isEmailAddressRegistered (final User user); + + /** + * Checks whether all required personal data is set + *

+ * @return Whether the required personal data is set + */ + boolean isRequiredPersonalDataSet (); + + /** + * Checks whether same email addresses have been entered + *

+ * @return Whether same email addresses have been entered + */ + boolean isSameEmailAddressEntered (); + + /** + * Checks whether same passwords has been entered + *

+ * @return Whether same passwords has been entered + */ + boolean isSamePasswordEntered (); + + /** + * Checks whether given user instance's name is used + *

+ * @param user User instance's name to check + *

+ * @return Whether it is already used + */ + boolean isUserNameRegistered (final User user); + + /** + * Checks whether a public user account is registered. This means that at + * least one user profile has its flag "public user profile" enabled. + *

+ * @return Whether at least one user has a public profile + */ + boolean isVisibleUserFound (); + + /** + * Checks if the user id is empty + *

+ * @return Whether the user id is empty + */ + boolean isUserIdEmpty (); +} diff --git a/src/java/org/mxchange/addressbook/converter/country/CountryConverter.java b/src/java/org/mxchange/addressbook/converter/country/CountryConverter.java new file mode 100644 index 00000000..6606143d --- /dev/null +++ b/src/java/org/mxchange/addressbook/converter/country/CountryConverter.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.converter.country; + +import java.text.MessageFormat; +import java.util.List; +import java.util.Objects; +import javax.annotation.PostConstruct; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; +import javax.inject.Inject; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.country.CountryWebApplicationController; +import org.mxchange.jcoreeelogger.beans.local.logger.Log; +import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal; +import org.mxchange.jcountry.data.Country; + +/** + * Converter for country instance + *

+ * @author Roland Haeder + */ +@FacesConverter (value = "country") +public class CountryConverter implements Converter { + + /** + * Country bean + */ + @Inject + private CountryWebApplicationController countryController; + + /** + * Logger instance + */ + @Log + private LoggerBeanLocal loggerBeanLocal; + + @Override + public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) { + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N + + // Get full list + List countryList = this.countryController.allCountries(); + + // Is the value null or empty? + if ((null == submittedValue) || (submittedValue.trim().isEmpty())) { + // Return null + return null; + } + + // Init value + Country country = null; + + // Try this better + try { + // Convert it to long + Long countryId = Long.parseLong(submittedValue); + + // Category id should not be below 1 + assert (countryId > 0) : "countryId is smaller than one: " + countryId; //NOI18N + + // Debug message + this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: countryId={0}", countryId)); //NOI18N + + // Try to find it + for (final Country cntry : countryList) { + // Is the id the same? (null-safe) + if (Objects.equals(cntry.getCountryId(), countryId)) { + // Found it + country = cntry; + break; + } + } + } catch (final NumberFormatException ex) { + // Log exception (maybe to much?) + this.loggerBeanLocal.logException(ex); + } + + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: country={0} - EXIT!", country)); //NOI18N + + // Return it + return country; + } + + @Override + public String getAsString (final FacesContext context, final UIComponent component, final Object value) { + // Is the object null? + if ((null == value) || ((String.valueOf(value)).isEmpty())) { + // Is null + return ""; //NOI18N + } else if (!(value instanceof Country)) { + // Not same interface + throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement Country.", value)); //NOI18N + } + + // Return category id + return String.valueOf(((Country) value).getCountryId()); + } + + /** + * Initialization of this converter + */ + @PostConstruct + public void init () { + // Try to get it + try { + // Get initial context + Context context = new InitialContext(); + + // Lookup logger + this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw it + throw new RuntimeException("context.lookup() failed.", ex); //NOI18N + } + } +} diff --git a/src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java b/src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java new file mode 100644 index 00000000..0769fb53 --- /dev/null +++ b/src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.converter.smsprovider; + +import java.text.MessageFormat; +import java.util.List; +import java.util.Objects; +import javax.annotation.PostConstruct; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.FacesConverter; +import javax.inject.Inject; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.smsprovider.SmsProviderWebApplicationController; +import org.mxchange.jcoreeelogger.beans.local.logger.Log; +import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal; +import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider; + +/** + * Converter for SMS provider instance + *

+ * @author Roland Haeder + */ +@FacesConverter (value = "cellphoneCarrier") +public class SmsProviderConverter implements Converter { + + /** + * Logger instance + */ + @Log + private LoggerBeanLocal loggerBeanLocal; + + /** + * SMS provider bean + */ + @Inject + private SmsProviderWebApplicationController providerController; + + @Override + public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) { + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N + + // Get full list + List providerList = this.providerController.allSmsProvider(); + + // Is the value null or empty? + if ((null == submittedValue) || (submittedValue.trim().isEmpty())) { + // Return null + return null; + } + + // Init value + SmsProvider provider = null; + + // Try this better + try { + // Convert it to long + Long providerId = Long.parseLong(submittedValue); + + // Category id should not be below 1 + assert (providerId > 0) : "providerId is smaller than one: " + providerId; //NOI18N + + // Debug message + this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: providerId={0}", providerId)); //NOI18N + + // Try to find it + for (final SmsProvider prov : providerList) { + // Is the id the same? (null-safe) + if (Objects.equals(prov.getProviderId(), providerId)) { + // Found it + provider = prov; + break; + } + } + } catch (final NumberFormatException ex) { + // Log exception (maybe to much?) + this.loggerBeanLocal.logException(ex); + } + + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: provider={0} - EXIT!", provider)); //NOI18N + + // Return it + return provider; + } + + @Override + public String getAsString (final FacesContext context, final UIComponent component, final Object value) { + // Is the object null? + if ((null == value) || ((String.valueOf(value)).isEmpty())) { + // Is null + return ""; //NOI18N + } else if (!(value instanceof SmsProvider)) { + // Not same interface + throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement SmsProvider.", value)); //NOI18N + } + + // Return category id + return String.valueOf(((SmsProvider) value).getProviderId()); + } + + /** + * Initialization of this converter + */ + @PostConstruct + public void init () { + // Try to get it + try { + // Get initial context + Context context = new InitialContext(); + + // Lookup logger + this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw it + throw new RuntimeException("context.lookup() failed.", ex); //NOI18N + } + } + +} diff --git a/src/java/org/mxchange/addressbook/converter/user/UserConverter.java b/src/java/org/mxchange/addressbook/converter/user/UserConverter.java new file mode 100644 index 00000000..d5e77694 --- /dev/null +++ b/src/java/org/mxchange/addressbook/converter/user/UserConverter.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2016 Roland Haeder + * + * 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 . + */ +package org.mxchange.addressbook.converter.user; + +import java.text.MessageFormat; +import javax.annotation.PostConstruct; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.convert.ConverterException; +import javax.faces.convert.FacesConverter; +import javax.inject.Inject; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.addressbook.beans.user.UserWebSessionController; +import org.mxchange.jcoreeelogger.beans.local.logger.Log; +import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.model.user.User; + +/** + * Converter for user id <-> valid user instance + *

+ * @author Roland Haeder + */ +@FacesConverter (value = "UserConverter") +public class UserConverter implements Converter { + + /** + * Logger instance + */ + @Log + private LoggerBeanLocal loggerBeanLocal; + + /** + * User bean + */ + @Inject + private UserWebSessionController userController; + + @Override + public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) { + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N + + // Is the value null or empty? + if ((null == submittedValue) || (submittedValue.trim().isEmpty())) { + // Return null + return null; + } + + // Init instance + User user = null; + + try { + // Try to parse the value as long + Long userId = Long.valueOf(submittedValue); + + // Debug message + this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: userId{0}", userId)); + + // Try to get user instance from it + user = this.userController.lookupUserById(userId); + + // Debug message + this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: user={0}", user)); + } catch (final NumberFormatException ex) { + // Throw again + throw new ConverterException(ex); + } catch (final UserNotFoundException ex) { + // Debug message + this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: Exception: {0} - Returning null ...", ex)); + + // Return null + return null; + } + + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: user={0} - EXIT!", user)); + + // Return it + return user; + } + + @Override + public String getAsString (final FacesContext context, final UIComponent component, final Object value) { + // Is the object null? + if ((null == value) || ((String.valueOf(value)).isEmpty())) { + // Is null + return ""; //NOI18N + } else if (!(value instanceof User)) { + // Not same interface + throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement User.", value)); //NOI18N + } + + // Return category id + return String.valueOf(((User) value).getUserId()); + } + + /** + * Initialization of this converter + */ + @PostConstruct + public void init () { + // Try to get it + try { + // Get initial context + Context context = new InitialContext(); + + // Lookup logger + this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw it + throw new RuntimeException("context.lookup() failed.", ex); //NOI18N + } + } +} diff --git a/web/WEB-INF/beans.xml b/web/WEB-INF/beans.xml new file mode 100644 index 00000000..0f4e2aab --- /dev/null +++ b/web/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/web/WEB-INF/faces-config.xml b/web/WEB-INF/faces-config.xml new file mode 100644 index 00000000..969fbf47 --- /dev/null +++ b/web/WEB-INF/faces-config.xml @@ -0,0 +1,176 @@ + + + + + de + en_US + + + + PrivacyTermsCheckboxValidator + org.mxchange.jcoreee.validator.bool.privacy_terms.PrivacyTermsCheckboxValidator + + + NameValidator + org.mxchange.jcoreee.validator.string.names.NameValidator + + + AddressbookNameValidator + org.mxchange.addressbook.validator.names.AddressbookNameValidator + + + PhoneNumberValidator + org.mxchange.jphone.validators.PhoneNumberValidator + + + AddressbookIdValidator + org.mxchange.addressbook.validator.addressbook.AddressbookIdValidator + + + UserProfileVisibilityValidator + org.mxchange.addressbook.validator.booleans.UserProfileVisibilityValidator + + + UserIdValidator + org.mxchange.addressbook.validator.user.UserIdValidator + + + * + + index + /index.xhtml + + + user_register + /user/register.xhtml + + + user_login + /user/login.xhtml + + + user_lost_passwd + /user/lost_passwd.xhtml + + + terms + /terms.xhtml + + + privacy + /privacy.xhtml + + + imprint + /imprint.xhtml + + + logout + /bye.xhtml + + + admin_index + /admin/admin_index.xhtml + + + login_index + /login/login_index.xhtml + + + user_resend_link + /user/resend_link.xhtml + + + login_own_addressbooks + /login/login_own_addressbooks.xhtml + + + login_other_addressbooks + /login/login_other_addressbooks.xhtml + + + user_list + /user/user_list.xhtml + + + admin_logout + /admin/admin_logout.xhtml + + + login_edit_address + /login/login_edit_address.xhtml + + + login_edit_user_data + /login/login_edit_user_data.xhtml + + + login_shared_addressbooks + /login/login_shared_addressbooks.xhtml + + + user_profile + /user/user_profile.xhtml + + + + /user/login.xhtml + + login + /login/login_index.xhtml + + + + /user/register.xhtml + + register_done + /user/register_done.xhtml + + + + /admin/admin_logout.xhtml + + index + /index.xhtml + + + + /login/login_own_addressbooks.xhtml + + login_add_addressbook + /login/login_add_addressbook.xhtml + + + user_show_addressbook + /user/show_addressbook.xhtml + + + show_addressbook_entries + /user/show_addressbook_entries.xhtml + + + + /user/user_list.xhtml + + login_list_sharing_addressbooks + /login/login_list_sharing_addressbooks.xhtml + + + + /user/show_addressbook.xhtml + + login_start_sharing_addressbook + /login/login_start_sharing_addressbook.xhtml + + + + /login/login_shared_addressbooks.xhtml + + user_show_addressbook + /user/show_addressbook.xhtml + + + diff --git a/web/WEB-INF/glassfish-web.xml b/web/WEB-INF/glassfish-web.xml new file mode 100644 index 00000000..b70617b4 --- /dev/null +++ b/web/WEB-INF/glassfish-web.xml @@ -0,0 +1,11 @@ + + + + /addressbook-war + + + + Keep a copy of the generated servlet class' java code. + + + -- 2.39.5