]> git.mxchange.org Git - jjobs-lib.git/commitdiff
added files from addressbook-lib:
authorRoland Haeder <roland@mxchange.org>
Wed, 2 Mar 2016 19:44:30 +0000 (20:44 +0100)
committerRoland Haeder <roland@mxchange.org>
Wed, 2 Mar 2016 19:44:30 +0000 (20:44 +0100)
- added a lot jars and classes which may need to be customized for jjobs
- added Java EE 7 API and generic Persistence (JPA 2.1)
- updated project files

37 files changed:
lib/javaee-api-7.0/javaee-api-7.0.jar [new file with mode: 0644]
lib/jcontacts-business-core.jar [new file with mode: 0644]
lib/jcontacts-core.jar [new file with mode: 0644]
lib/jcore-logger-lib.jar [new file with mode: 0644]
lib/jcore.jar [new file with mode: 0644]
lib/jcoreee.jar [new file with mode: 0644]
lib/jcountry-core.jar [new file with mode: 0644]
lib/jpa20-persistence/javax.persistence_2.1.0.v201304241213.jar [new file with mode: 0644]
lib/jphone-core.jar [new file with mode: 0644]
lib/juser-core.jar [new file with mode: 0644]
lib/juser-lib.jar [new file with mode: 0644]
lib/nblibraries.properties
nbproject/project.properties
src/org/mxchange/jcountry/data/AddressbookCountrySingletonBeanRemote.java [new file with mode: 0644]
src/org/mxchange/jjobs/events/addressbook/AddressbookLoadedEvent.java [new file with mode: 0644]
src/org/mxchange/jjobs/events/addressbook/LoadedAddressbookEvent.java [new file with mode: 0644]
src/org/mxchange/jjobs/events/sharing/AddressbookSharingEvent.java [new file with mode: 0644]
src/org/mxchange/jjobs/events/sharing/EndedAddressbookSharingEvent.java [new file with mode: 0644]
src/org/mxchange/jjobs/events/sharing/StartedAddressbookSharingEvent.java [new file with mode: 0644]
src/org/mxchange/jjobs/events/sharing/type/SharingType.java [new file with mode: 0644]
src/org/mxchange/jjobs/exceptions/AddressbookNameAlreadyUsedException.java [new file with mode: 0644]
src/org/mxchange/jjobs/exceptions/AddressbookNotFoundException.java [new file with mode: 0644]
src/org/mxchange/jjobs/exceptions/UserAlreadySharingAddressbookException.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/Addressbook.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/AddressbookSessionBeanRemote.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/UserAddressbook.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/entry/AddressbookEntry.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/entry/UserAddressbookEntry.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/shared/AddressbookShare.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/shared/ShareableAddressbook.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/addressbook/status/AddressbokStatus.java [new file with mode: 0644]
src/org/mxchange/jjobs/model/shared/SharedAddressbooksSessionBeanRemote.java [new file with mode: 0644]
src/org/mxchange/jjobs/validator/addressbook/AddressbookIdValidator.java [new file with mode: 0644]
src/org/mxchange/jjobs/validator/booleans/UserProfileVisibilityValidator.java [new file with mode: 0644]
src/org/mxchange/jjobs/validator/names/AddressbookNameValidator.java [new file with mode: 0644]
src/org/mxchange/jjobs/validator/user/UserIdValidator.java [new file with mode: 0644]
src/org/mxchange/jphone/phonenumbers/smsprovider/AddressbookSmsProviderSingletonBeanRemote.java [new file with mode: 0644]

diff --git a/lib/javaee-api-7.0/javaee-api-7.0.jar b/lib/javaee-api-7.0/javaee-api-7.0.jar
new file mode 100644 (file)
index 0000000..9e38d4c
Binary files /dev/null and b/lib/javaee-api-7.0/javaee-api-7.0.jar differ
diff --git a/lib/jcontacts-business-core.jar b/lib/jcontacts-business-core.jar
new file mode 100644 (file)
index 0000000..6b659a8
Binary files /dev/null and b/lib/jcontacts-business-core.jar differ
diff --git a/lib/jcontacts-core.jar b/lib/jcontacts-core.jar
new file mode 100644 (file)
index 0000000..0d39fc7
Binary files /dev/null and b/lib/jcontacts-core.jar differ
diff --git a/lib/jcore-logger-lib.jar b/lib/jcore-logger-lib.jar
new file mode 100644 (file)
index 0000000..ea0ec33
Binary files /dev/null and b/lib/jcore-logger-lib.jar differ
diff --git a/lib/jcore.jar b/lib/jcore.jar
new file mode 100644 (file)
index 0000000..a5001cd
Binary files /dev/null and b/lib/jcore.jar differ
diff --git a/lib/jcoreee.jar b/lib/jcoreee.jar
new file mode 100644 (file)
index 0000000..8fa7868
Binary files /dev/null and b/lib/jcoreee.jar differ
diff --git a/lib/jcountry-core.jar b/lib/jcountry-core.jar
new file mode 100644 (file)
index 0000000..e31915f
Binary files /dev/null and b/lib/jcountry-core.jar differ
diff --git a/lib/jpa20-persistence/javax.persistence_2.1.0.v201304241213.jar b/lib/jpa20-persistence/javax.persistence_2.1.0.v201304241213.jar
new file mode 100644 (file)
index 0000000..841d2e1
Binary files /dev/null and b/lib/jpa20-persistence/javax.persistence_2.1.0.v201304241213.jar differ
diff --git a/lib/jphone-core.jar b/lib/jphone-core.jar
new file mode 100644 (file)
index 0000000..c017984
Binary files /dev/null and b/lib/jphone-core.jar differ
diff --git a/lib/juser-core.jar b/lib/juser-core.jar
new file mode 100644 (file)
index 0000000..40c22b7
Binary files /dev/null and b/lib/juser-core.jar differ
diff --git a/lib/juser-lib.jar b/lib/juser-lib.jar
new file mode 100644 (file)
index 0000000..35588bb
Binary files /dev/null and b/lib/juser-lib.jar differ
index 6d0afb59d64978f1c42b37eda93de4d6acaa674c..09266ab51ba16c77f3b822de555a34cb3e59db75 100644 (file)
@@ -2,3 +2,11 @@ libs.CopyLibs.classpath=\
     ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar
 libs.CopyLibs.displayName=CopyLibs Task
 libs.CopyLibs.prop-version=2.0
+libs.javaee-api-7.0.classpath=\
+    ${base}/javaee-api-7.0/javaee-api-7.0.jar
+libs.javaee-api-7.0.displayName=Java EE 7 API Library
+libs.javaee-api-7.0.prop-maven-dependencies=javax:javaee-api:7.0:jar
+libs.jpa20-persistence.classpath=\
+    ${base}/jpa20-persistence/javax.persistence_2.1.0.v201304241213.jar
+libs.jpa20-persistence.displayName=Persistence (JPA 2.1)
+libs.jpa20-persistence.prop-maven-dependencies=org.eclipse.persistence:javax.persistence:2.1.0:jar
index be4ad67287827f499bff94dac5e52812fc985628..ca7fa8d7c8ba2d36c142565193e5ec57f47224aa 100644 (file)
@@ -30,12 +30,33 @@ dist.jar=${dist.dir}/jjobs-lib.jar
 dist.javadoc.dir=${dist.dir}/javadoc
 endorsed.classpath=
 excludes=
+file.reference.jcontacts-business-core.jar=lib/jcontacts-business-core.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.jcoreee.jar=lib/jcoreee.jar
+file.reference.jcountry-core.jar=lib/jcountry-core.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=**
 jar.compress=false
-javac.classpath=
+javac.classpath=\
+    ${file.reference.jcore.jar}:\
+    ${file.reference.jcoreee.jar}:\
+    ${file.reference.jcore-logger-lib.jar}:\
+    ${file.reference.jcountry-core.jar}:\
+    ${file.reference.jphone-core.jar}:\
+    ${file.reference.jcontacts-core.jar}:\
+    ${file.reference.jcontacts-business-core.jar}:\
+    ${file.reference.juser-core.jar}:\
+    ${file.reference.juser-lib.jar}:\
+    ${libs.javaee-api-7.0.classpath}:\
+    ${libs.jpa20-persistence.classpath}
 # Space-separated list of extra javac options
 javac.compilerargs=-Xlint:unchecked -Xlint:deprecation
 javac.deprecation=true
+javac.external.vm=false
 javac.processorpath=\
     ${javac.classpath}
 javac.source=1.7
@@ -71,5 +92,14 @@ run.test.classpath=\
     ${javac.test.classpath}:\
     ${build.test.classes.dir}
 source.encoding=UTF-8
+source.reference.jcontacts-business-core.jar=../jcontacts-business-core/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.jcoreee.jar=../jcoreee/src/
+source.reference.jcountry-core.jar=../jcountry-core/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/
 src.dir=src
 test.src.dir=test
diff --git a/src/org/mxchange/jcountry/data/AddressbookCountrySingletonBeanRemote.java b/src/org/mxchange/jcountry/data/AddressbookCountrySingletonBeanRemote.java
new file mode 100644 (file)
index 0000000..013ba4a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jcountry.data;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.ejb.Remote;
+
+/**
+ * A remote interface for country informations
+ * <p>
+ * @author Roland Haeder
+ */
+@Remote
+public interface AddressbookCountrySingletonBeanRemote extends Serializable {
+
+       /**
+        * All registered countries
+        * <p>
+        * @return A list of all countries
+        */
+       List<Country> allCountries ();
+}
diff --git a/src/org/mxchange/jjobs/events/addressbook/AddressbookLoadedEvent.java b/src/org/mxchange/jjobs/events/addressbook/AddressbookLoadedEvent.java
new file mode 100644 (file)
index 0000000..51d8072
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.events.addressbook;
+
+import java.io.Serializable;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+
+/**
+ * An interface for an event if an address book has been loaded
+ * <p>
+ * @author Roland Haeder
+ */
+public interface AddressbookLoadedEvent extends Serializable {
+
+       /**
+        * Getter for address book instance
+        * <p>
+        * @return Address book instance
+        */
+       Addressbook getAddressbook ();
+}
diff --git a/src/org/mxchange/jjobs/events/addressbook/LoadedAddressbookEvent.java b/src/org/mxchange/jjobs/events/addressbook/LoadedAddressbookEvent.java
new file mode 100644 (file)
index 0000000..f5f45e7
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.events.addressbook;
+
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+
+/**
+ * An event fired when an address book has been loaded
+ * <p>
+ * @author Roland Haeder
+ */
+public class LoadedAddressbookEvent implements AddressbookLoadedEvent {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 1L;
+
+       /**
+        * Adress book instance causing this event
+        */
+       private final Addressbook addressbook;
+
+       /**
+        * Constructor with address book instance
+        * <p>
+        * @param addressbook Address book instance
+        */
+       public LoadedAddressbookEvent (final Addressbook addressbook) {
+               this.addressbook = addressbook;
+       }
+
+       @Override
+       public Addressbook getAddressbook () {
+               return this.addressbook;
+       }
+}
diff --git a/src/org/mxchange/jjobs/events/sharing/AddressbookSharingEvent.java b/src/org/mxchange/jjobs/events/sharing/AddressbookSharingEvent.java
new file mode 100644 (file)
index 0000000..3e428bd
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.events.sharing;
+
+import java.io.Serializable;
+import org.mxchange.jjobs.events.sharing.type.SharingType;
+import org.mxchange.jjobs.model.addressbook.shared.ShareableAddressbook;
+
+/**
+ * An interface for address book sharing events
+ * <p>
+ * @author Roland Haeder
+ */
+public interface AddressbookSharingEvent extends Serializable {
+
+       /**
+        * Getter for address book share instance
+        * <p>
+        * @return Address book share instance
+        */
+       ShareableAddressbook getShareableAddressbook ();
+
+       /**
+        * Getter for sharing type enum
+        * <p>
+        * @return Sharing type enum
+        */
+       SharingType getSharingType ();
+}
diff --git a/src/org/mxchange/jjobs/events/sharing/EndedAddressbookSharingEvent.java b/src/org/mxchange/jjobs/events/sharing/EndedAddressbookSharingEvent.java
new file mode 100644 (file)
index 0000000..ee0ce48
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.events.sharing;
+
+import org.mxchange.jjobs.events.sharing.type.SharingType;
+import org.mxchange.jjobs.model.addressbook.shared.ShareableAddressbook;
+
+/**
+ * An event fired when a user ends sharing address books
+ * <p>
+ * @author Roland Haeder
+ */
+public class EndedAddressbookSharingEvent implements AddressbookSharingEvent {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 152_896_748_186_018_497L;
+
+       /**
+        * Shared address book entry
+        */
+       private final ShareableAddressbook shareableAddressbook;
+
+       /**
+        * Constructor with address book share entry
+        * <p>
+        * @param share Address book share entry
+        */
+       public EndedAddressbookSharingEvent (final ShareableAddressbook share) {
+               this.shareableAddressbook = share;
+       }
+
+       @Override
+       public ShareableAddressbook getShareableAddressbook () {
+               return this.shareableAddressbook;
+       }
+
+       @Override
+       public SharingType getSharingType () {
+               // Started sharing
+               return SharingType.ENDED;
+       }
+}
diff --git a/src/org/mxchange/jjobs/events/sharing/StartedAddressbookSharingEvent.java b/src/org/mxchange/jjobs/events/sharing/StartedAddressbookSharingEvent.java
new file mode 100644 (file)
index 0000000..56d971e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.events.sharing;
+
+import org.mxchange.jjobs.events.sharing.type.SharingType;
+import org.mxchange.jjobs.model.addressbook.shared.ShareableAddressbook;
+
+/**
+ * An event fired when a user starts sharing address books
+ * <p>
+ * @author Roland Haeder
+ */
+public class StartedAddressbookSharingEvent implements AddressbookSharingEvent {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 152_896_748_186_018_497L;
+
+       /**
+        * Shared address book entry
+        */
+       private final ShareableAddressbook shareableAddressbook;
+
+       /**
+        * Constructor with address book share entry
+        * <p>
+        * @param share Address book share entry
+        */
+       public StartedAddressbookSharingEvent (final ShareableAddressbook share) {
+               this.shareableAddressbook = share;
+       }
+
+       @Override
+       public ShareableAddressbook getShareableAddressbook () {
+               return this.shareableAddressbook;
+       }
+
+       @Override
+       public SharingType getSharingType () {
+               // Started sharing
+               return SharingType.STARTED;
+       }
+}
diff --git a/src/org/mxchange/jjobs/events/sharing/type/SharingType.java b/src/org/mxchange/jjobs/events/sharing/type/SharingType.java
new file mode 100644 (file)
index 0000000..f6a8a9f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.events.sharing.type;
+
+/**
+ * An enum for sharing types
+ * <p>
+ * @author Roland Haeder
+ */
+public enum SharingType {
+
+       /**
+        * Sharing has been started
+        */
+       STARTED,
+
+       /**
+        * Sharing has been ended
+        */
+       ENDED;
+
+}
diff --git a/src/org/mxchange/jjobs/exceptions/AddressbookNameAlreadyUsedException.java b/src/org/mxchange/jjobs/exceptions/AddressbookNameAlreadyUsedException.java
new file mode 100644 (file)
index 0000000..9ecb48a
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.exceptions;
+
+import java.text.MessageFormat;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+
+/**
+ * An exception thrown when the user has already used the name.
+ * <p>
+ * @author Roland Haeder
+ */
+public class AddressbookNameAlreadyUsedException extends Exception {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 58_169_748_928_767_381L;
+
+       /**
+        * Constructor with address book instance
+        * <p>
+        * @param addressbook Address book instance
+        */
+       public AddressbookNameAlreadyUsedException (final Addressbook addressbook) {
+               super(MessageFormat.format("User {0} has already used the name {1}.", addressbook.getAddressbookUser(), addressbook.getAddressbookName())); //NOI18N
+       }
+
+}
diff --git a/src/org/mxchange/jjobs/exceptions/AddressbookNotFoundException.java b/src/org/mxchange/jjobs/exceptions/AddressbookNotFoundException.java
new file mode 100644 (file)
index 0000000..859eaa4
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.exceptions;
+
+import java.text.MessageFormat;
+
+/**
+ * An exception thrown when the address book's id number is not valid, so no
+ * address book can be found.
+ * <p>
+ * @author Roland Haeder
+ */
+public class AddressbookNotFoundException extends Exception {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 14_986_976_417_658_920L;
+
+       /**
+        * Creates an exception with given id number that could not be found.
+        * <p>
+        * @param addressbookId Address book id number
+        */
+       public AddressbookNotFoundException (final Long addressbookId) {
+               super(MessageFormat.format("Address book with id number {0} does not exist.", addressbookId));
+       }
+
+}
diff --git a/src/org/mxchange/jjobs/exceptions/UserAlreadySharingAddressbookException.java b/src/org/mxchange/jjobs/exceptions/UserAlreadySharingAddressbookException.java
new file mode 100644 (file)
index 0000000..abb81e3
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.exceptions;
+
+import java.text.MessageFormat;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * An exception thrown whent the address book is already shared with given user
+ * <p>
+ * @author Roland Haeder
+ */
+public class UserAlreadySharingAddressbookException extends Exception {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 58_528_177_571_976_034L;
+
+       /**
+        * Constructor with address book being already shared with sharee
+        * <p>
+        * @param addressbook Address book instance
+        * @param sharee User instance the address book is being shared with
+        */
+       public UserAlreadySharingAddressbookException (final Addressbook addressbook, final User sharee) {
+               super(MessageFormat.format("Address book id {0} owned by user {1} is already shared with user {2}", addressbook.getAddressbookId(), addressbook.getAddressbookUser().getUserId(), sharee.getUserId()));
+       }
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/Addressbook.java b/src/org/mxchange/jjobs/model/addressbook/Addressbook.java
new file mode 100644 (file)
index 0000000..be76c3d
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import org.mxchange.jjobs.model.addressbook.status.AddressbokStatus;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A POJI for addressbooks
+ * <p>
+ * @author Roland Haeder
+ */
+public interface Addressbook extends Serializable {
+
+       /**
+        * Getter for id number
+        * <p>
+        * @return Id number
+        */
+       Long getAddressbookId ();
+
+       /**
+        * Setter for id number
+        * <p>
+        * @param addressbookId Id number
+        */
+       void setAddressbookId (final Long addressbookId);
+
+       /**
+        * Getter for addressbook creation timestamp
+        * <p>
+        * @return Addressbook creation timestamp
+        */
+       Calendar getAddressbookCreated ();
+
+       /**
+        * Setter for addressbook creation timestamp
+        * <p>
+        * @param addressbookCreated Addressbook creation timestamp
+        */
+       void setAddressbookCreated (final Calendar addressbookCreated);
+
+       /**
+        * Getter for addressbook's name
+        * <p>
+        * @return Addressbook's name
+        */
+       String getAddressbookName ();
+
+       /**
+        * Setter for addressbook's name
+        * <p>
+        * @param addressbookName Addressbook's name
+        */
+       void setAddressbookName (final String addressbookName);
+
+       /**
+        * Getter for addressbook status
+        * <p>
+        * @return Addressbook status
+        */
+       AddressbokStatus getAddressbookStatus ();
+
+       /**
+        * Setter for addressbook status
+        * <p>
+        * @param addressbookStatus Addressbook status
+        */
+       void setAddressbookStatus (final AddressbokStatus addressbookStatus);
+
+       /**
+        * Getter for addressbook's user (owner)
+        * <p>
+        * @return Addressbook's user (owner)
+        */
+       User getAddressbookUser ();
+
+       /**
+        * Setter for addressbook's user (owner)
+        * <p>
+        * @param addressbookUser Addressbook's user (owner)
+        */
+       void setAddressbookUser (final User addressbookUser);
+
+       /**
+        * Getter for last locked timestamp
+        * <p>
+        * @return Last locked timestamp
+        */
+       Calendar getAddressbookLastLocked ();
+
+       /**
+        * Setter for last locked timestamp
+        * <p>
+        * @param addressbookLastLocked Last locked timestamp
+        */
+       void setAddressbookLastLocked (final Calendar addressbookLastLocked);
+
+       /**
+        * Getter for last locked reason
+        * <p>
+        * @return Last locked reason
+        */
+       String getAddressbookLastLockedReason ();
+
+       /**
+        * Getter for last locked reason
+        * <p>
+        * @param addressbookLastLockedReason Last locked reason
+        */
+       void setAddressbookLastLockedReason (final String addressbookLastLockedReason);
+
+       @Override
+       boolean equals (final Object object);
+
+       @Override
+       int hashCode ();
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/AddressbookSessionBeanRemote.java b/src/org/mxchange/jjobs/model/addressbook/AddressbookSessionBeanRemote.java
new file mode 100644 (file)
index 0000000..b8b43ba
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.ejb.Remote;
+import org.mxchange.jjobs.exceptions.AddressbookNameAlreadyUsedException;
+import org.mxchange.jjobs.exceptions.AddressbookNotFoundException;
+import org.mxchange.jjobs.model.addressbook.entry.AddressbookEntry;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A remote session interface for addressbook handling
+ * <p>
+ * @author Roland Haeder
+ */
+@Remote
+public interface AddressbookSessionBeanRemote extends Serializable {
+
+       /**
+        * Retrieves a list of all users this user is not sharing the given address
+        * book with.
+        * <p>
+        * @param user User instance
+        * @param addressbook Address book instance
+        * <p>
+        * @return List of users
+        */
+       List<User> allUsersNotSharing (final User user, final Addressbook addressbook);
+
+       /**
+        * Count all shared address books by given user
+        * <p>
+        * @param user User instance
+        * <p>
+        * @return Count of all user's shared address books
+        */
+       Integer countAllUserSharedAddressbooks (final User user);
+
+       /**
+        * Some getter for an address book instance from given id number. If the
+        * address book is not found, an exception is thrown.
+        * <p>
+        * @param addressbookId Id number for address book instance
+        * <p>
+        * @return Address book instance
+        * <p>
+        * @throws org.mxchange.jjobs.exceptions.AddressbookNotFoundException
+        * If the address book cannot be found by given id number
+        * @throws NullPointerException If addressbookId is null
+        * @throws IllegalArgumentException If the id number is below 1
+        */
+       Addressbook getAddressbookById (final Long addressbookId) throws AddressbookNotFoundException;
+
+       /**
+        * Returns a list of all entries of given address book, whether the assigned
+        * user is the "owner" or "sharer" of the entry.
+        * <p>
+        * @param addressbook Address book instance
+        * <p>
+        * @return List of all entries
+        */
+       List<AddressbookEntry> allEntries (final Addressbook addressbook);
+
+       /**
+        * Some "getter" for a list of address books the logged-in user has created
+        * <p>
+        * @param loggedInUser Logged-in user
+        * <p>
+        * @return List of all address books
+        */
+       List<Addressbook> getUsersAddressbookList (final User loggedInUser);
+
+       /**
+        * Creates given address book by persisting it. A User instance must be set,
+        * else an exception is thrown.
+        * <p>
+        * @param addressbook Address book instance to create
+        * <p>
+        * @return Updated address book instance
+        * <p>
+        * @throws
+        * org.mxchange.jjobs.exceptions.AddressbookNameAlreadyUsedException
+        * If the address book's name has already been used by the user.
+        */
+       Addressbook createAddressbook (final Addressbook addressbook) throws AddressbookNameAlreadyUsedException;
+
+       /**
+        * Checks whether the given address book id is used (means available).
+        * <p>
+        * @param addressbookId Address book id to check
+        * <p>
+        * @return Whether the id is valid
+        */
+       boolean isAddressbookIdUsed (final Long addressbookId);
+
+       /**
+        * Checks if the given address book's name is already used by the user.
+        * <p>
+        * @param addressbook Address bok instance to check
+        * <p>
+        * @return Whether the name has already been used by the user
+        */
+       boolean isAddressbookNameUsed (final Addressbook addressbook);
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/UserAddressbook.java b/src/org/mxchange/jjobs/model/addressbook/UserAddressbook.java
new file mode 100644 (file)
index 0000000..b39095a
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook;
+
+import java.util.Calendar;
+import java.util.Objects;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import org.mxchange.jjobs.model.addressbook.status.AddressbokStatus;
+import org.mxchange.jusercore.model.user.LoginUser;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A POJO for user addressbooks
+ * <p>
+ * @author Roland Haeder
+ */
+@Entity (name = "addressbooks")
+@Table (name = "addressbooks")
+@NamedQueries (
+               {
+                       @NamedQuery (name = "AllUsersAddressbooks", query = "SELECT a FROM addressbooks AS a WHERE a.addressbookUser = :param ORDER BY a.addressbookId ASC"),
+                       @NamedQuery (name = "SearchUserAddressbookName", query = "SELECT a FROM addressbooks AS a WHERE a.addressbookUser = :user AND LOWER(a.addressbookName) LIKE LOWER(:name)"),
+                       @NamedQuery (name = "SearchAddressbookById", query = "SELECT a FROM addressbooks AS a WHERE a.addressbookId = :id")
+               }
+)
+public class UserAddressbook implements Addressbook, Comparable<Addressbook> {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 176_573_148_678_169L;
+
+       /**
+        * When this address book has been created
+        */
+       @Basic (optional = false)
+       @Temporal (value = TemporalType.TIMESTAMP)
+       @Column (name = "addressbook_created", nullable = false, updatable = false)
+       private Calendar addressbookCreated;
+
+       /**
+        * Id number
+        */
+       @Id
+       @GeneratedValue (strategy = GenerationType.IDENTITY)
+       @Column (name = "addressbook_id", length = 20, nullable = false, updatable = false)
+       private Long addressbookId;
+
+       /**
+        * Last locked timestamp
+        */
+       @Temporal (TemporalType.TIMESTAMP)
+       @Column (name = "addressbook_last_locked")
+       private Calendar addressbookLastLocked;
+
+       /**
+        * Last locked timestamp
+        */
+       @Lob
+       @Column (name = "addressbook_last_locked_reason")
+       private String addressbookLastLockedReason;
+
+       /**
+        * Name for this address book
+        */
+       @Basic (optional = false)
+       @Column (name = "addressbook_name", length = 50, nullable = false)
+       private String addressbookName;
+
+       /**
+        * Adress book status
+        */
+       @Basic (optional = false)
+       @Enumerated (EnumType.STRING)
+       @Column (name = "addressbook_status", nullable = false, length = 10)
+       private AddressbokStatus addressbookStatus;
+
+       /**
+        * Connection to "users" table
+        */
+       @JoinColumn (name = "addressbook_user_id", nullable = false)
+       @OneToOne (targetEntity = LoginUser.class, optional = false, cascade = CascadeType.MERGE)
+       private User addressbookUser;
+
+       /**
+        * Public constructor with address book name
+        * <p>
+        * @param addressbookName Address book name
+        * @param addressbookUser User instance
+        * @param addressbookCreated When this entry has been created
+        */
+       public UserAddressbook (final String addressbookName, final User addressbookUser, final Calendar addressbookCreated) {
+               // Call default constructor
+               this();
+
+               // Set name, user instance and creation timestamp
+               this.addressbookName = addressbookName;
+               this.addressbookUser = addressbookUser;
+               this.addressbookCreated = addressbookCreated;
+       }
+
+       /**
+        * Default protected constructor
+        */
+       protected UserAddressbook () {
+               // Set status to UNLOCKED
+               this.addressbookStatus = AddressbokStatus.UNLOCKED;
+       }
+
+       @Override
+       public int compareTo (final Addressbook addressbook) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+       }
+
+       @Override
+       public boolean equals (final Object object) {
+               if (object == null) {
+                       return false;
+               } else if (this.getClass() != object.getClass()) {
+                       return false;
+               }
+
+               final Addressbook other = (Addressbook) object;
+
+               if (!Objects.equals(this.getAddressbookName(), other.getAddressbookName())) {
+                       return false;
+               } else if (!Objects.equals(this.getAddressbookUser(), other.getAddressbookUser())) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       @Override
+       public int hashCode () {
+               int hash = 7;
+               hash = 59 * hash + Objects.hashCode(this.getAddressbookName());
+               hash = 59 * hash + Objects.hashCode(this.getAddressbookUser());
+               return hash;
+       }
+
+       @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 Calendar getAddressbookLastLocked () {
+               return this.addressbookLastLocked;
+       }
+
+       @Override
+       public void setAddressbookLastLocked (final Calendar addressbookLastLocked) {
+               this.addressbookLastLocked = addressbookLastLocked;
+       }
+
+       @Override
+       public String getAddressbookLastLockedReason () {
+               return this.addressbookLastLockedReason;
+       }
+
+       @Override
+       public void setAddressbookLastLockedReason (final String addressbookLastLockedReason) {
+               this.addressbookLastLockedReason = addressbookLastLockedReason;
+       }
+
+       @Override
+       public String getAddressbookName () {
+               return this.addressbookName;
+       }
+
+       @Override
+       public void setAddressbookName (final String addressbookName) {
+               this.addressbookName = addressbookName;
+       }
+
+       @Override
+       public AddressbokStatus getAddressbookStatus () {
+               return this.addressbookStatus;
+       }
+
+       @Override
+       public void setAddressbookStatus (final AddressbokStatus addressbookStatus) {
+               this.addressbookStatus = addressbookStatus;
+       }
+
+       @Override
+       public User getAddressbookUser () {
+               return this.addressbookUser;
+       }
+
+       @Override
+       public void setAddressbookUser (final User addressbookUser) {
+               this.addressbookUser = addressbookUser;
+       }
+
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/entry/AddressbookEntry.java b/src/org/mxchange/jjobs/model/addressbook/entry/AddressbookEntry.java
new file mode 100644 (file)
index 0000000..8bab00c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook.entry;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcontactsbusiness.BusinessContact;
+
+/**
+ * A POJI for addressbook entries
+ * <p>
+ * @author Roland Haeder
+ */
+public interface AddressbookEntry extends Serializable {
+
+       /**
+        * Getter for id number
+        * <p>
+        * @return Id number
+        */
+       Long getAddressbookEntryId ();
+
+       /**
+        * Setter for id number
+        * <p>
+        * @param addressbookEntryId Id number
+        */
+       void setAddressbookEntryId (final Long addressbookEntryId);
+
+       /**
+        * Getter for business contact
+        * <p>
+        * @return Business contact
+        */
+       BusinessContact getAddressbookEntryBusinessContact ();
+
+       /**
+        * Setter for business contact
+        * <p>
+        * @param addressbookEntryBusinessContact Business contact
+        */
+       void setAddressbookEntryBusinessContact (final BusinessContact addressbookEntryBusinessContact);
+
+       /**
+        * Getter for entry created timestamp
+        * <p>
+        * @return Entry created timestamp
+        */
+       Calendar getAddressbookEntryCreated ();
+
+       /**
+        * Setter for entry created timestamp
+        * <p>
+        * @param addressbookEntryCreated Entry created timestamp
+        */
+       void setAddressbookEntryCreated (final Calendar addressbookEntryCreated);
+
+       /**
+        * Getter for private contact
+        * <p>
+        * @return Private contact
+        */
+       Contact getAddressbookEntryPrivateContact ();
+
+       /**
+        * Setter for private contact
+        * <p>
+        * @param addressbookEntryPrivateContact Private contact
+        */
+       void setAddressbookEntryPrivateContact (final Contact addressbookEntryPrivateContact);
+
+       /**
+        * Getter for address book
+        * <p>
+        * @return Address book
+        */
+       Addressbook getAddressbookId ();
+
+       /**
+        * Setter for address book
+        * <p>
+        * @param addressbookId Address book
+        */
+       void setAddressbookId (final Addressbook addressbookId);
+
+       @Override
+       boolean equals (final Object object);
+
+       @Override
+       int hashCode ();
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/entry/UserAddressbookEntry.java b/src/org/mxchange/jjobs/model/addressbook/entry/UserAddressbookEntry.java
new file mode 100644 (file)
index 0000000..fba3327
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook.entry;
+
+import java.util.Calendar;
+import java.util.Objects;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jjobs.model.addressbook.UserAddressbook;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcontacts.contact.UserContact;
+import org.mxchange.jcontactsbusiness.BusinessContact;
+import org.mxchange.jcontactsbusiness.CompanyContact;
+
+/**
+ * A POJO for address book entries
+ * <p>
+ * @author Roland Haeder
+ */
+@Entity (name = "addressbook_entries")
+@Table (name = "addressbook_entries")
+@NamedQueries (
+               @NamedQuery (
+                               name = "SearchUsersAddressbookEntries",
+                               query = "SELECT e FROM addressbook_entries AS e INNER JOIN addressbooks AS a ON e.addressbookId = a WHERE e.addressbookId = :addressbook AND a.addressbookUser = :owner ORDER BY e.addressbookEntryId ASC")
+)
+public class UserAddressbookEntry implements AddressbookEntry, Comparable<AddressbookEntry> {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 178_581_768_581_960L;
+
+       /**
+        * Connection to table "business_contacts" (commercial contacts)
+        */
+       @JoinColumn (name = "entry_business_contact_id", updatable = false)
+       @OneToOne (targetEntity = CompanyContact.class, cascade = CascadeType.MERGE)
+       private BusinessContact addressbookEntryBusinessContact;
+
+       /**
+        * When this address book entry has been created
+        */
+       @Basic (optional = false)
+       @Temporal (TemporalType.TIMESTAMP)
+       @Column (name = "entry_created", nullable = false, updatable = false)
+       private Calendar addressbookEntryCreated;
+
+       /**
+        * Id number
+        */
+       @Id
+       @GeneratedValue (strategy = GenerationType.IDENTITY)
+       @Column (name = "entry_id", nullable = false, updatable = false)
+       private Long addressbookEntryId;
+
+       /**
+        * Connection to table "contacts" (private contacts)
+        */
+       @JoinColumn (name = "entry_private_contact_id", updatable = false)
+       @OneToOne (targetEntity = UserContact.class, cascade = CascadeType.MERGE)
+       private Contact addressbookEntryPrivateContact;
+
+       /**
+        * Connection to table "addressbooks"
+        */
+       @JoinColumn (name = "entry_addressbook_id", nullable = false, updatable = false)
+       @OneToOne (targetEntity = UserAddressbook.class, optional = false, cascade = CascadeType.MERGE)
+       private Addressbook addressbookId;
+
+       @Override
+       public int compareTo (final AddressbookEntry addressbookEntry) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+       }
+
+       @Override
+       public boolean equals (final Object object) {
+               if (object == null) {
+                       return false;
+               } else if (this.getClass() != object.getClass()) {
+                       return false;
+               }
+
+               final AddressbookEntry other = (AddressbookEntry) object;
+
+               if (!Objects.equals(this.getAddressbookEntryBusinessContact(), other.getAddressbookEntryBusinessContact())) {
+                       return false;
+               } else if (!Objects.equals(this.getAddressbookEntryPrivateContact(), other.getAddressbookEntryPrivateContact())) {
+                       return false;
+               } else if (!Objects.equals(this.getAddressbookId(), other.getAddressbookId())) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       @Override
+       public int hashCode () {
+               int hash = 3;
+               hash = 19 * hash + Objects.hashCode(this.getAddressbookEntryBusinessContact());
+               hash = 19 * hash + Objects.hashCode(this.getAddressbookEntryPrivateContact());
+               hash = 19 * hash + Objects.hashCode(this.getAddressbookId());
+               return hash;
+       }
+
+       @Override
+       public BusinessContact getAddressbookEntryBusinessContact () {
+               return this.addressbookEntryBusinessContact;
+       }
+
+       @Override
+       public void setAddressbookEntryBusinessContact (final BusinessContact addressbookEntryBusinessContact) {
+               this.addressbookEntryBusinessContact = addressbookEntryBusinessContact;
+       }
+
+       @Override
+       public Calendar getAddressbookEntryCreated () {
+               return this.addressbookEntryCreated;
+       }
+
+       @Override
+       public void setAddressbookEntryCreated (final Calendar addressbookEntryCreated) {
+               this.addressbookEntryCreated = addressbookEntryCreated;
+       }
+
+       @Override
+       public Long getAddressbookEntryId () {
+               return this.addressbookEntryId;
+       }
+
+       @Override
+       public void setAddressbookEntryId (final Long addressbookEntryId) {
+               this.addressbookEntryId = addressbookEntryId;
+       }
+
+       @Override
+       public Contact getAddressbookEntryPrivateContact () {
+               return this.addressbookEntryPrivateContact;
+       }
+
+       @Override
+       public void setAddressbookEntryPrivateContact (final Contact addressbookEntryPrivateContact) {
+               this.addressbookEntryPrivateContact = addressbookEntryPrivateContact;
+       }
+
+       @Override
+       public Addressbook getAddressbookId () {
+               return this.addressbookId;
+       }
+
+       @Override
+       public void setAddressbookId (final Addressbook addressbookId) {
+               this.addressbookId = addressbookId;
+       }
+
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/shared/AddressbookShare.java b/src/org/mxchange/jjobs/model/addressbook/shared/AddressbookShare.java
new file mode 100644 (file)
index 0000000..920a6a9
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook.shared;
+
+import java.text.MessageFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Objects;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jjobs.model.addressbook.UserAddressbook;
+import org.mxchange.jusercore.model.user.LoginUser;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A POJO for sharing address books with other users
+ * <p>
+ * @author Roland Haeder
+ */
+@Entity (name = "addressbook_shares")
+@Table (name = "addressbook_shares")
+@NamedQueries (
+               {
+                       @NamedQuery (
+                                       name = "SearchUserSharedAddressbooks",
+                                       query = "SELECT s FROM addressbook_shares AS s WHERE s.shareUserOwner = :user ORDER BY s.shareId ASC"
+                       ),
+                       @NamedQuery (
+                                       name = "SearchShareeAddressbookShare",
+                                       query = "SELECT s FROM addressbook_shares AS s WHERE s.shareAddressbook = :addressbook AND s.shareUserSharee = :sharee"
+                       )
+               }
+)
+public class AddressbookShare implements ShareableAddressbook, Comparable<ShareableAddressbook> {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 167_889_678_177_691_690L;
+
+       /**
+        * Address book this share is for
+        */
+       @JoinColumn (name = "share_addressbook_id", nullable = false, updatable = false)
+       @OneToOne (targetEntity = UserAddressbook.class, cascade = CascadeType.MERGE, optional = false)
+       private Addressbook shareAddressbook;
+
+       /**
+        * When this share has been created
+        */
+       @Basic (optional = false)
+       @Temporal (TemporalType.TIMESTAMP)
+       @Column (name = "share_created", nullable = false, updatable = false)
+       private Calendar shareCreated;
+
+       /**
+        * Id number
+        */
+       @Id
+       @GeneratedValue (strategy = GenerationType.IDENTITY)
+       @Column (name = "share_id", length = 20, nullable = false, updatable = false)
+       private Long shareId;
+
+       /**
+        * User who is owning the share
+        */
+       @JoinColumn (name = "share_owner_id", nullable = false, updatable = false)
+       @OneToOne (targetEntity = LoginUser.class, cascade = CascadeType.MERGE, optional = false)
+       private User shareUserOwner;
+
+       /**
+        * User the address book is shared with
+        */
+       @JoinColumn (name = "share_sharee_id", nullable = false, updatable = false)
+       @OneToOne (targetEntity = LoginUser.class, cascade = CascadeType.MERGE, optional = false)
+       private User shareUserSharee;
+
+       /**
+        * Constructor with address book and sharee instance. Both parameters must
+        * not be null, their id numbers must be set and the adress book's user
+        * instance must be set and have a valid id set.
+        * <p>
+        * @param addressbook Address book instance
+        * @param sharee User sharee instance
+        */
+       public AddressbookShare (final Addressbook addressbook, final User sharee) {
+               // Call protected constructor
+               this();
+
+               // Check all conditions
+               if (null == sharee) {
+                       // Throw NPE
+                       throw new NullPointerException("sharee is null"); //NOI18N
+               } else if (sharee.getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("sharee.userId is null"); //NOI18N
+               } else if (sharee.getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalStateException(MessageFormat.format("sharee.userId={0} is invalid", sharee.getUserId())); //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(), sharee)) {
+                       // Sharing with yourself!
+                       throw new IllegalStateException("User tries to share with himself."); //NOI18N
+               }
+
+               // Set all instances
+               this.shareAddressbook = addressbook;
+               this.shareUserOwner = addressbook.getAddressbookUser();
+               this.shareUserSharee = sharee;
+               this.shareCreated = new GregorianCalendar();
+       }
+
+       /**
+        * Default constructor for entity manager
+        */
+       protected AddressbookShare () {
+       }
+
+       @Override
+       public int compareTo (final ShareableAddressbook share) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+       }
+
+       @Override
+       public boolean equals (final Object object) {
+               if (object == null) {
+                       return false;
+               } else if (this.getClass() != object.getClass()) {
+                       return false;
+               }
+
+               final ShareableAddressbook other = (ShareableAddressbook) object;
+
+               if (!Objects.equals(this.getShareAddressbook(), other.getShareAddressbook())) {
+                       return false;
+               } else if (!Objects.equals(this.getShareUserOwner(), other.getShareUserOwner())) {
+                       return false;
+               } else if (!Objects.equals(this.getShareUserOwner(), other.getShareUserOwner())) {
+                       return false;
+               }
+
+               return Objects.equals(this.getShareUserSharee(), other.getShareUserSharee());
+       }
+
+       @Override
+       public int hashCode () {
+               int hash = 7;
+               hash = 19 * hash + Objects.hashCode(this.getShareAddressbook());
+               hash = 19 * hash + Objects.hashCode(this.getShareUserOwner());
+               hash = 19 * hash + Objects.hashCode(this.getShareUserSharee());
+               return hash;
+       }
+
+       @Override
+       public Addressbook getShareAddressbook () {
+               return this.shareAddressbook;
+       }
+
+       @Override
+       public void setShareAddressbook (final Addressbook shareAddressbook) {
+               this.shareAddressbook = shareAddressbook;
+       }
+
+       @Override
+       public Calendar getShareCreated () {
+               return this.shareCreated;
+       }
+
+       @Override
+       public void setShareCreated (final Calendar shareCreated) {
+               this.shareCreated = shareCreated;
+       }
+
+       @Override
+       public Long getShareId () {
+               return this.shareId;
+       }
+
+       @Override
+       public void setShareId (final Long shareId) {
+               this.shareId = shareId;
+       }
+
+       @Override
+       public User getShareUserOwner () {
+               return this.shareUserOwner;
+       }
+
+       @Override
+       public void setShareUserOwner (final User shareUserOwner) {
+               this.shareUserOwner = shareUserOwner;
+       }
+
+       @Override
+       public User getShareUserSharee () {
+               return this.shareUserSharee;
+       }
+
+       @Override
+       public void setShareUserSharee (final User shareUserSharee) {
+               this.shareUserSharee = shareUserSharee;
+       }
+
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/shared/ShareableAddressbook.java b/src/org/mxchange/jjobs/model/addressbook/shared/ShareableAddressbook.java
new file mode 100644 (file)
index 0000000..b091a45
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook.shared;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A POJI for shared address books
+ * <p>
+ * @author Roland Haeder
+ */
+public interface ShareableAddressbook extends Serializable {
+
+       /**
+        * Getter for shared address book instance
+        * <p>
+        * @return Shared address book instance
+        */
+       Addressbook getShareAddressbook ();
+
+       /**
+        * Setter for shared address book instance
+        * <p>
+        * @param shareAddressbook Shared address book instance
+        */
+       void setShareAddressbook (final Addressbook shareAddressbook);
+
+       /**
+        * Getter for id number
+        * <p>
+        * @return Id number
+        */
+       Long getShareId ();
+
+       /**
+        * Setter for id number
+        * <p>
+        * @param shareId Id number
+        */
+       void setShareId (final Long shareId);
+
+       /**
+        * Getter for address book owner instance
+        * <p>
+        * @return Address book owner instance
+        */
+       User getShareUserOwner ();
+
+       /**
+        * Setter for address book owner instance
+        * <p>
+        * @param shareUserOwner Address book owner instance
+        */
+       void setShareUserOwner (final User shareUserOwner);
+
+       /**
+        * Getter for address book sharee instance
+        * <p>
+        * @return Address book sharee instance
+        */
+       User getShareUserSharee ();
+
+       /**
+        * Setter for address book sharee instance
+        * <p>
+        * @param shareUserSharer Address book sharee instance
+        */
+       void setShareUserSharee (final User shareUserSharer);
+
+       /**
+        * Getter for share creation timestamp
+        * <p>
+        * @return Share creation timestamp
+        */
+       Calendar getShareCreated ();
+
+       /**
+        * Setter for share creation timestamp
+        * <p>
+        * @param shareCreated Share creation timestamp
+        */
+       void setShareCreated (final Calendar shareCreated);
+
+       @Override
+       boolean equals (final Object object);
+
+       @Override
+       int hashCode ();
+}
diff --git a/src/org/mxchange/jjobs/model/addressbook/status/AddressbokStatus.java b/src/org/mxchange/jjobs/model/addressbook/status/AddressbokStatus.java
new file mode 100644 (file)
index 0000000..527fbca
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.addressbook.status;
+
+import java.io.Serializable;
+
+/**
+ * An enum for the addressbook status
+ * <p>
+ * @author Roland Haeder
+ */
+public enum AddressbokStatus implements Serializable {
+
+       /**
+        * When the addressbook is unlocked
+        */
+       UNLOCKED("ADDRESSBOOK_STATUS_UNLOCKED"), //NOI18N
+
+       /**
+        * When the addressbook is locked by administrator
+        */
+       LOCKED("ADDRESSBOOK_STATUS_LOCKED"); //NOI18N
+
+       /**
+        * Message key
+        */
+       private final String messageKey;
+
+       /**
+        * Constructor
+        * <p>
+        * @param messageKey Message key for this enum
+        */
+       private AddressbokStatus (final String messageKey) {
+               this.messageKey = messageKey;
+       }
+
+       /**
+        * Getter for message key
+        * <p>
+        * @return Message key
+        */
+       public String getMessageKey () {
+               return this.messageKey;
+       }
+}
diff --git a/src/org/mxchange/jjobs/model/shared/SharedAddressbooksSessionBeanRemote.java b/src/org/mxchange/jjobs/model/shared/SharedAddressbooksSessionBeanRemote.java
new file mode 100644 (file)
index 0000000..959ecce
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.model.shared;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.ejb.Remote;
+import org.mxchange.jjobs.exceptions.UserAlreadySharingAddressbookException;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jjobs.model.addressbook.shared.ShareableAddressbook;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A remote interface for sharing address books
+ * <p>
+ * @author Roland Haeder
+ */
+@Remote
+public interface SharedAddressbooksSessionBeanRemote extends Serializable {
+
+       /**
+        * Retrieves a list of all user's shared address books. The list contains
+        * only the shares. But the address books and sharee can be easily
+        * extracted.
+        * <p>
+        * @param user User instance to get list of shared address books (shares)
+        * from
+        *
+        * @return List of shares (= shared address book entries)
+        */
+       List<ShareableAddressbook> allSharedAddressbooks (final User user);
+
+       /**
+        * Starts an address book share between currently logged-in user and
+        * assigned user for current address book.
+        * <p>
+        * @param sharee User sharee instance
+        * @param addressbook Address book instance
+        *
+        * @return Updated share instance
+        *
+        * @throws
+        * org.mxchange.jjobs.exceptions.UserAlreadySharingAddressbookException
+        * When the user is already sharing the address book
+        */
+       ShareableAddressbook startSharing (final User sharee, final Addressbook addressbook) throws UserAlreadySharingAddressbookException;
+
+       /**
+        * Checks if the given user is sharing address books with others
+        * <p>
+        * @param user User instance
+        *
+        * @return Whether the user is sharing address books
+        */
+       Boolean isUserSharingAddressbooks (final User user);
+
+}
diff --git a/src/org/mxchange/jjobs/validator/addressbook/AddressbookIdValidator.java b/src/org/mxchange/jjobs/validator/addressbook/AddressbookIdValidator.java
new file mode 100644 (file)
index 0000000..f93bc65
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.validator.addressbook;
+
+import java.text.MessageFormat;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.ValidatorException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jjobs.exceptions.AddressbookNotFoundException;
+import org.mxchange.jjobs.model.addressbook.Addressbook;
+import org.mxchange.jjobs.model.addressbook.AddressbookSessionBeanRemote;
+import org.mxchange.jcoreee.validator.number.BaseLongValidator;
+import org.mxchange.jcoreeelogger.beans.local.logger.Log;
+import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
+
+/**
+ * A validator for address book id verification
+ * <p>
+ * @author Roland Haeder
+ */
+@FacesValidator (value = "AddressbookIdValidator")
+public class AddressbookIdValidator extends BaseLongValidator {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 158_768_467_186_951_809L;
+
+       /**
+        * Remote bean
+        */
+       private AddressbookSessionBeanRemote addressbookBean;
+
+       /**
+        * Logger instance
+        */
+       @Log
+       private LoggerBeanLocal loggerBeanLocal;
+
+       /**
+        * Public consutructor
+        */
+       public AddressbookIdValidator () {
+               // 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
+
+                       // ... and user controller
+                       this.addressbookBean = (AddressbookSessionBeanRemote) context.lookup("java:global/addressbook-ejb/addressbook!org.mxchange.addressbook.model.addressbook.AddressbookSessionBeanRemote"); //NOI18N
+               } catch (final NamingException ex) {
+                       // Continue to throw it
+                       throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
+               }
+       }
+
+       @Override
+       public void validate (final FacesContext context, final UIComponent component, final Object value) throws ValidatorException {
+               // Trace message
+               this.loggerBeanLocal.logTrace(MessageFormat.format("validate: context={0},component={1},value={2} - CALLED!", context, component, value)); //NOI18N
+
+               // All accepted, required fields
+               String[] requiredFileds = {"addressbookId"}; //NOI18N
+
+               // Pre-validation (example: not null, not a string, empty string ...)
+               super.preValidate(context, component, value, requiredFileds, false);
+
+               // Cast to long
+               Long addressbookId = (Long) value;
+
+               // Is the address book id valid?
+               if (!this.addressbookBean.isAddressbookIdUsed(addressbookId)) {
+                       // Is not valid
+                       throw new ValidatorException(new FacesMessage(MessageFormat.format("No address book found with id {0}. Please check your link.", addressbookId))); //NOI18N
+               }
+
+               // Init variable
+               Addressbook addressbook;
+
+               // Try it
+               try {
+                       // Get full data
+                       addressbook = this.addressbookBean.getAddressbookById(addressbookId);
+
+                       // Is it set?
+                       if (addressbook == null) {
+                               // Is null?!
+                               throw new NullPointerException(MessageFormat.format("addressbook for id={0} is null", addressbookId)); //NOI18N
+                       }
+               } catch (final AddressbookNotFoundException ex) {
+                       // Continue to throw
+                       throw new ValidatorException(new FacesMessage(MessageFormat.format("Cannot find address book with id {0}", addressbookId)), ex); //NOI18N
+               }
+
+               // Trace message
+               this.loggerBeanLocal.logTrace("validate: EXIT!"); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/jjobs/validator/booleans/UserProfileVisibilityValidator.java b/src/org/mxchange/jjobs/validator/booleans/UserProfileVisibilityValidator.java
new file mode 100644 (file)
index 0000000..1d73fb0
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.validator.booleans;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import org.mxchange.jcoreee.validator.bool.BaseBooleanValidator;
+
+/**
+ * A validator for user profile visibility
+ * <p>
+ * @author Roland Haeder
+ */
+@FacesValidator (value = "UserProfileVisibilityValidator")
+public class UserProfileVisibilityValidator extends BaseBooleanValidator implements Validator {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 185_768_717_676_910_450L;
+
+       @Override
+       public void validate (final FacesContext context, final UIComponent component, final Object value) throws ValidatorException {
+               // Trace message
+               //this.getLogger().logTrace(MessageFormat.format("validate: context={0},component={1},value={2} - CALLED!", context, component, value)); //NOI18N
+
+               // All accepted, required fields
+               String[] requiredFileds = {"publicUserProfileFlag"}; //NOI18N
+
+               // Pre-validation (example: not null, not a string, empty string ...)
+               super.preValidate(context, component, value, requiredFileds, false);
+
+               // Trace message
+               //this.getLogger().logTrace("validate: EXIT!"); //NOI18N
+       }
+
+}
diff --git a/src/org/mxchange/jjobs/validator/names/AddressbookNameValidator.java b/src/org/mxchange/jjobs/validator/names/AddressbookNameValidator.java
new file mode 100644 (file)
index 0000000..27755ab
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.validator.names;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import org.mxchange.jcoreee.validator.string.BaseStringValidator;
+
+/**
+ * A validation class for addressbook names, such as first name or family name.
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@FacesValidator (value = "AddressbookNameValidator")
+public class AddressbookNameValidator extends BaseStringValidator implements Validator {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 27_587_896_710_689_451L;
+
+       @Override
+       public void validate (final FacesContext context, final UIComponent component, final Object value) throws ValidatorException {
+               // Trace message
+               //this.getLogger().logTrace(MessageFormat.format("validate: context={0},component={1},value={2} - CALLED!", context, component, value)); //NOI18N
+
+               // All accepted, required fields
+               String[] requiredFileds = {"addressbookName"}; //NOI18N
+
+               // Pre-validation (example: not null, not a string, empty string ...)
+               super.preValidate(context, component, value, requiredFileds, false);
+
+               // Trace message
+               //this.getLogger().logTrace("validate: EXIT!"); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/jjobs/validator/user/UserIdValidator.java b/src/org/mxchange/jjobs/validator/user/UserIdValidator.java
new file mode 100644 (file)
index 0000000..139a9a9
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.validator.user;
+
+import java.text.MessageFormat;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.enterprise.event.Observes;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcoreee.validator.number.BaseLongValidator;
+import org.mxchange.jcoreeelogger.beans.local.logger.Log;
+import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
+import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
+
+/**
+ * A validator for user ids
+ * <p>
+ * @author Roland Haeder
+ */
+@FacesValidator (value = "UserIdValidator")
+public class UserIdValidator extends BaseLongValidator implements Validator {
+
+       /**
+        * Cached user status
+        */
+       private static final Set<Long> cachedStatus = new TreeSet<>();
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 12_869_569_314_764_690L;
+
+       /**
+        * Logger instance
+        */
+       @Log
+       private LoggerBeanLocal loggerBeanLocal;
+
+       /**
+        * Remote bean
+        */
+       private UserSessionBeanRemote userBean;
+
+       /**
+        * Initialization of this converter
+        */
+       public UserIdValidator () {
+               // 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
+
+                       // ... and user controller
+                       this.userBean = (UserSessionBeanRemote) context.lookup("java:global/juser-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote"); //NOI18N
+               } catch (final NamingException ex) {
+                       // Continue to throw it
+                       throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
+               }
+       }
+
+       /**
+        * Event fired when the user registration is complete
+        * <p>
+        * @param event User registration event
+        */
+       public void afterRegistrationEvent (final @Observes UserRegisteredEvent event) {
+               // Trace message
+               this.loggerBeanLocal.logTrace(MessageFormat.format("UserIdValidator:afterRegistrationEvent: 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
+               this.loggerBeanLocal.logDebug(MessageFormat.format("UserIdValidator:afterRegistrationEvent: registeredUser={0}", registeredUser)); //NOI18N
+
+               // Update cache
+               UserIdValidator.cachedStatus.add(registeredUser.getUserId());
+
+               // Trace message
+               this.loggerBeanLocal.logTrace("UserIdValidator:afterRegistrationEvent: EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void validate (final FacesContext context, final UIComponent component, final Object value) throws ValidatorException {
+               // Trace message
+               this.loggerBeanLocal.logTrace(MessageFormat.format("validate: context={0},component={1},value={2} - CALLED!", context, component, value)); //NOI18N
+
+               // All accepted, required fields
+               String[] requiredFileds = {"userId"}; //NOI18N
+
+               // Pre-validation (example: not null, not a string, empty string ...)
+               super.preValidate(context, component, value, requiredFileds, false);
+
+               // Cast value
+               Long userId = (Long) value;
+
+               // Define variable
+               Boolean ifUserExists;
+
+               // Is a map entry there?
+               if (UserIdValidator.cachedStatus.contains(userId)) {
+                       // Get from cache
+                       ifUserExists = Boolean.TRUE;
+               } else {
+                       // Get status
+                       ifUserExists = this.userBean.ifUserIdExists(userId);
+               }
+
+               // Is the user id valid?
+               if (!ifUserExists) {
+                       // Is not valid
+                       throw new ValidatorException(new FacesMessage(MessageFormat.format("No user found with id {0}. Please check your link.", userId))); //NOI18N
+               }
+
+               // Add to cache if valid
+               UserIdValidator.cachedStatus.add(userId);
+
+               // Trace message
+               this.loggerBeanLocal.logTrace("validate: EXIT!"); //NOI18N
+       }
+
+}
diff --git a/src/org/mxchange/jphone/phonenumbers/smsprovider/AddressbookSmsProviderSingletonBeanRemote.java b/src/org/mxchange/jphone/phonenumbers/smsprovider/AddressbookSmsProviderSingletonBeanRemote.java
new file mode 100644 (file)
index 0000000..0be6c1d
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jphone.phonenumbers.smsprovider;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.ejb.Remote;
+
+/**
+ * A remote interface for cellphone carrier data retrieval
+ * <p>
+ * @author Roland Haeder
+ */
+@Remote
+public interface AddressbookSmsProviderSingletonBeanRemote extends Serializable {
+
+       /**
+        * All registered SMS providers
+        * <p>
+        * @return A list of all SMS providers
+        */
+       List<SmsProvider> allSmsProvider ();
+}