]> git.mxchange.org Git - addressbook-lib.git/commitdiff
Moved project files again + lib/jcore.jar added. This makes jcore more decentralized...
authorRoland Haeder <roland@mxchange.org>
Mon, 17 Aug 2015 15:29:30 +0000 (17:29 +0200)
committerRoland Haeder <roland@mxchange.org>
Mon, 17 Aug 2015 15:29:30 +0000 (17:29 +0200)
Signed-off-by: Roland Häder <roland@mxchange.org>
73 files changed:
.gitignore
Addressbook/README.txt [deleted file]
Addressbook/VERSIONS.txt [deleted file]
Addressbook/build.xml [deleted file]
Addressbook/install/tables.sql [deleted file]
Addressbook/lib/log4j-api-2.3.jar [deleted file]
Addressbook/lib/log4j-core-2.3.jar [deleted file]
Addressbook/nbproject/build-impl.xml [deleted file]
Addressbook/nbproject/genfiles.properties [deleted file]
Addressbook/nbproject/project.properties [deleted file]
Addressbook/nbproject/project.xml [deleted file]
Addressbook/src/log4j2.xml [deleted file]
Addressbook/src/org/mxchange/addressbook/BaseAddressbookSystem.java [deleted file]
Addressbook/src/org/mxchange/addressbook/application/AddressbookApplication.java [deleted file]
Addressbook/src/org/mxchange/addressbook/client/AddressbookClient.java [deleted file]
Addressbook/src/org/mxchange/addressbook/client/BaseAddressbookClient.java [deleted file]
Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java [deleted file]
Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java [deleted file]
Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java [deleted file]
Addressbook/src/org/mxchange/addressbook/contact/book/BookContact.java [deleted file]
Addressbook/src/org/mxchange/addressbook/contact/user/UserContact.java [deleted file]
Addressbook/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java [deleted file]
Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java [deleted file]
Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java [deleted file]
Addressbook/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java [deleted file]
Addressbook/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java [deleted file]
Addressbook/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/AddressbookMenu.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/BaseMenu.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/Menu.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/MenuTools.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java [deleted file]
Addressbook/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java [deleted file]
Addressbook/src/org/mxchange/localization/bundle_de_DE.properties [deleted file]
Addressbook/src/org/mxchange/localization/bundle_en_US.properties [deleted file]
README.txt [new file with mode: 0644]
VERSIONS.txt [new file with mode: 0644]
install/tables.sql [new file with mode: 0644]
lib/jcore.jar [new file with mode: 0644]
lib/log4j-api-2.3.jar [new file with mode: 0644]
lib/log4j-core-2.3.jar [new file with mode: 0644]
nbproject/build-impl.xml [new file with mode: 0644]
nbproject/genfiles.properties [new file with mode: 0644]
nbproject/project.properties [new file with mode: 0644]
nbproject/project.xml [new file with mode: 0644]
src/log4j2.xml [new file with mode: 0644]
src/org/mxchange/addressbook/BaseAddressbookSystem.java [new file with mode: 0644]
src/org/mxchange/addressbook/application/AddressbookApplication.java [new file with mode: 0644]
src/org/mxchange/addressbook/client/AddressbookClient.java [new file with mode: 0644]
src/org/mxchange/addressbook/client/BaseAddressbookClient.java [new file with mode: 0644]
src/org/mxchange/addressbook/client/console/ConsoleClient.java [new file with mode: 0644]
src/org/mxchange/addressbook/client/gui/AddressbookFrame.java [new file with mode: 0644]
src/org/mxchange/addressbook/client/gui/SwingClient.java [new file with mode: 0644]
src/org/mxchange/addressbook/contact/book/BookContact.java [new file with mode: 0644]
src/org/mxchange/addressbook/contact/user/UserContact.java [new file with mode: 0644]
src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java [new file with mode: 0644]
src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java [new file with mode: 0644]
src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java [new file with mode: 0644]
src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java [new file with mode: 0644]
src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java [new file with mode: 0644]
src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/AddressbookMenu.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/BaseMenu.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/Menu.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/MenuTools.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/console/ConsoleMenu.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/item/BaseMenuItem.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java [new file with mode: 0644]
src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java [new file with mode: 0644]
src/org/mxchange/localization/bundle_de_DE.properties [new file with mode: 0644]
src/org/mxchange/localization/bundle_en_US.properties [new file with mode: 0644]

index 3d96b71e0395206311952b8d4b36070a267698d1..8f32b37c93689662609636e2c3c1390022a19cf6 100644 (file)
@@ -1,6 +1,6 @@
-/Addressbook/nbproject/private/\r
-/Addressbook/manifest.mf\r
-/Addressbook/build/\r
-/Addressbook/data/*.*\r
-/Addressbook/dist/\r
-/Addressbook/*.properties\r
+/nbproject/private/\r
+/manifest.mf\r
+/build/\r
+/data/*.*\r
+/dist/\r
+/*.properties\r
diff --git a/Addressbook/README.txt b/Addressbook/README.txt
deleted file mode 100644 (file)
index 20590e3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-How to launch:
-==============
-
-1) Build it: (you need ant tools)
-ant jar
-
-2) Go to dist folder and create "data":
-cd dist
-mkdir data
-
-3) Launch it
-$ java -jar Addressbook.jar
-
-4) The GUI can also be launched:
-$ java -jar Addressbook.jar -gui
-
-If you got an exception, maybe you bumbed into a stub method (unfinished). To reduce possibilities of
-crashes try the usual approach:
-
-$ java -ea -jar Addressbook.jar -gui
-
-Please report any errors back to me. And yes, not all is finished. :)
-
-The file config.properties will be created on first run for you. After that you
-can customize it. Supported database backends are:
-
-base64csv - The default backend, BASE64-encoded CSV strings
-mysql     - The unfinished MySQL backend
-
-Good luck!
diff --git a/Addressbook/VERSIONS.txt b/Addressbook/VERSIONS.txt
deleted file mode 100644 (file)
index 9d25667..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-============================================
-AddressbookApplication management:
-============================================
-
-Inernet("public" service) and Intranet
-
-Version 1.0+:
-- Single-user local application
-- Fields:
-  + Gender
-  + Surname
-  + Family name
-  + Company name
-  + Street + number
-  + ZIP code
-  + City
-  + Landline number
-  + Fax number
-  + Cell phone number
-  + Email address
-  + Birth day
-  + Comment (?)
-- Edit own data
-- Add new contact
-- Edit contacts
-- Delete contacts
-- Categorization of contacts
-
-Version 1.1+:
-- Permanent storage in database
-
-Version 2.0+:
-- Multi-user web application
-- Local user registration / login / resend confirmation link / password
-  recovery
-- User groups (aka. teams)
-- Administration area (user role)
-  + Create/edit/delete groups
-  + Edit/delete/lock/unlock user
-  + Assign user roles/rights
-- Allow other users / groups to view addressbook
-  + Full addressbook
-  + Only some categories
-- VCard export
-  + Allow users/guests (not recommended)
-- XML export of addressbook and compressable (ZIP)
-- Form to contact other user/group without need of mail program
-  + User can disabled this
-- Directory for ussers/groups (who allowed to be listed)
-  + Simple click to add user to own addressbook
-  + Search form?
-
-Version 2.1+:
-- Multi-language support
-
-Version 2.2+:("socialized")
-- "Social login" (OpenID consumer)
-  + Connect user account to social account
-  + Sync own data?
-- "Social profile"
-  + OpenID provider
-  + RSS/activity feed 
-
-============================================
-Time esitmation:
-============================================
-1.0 (console):
-  + 2 days
-
-1.1 (database):
-  + 2 day
-  + Initial tables: contacts, categories, contact_category
-
-2.0 (web):
-  + 3 days
-  + Additional tables: admins (?), admin_rights, groups,
-   users, user_contacts, user_user_rights, user_category_rights, 
-
-2.1 (language)
-  + 1 day
-  + Additional tables: languages (disable, enable language "pack" ?)
-
-2.2 (social):
-  + 3 days
-  + Additional tables: ???
diff --git a/Addressbook/build.xml b/Addressbook/build.xml
deleted file mode 100644 (file)
index b72f99d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- You may freely edit this file. See commented blocks below for -->
-<!-- some examples of how to customize the build. -->
-<!-- (If you delete it and reopen the project it will be recreated.) -->
-<!-- By default, only the Clean and Build commands use this build script. -->
-<!-- Commands such as Run, Debug, and Test only use this build script if -->
-<!-- the Compile on Save feature is turned off for the project. -->
-<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
-<!-- in the project's Project Properties dialog box.-->
-<project name="Addressbook" default="default" basedir=".">
-    <description>Builds, tests, and runs the project Addressbook.</description>
-    <import file="nbproject/build-impl.xml"/>
-    <!--
-
-    There exist several targets which are by default empty and which can be 
-    used for execution of your tasks. These targets are usually executed 
-    before and after some main targets. They are: 
-
-      -pre-init:                 called before initialization of project properties
-      -post-init:                called after initialization of project properties
-      -pre-compile:              called before javac compilation
-      -post-compile:             called after javac compilation
-      -pre-compile-single:       called before javac compilation of single file
-      -post-compile-single:      called after javac compilation of single file
-      -pre-compile-test:         called before javac compilation of JUnit tests
-      -post-compile-test:        called after javac compilation of JUnit tests
-      -pre-compile-test-single:  called before javac compilation of single JUnit test
-      -post-compile-test-single: called after javac compilation of single JUunit test
-      -pre-jar:                  called before JAR building
-      -post-jar:                 called after JAR building
-      -post-clean:               called after cleaning build products
-
-    (Targets beginning with '-' are not intended to be called on their own.)
-
-    Example of inserting an obfuscator after compilation could look like this:
-
-        <target name="-post-compile">
-            <obfuscate>
-                <fileset dir="${build.classes.dir}"/>
-            </obfuscate>
-        </target>
-
-    For list of available properties check the imported 
-    nbproject/build-impl.xml file. 
-
-
-    Another way to customize the build is by overriding existing main targets.
-    The targets of interest are: 
-
-      -init-macrodef-javac:     defines macro for javac compilation
-      -init-macrodef-junit:     defines macro for junit execution
-      -init-macrodef-debug:     defines macro for class debugging
-      -init-macrodef-java:      defines macro for class execution
-      -do-jar:                  JAR building
-      run:                      execution of project 
-      -javadoc-build:           Javadoc generation
-      test-report:              JUnit report generation
-
-    An example of overriding the target for project execution could look like this:
-
-        <target name="run" depends="Addressbook-impl.jar">
-            <exec dir="bin" executable="launcher.exe">
-                <arg file="${dist.jar}"/>
-            </exec>
-        </target>
-
-    Notice that the overridden target depends on the jar target and not only on 
-    the compile target as the regular run target does. Again, for a list of available 
-    properties which you can use, check the target you are overriding in the
-    nbproject/build-impl.xml file. 
-
-       -->
-</project>
diff --git a/Addressbook/install/tables.sql b/Addressbook/install/tables.sql
deleted file mode 100644 (file)
index a08e1de..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
-SET time_zone = "+00:00";
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
-
-
-DROP TABLE IF EXISTS `contacts`;
-CREATE TABLE IF NOT EXISTS `contacts` (
-`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key',
-  `own_contact` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether own contact',
-  `gender` varchar(10) NOT NULL DEFAULT 'UNKNOWN' COMMENT 'Gender',
-  `surname` varchar(100) NOT NULL COMMENT 'Surname',
-  `family_name` varchar(100) NOT NULL COMMENT 'Family name',
-  `company_name` varchar(255) DEFAULT NULL COMMENT 'Company name',
-  `street` varchar(255) DEFAULT NULL COMMENT 'Street name',
-  `house_number` smallint(5) unsigned DEFAULT NULL COMMENT 'House number',
-  `city` varchar(100) DEFAULT NULL COMMENT 'City name',
-  `zip_code` smallint(5) unsigned DEFAULT NULL COMMENT 'ZIP code',
-  `country_code` char(2) DEFAULT NULL COMMENT 'Country code',
-  `phone_number` varchar(100) DEFAULT NULL COMMENT 'Phone number',
-  `cellphone_number` varchar(100) DEFAULT NULL COMMENT 'Cellphone number',
-  `fax_number` varchar(100) DEFAULT NULL COMMENT 'Fax number',
-  `email_address` varchar(100) DEFAULT NULL COMMENT 'Email addres',
-  `birthday` date DEFAULT NULL COMMENT 'Birth day',
-  `comment` tinytext NOT NULL COMMENT 'Comment',
-  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Entry created',
-  `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Contacts data' AUTO_INCREMENT=1 ;
-
-
-ALTER TABLE `contacts`
- ADD PRIMARY KEY (`id`);
-
-
-ALTER TABLE `contacts`
-MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key';
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/Addressbook/lib/log4j-api-2.3.jar b/Addressbook/lib/log4j-api-2.3.jar
deleted file mode 100644 (file)
index 2a61bbe..0000000
Binary files a/Addressbook/lib/log4j-api-2.3.jar and /dev/null differ
diff --git a/Addressbook/lib/log4j-core-2.3.jar b/Addressbook/lib/log4j-core-2.3.jar
deleted file mode 100644 (file)
index 5438b0b..0000000
Binary files a/Addressbook/lib/log4j-core-2.3.jar and /dev/null differ
diff --git a/Addressbook/nbproject/build-impl.xml b/Addressbook/nbproject/build-impl.xml
deleted file mode 100644 (file)
index 4c95079..0000000
+++ /dev/null
@@ -1,1429 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-*** GENERATED FROM project.xml - DO NOT EDIT  ***\r
-***         EDIT ../build.xml INSTEAD         ***\r
-\r
-For the purpose of easier reading the script\r
-is divided into following sections:\r
-\r
-  - initialization\r
-  - compilation\r
-  - jar\r
-  - execution\r
-  - debugging\r
-  - javadoc\r
-  - test compilation\r
-  - test execution\r
-  - test debugging\r
-  - applet\r
-  - cleanup\r
-\r
-        -->\r
-<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Addressbook-impl">\r
-    <fail message="Please build using Ant 1.8.0 or higher.">\r
-        <condition>\r
-            <not>\r
-                <antversion atleast="1.8.0"/>\r
-            </not>\r
-        </condition>\r
-    </fail>\r
-    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>\r
-    <!-- \r
-                ======================\r
-                INITIALIZATION SECTION \r
-                ======================\r
-            -->\r
-    <target name="-pre-init">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="-pre-init" name="-init-private">\r
-        <property file="nbproject/private/config.properties"/>\r
-        <property file="nbproject/private/configs/${config}.properties"/>\r
-        <property file="nbproject/private/private.properties"/>\r
-    </target>\r
-    <target depends="-pre-init,-init-private" name="-init-user">\r
-        <property file="${user.properties.file}"/>\r
-        <!-- The two properties below are usually overridden -->\r
-        <!-- by the active platform. Just a fallback. -->\r
-        <property name="default.javac.source" value="1.4"/>\r
-        <property name="default.javac.target" value="1.4"/>\r
-    </target>\r
-    <target depends="-pre-init,-init-private,-init-user" name="-init-project">\r
-        <property file="nbproject/configs/${config}.properties"/>\r
-        <property file="nbproject/project.properties"/>\r
-    </target>\r
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">\r
-        <property name="platform.java" value="${java.home}/bin/java"/>\r
-        <available file="${manifest.file}" property="manifest.available"/>\r
-        <condition property="splashscreen.available">\r
-            <and>\r
-                <not>\r
-                    <equals arg1="${application.splash}" arg2="" trim="true"/>\r
-                </not>\r
-                <available file="${application.splash}"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="main.class.available">\r
-            <and>\r
-                <isset property="main.class"/>\r
-                <not>\r
-                    <equals arg1="${main.class}" arg2="" trim="true"/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <condition property="profile.available">\r
-            <and>\r
-                <isset property="javac.profile"/>\r
-                <length length="0" string="${javac.profile}" when="greater"/>\r
-                <matches pattern="1\.[89](\..*)?" string="${javac.source}"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="do.archive">\r
-            <or>\r
-                <not>\r
-                    <istrue value="${jar.archive.disabled}"/>\r
-                </not>\r
-                <istrue value="${not.archive.disabled}"/>\r
-            </or>\r
-        </condition>\r
-        <condition property="do.mkdist">\r
-            <and>\r
-                <isset property="do.archive"/>\r
-                <isset property="libs.CopyLibs.classpath"/>\r
-                <not>\r
-                    <istrue value="${mkdist.disabled}"/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <condition property="do.archive+manifest.available">\r
-            <and>\r
-                <isset property="manifest.available"/>\r
-                <istrue value="${do.archive}"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="do.archive+main.class.available">\r
-            <and>\r
-                <isset property="main.class.available"/>\r
-                <istrue value="${do.archive}"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="do.archive+splashscreen.available">\r
-            <and>\r
-                <isset property="splashscreen.available"/>\r
-                <istrue value="${do.archive}"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="do.archive+profile.available">\r
-            <and>\r
-                <isset property="profile.available"/>\r
-                <istrue value="${do.archive}"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="have.tests">\r
-            <or>\r
-                <available file="${test.src.dir}"/>\r
-            </or>\r
-        </condition>\r
-        <condition property="have.sources">\r
-            <or>\r
-                <available file="${src.dir}"/>\r
-            </or>\r
-        </condition>\r
-        <condition property="netbeans.home+have.tests">\r
-            <and>\r
-                <isset property="netbeans.home"/>\r
-                <isset property="have.tests"/>\r
-            </and>\r
-        </condition>\r
-        <condition property="no.javadoc.preview">\r
-            <and>\r
-                <isset property="javadoc.preview"/>\r
-                <isfalse value="${javadoc.preview}"/>\r
-            </and>\r
-        </condition>\r
-        <property name="run.jvmargs" value=""/>\r
-        <property name="run.jvmargs.ide" value=""/>\r
-        <property name="javac.compilerargs" value=""/>\r
-        <property name="work.dir" value="${basedir}"/>\r
-        <condition property="no.deps">\r
-            <and>\r
-                <istrue value="${no.dependencies}"/>\r
-            </and>\r
-        </condition>\r
-        <property name="javac.debug" value="true"/>\r
-        <property name="javadoc.preview" value="true"/>\r
-        <property name="application.args" value=""/>\r
-        <property name="source.encoding" value="${file.encoding}"/>\r
-        <property name="runtime.encoding" value="${source.encoding}"/>\r
-        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">\r
-            <and>\r
-                <isset property="javadoc.encoding"/>\r
-                <not>\r
-                    <equals arg1="${javadoc.encoding}" arg2=""/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <property name="javadoc.encoding.used" value="${source.encoding}"/>\r
-        <property name="includes" value="**"/>\r
-        <property name="excludes" value=""/>\r
-        <property name="do.depend" value="false"/>\r
-        <condition property="do.depend.true">\r
-            <istrue value="${do.depend}"/>\r
-        </condition>\r
-        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>\r
-        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">\r
-            <and>\r
-                <isset property="endorsed.classpath"/>\r
-                <not>\r
-                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">\r
-            <isset property="profile.available"/>\r
-        </condition>\r
-        <condition else="false" property="jdkBug6558476">\r
-            <and>\r
-                <matches pattern="1\.[56]" string="${java.specification.version}"/>\r
-                <not>\r
-                    <os family="unix"/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <property name="javac.fork" value="${jdkBug6558476}"/>\r
-        <property name="jar.index" value="false"/>\r
-        <property name="jar.index.metainf" value="${jar.index}"/>\r
-        <property name="copylibs.rebase" value="true"/>\r
-        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>\r
-        <condition property="junit.available">\r
-            <or>\r
-                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>\r
-                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>\r
-            </or>\r
-        </condition>\r
-        <condition property="testng.available">\r
-            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>\r
-        </condition>\r
-        <condition property="junit+testng.available">\r
-            <and>\r
-                <istrue value="${junit.available}"/>\r
-                <istrue value="${testng.available}"/>\r
-            </and>\r
-        </condition>\r
-        <condition else="testng" property="testng.mode" value="mixed">\r
-            <istrue value="${junit+testng.available}"/>\r
-        </condition>\r
-        <condition else="" property="testng.debug.mode" value="-mixed">\r
-            <istrue value="${junit+testng.available}"/>\r
-        </condition>\r
-    </target>\r
-    <target name="-post-init">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">\r
-        <fail unless="src.dir">Must set src.dir</fail>\r
-        <fail unless="test.src.dir">Must set test.src.dir</fail>\r
-        <fail unless="build.dir">Must set build.dir</fail>\r
-        <fail unless="dist.dir">Must set dist.dir</fail>\r
-        <fail unless="build.classes.dir">Must set build.classes.dir</fail>\r
-        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>\r
-        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>\r
-        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>\r
-        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>\r
-        <fail unless="dist.jar">Must set dist.jar</fail>\r
-    </target>\r
-    <target name="-init-macrodef-property">\r
-        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">\r
-            <attribute name="name"/>\r
-            <attribute name="value"/>\r
-            <sequential>\r
-                <property name="@{name}" value="${@{value}}"/>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">\r
-        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${src.dir}" name="srcdir"/>\r
-            <attribute default="${build.classes.dir}" name="destdir"/>\r
-            <attribute default="${javac.classpath}" name="classpath"/>\r
-            <attribute default="${javac.processorpath}" name="processorpath"/>\r
-            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="${javac.debug}" name="debug"/>\r
-            <attribute default="${empty.dir}" name="sourcepath"/>\r
-            <attribute default="${empty.dir}" name="gensrcdir"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property location="${build.dir}/empty" name="empty.dir"/>\r
-                <mkdir dir="${empty.dir}"/>\r
-                <mkdir dir="@{apgeneratedsrcdir}"/>\r
-                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">\r
-                    <src>\r
-                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
-                            <include name="*"/>\r
-                        </dirset>\r
-                    </src>\r
-                    <classpath>\r
-                        <path path="@{classpath}"/>\r
-                    </classpath>\r
-                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                    <compilerarg line="${javac.profile.cmd.line.arg}"/>\r
-                    <compilerarg line="${javac.compilerargs}"/>\r
-                    <compilerarg value="-processorpath"/>\r
-                    <compilerarg path="@{processorpath}:${empty.dir}"/>\r
-                    <compilerarg line="${ap.processors.internal}"/>\r
-                    <compilerarg line="${annotation.processing.processor.options}"/>\r
-                    <compilerarg value="-s"/>\r
-                    <compilerarg path="@{apgeneratedsrcdir}"/>\r
-                    <compilerarg line="${ap.proc.none.internal}"/>\r
-                    <customize/>\r
-                </javac>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">\r
-        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${src.dir}" name="srcdir"/>\r
-            <attribute default="${build.classes.dir}" name="destdir"/>\r
-            <attribute default="${javac.classpath}" name="classpath"/>\r
-            <attribute default="${javac.processorpath}" name="processorpath"/>\r
-            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="${javac.debug}" name="debug"/>\r
-            <attribute default="${empty.dir}" name="sourcepath"/>\r
-            <attribute default="${empty.dir}" name="gensrcdir"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property location="${build.dir}/empty" name="empty.dir"/>\r
-                <mkdir dir="${empty.dir}"/>\r
-                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">\r
-                    <src>\r
-                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
-                            <include name="*"/>\r
-                        </dirset>\r
-                    </src>\r
-                    <classpath>\r
-                        <path path="@{classpath}"/>\r
-                    </classpath>\r
-                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                    <compilerarg line="${javac.profile.cmd.line.arg}"/>\r
-                    <compilerarg line="${javac.compilerargs}"/>\r
-                    <customize/>\r
-                </javac>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">\r
-        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${src.dir}" name="srcdir"/>\r
-            <attribute default="${build.classes.dir}" name="destdir"/>\r
-            <attribute default="${javac.classpath}" name="classpath"/>\r
-            <sequential>\r
-                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">\r
-                    <classpath>\r
-                        <path path="@{classpath}"/>\r
-                    </classpath>\r
-                </depend>\r
-            </sequential>\r
-        </macrodef>\r
-        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${build.classes.dir}" name="destdir"/>\r
-            <sequential>\r
-                <fail unless="javac.includes">Must set javac.includes</fail>\r
-                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">\r
-                    <path>\r
-                        <filelist dir="@{destdir}" files="${javac.includes}"/>\r
-                    </path>\r
-                    <globmapper from="*.java" to="*.class"/>\r
-                </pathconvert>\r
-                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>\r
-                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>\r
-                <delete>\r
-                    <files includesfile="${javac.includesfile.binary}"/>\r
-                </delete>\r
-                <delete>\r
-                    <fileset file="${javac.includesfile.binary}"/>\r
-                </delete>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target if="${junit.available}" name="-init-macrodef-junit-init">\r
-        <condition else="false" property="nb.junit.batch" value="true">\r
-            <and>\r
-                <istrue value="${junit.available}"/>\r
-                <not>\r
-                    <isset property="test.method"/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <condition else="false" property="nb.junit.single" value="true">\r
-            <and>\r
-                <istrue value="${junit.available}"/>\r
-                <isset property="test.method"/>\r
-            </and>\r
-        </condition>\r
-    </target>\r
-    <target name="-init-test-properties">\r
-        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>\r
-        <property name="test.binarytestincludes" value=""/>\r
-        <property name="test.binaryexcludes" value=""/>\r
-    </target>\r
-    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">\r
-        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property name="junit.forkmode" value="perTest"/>\r
-                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
-                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="test-sys-prop."/>\r
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <formatter type="brief" usefile="false"/>\r
-                    <formatter type="xml"/>\r
-                    <jvmarg value="-ea"/>\r
-                    <customize/>\r
-                </junit>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">\r
-        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property name="junit.forkmode" value="perTest"/>\r
-                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
-                    <batchtest todir="${build.test.results.dir}">\r
-                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">\r
-                            <filename name="@{testincludes}"/>\r
-                        </fileset>\r
-                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">\r
-                            <filename name="${test.binarytestincludes}"/>\r
-                        </fileset>\r
-                    </batchtest>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="test-sys-prop."/>\r
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <formatter type="brief" usefile="false"/>\r
-                    <formatter type="xml"/>\r
-                    <jvmarg value="-ea"/>\r
-                    <customize/>\r
-                </junit>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>\r
-    <target if="${testng.available}" name="-init-macrodef-testng">\r
-        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">\r
-                    <isset property="test.method"/>\r
-                </condition>\r
-                <union id="test.set">\r
-                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">\r
-                        <filename name="@{testincludes}"/>\r
-                    </fileset>\r
-                </union>\r
-                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>\r
-                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="Addressbook" testname="TestNG tests" workingDir="${work.dir}">\r
-                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>\r
-                    <propertyset>\r
-                        <propertyref prefix="test-sys-prop."/>\r
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-                    </propertyset>\r
-                    <customize/>\r
-                </testng>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target name="-init-macrodef-test-impl">\r
-        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element implicit="true" name="customize" optional="true"/>\r
-            <sequential>\r
-                <echo>No tests executed.</echo>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">\r
-        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element implicit="true" name="customize" optional="true"/>\r
-            <sequential>\r
-                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
-                    <customize/>\r
-                </j2seproject3:junit>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">\r
-        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element implicit="true" name="customize" optional="true"/>\r
-            <sequential>\r
-                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
-                    <customize/>\r
-                </j2seproject3:testng>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">\r
-        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <sequential>\r
-                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
-                    <customize>\r
-                        <classpath>\r
-                            <path path="${run.test.classpath}"/>\r
-                        </classpath>\r
-                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                        <jvmarg line="${run.jvmargs}"/>\r
-                        <jvmarg line="${run.jvmargs.ide}"/>\r
-                    </customize>\r
-                </j2seproject3:test-impl>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">\r
-        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property name="junit.forkmode" value="perTest"/>\r
-                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
-                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="test-sys-prop."/>\r
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <formatter type="brief" usefile="false"/>\r
-                    <formatter type="xml"/>\r
-                    <jvmarg value="-ea"/>\r
-                    <jvmarg line="${debug-args-line}"/>\r
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
-                    <customize/>\r
-                </junit>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">\r
-        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property name="junit.forkmode" value="perTest"/>\r
-                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
-                    <batchtest todir="${build.test.results.dir}">\r
-                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">\r
-                            <filename name="@{testincludes}"/>\r
-                        </fileset>\r
-                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">\r
-                            <filename name="${test.binarytestincludes}"/>\r
-                        </fileset>\r
-                    </batchtest>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="test-sys-prop."/>\r
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <formatter type="brief" usefile="false"/>\r
-                    <formatter type="xml"/>\r
-                    <jvmarg value="-ea"/>\r
-                    <jvmarg line="${debug-args-line}"/>\r
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
-                    <customize/>\r
-                </junit>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">\r
-        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <element implicit="true" name="customize" optional="true"/>\r
-            <sequential>\r
-                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
-                    <customize/>\r
-                </j2seproject3:junit-debug>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target if="${testng.available}" name="-init-macrodef-testng-debug">\r
-        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${main.class}" name="testClass"/>\r
-            <attribute default="" name="testMethod"/>\r
-            <element name="customize2" optional="true"/>\r
-            <sequential>\r
-                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">\r
-                    <isset property="test.method"/>\r
-                </condition>\r
-                <condition else="-suitename Addressbook -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">\r
-                    <matches pattern=".*\.xml" string="@{testClass}"/>\r
-                </condition>\r
-                <delete dir="${build.test.results.dir}" quiet="true"/>\r
-                <mkdir dir="${build.test.results.dir}"/>\r
-                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">\r
-                    <customize>\r
-                        <customize2/>\r
-                        <jvmarg value="-ea"/>\r
-                        <arg line="${testng.debug.mode}"/>\r
-                        <arg line="-d ${build.test.results.dir}"/>\r
-                        <arg line="-listener org.testng.reporters.VerboseReporter"/>\r
-                        <arg line="${testng.cmd.args}"/>\r
-                    </customize>\r
-                </j2seproject3:debug>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">\r
-        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${main.class}" name="testClass"/>\r
-            <attribute default="" name="testMethod"/>\r
-            <element implicit="true" name="customize2" optional="true"/>\r
-            <sequential>\r
-                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">\r
-                    <customize2/>\r
-                </j2seproject3:testng-debug>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">\r
-        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <attribute default="${main.class}" name="testClass"/>\r
-            <attribute default="" name="testMethod"/>\r
-            <sequential>\r
-                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
-                    <customize>\r
-                        <classpath>\r
-                            <path path="${run.test.classpath}"/>\r
-                        </classpath>\r
-                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                        <jvmarg line="${run.jvmargs}"/>\r
-                        <jvmarg line="${run.jvmargs.ide}"/>\r
-                    </customize>\r
-                </j2seproject3:test-debug-impl>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">\r
-        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${includes}" name="includes"/>\r
-            <attribute default="${excludes}" name="excludes"/>\r
-            <attribute default="**" name="testincludes"/>\r
-            <attribute default="" name="testmethods"/>\r
-            <attribute default="${main.class}" name="testClass"/>\r
-            <attribute default="" name="testMethod"/>\r
-            <sequential>\r
-                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">\r
-                    <customize2>\r
-                        <syspropertyset>\r
-                            <propertyref prefix="test-sys-prop."/>\r
-                            <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-                        </syspropertyset>\r
-                    </customize2>\r
-                </j2seproject3:testng-debug-impl>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>\r
-    <!--\r
-                pre NB7.2 profiling section; consider it deprecated\r
-            -->\r
-    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>\r
-    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">\r
-        <macrodef name="resolve">\r
-            <attribute name="name"/>\r
-            <attribute name="value"/>\r
-            <sequential>\r
-                <property name="@{name}" value="${env.@{value}}"/>\r
-            </sequential>\r
-        </macrodef>\r
-        <macrodef name="profile">\r
-            <attribute default="${main.class}" name="classname"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property environment="env"/>\r
-                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>\r
-                <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">\r
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                    <jvmarg value="${profiler.info.jvmargs.agent}"/>\r
-                    <jvmarg line="${profiler.info.jvmargs}"/>\r
-                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>\r
-                    <arg line="${application.args}"/>\r
-                    <classpath>\r
-                        <path path="${run.classpath}"/>\r
-                    </classpath>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="run-sys-prop."/>\r
-                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <customize/>\r
-                </java>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">\r
-        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>\r
-        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>\r
-    </target>\r
-    <!--\r
-                end of pre NB7.2 profiling section\r
-            -->\r
-    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">\r
-        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">\r
-            <attribute default="${main.class}" name="name"/>\r
-            <attribute default="${debug.classpath}" name="classpath"/>\r
-            <attribute default="" name="stopclassname"/>\r
-            <sequential>\r
-                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">\r
-                    <classpath>\r
-                        <path path="@{classpath}"/>\r
-                    </classpath>\r
-                </nbjpdastart>\r
-            </sequential>\r
-        </macrodef>\r
-        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">\r
-            <attribute default="${build.classes.dir}" name="dir"/>\r
-            <sequential>\r
-                <nbjpdareload>\r
-                    <fileset dir="@{dir}" includes="${fix.classes}">\r
-                        <include name="${fix.includes}*.class"/>\r
-                    </fileset>\r
-                </nbjpdareload>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target name="-init-debug-args">\r
-        <property name="version-output" value="java version &quot;${ant.java.version}"/>\r
-        <condition property="have-jdk-older-than-1.4">\r
-            <or>\r
-                <contains string="${version-output}" substring="java version &quot;1.0"/>\r
-                <contains string="${version-output}" substring="java version &quot;1.1"/>\r
-                <contains string="${version-output}" substring="java version &quot;1.2"/>\r
-                <contains string="${version-output}" substring="java version &quot;1.3"/>\r
-            </or>\r
-        </condition>\r
-        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">\r
-            <istrue value="${have-jdk-older-than-1.4}"/>\r
-        </condition>\r
-        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">\r
-            <os family="windows"/>\r
-        </condition>\r
-        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">\r
-            <isset property="debug.transport"/>\r
-        </condition>\r
-    </target>\r
-    <target depends="-init-debug-args" name="-init-macrodef-debug">\r
-        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${main.class}" name="classname"/>\r
-            <attribute default="${debug.classpath}" name="classpath"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <java classname="@{classname}" dir="${work.dir}" fork="true">\r
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                    <jvmarg line="${debug-args-line}"/>\r
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
-                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>\r
-                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>\r
-                    <jvmarg line="${run.jvmargs}"/>\r
-                    <jvmarg line="${run.jvmargs.ide}"/>\r
-                    <classpath>\r
-                        <path path="@{classpath}"/>\r
-                    </classpath>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="run-sys-prop."/>\r
-                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <customize/>\r
-                </java>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target name="-init-macrodef-java">\r
-        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">\r
-            <attribute default="${main.class}" name="classname"/>\r
-            <attribute default="${run.classpath}" name="classpath"/>\r
-            <attribute default="jvm" name="jvm"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <java classname="@{classname}" dir="${work.dir}" fork="true">\r
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
-                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>\r
-                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>\r
-                    <jvmarg line="${run.jvmargs}"/>\r
-                    <jvmarg line="${run.jvmargs.ide}"/>\r
-                    <classpath>\r
-                        <path path="@{classpath}"/>\r
-                    </classpath>\r
-                    <syspropertyset>\r
-                        <propertyref prefix="run-sys-prop."/>\r
-                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
-                    </syspropertyset>\r
-                    <customize/>\r
-                </java>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target name="-init-macrodef-copylibs">\r
-        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">\r
-            <attribute default="${manifest.file}" name="manifest"/>\r
-            <element name="customize" optional="true"/>\r
-            <sequential>\r
-                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
-                <pathconvert property="run.classpath.without.build.classes.dir">\r
-                    <path path="${run.classpath}"/>\r
-                    <map from="${build.classes.dir.resolved}" to=""/>\r
-                </pathconvert>\r
-                <pathconvert pathsep=" " property="jar.classpath">\r
-                    <path path="${run.classpath.without.build.classes.dir}"/>\r
-                    <chainedmapper>\r
-                        <flattenmapper/>\r
-                        <filtermapper>\r
-                            <replacestring from=" " to="%20"/>\r
-                        </filtermapper>\r
-                        <globmapper from="*" to="lib/*"/>\r
-                    </chainedmapper>\r
-                </pathconvert>\r
-                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>\r
-                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">\r
-                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>\r
-                    <manifest>\r
-                        <attribute name="Class-Path" value="${jar.classpath}"/>\r
-                        <customize/>\r
-                    </manifest>\r
-                </copylibs>\r
-            </sequential>\r
-        </macrodef>\r
-    </target>\r
-    <target name="-init-presetdef-jar">\r
-        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">\r
-            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">\r
-                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>\r
-            </jar>\r
-        </presetdef>\r
-    </target>\r
-    <target name="-init-ap-cmdline-properties">\r
-        <property name="annotation.processing.enabled" value="true"/>\r
-        <property name="annotation.processing.processors.list" value=""/>\r
-        <property name="annotation.processing.processor.options" value=""/>\r
-        <property name="annotation.processing.run.all.processors" value="true"/>\r
-        <property name="javac.processorpath" value="${javac.classpath}"/>\r
-        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>\r
-        <condition property="ap.supported.internal" value="true">\r
-            <not>\r
-                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>\r
-            </not>\r
-        </condition>\r
-    </target>\r
-    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">\r
-        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">\r
-            <isfalse value="${annotation.processing.run.all.processors}"/>\r
-        </condition>\r
-        <condition else="" property="ap.proc.none.internal" value="-proc:none">\r
-            <isfalse value="${annotation.processing.enabled}"/>\r
-        </condition>\r
-    </target>\r
-    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">\r
-        <property name="ap.cmd.line.internal" value=""/>\r
-    </target>\r
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>\r
-    <!--\r
-                ===================\r
-                COMPILATION SECTION\r
-                ===================\r
-            -->\r
-    <target name="-deps-jar-init" unless="built-jar.properties">\r
-        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>\r
-        <delete file="${built-jar.properties}" quiet="true"/>\r
-    </target>\r
-    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">\r
-        <echo level="warn" message="Cycle detected: Addressbook was already built"/>\r
-    </target>\r
-    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">\r
-        <mkdir dir="${build.dir}"/>\r
-        <touch file="${built-jar.properties}" verbose="false"/>\r
-        <property file="${built-jar.properties}" prefix="already.built.jar."/>\r
-        <antcall target="-warn-already-built-jar"/>\r
-        <propertyfile file="${built-jar.properties}">\r
-            <entry key="${basedir}" value=""/>\r
-        </propertyfile>\r
-        <antcall target="-maybe-call-dep">\r
-            <param name="call.built.properties" value="${built-jar.properties}"/>\r
-            <param location="${project.jcore}" name="call.subproject"/>\r
-            <param location="${project.jcore}/build.xml" name="call.script"/>\r
-            <param name="call.target" value="jar"/>\r
-            <param name="transfer.built-jar.properties" value="${built-jar.properties}"/>\r
-            <param name="transfer.not.archive.disabled" value="true"/>\r
-        </antcall>\r
-    </target>\r
-    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>\r
-    <target depends="init" name="-check-automatic-build">\r
-        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>\r
-    </target>\r
-    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">\r
-        <antcall target="clean"/>\r
-    </target>\r
-    <target depends="init,deps-jar" name="-pre-pre-compile">\r
-        <mkdir dir="${build.classes.dir}"/>\r
-    </target>\r
-    <target name="-pre-compile">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target if="do.depend.true" name="-compile-depend">\r
-        <pathconvert property="build.generated.subdirs">\r
-            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
-                <include name="*"/>\r
-            </dirset>\r
-        </pathconvert>\r
-        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>\r
-    </target>\r
-    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">\r
-        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>\r
-        <copy todir="${build.classes.dir}">\r
-            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
-        </copy>\r
-    </target>\r
-    <target if="has.persistence.xml" name="-copy-persistence-xml">\r
-        <mkdir dir="${build.classes.dir}/META-INF"/>\r
-        <copy todir="${build.classes.dir}/META-INF">\r
-            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>\r
-        </copy>\r
-    </target>\r
-    <target name="-post-compile">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>\r
-    <target name="-pre-compile-single">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">\r
-        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>\r
-        <j2seproject3:force-recompile/>\r
-        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>\r
-    </target>\r
-    <target name="-post-compile-single">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>\r
-    <!--\r
-                ====================\r
-                JAR BUILDING SECTION\r
-                ====================\r
-            -->\r
-    <target depends="init" name="-pre-pre-jar">\r
-        <dirname file="${dist.jar}" property="dist.jar.dir"/>\r
-        <mkdir dir="${dist.jar.dir}"/>\r
-    </target>\r
-    <target name="-pre-jar">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">\r
-        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>\r
-        <touch file="${tmp.manifest.file}" verbose="false"/>\r
-    </target>\r
-    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">\r
-        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>\r
-        <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>\r
-    </target>\r
-    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">\r
-        <manifest file="${tmp.manifest.file}" mode="update">\r
-            <attribute name="Main-Class" value="${main.class}"/>\r
-        </manifest>\r
-    </target>\r
-    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">\r
-        <manifest file="${tmp.manifest.file}" mode="update">\r
-            <attribute name="Profile" value="${javac.profile}"/>\r
-        </manifest>\r
-    </target>\r
-    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">\r
-        <basename file="${application.splash}" property="splashscreen.basename"/>\r
-        <mkdir dir="${build.classes.dir}/META-INF"/>\r
-        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>\r
-        <manifest file="${tmp.manifest.file}" mode="update">\r
-            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>\r
-        </manifest>\r
-    </target>\r
-    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">\r
-        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>\r
-        <echo level="info">To run this application from the command line without Ant, try:</echo>\r
-        <property location="${dist.jar}" name="dist.jar.resolved"/>\r
-        <echo level="info">java -jar "${dist.jar.resolved}"</echo>\r
-    </target>\r
-    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">\r
-        <j2seproject1:jar manifest="${tmp.manifest.file}"/>\r
-        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
-        <property location="${dist.jar}" name="dist.jar.resolved"/>\r
-        <pathconvert property="run.classpath.with.dist.jar">\r
-            <path path="${run.classpath}"/>\r
-            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>\r
-        </pathconvert>\r
-        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">\r
-            <isset property="main.class.available"/>\r
-        </condition>\r
-        <condition else="debug" property="jar.usage.level" value="info">\r
-            <isset property="main.class.available"/>\r
-        </condition>\r
-        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>\r
-    </target>\r
-    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">\r
-        <delete>\r
-            <fileset file="${tmp.manifest.file}"/>\r
-        </delete>\r
-    </target>\r
-    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>\r
-    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>\r
-    <target name="-post-jar">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>\r
-    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>\r
-    <!--\r
-                =================\r
-                EXECUTION SECTION\r
-                =================\r
-            -->\r
-    <target depends="init,compile" description="Run a main class." name="run">\r
-        <j2seproject1:java>\r
-            <customize>\r
-                <arg line="${application.args}"/>\r
-            </customize>\r
-        </j2seproject1:java>\r
-    </target>\r
-    <target name="-do-not-recompile">\r
-        <property name="javac.includes.binary" value=""/>\r
-    </target>\r
-    <target depends="init,compile-single" name="run-single">\r
-        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
-        <j2seproject1:java classname="${run.class}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single" name="run-test-with-main">\r
-        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
-        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>\r
-    </target>\r
-    <!--\r
-                =================\r
-                DEBUGGING SECTION\r
-                =================\r
-            -->\r
-    <target depends="init" if="netbeans.home" name="-debug-start-debugger">\r
-        <j2seproject1:nbjpdastart name="${debug.class}"/>\r
-    </target>\r
-    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">\r
-        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>\r
-    </target>\r
-    <target depends="init,compile" name="-debug-start-debuggee">\r
-        <j2seproject3:debug>\r
-            <customize>\r
-                <arg line="${application.args}"/>\r
-            </customize>\r
-        </j2seproject3:debug>\r
-    </target>\r
-    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>\r
-    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">\r
-        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>\r
-    </target>\r
-    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>\r
-    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">\r
-        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>\r
-        <j2seproject3:debug classname="${debug.class}"/>\r
-    </target>\r
-    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>\r
-    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">\r
-        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>\r
-        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>\r
-    <target depends="init" name="-pre-debug-fix">\r
-        <fail unless="fix.includes">Must set fix.includes</fail>\r
-        <property name="javac.includes" value="${fix.includes}.java"/>\r
-    </target>\r
-    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">\r
-        <j2seproject1:nbjpdareload/>\r
-    </target>\r
-    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>\r
-    <!--\r
-                =================\r
-                PROFILING SECTION\r
-                =================\r
-            -->\r
-    <!--\r
-                pre NB7.2 profiler integration\r
-            -->\r
-    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">\r
-        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
-        <nbprofiledirect>\r
-            <classpath>\r
-                <path path="${run.classpath}"/>\r
-            </classpath>\r
-        </nbprofiledirect>\r
-        <profile/>\r
-    </target>\r
-    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">\r
-        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>\r
-        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
-        <nbprofiledirect>\r
-            <classpath>\r
-                <path path="${run.classpath}"/>\r
-            </classpath>\r
-        </nbprofiledirect>\r
-        <profile classname="${profile.class}"/>\r
-    </target>\r
-    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">\r
-        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
-        <nbprofiledirect>\r
-            <classpath>\r
-                <path path="${run.classpath}"/>\r
-            </classpath>\r
-        </nbprofiledirect>\r
-        <profile classname="sun.applet.AppletViewer">\r
-            <customize>\r
-                <arg value="${applet.url}"/>\r
-            </customize>\r
-        </profile>\r
-    </target>\r
-    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">\r
-        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
-        <nbprofiledirect>\r
-            <classpath>\r
-                <path path="${run.test.classpath}"/>\r
-            </classpath>\r
-        </nbprofiledirect>\r
-        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">\r
-            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>\r
-            <jvmarg value="${profiler.info.jvmargs.agent}"/>\r
-            <jvmarg line="${profiler.info.jvmargs}"/>\r
-            <test name="${profile.class}"/>\r
-            <classpath>\r
-                <path path="${run.test.classpath}"/>\r
-            </classpath>\r
-            <syspropertyset>\r
-                <propertyref prefix="test-sys-prop."/>\r
-                <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
-            </syspropertyset>\r
-            <formatter type="brief" usefile="false"/>\r
-            <formatter type="xml"/>\r
-        </junit>\r
-    </target>\r
-    <!--\r
-                end of pre NB72 profiling section\r
-            -->\r
-    <target if="netbeans.home" name="-profile-check">\r
-        <condition property="profiler.configured">\r
-            <or>\r
-                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>\r
-                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>\r
-            </or>\r
-        </condition>\r
-    </target>\r
-    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">\r
-        <startprofiler/>\r
-        <antcall target="run"/>\r
-    </target>\r
-    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">\r
-        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
-        <startprofiler/>\r
-        <antcall target="run-single"/>\r
-    </target>\r
-    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>\r
-    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">\r
-        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>\r
-        <startprofiler/>\r
-        <antcall target="test-single"/>\r
-    </target>\r
-    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">\r
-        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
-        <startprofiler/>\r
-        <antcal target="run-test-with-main"/>\r
-    </target>\r
-    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">\r
-        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
-        <startprofiler/>\r
-        <antcall target="run-applet"/>\r
-    </target>\r
-    <!--\r
-                ===============\r
-                JAVADOC SECTION\r
-                ===============\r
-            -->\r
-    <target depends="init" if="have.sources" name="-javadoc-build">\r
-        <mkdir dir="${dist.javadoc.dir}"/>\r
-        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">\r
-            <and>\r
-                <isset property="endorsed.classpath.cmd.line.arg"/>\r
-                <not>\r
-                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>\r
-                </not>\r
-            </and>\r
-        </condition>\r
-        <condition else="" property="bug5101868workaround" value="*.java">\r
-            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>\r
-        </condition>\r
-        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">\r
-            <classpath>\r
-                <path path="${javac.classpath}"/>\r
-            </classpath>\r
-            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">\r
-                <filename name="**/*.java"/>\r
-            </fileset>\r
-            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
-                <include name="**/*.java"/>\r
-                <exclude name="*.java"/>\r
-            </fileset>\r
-            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>\r
-        </javadoc>\r
-        <copy todir="${dist.javadoc.dir}">\r
-            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">\r
-                <filename name="**/doc-files/**"/>\r
-            </fileset>\r
-            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
-                <include name="**/doc-files/**"/>\r
-            </fileset>\r
-        </copy>\r
-    </target>\r
-    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">\r
-        <nbbrowse file="${dist.javadoc.dir}/index.html"/>\r
-    </target>\r
-    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>\r
-    <!--\r
-                =========================\r
-                TEST COMPILATION SECTION\r
-                =========================\r
-            -->\r
-    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">\r
-        <mkdir dir="${build.test.classes.dir}"/>\r
-    </target>\r
-    <target name="-pre-compile-test">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target if="do.depend.true" name="-compile-test-depend">\r
-        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>\r
-    </target>\r
-    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">\r
-        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>\r
-        <copy todir="${build.test.classes.dir}">\r
-            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
-        </copy>\r
-    </target>\r
-    <target name="-post-compile-test">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>\r
-    <target name="-pre-compile-test-single">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">\r
-        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>\r
-        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>\r
-        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>\r
-        <copy todir="${build.test.classes.dir}">\r
-            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
-        </copy>\r
-    </target>\r
-    <target name="-post-compile-test-single">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>\r
-    <!--\r
-                =======================\r
-                TEST EXECUTION SECTION\r
-                =======================\r
-            -->\r
-    <target depends="init" if="have.tests" name="-pre-test-run">\r
-        <mkdir dir="${build.test.results.dir}"/>\r
-    </target>\r
-    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">\r
-        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>\r
-    </target>\r
-    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">\r
-        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
-    </target>\r
-    <target depends="init" if="have.tests" name="test-report"/>\r
-    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>\r
-    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>\r
-    <target depends="init" if="have.tests" name="-pre-test-run-single">\r
-        <mkdir dir="${build.test.results.dir}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">\r
-        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>\r
-        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">\r
-        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
-    </target>\r
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>\r
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">\r
-        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>\r
-        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>\r
-        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">\r
-        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
-    </target>\r
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>\r
-    <!--\r
-                =======================\r
-                TEST DEBUGGING SECTION\r
-                =======================\r
-            -->\r
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">\r
-        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>\r
-        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">\r
-        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>\r
-        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>\r
-        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>\r
-    </target>\r
-    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">\r
-        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>\r
-    </target>\r
-    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>\r
-    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>\r
-    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">\r
-        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>\r
-    </target>\r
-    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>\r
-    <!--\r
-                =========================\r
-                APPLET EXECUTION SECTION\r
-                =========================\r
-            -->\r
-    <target depends="init,compile-single" name="run-applet">\r
-        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
-        <j2seproject1:java classname="sun.applet.AppletViewer">\r
-            <customize>\r
-                <arg value="${applet.url}"/>\r
-            </customize>\r
-        </j2seproject1:java>\r
-    </target>\r
-    <!--\r
-                =========================\r
-                APPLET DEBUGGING  SECTION\r
-                =========================\r
-            -->\r
-    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">\r
-        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
-        <j2seproject3:debug classname="sun.applet.AppletViewer">\r
-            <customize>\r
-                <arg value="${applet.url}"/>\r
-            </customize>\r
-        </j2seproject3:debug>\r
-    </target>\r
-    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>\r
-    <!--\r
-                ===============\r
-                CLEANUP SECTION\r
-                ===============\r
-            -->\r
-    <target name="-deps-clean-init" unless="built-clean.properties">\r
-        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>\r
-        <delete file="${built-clean.properties}" quiet="true"/>\r
-    </target>\r
-    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">\r
-        <echo level="warn" message="Cycle detected: Addressbook was already built"/>\r
-    </target>\r
-    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">\r
-        <mkdir dir="${build.dir}"/>\r
-        <touch file="${built-clean.properties}" verbose="false"/>\r
-        <property file="${built-clean.properties}" prefix="already.built.clean."/>\r
-        <antcall target="-warn-already-built-clean"/>\r
-        <propertyfile file="${built-clean.properties}">\r
-            <entry key="${basedir}" value=""/>\r
-        </propertyfile>\r
-        <antcall target="-maybe-call-dep">\r
-            <param name="call.built.properties" value="${built-clean.properties}"/>\r
-            <param location="${project.jcore}" name="call.subproject"/>\r
-            <param location="${project.jcore}/build.xml" name="call.script"/>\r
-            <param name="call.target" value="clean"/>\r
-            <param name="transfer.built-clean.properties" value="${built-clean.properties}"/>\r
-            <param name="transfer.not.archive.disabled" value="true"/>\r
-        </antcall>\r
-    </target>\r
-    <target depends="init" name="-do-clean">\r
-        <delete dir="${build.dir}"/>\r
-        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>\r
-    </target>\r
-    <target name="-post-clean">\r
-        <!-- Empty placeholder for easier customization. -->\r
-        <!-- You can override this target in the ../build.xml file. -->\r
-    </target>\r
-    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>\r
-    <target name="-check-call-dep">\r
-        <property file="${call.built.properties}" prefix="already.built."/>\r
-        <condition property="should.call.dep">\r
-            <and>\r
-                <not>\r
-                    <isset property="already.built.${call.subproject}"/>\r
-                </not>\r
-                <available file="${call.script}"/>\r
-            </and>\r
-        </condition>\r
-    </target>\r
-    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">\r
-        <ant antfile="${call.script}" inheritall="false" target="${call.target}">\r
-            <propertyset>\r
-                <propertyref prefix="transfer."/>\r
-                <mapper from="transfer.*" to="*" type="glob"/>\r
-            </propertyset>\r
-        </ant>\r
-    </target>\r
-</project>\r
diff --git a/Addressbook/nbproject/genfiles.properties b/Addressbook/nbproject/genfiles.properties
deleted file mode 100644 (file)
index 5cab81f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-build.xml.data.CRC32=39498655\r
-build.xml.script.CRC32=e7acbc61\r
-build.xml.stylesheet.CRC32=8064a381@1.75.2.48\r
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\r
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\r
-nbproject/build-impl.xml.data.CRC32=b3f3ee43\r
-nbproject/build-impl.xml.script.CRC32=96150614\r
-nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48\r
diff --git a/Addressbook/nbproject/project.properties b/Addressbook/nbproject/project.properties
deleted file mode 100644 (file)
index 7cc6fa2..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=false
-annotation.processing.processors.list=
-annotation.processing.run.all.processors=true
-annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
-application.title=Addressbook
-application.vendor=Roland Haeder
-build.classes.dir=${build.dir}/classes
-build.classes.excludes=**/*.java,**/*.form
-# This directory is removed when the project is cleaned:
-build.dir=build
-build.generated.dir=${build.dir}/generated
-build.generated.sources.dir=${build.dir}/generated-sources
-# Only compile against the classpath explicitly listed here:
-build.sysclasspath=ignore
-build.test.classes.dir=${build.dir}/test/classes
-build.test.results.dir=${build.dir}/test/results
-# Uncomment to specify the preferred debugger connection transport:
-#debug.transport=dt_socket
-debug.classpath=\
-    ${run.classpath}
-debug.test.classpath=\
-    ${run.test.classpath}
-# Files in build.classes.dir which should be excluded from distribution jar
-dist.archive.excludes=
-# This directory is removed when the project is cleaned:
-dist.dir=dist
-dist.jar=${dist.dir}/Addressbook.jar
-dist.javadoc.dir=${dist.dir}/javadoc
-endorsed.classpath=
-excludes=
-file.reference.log4j-api-2.3.jar=C:\\Users\\KLC\\Documents\\NetBeansProjects\\jcore\\lib\\log4j-api-2.3.jar
-file.reference.log4j-core-2.3.jar=C:\\Users\\KLC\\Documents\\NetBeansProjects\\jcore\\lib\\log4j-core-2.3.jar
-includes=**
-jar.compress=false
-javac.classpath=\
-    ${file.reference.log4j-api-2.3.jar}:\
-    ${file.reference.log4j-core-2.3.jar}:\
-    ${reference.jcore.jar}
-# Space-separated list of extra javac options
-javac.compilerargs=-Xlint:deprecation -Xlint:unchecked
-javac.deprecation=false
-javac.processorpath=\
-    ${javac.classpath}
-javac.source=1.7
-javac.target=1.7
-javac.test.classpath=\
-    ${javac.classpath}:\
-    ${build.classes.dir}
-javac.test.processorpath=\
-    ${javac.test.classpath}
-javadoc.additionalparam=
-javadoc.author=false
-javadoc.encoding=${source.encoding}
-javadoc.noindex=false
-javadoc.nonavbar=false
-javadoc.notree=false
-javadoc.private=false
-javadoc.reference.log4j-api-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-api-2.3-javadoc.jar
-javadoc.reference.log4j-core-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-core-2.3-javadoc.jar
-javadoc.splitindex=true
-javadoc.use=true
-javadoc.version=false
-javadoc.windowtitle=
-main.class=org.mxchange.addressbook.application.AddressbookApplication
-manifest.file=manifest.mf
-meta.inf.dir=${src.dir}/META-INF
-mkdist.disabled=false
-platform.active=default_platform
-project.jcore=../../jcore
-project.license=gpl30
-reference.jcore.jar=${project.jcore}/dist/jcore.jar
-run.classpath=\
-    ${javac.classpath}:\
-    ${build.classes.dir}
-# Space-separated list of JVM arguments used when running the project.
-# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
-# To set system properties for unit tests define test-sys-prop.name=value:
-run.jvmargs=-ea
-run.test.classpath=\
-    ${javac.test.classpath}:\
-    ${build.test.classes.dir}
-source.encoding=UTF-8
-source.reference.log4j-api-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-api-2.3-sources.jar
-source.reference.log4j-core-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-core-2.3-sources.jar
-src.dir=src
-test.src.dir=test
diff --git a/Addressbook/nbproject/project.xml b/Addressbook/nbproject/project.xml
deleted file mode 100644 (file)
index 6b25f3e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<project xmlns="http://www.netbeans.org/ns/project/1">\r
-    <type>org.netbeans.modules.java.j2seproject</type>\r
-    <configuration>\r
-        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">\r
-            <name>Addressbook</name>\r
-            <source-roots>\r
-                <root id="src.dir"/>\r
-            </source-roots>\r
-            <test-roots>\r
-                <root id="test.src.dir"/>\r
-            </test-roots>\r
-        </data>\r
-        <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">\r
-            <reference>\r
-                <foreign-project>jcore</foreign-project>\r
-                <artifact-type>jar</artifact-type>\r
-                <script>build.xml</script>\r
-                <target>jar</target>\r
-                <clean-target>clean</clean-target>\r
-                <id>jar</id>\r
-            </reference>\r
-        </references>\r
-    </configuration>\r
-</project>\r
diff --git a/Addressbook/src/log4j2.xml b/Addressbook/src/log4j2.xml
deleted file mode 100644 (file)
index 1ebbd9f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2015 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/>.
--->
-<Configuration status="INFO">
-       <Appenders>
-               <Console name="STDOUT" target="SYSTEM_OUT">
-                       <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
-               </Console>
-       </Appenders>
-       <Loggers>
-               <Root level="trace">
-                       <AppenderRef ref="STDOUT" level="TRACE"/>
-               </Root>
-       </Loggers>
-</Configuration>
diff --git a/Addressbook/src/org/mxchange/addressbook/BaseAddressbookSystem.java b/Addressbook/src/org/mxchange/addressbook/BaseAddressbookSystem.java
deleted file mode 100644 (file)
index aa8c235..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook;
-
-import org.mxchange.jcore.BaseFrameworkSystem;
-
-/**
- * General class for addressbook application
- *
- * @author Roland Haeder
- */
-public class BaseAddressbookSystem extends BaseFrameworkSystem {
-       /**
-        * No instances can be created of this class
-        */
-       protected BaseAddressbookSystem () {
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/application/AddressbookApplication.java b/Addressbook/src/org/mxchange/addressbook/application/AddressbookApplication.java
deleted file mode 100644 (file)
index 4be3359..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.application;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import org.mxchange.addressbook.BaseAddressbookSystem;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.client.console.ConsoleClient;
-import org.mxchange.addressbook.client.gui.SwingClient;
-import org.mxchange.jcore.BaseFrameworkSystem;
-import org.mxchange.jcore.application.Application;
-import org.mxchange.jcore.client.Client;
-import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
-import org.mxchange.jcore.manager.application.ApplicationManager;
-
-/**
- * ============================================
- * AddressbookApplication management:
- * ============================================
- * 
- * Inernet("public" service) and Intranet
- * 
- * Version 1.0+:
- * - Single-user local application
- * - Fields:
- *   + Gender
- *   + Surname
- *   + Family name
- *   + Company name
- *   + Street + number
- *   + ZIP code
- *   + City
- *   + Landline number
- *   + Fax number
- *   + Cell phone number
- *   + Email address
- *   + Birth day
- *   + Comment (?)
- * - Edit own data
- * - Add new contact
- * - Edit contacts
- * - Delete contacts
- * - Categorization of contacts
- * 
- * Version 1.1+:
- * - Permanent storage in database
- * 
- * Version 2.0+:
- * - Multi-user web application
- * - Local user registration / login / resend confirmation link / password
- *   recovery
- * - User groups (aka. teams)
- * - Administration area (user role)
- *   + Create/edit/delete groups
- *   + Edit/delete/lock/unlock user
- *   + Assign user roles/rights
- * - Allow other users / groups to view addressbook
- *   + Full addressbook
- *   + Only some categories
- * - VCard export
- *   + Allow users/guests (not recommended)
- * - XML export of addressbook and compressable (ZIP)
- * - Form to contact other user/group without need of mail program
- *   + User can disabled this
- * - Directory for ussers/groups (who allowed to be listed)
- *   + Simple click to add user to own addressbook
- *   + Search form?
- * 
- * Version 2.1+:
- * - Multi-language support
- * 
- * Version 2.2+:("socialized")
- * - "Social login" (OpenID consumer)
- *   + Connect user account to social account
- *   + Sync own data?
- * - "Social profile"
- *   + OpenID provider
- *   + RSS/activity feed 
- * 
- * ============================================
- * Time esitmation:
- * ============================================
- * 1.0 (console):
- *   + 2 days
- * 
- * 1.1 (database):
- *   + 2 day
- *   + Initial tables: contacts, categories, contact_category
- * 
- * 2.0 (web):
- *   + 3 days
- *   + Additional tables: admins (?), admin_rights, groups,
- *    users, user_contacts, user_user_rights, user_category_rights, 
- * 
- * 2.1 (language)
- *   + 1 day
- *   + Additional tables: languages (disable, enable language "pack" ?)
- * 
- * 2.2 (social):
- *   + 3 days
- *   + Additional tables: ???
-*
- * @author Roland Haeder
- * @version 0.0
- */
-public class AddressbookApplication extends BaseAddressbookSystem implements Application {
-
-       /**
-        * Application title
-        */
-       public static final String APP_TITLE = "Adressbuch"; //NOI18N
-
-       /**
-        * Application version
-        */
-       public static final String APP_VERSION = "0.0"; //NOI18N
-
-       /**
-        * Console client is enabled by default
-        */
-       private boolean consoleClient = true;
-
-       /**
-        * GUI client is disabled by default
-        */
-       private boolean guiClient = false;
-
-       /**
-        * Protected constructor
-        * @throws java.io.IOException If any IO error occurs
-        */
-       protected AddressbookApplication () throws IOException {
-               // Init properties file
-               this.initProperties();
-
-               // Init bundle
-               this.initBundle();
-       }
-
-       /**
-        * Bootstraps application
-        */
-       @Override
-       public void doBootstrap () {
-               this.getLogger().debug("Initializing application ..."); //NOI18N
-
-               // Init client variable
-               Client client = null;
-
-               // Is console or Swing choosen?
-               if (this.isConsole()) {
-                       // Debug message
-                       this.getLogger().debug("Initializing console client ..."); //NOI18N
-
-                       // Init console client instance
-                       client = new ConsoleClient(this);
-               } else if (this.isGui()) {
-                       // Debug message
-                       this.getLogger().debug("Initializing GUI (Swing) client ..."); //NOI18N
-
-                       // Init console instance
-                       client = new SwingClient(this);
-               } else {
-                       // Not client choosen
-                       this.getLogger().error("No client choosen. Cannot launch."); //NOI18N
-                       System.exit(1);
-               }
-
-               // Init client
-               client.init();
-
-               // Set client instance
-               this.setClient(client);
-
-               // The application is running at this point
-               this.getClient().enableIsRunning();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Main loop of the application
-        */
-       @Override
-       public void doMainLoop () {
-               // Get client and cast it
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // @TODO The application should be running now
-               // Output introduction
-               this.showIntro();
-
-               // Set current menu to main
-               client.setCurrentMenu("main"); //NOI18N
-
-               // --- Main loop starts here ---
-               while (this.getClient().isRunning()) {
-                       // The application is still active, show menu selection
-                       client.showCurrentMenu();
-
-                       try {
-                               // Ask for user input and run proper method
-                               client.doUserMenuChoice();
-                       } catch (final UnhandledUserChoiceException ex) {
-                               this.getLogger().catching(ex);
-                       }
-
-                       try {
-                               // Sleep a little to reduce system load
-                               Thread.sleep(100);
-                       } catch (final InterruptedException ex) {
-                               // Ignore it
-                       }
-               }
-               // --- Main loop ends here ---
-
-               // Debug message
-               this.getLogger().debug("Main loop exit - shutting down ..."); //NOI18N
-       }
-
-       /**
-        * Shuts down the application.
-        */
-       @Override
-       public void doShutdown () throws SQLException, IOException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-               
-               // Shutdown client
-               this.getClient().doShutdown();
-               
-               this.getLogger().info("End of program (last line)"); //NOI18N
-               System.exit(0);
-       }
-
-       /**
-        * Enables console client by setting propper flag
-        */
-       private void enableConsoleClient () {
-               this.getLogger().debug("Enabling console client (may become optional client) ..."); //NOI18N
-               this.consoleClient = true;
-               this.guiClient = false;
-       }
-
-       /**
-        * Enables GUI client by setting propper flag
-        */
-       private void enableGuiClient () {
-               this.getLogger().debug("Enabling GUI client (may become new default client) ..."); //NOI18N
-               this.consoleClient = false;
-               this.guiClient = true;
-       }
-
-       /**
-        * Checks whether the client shoule be console client should be launched by
-        * checking if -console is set.
-        *
-        * @return Whether console client should be taken
-        */
-       private boolean isConsole () {
-               return this.consoleClient;
-       }
-
-       /**
-        * Checks whether the client shoule be GUI client should be launched by
-        * checking if -gui is set.
-        *
-        * @return Whether GUI client should be taken
-        */
-       private boolean isGui () {
-               return this.guiClient;
-       }
-
-       /**
-        * Parses all given arguments
-        *
-        * @param args Arguments from program launch
-        */
-       private void parseArguments (final String[] args) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("args()={0} - CALLED!", args.length)); //NOI18N
-
-               // Debug message
-               this.getLogger().debug(MessageFormat.format("Parsing {0} arguments ...", args.length)); //NOI18N
-
-               for (final String arg : args) {
-                       // Switch on it
-                       switch (arg) {
-                               case "-console": //NOI18N
-                                       enableConsoleClient();
-                                       break;
-
-                               case "-gui": //NOI18N
-                                       enableGuiClient();
-                                       break;
-                       }
-               }
-       }
-
-       /**
-        * Show introduction which depends on client
-        */
-       private void showIntro () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Let the client show it
-               this.getClient().showWelcome();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Launches the application
-        *
-        * @param args Arguments handled to program
-        */
-       private void start (final String args[]) {
-               this.getLogger().info("Program is started."); //NOI18N
-               try {
-                       // Init properties file
-                       this.initProperties();
-               } catch (final IOException ex) {
-                       // Something bad happened
-                       this.abortProgramWithException(ex);
-               }
-
-               // Parse arguments
-               this.parseArguments(args);
-
-               // Launch application
-               ApplicationManager.getManager(this).start();
-
-               // Good bye, but this should not be reached ...
-               this.getLogger().warn("Unusual exit reached."); //NOI18N
-               try {
-                       this.doShutdown();
-               } catch (final SQLException | IOException ex) {
-                       this.abortProgramWithException(ex);
-               }
-       }
-
-       /**
-        * Main method (entry point)
-        *
-        * @param args the command line arguments
-        */
-       public static void main (String[] args) {
-               try {
-                       // Start application
-                       new AddressbookApplication().start(args);
-               } catch (final IOException ex) {
-                       // Get instance
-                       BaseFrameworkSystem.getInstance().getLogger().catching(ex);
-                       System.exit(1);
-               }
-       }
-
-       /**
-        * Getter for printable application name
-        *
-        * @return A printable name
-        */
-       public static String printableTitle () {
-               return MessageFormat.format("{0} v{1}", APP_TITLE, APP_VERSION); //NOI18N
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/client/AddressbookClient.java b/Addressbook/src/org/mxchange/addressbook/client/AddressbookClient.java
deleted file mode 100644 (file)
index dde3c17..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.client;
-
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.jcore.client.Client;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
-
-/**
- * A special client interface for addressbook applications.
- * 
- * @author Roland Haeder
- */
-public interface AddressbookClient extends Client {
-
-       /**
-        * The user changes own name data
-        *
-        * @param contact
-        */
-       public void doChangeOwnNameData (final Contact contact);
-
-       /**
-        * The user changes own address data
-        *
-        * @param contact Contact instance to change
-        */
-       public void doChangeOwnAddressData (final Contact contact);
-
-       /**
-        * The user changes own other data
-        *
-        * @param contact Constact instance to change
-        */
-       public void doChangeOwnOtherData (final Contact contact);
-
-       /**
-        * Allows the user to enter own data
-        *
-        * @return Finished Contact instance
-        */
-       public Contact doEnterOwnData ();
-
-       /**
-        * Asks the user to enter his/her gender (M=Male, F=Female, C=Company)
-        *
-        * @param message Message to output
-        * @return Gender enum
-        */
-       public Gender enterGender (final String message);
-
-       /**
-        * Let the user choose what to change on the address: [n]ame, [a]ddress,
-        * [o]ther
-        *
-        * @param contact Contact instance to let the user change data
-        * @throws UnhandledUserChoiceException If choice is not supported
-        */
-       public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException;
-
-       /**
-        * Asks the user for a choice and proceeds accordingly
-        *
-        * @throws UnhandledUserChoiceException If choice is not supported
-        */
-       public void doUserMenuChoice () throws UnhandledUserChoiceException;
-
-       /**
-        * Asks the the user to enter a single character which must match validChars
-        *
-        * @param       validChars Valid chars that are accepted
-        * @param       message Message to user
-        * @return      Allowed character
-        */
-       public char enterChar (final char[] validChars, final String message);
-
-       /**
-        * Reads a string of minimum and maximum length from the user. An empty
-        * string should be generally not allowed, but might be okay for e.g.
-        * company name.
-        *
-        * @param minLength     Minimum length of the string to read
-        * @param maxLength     Maximum length of the string to read
-        * @param message       Message to user
-        * @param allowEmpty Whether empty strings are allowed
-        * @return Entered string by user or null if empty string is allowed
-        */
-       public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty);
-
-       /**
-        * Reads an integer (int) from the user
-        *
-        * @param minimum Minimum allowed number
-        * @param maximum Maximum allowed number
-        * @param message       Message to user
-        * @return Entered string by user or null if empty string is allowed
-        */
-       public int enterInt (final int minimum, final int maximum, final String message);
-
-       /**
-        * Setter for current menu choice
-        *
-        * @param currentMenu Current menu choice
-        */
-       public void setCurrentMenu (final String currentMenu);
-
-       /**
-        * Some "Getter" for menu item
-        *
-        * @param accessKey Key to press to access this menu
-        * @param text Text to show to user
-        * @return
-        */
-       public SelectableMenuItem getMenuItem (final char accessKey, final String text);
-
-       /**
-        * Shows given menu entry in client
-        *
-        * @param item Menu item to show
-        */
-       public void showEntry (final SelectableMenuItem item);
-
-       /**
-        * Shows current menu selection to the user
-        */
-       public void showCurrentMenu ();
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/client/BaseAddressbookClient.java b/Addressbook/src/org/mxchange/addressbook/client/BaseAddressbookClient.java
deleted file mode 100644 (file)
index 2f2e2aa..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.client;
-
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import org.mxchange.addressbook.manager.contact.AddressbookContactManager;
-import org.mxchange.addressbook.menu.Menu;
-import org.mxchange.jcore.client.BaseClient;
-import org.mxchange.jcore.client.Client;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
-import org.mxchange.jcore.manager.database.ManageableDatabase;
-
-/**
- * A general addressbook client
- *
- * @author Roland Haeder
- */
-public abstract class BaseAddressbookClient extends BaseClient {
-
-       /**
-        * Current menu choice
-        */
-       private String currentMenu;
-
-       /**
-        * Menu system
-        */
-       private final Map<String, Menu> menus;
-
-       /**
-        * No instances can be created of this class
-        */
-       protected BaseAddressbookClient () {
-               // Init menu map
-               this.menus = new HashMap<>(10);
-       }
-
-       /**
-        * Current menu choice
-        *
-        * @return the currentMenu
-        */
-       public final String getCurrentMenu () {
-               return this.currentMenu;
-       }
-
-       /**
-        * Current menu choice
-        *
-        * @param currentMenu the currentMenu to set
-        */
-       public final void setCurrentMenu (final String currentMenu) {
-               this.currentMenu = currentMenu;
-       }
-
-       /**
-        * "Getter" for given menu type
-        *
-        * @param menuType Menu type instance to return
-        * @return Menu or null if not found
-        */
-       public Menu getMenu (final String menuType) {
-               // Default is not found
-               Menu menu = null;
-
-               // Check array
-               if (this.getMenus().containsKey(menuType)) {
-                       // Found!
-                       menu = this.getMenus().get(menuType);
-               }
-
-               // Return it
-               return menu;
-       }
-
-       /**
-        * Fills menu map with swing menus
-        */
-       protected abstract void fillMenuMap ();
-
-       /**
-        * Getter for menus map
-        *
-        * @return Map of all menus
-        */
-       protected final Map<String, Menu> getMenus () {
-               return this.menus;
-       }
-
-       /**
-        * Initializes contact manager
-        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported
-        * @throws java.sql.SQLException If any SQL error occurs
-        */
-       protected void initContactManager () throws UnsupportedDatabaseBackendException, SQLException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-               
-               // Debug message
-               this.getLogger().debug("Initializing contact manager ..."); //NOI18N
-               
-               // Init contact manager with console client
-               // @TODO Static initial amount of contacts
-               ManageableDatabase manager = new AddressbookContactManager((Client) this);
-               
-               // Set it here
-               this.setContactManager(manager);
-               
-               // Debug message
-               this.getLogger().debug("Contact manager has been initialized."); //NOI18N
-               
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Shows given menu
-        *
-        * @param menuType Given menu to show
-        */
-       protected void showMenu (final String menuType) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("menuType={0} - CALLED!", menuType)); //NOI18N
-
-               Menu menu = this.getMenu(menuType);
-
-               // Is the menu set?
-               if (!(menu instanceof Menu)) {
-                       // Not found
-                       // @todo Own exception?
-                       throw new NullPointerException(MessageFormat.format("Menu '{0}' not found.", menuType)); //NOI18N
-               }
-
-               // Show menu
-               menu.show(this);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java b/Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java
deleted file mode 100644 (file)
index 6ed15fb..0000000
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.client.console;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Scanner;
-import org.mxchange.addressbook.application.AddressbookApplication;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.client.BaseAddressbookClient;
-import org.mxchange.addressbook.contact.user.UserContact;
-import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
-import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact;
-import org.mxchange.addressbook.menu.Menu;
-import org.mxchange.addressbook.menu.MenuTools;
-import org.mxchange.addressbook.menu.console.ConsoleMenu;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.addressbook.menu.item.console.ConsoleMenuItem;
-import org.mxchange.jcore.application.Application;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
-
-/**
- * A client for the console
- *
- * @author Roland Haeder
- */
-public class ConsoleClient extends BaseAddressbookClient implements AddressbookClient {
-
-       /**
-        * Scanner instance for reading data from console input
-        */
-       private final Scanner scanner;
-
-       /**
-        * Parameterless constructor
-        *
-        * @param application An instance of an Application class
-        */
-       public ConsoleClient (final Application application) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("application={0} - CALLED!", application)); //NOI18N
-
-               // Set application instance
-               this.setApplication(application);
-
-               // Init scanner instance
-               this.scanner = new Scanner(System.in, "UTF-8"); //NOI18N
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Displays a textual address "box" of given contact
-        *
-        * @param contact Contact to show address for
-        */
-       @Override
-       public void displayAddressBox (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Is it null?
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Simple display ...
-               this.outputMessage(MessageFormat.format("Strasse, PLZ Ort, Land: {0}\n{1} {2}\n{3}", contact.getStreet(), contact.getZipCode(), contact.getCity(), contact.getCountryCode()));
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Displays a textual name "box" of given contact
-        *
-        * @param contact Contact to show name for
-        */
-       @Override
-       public void displayNameBox (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Is it null?
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Get translated gender as the user may want to see "Mr.", "Mrs."
-               String gender = contact.getTranslatedGender();
-
-               // Get company name
-               String companyName = contact.getCompanyName();
-
-               // If it is empty/null, then assume private contact
-               if ((companyName == null) || (companyName.isEmpty())) {
-                       // Now put all together: gender, surname, family name
-                       // @todo Use mask
-                       this.outputMessage(MessageFormat.format("Anrede, Vorname, Name: {0} {1} {2}", gender, contact.getSurname(), contact.getFamilyName()));
-               } else {
-                       // Company contact
-                       this.outputMessage(MessageFormat.format("Firma: {0}\nAnsprechpartner: {1} {2} {3}", companyName, gender, contact.getSurname(), contact.getFamilyName()));
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Displays a textual other data "box" of given contact
-        *
-        * @param contact Contact to show other data for
-        */
-       @Override
-       public void displayOtherDataBox (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Is it null?
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Cellphone and such ...
-               this.outputMessage(MessageFormat.format("Telefonnumer: {0}\nFaxnummer: {1}\nHandy: {2}\nKommentar:\n{3}", contact.getPhoneNumber(), contact.getFaxNumber(), contact.getCellphoneNumber(), contact.getComment()));
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void doChangeOwnAddressData (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Is it null?
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Make sure it is own contact
-               if (!contact.isOwnContact()) {
-                       // Not own contact
-                       throw new IllegalArgumentException("Contact is not own data."); //NOI18N
-               }
-
-               // Get manager and cast it
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
-
-               // Own street and number
-               String streetNumber = manager.enterOwnStreet();
-
-               // Get zip code
-               Long zipCode = (long) manager.enterOwnZipCode();
-
-               // Get city name
-               String city = manager.enterOwnCity();
-
-               // Get country code
-               String countryCode = manager.enterOwnCountryCode();
-
-               // Update address data
-               contact.setStreet(streetNumber);
-               contact.setZipCode(zipCode);
-               contact.setCity(city);
-               contact.setCountryCode(countryCode);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void doChangeOwnNameData (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Is it null?
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Make sure it is own contact
-               if (!contact.isOwnContact()) {
-                       // Not own contact
-                       throw new IllegalArgumentException("Contact is not own data."); //NOI18N
-               }
-
-               // Get manager and cast it
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
-
-               // Gender:
-               Gender gender = manager.enterOwnGender();
-
-               // Surname
-               String surname = manager.enterOwnSurname();
-
-               // Family name
-               String familyName = manager.enterOwnFamilyName();
-
-               // And company
-               String companyName = manager.enterOwnCompanyName();
-
-               // Update contact instance
-               contact.setGender(gender);
-               contact.setSurname(surname);
-               contact.setFamilyName(familyName);
-               contact.setCompanyName(companyName);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void doChangeOwnOtherData (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Is it null?
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Make sure it is own contact
-               if (!contact.isOwnContact()) {
-                       // Not own contact
-                       throw new IllegalArgumentException("Contact is not own data."); //NOI18N
-               }
-
-               // Get manager and cast it
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
-
-               // Phone number
-               String phoneNumber = manager.enterOwnPhoneNumber();
-
-               // Phone number
-               String cellphonePhoneNumber = manager.enterOwnCellNumber();
-
-               // Fax number
-               String faxNumber = manager.enterOwnFaxNumber();
-
-               // Email address
-               String email = manager.enterOwnEmailAddress();
-
-               // Comment
-               String comment = manager.enterOwnComment();
-
-               // Update contact instance
-               contact.setPhoneNumber(phoneNumber);
-               contact.setCellphoneNumber(cellphonePhoneNumber);
-               contact.setFaxNumber(faxNumber);
-               contact.setEmailAddress(email);
-               contact.setComment(comment);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public Contact doEnterOwnData () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get manager and cast it
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
-
-               // First ask for gender
-               Gender gender = manager.enterOwnGender();
-
-               // 2nd for surname
-               String surname = manager.enterOwnSurname();
-
-               // And 3rd for family name
-               String familyName = manager.enterOwnFamilyName();
-
-               // Company name ...
-               String companyName = manager.enterOwnCompanyName();
-
-               // Construct UserContact instance
-               Contact contact = new UserContact(gender, surname, familyName, companyName);
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
-
-               // And return object
-               return contact;
-       }
-
-       /**
-        * Shutdown this client
-        */
-       @Override
-       public void doShutdown () throws SQLException, IOException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Parent call
-               super.doShutdown();
-
-               // @TODO Add other shutdown stuff
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void doUserMenuChoice () throws UnhandledUserChoiceException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get all access keys from menu
-               char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.getMenus(), this.getCurrentMenu());
-
-               // Output textural message and ask for a char as input
-               char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Programm beenden): ");
-
-               // Get manager and cast it
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
-
-               // Try it!
-               try {
-                       // @TODO Rewrite this ugly switch() block
-                       switch (choice) {
-                               case '1':
-                                       try {
-                                               // Enter/add own data
-                                               manager.doEnterOwnData();
-                                       } catch (final ContactAlreadyAddedException ex) {
-                                               // Already added
-                                               this.outputMessage("Sie haben bereits Ihre eigenen Daten eingegeben.");
-                                       }
-                                       break;
-
-                               case '2': // Change own data
-                                       manager.doChangeOwnData();
-                                       break;
-
-                               case '3': // Add new addess
-                                       manager.doAddOtherAddress();
-                                       break;
-
-                               case '4': // List contacts
-                                       manager.doListContacts();
-                                       break;
-
-                               case '5': // Search addresses
-                                       manager.doSearchContacts();
-                                       break;
-
-                               case '6': // Change other addess
-                                       manager.doChangeOtherAddress();
-                                       break;
-
-                               case '7': // Delete other address
-                                       manager.doDeleteOtherAddress();
-                                       break;
-
-                       case '0': {
-                       try {
-                               // Program exit
-                               this.getApplication().doShutdown();
-                       } catch (final SQLException | IOException ex) {
-                               this.abortProgramWithException(ex);
-                       }
-               }
-                               break;
-
-                               default:
-                                       // @TODO throw own exception
-                                       throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N
-                       }
-               } catch (final IOException | BadTokenException ex) {
-                       // Something bad happened
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Asks the the user to enter a single character which must match validChars
-        *
-        * @param       validChars Valid chars that are accepted
-        * @param       message Message to user
-        * @return      Allowed character
-        */
-       @Override
-       public char enterChar (final char[] validChars, final String message) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("validChars={0},message={1} - CALLED!", Arrays.toString(validChars), message)); //NOI18N
-
-               // The validChars must not null be null and filled with at least one char
-               if (validChars == null) {
-                       // Is null
-                       throw new NullPointerException("validChars is null"); //NOI18N
-               } else if (validChars.length == 0) {
-                       // Is not filled
-                       throw new IllegalArgumentException("validChars is not filled."); //NOI18N
-               }
-
-               char input = 0;
-
-               // Sort array, else binarySearch() won't work
-               Arrays.sort(validChars);
-
-               // Keep asking until valid char has been entered
-               while (Arrays.binarySearch(validChars, input) < 0) {
-                       // Output message
-                       System.out.print(message);
-
-                       // Read char
-                       input = this.readChar();
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
-
-               // Return read char
-               return input;
-       }
-
-       /**
-        * Asks the user to enter his/her gender
-        *
-        * @param message Message to the user
-        * @return Gender enum
-        */
-       @Override
-       public Gender enterGender (final String message) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("message={0} - CALLED!", message)); //NOI18N
-
-               // Get valid chars
-               char[] validChars = Gender.validChars();
-
-               // Debug message
-               //* NOISY-DEBUG: */ System.out.println(validChars);
-               // Call inner method
-               char gender = this.enterChar(validChars, message);
-
-               // Now get a Gender instance back
-               Gender g = Gender.fromChar(gender);
-
-               // g must not be null
-               assert(g instanceof Gender) : "g is not set."; //NOI18N
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("g={0} - EXIT!", g)); //NOI18N
-
-               // Return it
-               return g;
-       }
-
-       /**
-        * Reads an integer (int) with a textural message from the user
-        *
-        * @param minimum Minimum allowed number
-        * @param maximum Maximum allowed number
-        * @param message Messager to display in console
-        * @return
-        */
-       @Override
-       public int enterInt (final int minimum, final int maximum, final String message) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("minimum={0},maximum={1},message={2} - CALLED!", minimum, maximum, message)); //NOI18N
-
-               // Minimum should not be below zero
-               assert (minimum >= 0);
-               assert (maximum > minimum);
-
-               // Init input
-               int input = -1;
-
-               while ((input < minimum) || (input > maximum)) {
-                       // Output message
-                       System.out.print(message);
-
-                       // Read integer from user
-                       input = this.readInt();
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
-
-               // Return it
-               return input;
-       }
-
-       /**
-        * Reads a string of minimum and maximum length from the user
-        *
-        * @param minLength     Minimum length of the string to read
-        * @param maxLength     Maximum length of the string to read
-        * @param message       Message to user
-        * @param allowEmpty Whether to allow empty string
-        * @return Entered string by user or null for empty strings
-        */
-       @Override
-       public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("minLength={0},maxLength={1},message={2}allowEmpty={3} - CALLED!", minLength, maxLength, message, allowEmpty)); //NOI18N
-
-               // Check on length, e.g. country codes are excactly 2 chars long
-               assert (maxLength >= minLength);
-
-               // Init input
-               String input = null;
-
-               // Check if it is to short or to long
-               while (((input == null) || ((input.length() < minLength) && (!allowEmpty))) || ((input.length() > 0) && (input.length() < minLength) && (allowEmpty)) || ((input instanceof String) && (input.length() > maxLength))) {
-                       // Output message
-                       System.out.print(message);
-
-                       // Read line
-                       input = this.readString();
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
-
-               // Return it
-               return input;
-       }
-
-       /**
-        * Returns a console menu item
-        *
-        * @param accessKey Key to access the menu
-        * @param text Text to show to user
-        * @return A SelectableMenuItem
-        * @todo Make sure the access key is unique
-        */
-       @Override
-       public SelectableMenuItem getMenuItem (final char accessKey, final String text) {
-               // Return a new console menu item
-               return new ConsoleMenuItem(accessKey, text);
-       }
-
-       /**
-        * Initializes this client
-        */
-       @Override
-       public void init () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Init contact manager here
-               try {
-                       this.initContactManager();
-               } catch (final UnsupportedDatabaseBackendException | SQLException ex) {
-                       // End here
-                       this.abortProgramWithException(ex);
-               }
-
-               // Fill menu map
-               this.fillMenuMap();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Displays textural message to the user
-        *
-        * @param message
-        */
-       @Override
-       public void outputMessage (final String message) {
-               System.out.println(message);
-       }
-
-       /**
-        * Shows textural menu on console
-        */
-       @Override
-       public void showCurrentMenu () {
-               this.showMenu(this.getCurrentMenu());
-       }
-
-       /**
-        * Shows given menu entry to user
-        *
-        * @param item Menu entry
-        */
-       @Override
-       public void showEntry (final SelectableMenuItem item) {
-               // Access key then text
-               this.outputMessage(MessageFormat.format("[{0}] {1}", item.getAccessKey(), item.getText()));
-       }
-
-       /**
-        * Shows a textural message to the user
-        */
-       @Override
-       public void showWelcome () {
-               this.outputMessage(MessageFormat.format("Welcome to {0}", AddressbookApplication.printableTitle()));
-               this.outputMessage("");
-               this.outputMessage("Copyright(c) 2015 by Roland Haeder, this is free software");
-
-               // Debug message
-               this.getLogger().debug("Intro shown to user"); //NOI18N
-       }
-
-       @Override
-       public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
-
-               // Contact must not be null
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Ask the user for editing [name], [a]ddress or [other] data
-               char choice = this.enterChar(new char[] {'n', 'a', 'o', 'x'}, "Welchen Daten möchten Sie ändern? (n=Namensdaten, a=Anschriftsdaten, o=Andere, x=Zurück zur Hauptauswahl) ");
-
-               // Get manager and cast it
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
-
-               // @TODO Get rid of this ugly switch block, too
-               switch (choice) {
-                       case 'n': // Name data
-                               manager.doChangeNameData(contact);
-                               break;
-
-                       case 'a': // Address data
-                               manager.doChangeAddressData(contact);
-                               break;
-
-                       case 'o': // Other data
-                               manager.doChangeOtherData(contact);
-                               break;
-
-                       case 'x': // Exit this menu
-                               // Ignored as it should go back
-                               break;
-
-                       default:
-                               // @TODO throw own exception
-                               throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Reads one character
-        *
-        * @return A single character
-        */
-       private char readChar () {
-               // Read line
-               String input = this.readString();
-
-               // Debug message
-               this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N
-
-               // This must be only one character
-               if (input.length() != 1) {
-                       // Return zero
-                       return 0;
-               }
-
-               // Get char from first (and only) position
-               return input.charAt(0);
-       }
-
-       /**
-        * Reads an integer (int) from user
-        *
-        * @return An integer number
-        */
-       private int readInt () {
-               // First read a string
-               String input = this.readString();
-
-               // Debug message
-               this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N
-
-               // Init number with invalid value
-               int num = -1;
-
-               // Parse number, this can be risky
-               try {
-                       num = Integer.parseInt(input);
-               } catch (final NumberFormatException e) {
-                       this.outputMessage("Bitte geben Sie nur Zahlen ein!");
-                       this.getLogger().warn(MessageFormat.format("No numbers-only entered. input={0},message={1}", input, e.getMessage())); //NOI18N
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("num={0} - EXIT!", num)); //NOI18N
-
-               // Return read number
-               return num;
-       }
-
-       /**
-        * Reads a string from a scanner until RETURN is pressed
-        *
-        * @return Read string from scanner
-        */
-       private String readString () {
-               return this.scanner.nextLine();
-       }
-
-       /**
-        * Fills menu map with menu entries
-        */
-       @Override
-       protected final void fillMenuMap () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Initialize first (main) menu
-               Menu menu = new ConsoleMenu("main", this); //NOI18N
-
-               // Add it
-               this.getMenus().put("main", menu); //NOI18N
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java b/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
deleted file mode 100644 (file)
index 4bdb6e9..0000000
+++ /dev/null
@@ -1,1002 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.client.gui;
-
-import java.awt.BorderLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.io.IOException;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JFormattedTextField;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.border.TitledBorder;
-import javax.swing.table.TableModel;
-import org.mxchange.addressbook.BaseAddressbookSystem;
-import org.mxchange.addressbook.application.AddressbookApplication;
-import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
-import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact;
-import org.mxchange.jcore.client.Client;
-import org.mxchange.jcore.client.gui.ClientFrame;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException;
-import org.mxchange.jcore.model.swing.contact.ContactTableModel;
-
-/**
- *
- * @author Roland Haeder
- */
-public class AddressbookFrame extends BaseAddressbookSystem implements ClientFrame {
-
-       /**
-        * Own instance
-        */
-       private static ClientFrame self;
-
-       /**
-        * Singelton getter for this frame instance.
-        *
-        * @param client Client instance
-        * @return Returns a singelton instance of this frame
-        */
-       public static final ClientFrame getSelfInstance (final Client client) {
-               // Is it set?
-               if (!(self instanceof ClientFrame)) {
-                       // Create new instance
-                       self = new AddressbookFrame(client);
-               }
-
-               // Return instance
-               return self;
-       }
-
-       /**
-        * Dialog box "add contact"
-        */
-       private JDialog addContact;
-
-       /**
-        * Frame instance for "add own data"
-        */
-       private JMenuItem addOwnItem;
-
-       /**
-        * Instance to table model
-        */
-       private TableModel dataModel;
-
-       /**
-        * Table instance
-        */
-       private JTable dataTable;
-
-       /**
-        * Frame instance for "edit own data"
-        */
-       private JMenuItem editOwnItem;
-
-       /**
-        * Frame instance
-        */
-       private final JFrame frame;
-
-       /**
-        * Whether this frame has been initialized
-        */
-       private boolean initialized;
-
-       /**
-        * Status label needs to be updated
-        */
-       private JLabel statusLabel;
-
-       /**
-        * Creates an instance of this frame with a client instance
-        *
-        * @param client
-        */
-       private AddressbookFrame (final Client client) {
-               // Debug line
-               this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
-
-               // Set frame instance
-               this.frame = new JFrame();
-               this.frame.setTitle(this.generateFrameTitle("main")); //NOI18N
-
-               // Set client here
-               this.setClient(client);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public Contact doEnterOwnData () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Is the "add contact" window visible?
-               if (this.addContact.isVisible()) {
-                       // Something bad happened
-                       throw new IllegalStateException("Window addContact is already visible."); //NOI18N
-               }
-
-               // Disable main window
-               this.frame.setEnabled(false);
-
-               // Make other window visible
-               this.addContact.setVisible(true);
-
-               // Trace message
-               this.getLogger().trace("Returning null : EXIT!"); //NOI18N
-
-               // Return value is not supported
-               return null;
-       }
-
-       /**
-        * Shutdown this frame
-        */
-       @Override
-       public void doShutdown () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // First only show shutdown status
-               this.updateStatus("shutdown"); //NOI18N
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-
-       /**
-        * Enables main window (frame)
-        */
-       @Override
-       public void enableMainWindow () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Enable it again
-               this.frame.setEnabled(true);
-
-               // Request focus for this window
-               this.frame.requestFocus();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Setups the frame, do not set isInitialized here
-        *
-        * @param client Client instance
-        */
-       @Override
-       public void setupFrame (final Client client) throws IOException, BadTokenException {
-               // Debug line
-               this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
-
-               // Get and cast manager instance
-               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getClient().getManager();
-
-               // Has the user entered own data?
-               if (manager.isOwnContactAdded()) {
-                       // Debug message
-                       this.getLogger().debug("Disabling menus: isOwnContactAdded()=false"); //NOI18N
-
-                       // Not entered yet, so disable "add" menu
-                       this.addOwnItem.setEnabled(false);
-               } else {
-                       // Disable "edit"
-                       this.editOwnItem.setEnabled(false);
-               }
-
-               // Make the frame visible
-               this.frame.setVisible(true);
-
-               // All done here
-               this.updateStatus("done"); //NOI18N
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initalizes this frame. Having initComponents() exposed (publicly
-        * accessible) means that any other object can initialize components which
-        * you may not want.
-        *
-        * @throws
-        * org.mxchange.jcore.exceptions.FrameAlreadyInitializedException If
-        * this method has been called twice
-        */
-       @Override
-       public void init () throws FrameAlreadyInitializedException {
-               // Debug line
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Has this frame been initialized?
-               if (this.isInitialized()) {
-                       // Throw exception
-                       throw new FrameAlreadyInitializedException();
-               }
-
-               // Init components
-               this.initComponents();
-
-               // Set flag
-               this.initialized = true;
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Returns field isInitialized. This flag indicates whether this frame has
-        * been initialized or not.
-        *
-        * @return Field isInitialized
-        */
-       @Override
-       public final boolean isInitialized () {
-               return this.initialized;
-       }
-
-       /**
-        * Shuts down the application.
-        */
-       @Override
-       public void shutdownApplication () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // To do this, the frame must be initialized
-               if (!this.isInitialized()) {
-                       // Not initalized, so bad call
-                       this.getLogger().fatal("Bad call of shutdownApplication(). Please report this."); //NOI18N
-                       return;
-               }
-
-               // Call shutdown method
-               try {
-                       this.getClient().getApplication().doShutdown();
-               } catch (final SQLException | IOException ex) {
-                       // Abort here
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Adds a new menu item with given key to menu instance
-        *
-        * @param menu Menu instance to add item to
-        * @param key Message key part
-        * @param listener Listener instance
-        */
-       private void addMenuItem (final JMenu menu, final String key, final ActionListener listener) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("menu={0},key={1},listener={2} - CALLED!", menu, key, listener)); //NOI18N
-               
-               // New instance
-               JMenuItem item = this.initMenuItemWithTooltip(key);
-               
-               // Add listener
-               item.addActionListener(listener);
-               
-               // Add item -> menu
-               menu.add(item);
-               
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Adds a JTextField with label and tool tip to given panel
-        *
-        * @param panel Panel instance to add text field
-        * @param key Part of message key from resource bundle
-        * @param fieldLength Length of text field
-        */
-       private void addTextFieldWithLabelToPanel (final JPanel panel, final String key, final int fieldLength) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("panel={0},key={1},fieldLength={2} - CALLED!", panel, key, fieldLength)); //NOI18N
-               
-               // Init label for given key
-               JLabel label = new JLabel(this.getBundle().getString(String.format("AddressbookFrame.%s.text", key))); //NOI18N
-               
-               // And input box wih tool tip
-               JTextField field = new JTextField(fieldLength);
-               field.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.%s.toolTipText", key))); //NOI18N
-               
-               // Add both to panel
-               panel.add(label);
-               panel.add(field);
-               
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Generates a title for borders
-        *
-        * @param key Key part to look for
-        * @return Human-readable title
-        */
-       private String generateBorderTitle (final String key) {
-               // Call bundle instance
-               return this.getBundle().getString(String.format("AddressbookFrame.border.%s.title.text", key)); //NOI18N
-       }
-
-       /**
-        * Generates a title for all frames based on given sub title key. If null is
-        * given, the sub title is not generated.
-        *
-        * @param subKey Key for sub title resource
-        * @return A full application title
-        */
-       private String generateFrameTitle (final String subKey) {
-               // Base title
-               String title = AddressbookApplication.printableTitle();
-
-               // Is key given?
-               if (subKey != null) {
-                       // Add sub title
-                       title = String.format("%s - %s", title, this.getBundle().getString(String.format("AddressbookFrame.%s.title.text", subKey))); //NOI18N
-               }
-
-               // Return it
-               return title;
-       }
-
-       /**
-        * Initializes "add" and "cancel" buttons
-        */
-       private void initAddCancelButtons () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Init panel
-               JPanel panel = new JPanel();
-               panel.setLayout(new GridLayout(1, 2, 10, 10));
-
-               // Generate "add" button
-               JButton addButton = new JButton(this.getBundle().getString("AddressbookFrame.button.addAddress.text"));
-
-               // Add listener
-               addButton.addActionListener(new AddActionListener(this.addContact, this));
-
-               // Add button to panel
-               panel.add(addButton);
-
-               // Generate "cancel" button
-               JButton cancelButton = new JButton(this.getBundle().getString("AddressbookFrame.button.cancel.text"));
-
-               // Add listener
-               cancelButton.addActionListener(new CancelActionListener(this.addContact, this));
-
-               // Add button to panel
-               panel.add(cancelButton);
-
-               // Add panel to main panel
-               this.addContact.add(panel);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes "add contact" dialog
-        */
-       private void initAddContactDialog () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Instance dialog and set title
-               this.addContact = new JDialog();
-               this.addContact.setTitle(this.generateFrameTitle("dialog.addContact")); //NOI18N
-
-               // Set layout
-               this.addContact.setLayout(new GridLayout(0, 1, 2, 2));
-
-               // Only hide it on close and make it appear in middle of screen
-               this.addContact.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
-               this.addContact.setLocationRelativeTo(this.frame);
-
-               // Set always on top and auto-focus
-               this.addContact.setAlwaysOnTop(true);
-               this.addContact.setAutoRequestFocus(true);
-
-               // Initial dimension
-               this.addContact.setSize(500, 500);
-
-               // And it is not resizeable
-               this.addContact.setResizable(false);
-
-               /*
-                * Add listener which asks for confirmation, if data has been entered
-                * but not saved yet. The user may appriciate this ... ;-)
-                *
-                * @TODO Unfinished
-                */
-               this.addContact.addWindowListener(new WindowAdapter() {
-                       /**
-                        * Invoked when a window has been closed.
-                        */
-                       @Override
-                       public void windowClosed (final WindowEvent e) {
-                               // Enable main window again
-                               AddressbookFrame.getSelfInstance(null).enableMainWindow();
-                       }
-
-                       /**
-                        * Invoked when a window is in the process of being closed. The
-                        * close operation can be overridden at this point.
-                        */
-                       @Override
-                       public void windowClosing (final WindowEvent e) {
-                               e.getWindow().dispose();
-                       }
-               });
-
-               // Init 3 panels:
-               // 1) "name" panel
-               initNameDataPanel(this.addContact);
-
-               // 2) "address" panel
-               initAddressDataPanel(this.addContact);
-
-               // 3) "other" panel
-               initOtherDataPanel(this.addContact);
-
-               // 4) "Add" and "Cancel" buttons, combined they are unique for this dialog
-               initAddCancelButtons();
-
-               // x)Only for developing:
-               /* DEBUG: */ this.addContact.setVisible(true);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes address panel
-        *
-        * @param dialog A JDialog instance to this components to
-        */
-       private void initAddressDataPanel (final JDialog dialog) {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Panel "address" input boxes
-               JPanel addressPanel = new JPanel();
-               addressPanel.setLayout(new GridLayout(0, 4, 3, 3));
-
-               // Set border to titled version
-               addressPanel.setBorder(new TitledBorder(this.generateBorderTitle("address"))); //NOI18N
-
-               // Add text field for street
-               this.addTextFieldWithLabelToPanel(addressPanel, "street", 20); //NOI18N
-
-               // Number label
-               JLabel numberLabel = new JLabel(this.getBundle().getString("AddressbookFrame.number.text"));
-
-               // And text field, but only accept numbers
-               JFormattedTextField number = new JFormattedTextField();
-               number.setToolTipText(this.getBundle().getString("AddressbookFrame.number.toolTipText"));
-
-               // Add both to street panel
-               addressPanel.add(numberLabel);
-               addressPanel.add(number);
-
-               // Label for ZIP code, again numbers only
-               JLabel zipLabel = new JLabel(this.getBundle().getString("AddressbookFrame.zip.text"));
-
-               // Init text field with label
-               JFormattedTextField zip = new JFormattedTextField();
-               zip.setToolTipText(this.getBundle().getString("AddressbookFrame.zip.toolTipText"));
-
-               // Add both to street panel
-               addressPanel.add(zipLabel);
-               addressPanel.add(zip);
-
-               // Add text field for city name
-               this.addTextFieldWithLabelToPanel(addressPanel, "city", 20); //NOI18N
-
-               // Add panel to dialog
-               dialog.add(addressPanel);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initialize components
-        */
-       private void initComponents () {
-               // Debug line
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Set default close operation
-               this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
-               // Register shutdown listener
-               this.frame.addWindowListener(new WindowAdapter() {
-                       /**
-                        * Invoked when a window has been closed.
-                        */
-                       @Override
-                       public void windowClosed (final WindowEvent e) {
-                               // Shutdown application cleanly
-                               self.shutdownApplication();
-                       }
-
-                       /**
-                        * Invoked when a window is in the process of being closed. The
-                        * close operation can be overridden at this point.
-                        */
-                       @Override
-                       public void windowClosing (final WindowEvent e) {
-                               // Also shutdown cleanly here
-                               self.shutdownApplication();
-                       }
-               });
-
-               // Setup layout manager
-               this.frame.setLayout(new BorderLayout(2, 2));
-
-               // Set window size
-               this.frame.setSize(700, 400);
-
-               // Center window in middle of screen, instead of top-left corner
-               this.frame.setLocationRelativeTo(null);
-
-               // Init menu system
-               initMenuSystem();
-
-               // Init table
-               initTable();
-
-               // Init status panel
-               initStatusPanel();
-
-               // Init other windows
-               initOtherDialogs();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes a menu item instance with tool tip
-        * 
-        * @param key Message key part
-        * @return A finished JMenuItem instance
-        */
-       private JMenuItem initMenuItemWithTooltip (final String key) {
-               // Debug line
-               this.getLogger().trace(MessageFormat.format("key={0} - CALLED!", key)); //NOI18N
-
-               JMenuItem item = new JMenuItem(this.getBundle().getString(String.format("AddressbookFrame.menuItem.%s.text", key))); //NOI18N
-               item.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.menuItem.%s.toolTipText", key))); //NOI18N
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("item={0} - EXIT!", item)); //NOI18N
-
-               // Return it
-               return item;
-       }
-
-       /**
-        * Initializes the menu system
-        */
-       private void initMenuSystem () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Init menu bar, menu and item instances
-               JMenuBar menuBar = new JMenuBar();
-               JMenu menu;
-               JMenuItem item;
-
-               // Init some menus:
-               // 1) File menu
-               menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
-
-               // Add menu items:
-               // 1.x) Exit program (should be last)
-               this.addMenuItem(menu, "exitProgram", new ActionListener() { //NOI18N
-                       /**
-                        * If the user has performed this action
-                        *
-                        * @param e An instance of an ActionEvent class
-                        */
-                       @Override
-                       public void actionPerformed (final ActionEvent e) {
-                               self.shutdownApplication();
-                       }
-               });
-
-               // Add menu -> menu bar
-               menuBar.add(menu);
-
-               // Init some menus:
-               // 2) Addressbook menu
-               menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
-
-               // 2.1) Add own data
-               this.addOwnItem = this.initMenuItemWithTooltip("addOwnData"); //NOI18N
-
-               // Add listener to exit menu
-               this.addOwnItem.addActionListener(new ActionListener() {
-                       /**
-                        * If the user has performed this action
-                        *
-                        * @param e An instance of an ActionEvent class
-                        */
-                       @Override
-                       public void actionPerformed (final ActionEvent e) {
-                               try {
-                                       ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
-                                       manager.doEnterOwnData();
-                               } catch (final ContactAlreadyAddedException ex) {
-                                       // Already added, log away
-                                       // @TODO maybe output message here?
-                                       self.logException(ex);
-                               } catch (final IOException | BadTokenException ex) {
-                                       // Somethind bad happened here
-                                       // @TODO Output error message here?
-                               }
-                       }
-               });
-
-               // Add item -> menu
-               menu.add(this.addOwnItem);
-
-               // 2.2) Edit own data
-               this.editOwnItem = this.initMenuItemWithTooltip("editOwnData"); //NOI18N
-
-               // Add listener to exit menu
-               this.editOwnItem.addActionListener(new ActionListener() {
-                       /**
-                        * If the user has performed this action
-                        *
-                        * @param e An instance of an ActionEvent class
-                        */
-                       @Override
-                       public void actionPerformed (final ActionEvent e) {
-                               ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
-                               try {
-                                       manager.doChangeOwnData();
-                               } catch (final IOException | BadTokenException ex) {
-                                       self.logException(ex);
-                               }
-                       }
-               });
-
-               // Add item -> menu
-               menu.add(this.editOwnItem);
-
-               // Init more menus:
-               // 1) Add new contact
-               this.addMenuItem(menu, "addNewContact", new ActionListener() { //NOI18N
-                       /**
-                        * If the user has performed this action
-                        *
-                        * @param e An instance of an ActionEvent class
-                        */
-                       @Override
-                       public void actionPerformed (final ActionEvent e) {
-                               ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
-                               manager.doAddOtherAddress();
-                       }
-               });
-
-               // Add menu -> menu bar
-               menuBar.add(menu);
-
-               // Add menu bar -> frame
-               this.frame.add(menuBar, BorderLayout.NORTH);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes name panel
-        *
-        * @param dialog A JDialog instance to this components to
-        */
-       private void initNameDataPanel (final JDialog dialog) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N
-
-               // Panel "name" input boxes
-               JPanel namePanel = new JPanel();
-               namePanel.setLayout(new GridLayout(0, 2, 3, 3));
-
-               // Set border to titled version
-               namePanel.setBorder(new TitledBorder(this.generateBorderTitle("name"))); //NOI18N
-
-               // Gender text field
-               JLabel gLabel = new JLabel(this.getBundle().getString("AddressbookFrame.gender.text"));
-
-               // Get all genders
-               Gender[] genders = Gender.values();
-
-               // Init gender combo box with tool tip
-               JComboBox<Gender> gender = new JComboBox<>(new DefaultComboBoxModel<>(genders));
-               gender.setToolTipText(this.getBundle().getString("AddressbookFrame.gender.toolTipText"));
-
-               // Add both to gender panel
-               namePanel.add(gLabel);
-               namePanel.add(gender);
-
-               // Add text field for surname
-               this.addTextFieldWithLabelToPanel(namePanel, "surname", 20); //NOI18N
-
-               // Add text field for family name
-               this.addTextFieldWithLabelToPanel(namePanel, "familyName", 20); //NOI18N
-
-               // Finally add panel to dialog
-               dialog.add(namePanel);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes "other" data panel
-        *
-        * @param dialog A JDialog instance to this components to
-        * @todo Fill this with life
-        */
-       private void initOtherDataPanel (final JDialog dialog) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N
-
-               // Panel "other" input boxes
-               JPanel otherPanel = new JPanel();
-               otherPanel.setLayout(new GridLayout(0, 2, 3, 3));
-               otherPanel.setBorder(new TitledBorder(this.generateBorderTitle("other"))); //NOI18N
-
-               // Add text field for email address
-               this.addTextFieldWithLabelToPanel(otherPanel, "emailAddress", 20); //NOI18N
-
-               // Add text field for phone number
-               this.addTextFieldWithLabelToPanel(otherPanel, "phoneNumber", 20); //NOI18N
-
-               // Add text field for cellphone number
-               this.addTextFieldWithLabelToPanel(otherPanel, "cellphoneNumber", 20); //NOI18N
-
-               // Add text field for fax number
-               this.addTextFieldWithLabelToPanel(otherPanel, "faxNumber", 20); //NOI18N
-
-               // Init label
-               JLabel commentLabel = new JLabel(this.getBundle().getString("AddressbookFrame.comment.text"));
-
-               // Init text area with tool tip
-               JTextArea comment = new JTextArea(5, 20);
-               comment.setToolTipText(this.getBundle().getString("AddressbookFrame.comment.toolTipText"));
-
-               // Add both to panel
-               otherPanel.add(commentLabel);
-               otherPanel.add(comment);
-
-               // Finally add panel to dialog
-               dialog.add(otherPanel);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initialize other dialogs (e.g. "Add contact")
-        */
-       private void initOtherDialogs () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Init other windows:
-               // 1) Add contact
-               initAddContactDialog();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes status panel
-        */
-       private void initStatusPanel () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Init status label (which needs to be updated
-               this.statusLabel = new JLabel();
-               this.updateStatus("initializing"); //NOI18N
-
-               // Init status bar in south
-               JPanel panel = new JPanel();
-               panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
-               panel.add(this.statusLabel);
-               panel.setBorder(BorderFactory.createEtchedBorder());
-
-               // Add panel to frame
-               this.frame.add(panel, BorderLayout.SOUTH);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Initializes the table which will show all contacts
-        */
-       private void initTable () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Instance table model
-               this.dataModel = new ContactTableModel(this.getClient());
-
-               // Instance table
-               this.dataTable = new JTable(this.dataModel);
-
-               // Add mouse listener
-               this.dataTable.addMouseListener(new MouseAdapter() {
-                       /**
-                        * If the user peformed a click on a cell
-                        *
-                        * @param e Mouse event instance
-                        */
-                       @Override
-                       public void mouseClicked (final MouseEvent e) {
-                               throw new UnsupportedOperationException("Unfinished."); //NOI18N
-                       }
-               });
-
-               // Instance scroll pane
-               JScrollPane scroller = new JScrollPane();
-
-               // Add table to scroll pane
-               scroller.setViewportView(this.dataTable);
-               scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
-               scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-
-               // Add pane to frame
-               this.frame.add(scroller, BorderLayout.CENTER);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Updates status to given type
-        *
-        * @param type Status type
-        */
-       private void updateStatus (final String type) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("type={0} - CALLED!", type)); //NOI18N
-
-               // Set status message
-               this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type))); //NOI18N
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Class for "add address" button
-        */
-       private static class AddActionListener extends BaseAddressbookSystem implements ActionListener {
-               /**
-                * Dialog instance
-                */
-               private final JDialog dialog;
-
-               /**
-                * Frame (not JFrame) instance
-                */
-               private final ClientFrame frame;
-
-               /**
-                * Constructor for action listener
-                * 
-                * @param dialog Dialog instance to call back
-                * @param frame Frame instance (not JFrame)
-                */
-               protected AddActionListener (final JDialog dialog, final ClientFrame frame) {
-                       // Set dialog and frame here
-                       this.dialog = dialog;
-                       this.frame = frame;
-               }
-
-               /**
-                * If the action has been performed
-                *
-                * @param e The performed action event
-                */
-               @Override
-               public void actionPerformed (final ActionEvent e) {
-                       throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-               }
-       }
-
-       /**
-        * Class for "cancel address" button
-        */
-       private static class CancelActionListener extends BaseAddressbookSystem implements ActionListener {
-               /**
-                * Dialog instance
-                */
-               private final JDialog dialog;
-
-               /**
-                * Frame (not JFrame) instance
-                */
-               private final ClientFrame frame;
-
-               /**
-                * Constructor for action listener
-                * 
-                * @param dialog Dialog instance to call back
-                * @param frame Frame instance (not JFrame)
-                */
-               protected CancelActionListener (final JDialog dialog, final ClientFrame frame) {
-                       // Set dialog and frame here
-                       this.dialog = dialog;
-                       this.frame = frame;
-               }
-
-               /**
-                * If the action has been performed
-                *
-                * @param e The performed action event
-                */
-               @Override
-               public void actionPerformed (final ActionEvent e) {
-                       throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-               }
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java b/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java
deleted file mode 100644 (file)
index 4c7cb13..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.client.gui;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.client.BaseAddressbookClient;
-import org.mxchange.addressbook.menu.Menu;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.jcore.application.Application;
-import org.mxchange.jcore.client.gui.ClientFrame;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException;
-import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
-
-/**
- *
- * @author Roland Haeder
- */
-public class SwingClient extends BaseAddressbookClient implements AddressbookClient {
-
-       /**
-        * Swing frame instance
-        */
-       private final ClientFrame frame;
-
-       /**
-        * Constructor with an Application instance.
-        *
-        * @param application Application instance
-        */
-       public SwingClient (final Application application) {
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Set application instance
-               this.setApplication(application);
-
-               // Init frame instance
-               this.frame = AddressbookFrame.getSelfInstance(this);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void displayAddressBox (final Contact contact) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void displayNameBox (final Contact contact) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void displayOtherDataBox (final Contact contact) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void doChangeOwnAddressData (Contact contact) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void doChangeOwnNameData (Contact contact) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void doChangeOwnOtherData (Contact contact) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       /**
-        * Shows dialog to enter new contact
-        *
-        * @return Returns finished Contact instance
-        */
-       @Override
-       public Contact doEnterOwnData () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Deligate this call to the frame
-               return this.frame.doEnterOwnData();
-       }
-
-       /**
-        * Shuts down this client
-        */
-       @Override
-       public void doShutdown () throws SQLException, IOException {
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Parent call
-               super.doShutdown();
-
-               // Shutdown frame
-               this.frame.doShutdown();
-
-               // @TODO Add other shutdown stuff
-               // Debug message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void doUserMenuChoice () throws UnhandledUserChoiceException {
-               // Debug message
-               //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!");
-
-               // Not implemented here
-       }
-
-       @Override
-       public char enterChar (final char[] validChars, String message) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public Gender enterGender (final String message) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public int enterInt (final int minimum, final int maximum, final String message) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public Menu getMenu (final String menuType) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       /**
-        * Returns a Swing menu item
-        *
-        * @param accessKey Key to access the menu
-        * @param text Text to show to user
-        * @return A SelectableMenuItem
-        */
-       @Override
-       public SelectableMenuItem getMenuItem (final char accessKey, final String text) {
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Returns null as the menu is now no longer controlled here.
-               return null;
-       }
-
-       /**
-        * Inizializes this client
-        */
-       @Override
-       public void init () {
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               try {
-                       // Init contact manager here
-                       this.initContactManager();
-
-                       // Init frame
-                       this.frame.init();
-
-                       // Now start the frame
-                       this.frame.setupFrame(this);
-               } catch (final FrameAlreadyInitializedException | UnsupportedDatabaseBackendException | IOException | BadTokenException | SQLException ex) {
-                       // Abort program
-                       this.abortProgramWithException(ex);
-               }
-
-               // Debug message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void outputMessage (final String message) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void showCurrentMenu () {
-               // Debug message
-               //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!");
-
-               // Not implemented here
-       }
-
-       @Override
-       public void showEntry (final SelectableMenuItem item) {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       @Override
-       public void showWelcome () {
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Not implemented here
-       }
-
-       @Override
-       public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException {
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
-       }
-
-       /**
-        * Fills menu map with swing menus
-        */
-       @Override
-       protected final void fillMenuMap () {
-               // Nothing to fill here as the Swing frame is handling this all
-               throw new UnsupportedOperationException("Not implemented."); //NOI18N
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/contact/book/BookContact.java b/Addressbook/src/org/mxchange/addressbook/contact/book/BookContact.java
deleted file mode 100644 (file)
index d4f4bf1..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.contact.book;
-
-import org.mxchange.jcore.contact.BaseContact;
-import org.mxchange.jcore.contact.Contact;
-
-/**
- * A contact that can be placed into "contact books"
- *
- * @author Roland Haeder
- * @version 0.0
- */
-public class BookContact extends BaseContact implements Contact {
-
-       /**
-        * Default constructor, may only be used from database backend
-        */
-       public BookContact () {
-       }
-
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/contact/user/UserContact.java b/Addressbook/src/org/mxchange/addressbook/contact/user/UserContact.java
deleted file mode 100644 (file)
index 1ca7f89..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.contact.user;
-
-import java.text.MessageFormat;
-import org.mxchange.addressbook.contact.book.BookContact;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-
-/**
- *
- * @author Roland Haeder
- * @todo After a Collection has been used in ContactManager, change to
- * BaseContact
- */
-public class UserContact extends BookContact implements Contact {
-
-       /**
-        * Creates own contact entry
-        *
-        * @param gender Gender to be set
-        * @param surname Surname to be set
-        * @param familyName Family name to be set
-        * @param companyName Company name
-        * @todo Add validation of data
-        */
-       public UserContact (final Gender gender, final String surname, final String familyName, final String companyName) {
-               // Make sure all constructors are called
-               this();
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("gender={0},surname={1},familyName={2},companyName={3} - CALLED!", gender, surname, familyName, companyName)); //NOI18N
-
-               // Update all data
-               this.setGender(gender);
-               this.setSurname(surname);
-               this.setFamilyName(familyName);
-               this.setCompanyName(companyName);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Default constructor, may only be used from database backend
-        */
-       public UserContact () {
-               this.enableFlagOwnContact();
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java b/Addressbook/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java
deleted file mode 100644 (file)
index 4596c57..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.database.contact;
-
-/**
- * A class holding constants for contact table
- *
- * @author Roland Haeder
- */
-public final class AddressbookContactDatabaseConstants {
-       /**
-        * Column own_contact
-        */
-       public static final String COLUMN_OWN_CONTACT = "own_contact"; //NOI18N
-
-       /**
-        * Column id
-        */
-       public static final String COLUMN_ID = "id";
-
-       /**
-        * No instances are allowed as this class only holds static attributes
-        */
-       private AddressbookContactDatabaseConstants () {
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java b/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java
deleted file mode 100644 (file)
index 89802a8..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.database.frontend.contact;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.StringTokenizer;
-import org.mxchange.addressbook.contact.book.BookContact;
-import org.mxchange.addressbook.contact.user.UserContact;
-import org.mxchange.addressbook.database.contact.AddressbookContactDatabaseConstants;
-import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
-import org.mxchange.addressbook.manager.contact.AddressbookContactManager;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.criteria.searchable.SearchCriteria;
-import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
-import org.mxchange.jcore.database.frontend.BaseDatabaseFrontend;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storeable;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
-
-/**
- * Stores and retrieves Contact instances
- *
- * @author Roland Haeder
- */
-public class AddressbookContactDatabaseFrontend extends BaseDatabaseFrontend implements AddressbookContactFrontend {
-
-       /**
-        * Constructor which accepts a contact manager
-        *
-        * @param manager Manager instance
-        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported
-        * @throws java.sql.SQLException If an SQL error occurs
-        */
-       public AddressbookContactDatabaseFrontend (final AddressbookContactManager manager) throws UnsupportedDatabaseBackendException, SQLException {
-               // Call own constructor
-               this();
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("manager={0} - CALLED!", manager)); //NOI18N
-
-               // Manager instance must not be null
-               if (manager == null) {
-                       // Abort here
-                       throw new NullPointerException("manager is null"); //NOI18N
-               }
-
-               // Set contact manager
-               this.setContactManager(manager);
-       }
-
-       /**
-        * Default but protected constructor
-        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported
-        * @throws java.sql.SQLException Any SQL exception from e.g. MySQL connector
-        */
-       protected AddressbookContactDatabaseFrontend () throws UnsupportedDatabaseBackendException, SQLException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Set "table" name
-               this.setTableName("contacts"); //NOI18N
-
-               // Initalize backend
-               this.initBackend();
-       }
-
-       /**
-        * Adds given contact instance to database
-        *
-        * @param contact Contact instance
-        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact instance is already found
-        */
-       @Override
-       public void addContact (final Contact contact) throws ContactAlreadyAddedException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Make sure the contact is set
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               try {
-                       // First check if the contact is there
-                       if (this.isContactFound(contact)) {
-                               // Already there
-                               throw new ContactAlreadyAddedException(contact);
-                       }
-
-                       // Then add it
-                       this.getBackend().store((Storeable) contact);
-               } catch (final IOException | BadTokenException ex) {
-                       // Abort here
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-       }
-
-       /**
-        * Shuts down the database layer
-        */
-       @Override
-       public void doShutdown () throws SQLException, IOException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Shutdown backend
-               this.getBackend().doShutdown();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public Object emptyStringToNull (final String key, final Object value) {
-               throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: key={0},value={1}", key, value));
-       }
-
-       /**
-        * Some "getter" for total contact count
-        *
-        * @return Total contact count
-        */
-       @Override
-       public int getContactsCount () throws SQLException {
-               // And deligate to backend
-               return this.getBackend().getTotalCount(); //NOI18N
-       }
-
-       /**
-        * Some "getter" for own contact instance
-        *
-        * @return Own contact instance
-        */
-       @Override
-       public Contact getOwnContact () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get row index back from backend
-               int rowIndex = this.getBackend().getRowIndexFromColumn(AddressbookContactDatabaseConstants.COLUMN_OWN_CONTACT, true);
-
-               // Debug message
-               this.getLogger().debug(MessageFormat.format("rowIndex={0}", rowIndex));
-
-               // Init instance
-               Contact contact = null;
-
-               try {
-                       // Now simply read the row
-                       contact = (Contact) this.getBackend().readRow(rowIndex);
-               } catch (final BadTokenException ex) {
-                       // Bad token found
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact));
-
-               // Return it
-               return contact;
-       }
-
-       /**
-        * Checks if given Contact is found
-        * 
-        * @param contact Contact instance to check
-        * @return Whether the given Contact instance is found
-        */
-       @Override
-       public boolean isContactFound (final Contact contact) throws BadTokenException {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // contact should not be null
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Default is not found
-               boolean isFound = false;
-
-               // Start iteration
-               Iterator<? extends Storeable> iterator = this.getBackend().iterator();
-
-               // Check all entries
-               while (iterator.hasNext()) {
-                       // Get next element
-                       Contact c = (Contact) iterator.next();
-
-                       // Debug message
-                       this.getLogger().debug(MessageFormat.format("c={0},contact={1}", c, contact)); //NOI18N
-
-                       // Is it added?
-                       if (c.equals(contact)) {
-                               // Is found
-                               isFound = true;
-                               break;
-                       }
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("isFound={0} - EXIT!", isFound)); //NOI18N
-
-               // Return it
-               return isFound;
-       }
-
-       /**
-        * Checks whether own contact is found in database
-        *
-        * @return Whether own contact is found
-        * @throws org.mxchange.jcore.exceptions.BadTokenException Continued throw
-        * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
-        * @throws java.lang.NoSuchMethodException If a method cannot be found
-        * @throws java.lang.IllegalAccessException If a method is not accessible
-        * @throws java.lang.reflect.InvocationTargetException Any other problems?
-        */
-       @Override
-       public boolean isOwnContactFound () throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-               // Get search criteria instance
-               SearchableCriteria critera = new SearchCriteria();
-
-               // Add condition
-               critera.addCriteria(AddressbookContactDatabaseConstants.COLUMN_OWN_CONTACT, true);
-
-               // Get result
-               Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(critera);
-
-               // Deligate this call to backend
-               return result.hasNext();
-       }
-
-       /**
-        * Reads a single row and parses it to a contact instance
-        *
-        * @param rowIndex Row index (also how much to skip)
-        * @return Contact instance
-        */
-       @Override
-       public Contact readSingleContact (final int rowIndex) {
-               try {
-                       // Deligate this to backend instance
-                       return (Contact) this.getBackend().readRow(rowIndex);
-               } catch (final BadTokenException ex) {
-                       // Bad token found
-                       this.abortProgramWithException(ex);
-               }
-
-               // Bad state, should not be reached
-               throw new IllegalStateException("This should not be reached");
-       }
-
-       @Override
-       public Storeable toStoreable (final Map<String, String> map) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-               throw new UnsupportedOperationException("Not supported yet: map=" + map);
-       }
-
-       @Override
-       public String getIdName () {
-               // Return id column
-               return AddressbookContactDatabaseConstants.COLUMN_ID;
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java b/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java
deleted file mode 100644 (file)
index 213575e..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2015 Roland Häder
- *
- * 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.addressbook.database.frontend.contact;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.SQLException;
-import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.database.frontend.DatabaseFrontend;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-
-/**
- * An interface for addressbook contact database frontends
- *
- * @author Roland Häder
- */
-public interface AddressbookContactFrontend extends DatabaseFrontend {
-
-       /**
-        * Adds given contact instance to database
-        *
-        * @param contact Contact instance to add
-        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added
-        */
-       public void addContact (final Contact contact) throws ContactAlreadyAddedException;
-
-       /**
-        * Some "getter" for total contacts count
-        *
-        * @return Total contacts count
-        * @throws java.sql.SQLException If any SQL error occurs
-        */
-       public int getContactsCount () throws SQLException;
-
-       /**
-        * Checks if given Contact is found
-        * 
-        * @param contact Contact instance to check
-        * @return Whether the given Contact instance is found
-        * @throws java.sql.SQLException If an SQL error occurs
-        * @throws java.io.IOException If an IO error occurs
-        * @throws org.mxchange.jcore.exceptions.BadTokenException Continued throw
-        * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
-        * @throws java.lang.NoSuchMethodException If a method cannot be found
-        * @throws java.lang.IllegalAccessException If a method is not accessible
-        * @throws java.lang.reflect.InvocationTargetException Any other problems?
-        */
-       public boolean isContactFound (final Contact contact) throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-
-       /**
-        * Some "getter" for own contact instance
-        *
-        * @return Own contact instance
-        */
-       public Contact getOwnContact ();
-
-       /**
-        * Checks whether own contact is found
-        * 
-        * @return Whether own contact is found
-        * @throws java.sql.SQLException If any SQL error occurs
-        * @throws java.io.IOException If an IO error occurs
-        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
-        * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
-        * @throws java.lang.NoSuchMethodException If a method cannot be found
-        * @throws java.lang.IllegalAccessException If a method is not accessible
-        * @throws java.lang.reflect.InvocationTargetException Any other problems?
-        */
-       public boolean isOwnContactFound () throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-
-       /**
-        * Reads a single row and parses it to a contact instance
-        *
-        * @param rowIndex Row index (also how much to skip)
-        * @return Contact instance
-        */
-       public Contact readSingleContact (final int rowIndex);
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java b/Addressbook/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java
deleted file mode 100644 (file)
index 634f4b4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.exceptions;
-
-import java.text.MessageFormat;
-import org.mxchange.jcore.contact.Contact;
-
-/**
- * Thrown if the given Contact instance is already added
- * 
- * @author Roland Haeder
- */
-public class ContactAlreadyAddedException extends Exception {
-
-       /**
-        * Constructor with a Contact instance
-        *
-        * @param contact Contact that is already added
-        */
-       public ContactAlreadyAddedException (final Contact contact) {
-               super(MessageFormat.format("Contact with gender={0}, surname={1} and familyName={2} already added.", contact.getGender(), contact.getSurname(), contact.getFamilyName()));
-       }
-
-       /**
-        * Default constructor, may be used if no contact instance is available
-        */
-       public ContactAlreadyAddedException () {
-               super("Contact already added");
-       }
-       
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java b/Addressbook/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java
deleted file mode 100644 (file)
index ef41687..0000000
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.manager.contact;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.database.frontend.contact.AddressbookContactDatabaseFrontend;
-import org.mxchange.addressbook.database.frontend.contact.AddressbookContactFrontend;
-import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
-import org.mxchange.jcore.client.Client;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
-import org.mxchange.jcore.manager.BaseManager;
-
-/**
- * A manager for contacts.
- *
- * @author Roland Haeder
- * @version 0.0
- */
-public class AddressbookContactManager extends BaseManager implements ManageableAddressbookContact {
-
-       /**
-        * Column name list
-        */
-       private final List<String> columnNames;
-
-       /**
-        * A AddressbookContactFrontend instance
-        */
-       private final AddressbookContactFrontend contactDatabase;
-
-       /**
-        * Translated column name list
-        */
-       private final List<String> translatedColumnNames;
-
-       /**
-        * Constructor which accepts maxContacts for maximum (initial) contacts and
-        * a client instance.
-        *
-        * @param client Client instance to use
-        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the configured database backend is not supported
-        * @throws java.sql.SQLException If an SQL error occurs
-        */
-       public AddressbookContactManager (final Client client) throws UnsupportedDatabaseBackendException, SQLException {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("client={1} - CALLED!", client)); //NOI18N
-
-               // Make sure all parameters are set correctly
-               if (client == null) {
-                       // Abort here
-                       throw new NullPointerException("client is null"); //NOI18N
-               }
-
-               // Set client instance
-               this.setClient(client);
-
-               // Init database connection
-               this.contactDatabase = new AddressbookContactDatabaseFrontend(this);
-
-               // Initialize list
-               this.columnNames = new ArrayList<>(15);
-               this.translatedColumnNames = new ArrayList<>(15);
-
-               // And fill it
-               this.fillColumnNamesFromBundle();
-
-               // Debug message
-               //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
-       }
-
-       /**
-        * Adds given Contact instance to list
-        *
-        * @param contact Contact instance to add
-        */
-       @Override
-       public void addContact (final Contact contact)  throws ContactAlreadyAddedException {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
-
-               // Contact instance must not be null
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Add it
-               this.getContactDatabase().addContact(contact);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Let the user add a new other address
-        */
-       @Override
-       public void doAddOtherAddress () {
-               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
-       }
-
-       /**
-        * Let the user change address data
-        *
-        * @param contact Instance to change data
-        */
-       @Override
-       public void doChangeAddressData (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
-
-               // Contact must not be null
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               // First display it again
-               client.displayAddressBox(contact);
-
-               // Is it own data?
-               if (contact.isOwnContact()) {
-                       // Deligate to client
-                       client.doChangeOwnAddressData(contact);
-               } else {
-                       // Other contact's address data to change
-                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Let the user change "name data"
-        *
-        * @param contact Instance to change data
-        */
-       @Override
-       public void doChangeNameData (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
-
-               // Contact must not be null
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               // First display them again
-               client.displayNameBox(contact);
-
-               // Is this own data?
-               if (contact.isOwnContact()) {
-                       // Re-ask own data
-                       client.doChangeOwnNameData(contact);
-               } else {
-                       // Then re-ask them ...
-                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Let the user change other address
-        */
-       @Override
-       public void doChangeOtherAddress () {
-               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
-       }
-
-       /**
-        * Let the user change other data
-        *
-        * @param contact Instance to change data
-        * @todo Didn't handle birthday
-        */
-       @Override
-       public void doChangeOtherData (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
-
-               // Contact must not be null
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               // First display them again
-               client.displayOtherDataBox(contact);
-
-               // Is this own data?
-               if (contact.isOwnContact()) {
-                       // Re-ask own data
-                       client.doChangeOwnOtherData(contact);
-               } else {
-                       // Then re-ask them ...
-                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Allows the user to change his/her own data
-        */
-       @Override
-       public void doChangeOwnData () throws IOException , BadTokenException{
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               /*
-                * First check if the user has registered own contact, before that
-                * nothing can be changed.
-                */
-               if (!this.isOwnContactAdded()) {
-                       // Not added
-                       this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben."); //NOI18N
-
-                       // Skip any below code
-                       return;
-               }
-
-               // Instance
-               Contact contact = this.getOwnContact();
-
-               // It must be found
-               assert (contact instanceof Contact);
-
-               // Display contact
-               contact.show(this.getClient());
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               try {
-                       // Ask user what to change
-                       client.userChooseChangeContactData(contact);
-               } catch (final UnhandledUserChoiceException ex) {
-                       this.getLogger().catching(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Let the user delete other address
-        */
-       @Override
-       public void doDeleteOtherAddress () {
-               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
-       }
-
-       /**
-        * Asks user for own data
-        */
-       @Override
-       public void doEnterOwnData () throws ContactAlreadyAddedException, IOException , BadTokenException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Is own contact already added?
-               if (this.isOwnContactAdded()) {
-                       // Don't continue here
-                       throw new ContactAlreadyAddedException();
-               }
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               // Deligate this call to the client
-               Contact contact = client.doEnterOwnData();
-
-               // Is it set?
-               if (contact instanceof Contact) {
-                       // Add it to contact "book"
-                       this.registerContact(contact);
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       @Override
-       public void doListContacts () {
-               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
-       }
-
-       @Override
-       public void doSearchContacts () {
-               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
-       }
-
-       /**
-        * Shuts down this contact manager
-        * 
-        * @throws java.sql.SQLException If an SQL error occurs
-        * @throws java.io.IOException If an IO error occurs
-        */
-       @Override
-       public void doShutdown () throws SQLException, IOException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Shut down the database layer
-               this.getContactDatabase().doShutdown();
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Asks the user for his/her cellphone number
-        *
-        * @return User's cellphone number
-        */
-       @Override
-       public String enterOwnCellNumber () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
-       }
-
-       /**
-        * Asks the user for his/her city's name
-        *
-        * @return City's name of the user
-        */
-       @Override
-       public String enterOwnCity () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
-       }
-
-       /**
-        * Asks the user for his/her city's name
-        *
-        * @return City's name of the user
-        */
-       @Override
-       public String enterOwnComment () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
-       }
-
-       /**
-        * Asks the user for his/her company name
-        *
-        * @return User's company name
-        */
-       @Override
-       public String enterOwnCompanyName () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
-       }
-
-       /**
-        * Asks user for his/her own country code
-        *
-        * @return User's own country code
-        */
-       @Override
-       public String enterOwnCountryCode () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
-       }
-
-       /**
-        * Asks user for his/her own country code
-        *
-        * @return User's own country code
-        */
-       @Override
-       public String enterOwnEmailAddress () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
-       }
-
-       /**
-        * Asks the user for family name
-        *
-        * @return Family name of the user
-        */
-       @Override
-       public String enterOwnFamilyName () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
-       }
-
-       /**
-        * Asks the user for family name
-        *
-        * @return Family name of the user
-        */
-       @Override
-       public String enterOwnFaxNumber () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
-       }
-
-       /**
-        * Asks the user for gender, until a valid has been entered
-        *
-        * @return Gender of the user
-        */
-       @Override
-       public Gender enterOwnGender () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
-       }
-
-       /**
-        * Asks the user for phone number
-        *
-        * @return Phone number of the user
-        */
-       @Override
-       public String enterOwnPhoneNumber () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
-       }
-
-       /**
-        * Asks the user for own street (including number)
-        *
-        * @return Own street an number
-        */
-       @Override
-       public String enterOwnStreet () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
-       }
-
-       /**
-        * Asks the user for surname
-        *
-        * @return Surname of the user
-        */
-       @Override
-       public String enterOwnSurname () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
-       }
-
-       /**
-        * Asks the user for own ZIP code
-        *
-        * @return ZIP code
-        */
-       @Override
-       public int enterOwnZipCode () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Get and cast client instance
-               AddressbookClient client = (AddressbookClient) this.getClient();
-
-               return client.enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
-       }
-
-       @Override
-       public final int getColumnCount () {
-               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
-
-               return this.columnNames.size();
-       }
-
-       /**
-        * Getter for column name at given index.
-        *
-        * @param columnIndex Column index
-        * @return Database column name
-        */
-       @Override
-       public String getColumnName (final int columnIndex) {
-               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
-
-               // Get column name at index
-               return this.columnNames.get(columnIndex);
-       }
-
-       /**
-        * Getter for translated column name at given index.
-        *
-        * @param columnIndex Column index
-        * @return Human-readable column name
-        */
-       @Override
-       public String getTranslatedColumnName (final int columnIndex) {
-               assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
-
-               // Get column name at index
-               return this.translatedColumnNames.get(columnIndex);
-       }
-
-       /**
-        * Somewhat "getter" for value from given row and column index
-        *
-        * @param rowIndex Row index
-        * @param columnIndex Column index
-        * @return Value from given row/column
-        */
-       @Override
-       public Object getValueFromRowColumn (final int rowIndex, final int columnIndex) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("rowIndex={0},columnIndex={1} CALLED!", rowIndex, columnIndex));
-
-               // Then get specific row from database which is a Contact instance
-               Contact contact = this.getContactDatabase().readSingleContact(rowIndex);
-
-               // Debug message
-               this.getLogger().debug(MessageFormat.format("contact={0}", contact));
-
-               // It may return null
-               if (contact == null) {
-                       // Nothing found
-                       this.getLogger().warn("contact is null - returning null ...");
-                       return null;
-               }
-
-               // Convert column index -> name
-               String columnName = this.getColumnName(columnIndex);
-
-               // Debug message
-               this.getLogger().debug(MessageFormat.format("columnName={0}", columnName));
-
-               // Now get that column
-               Object value = null;
-               try {
-                       value = contact.getValueFromColumn(columnName);
-               } catch (final IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value));
-
-               // Return it
-               return value;
-       }
-
-       /**
-        * Checks whether own contact is already added by checking all entries for
-        * isOwnContact flag
-        *
-        * @return Whether own contact is already added
-        */
-       @Override
-       public boolean isOwnContactAdded () throws IOException, BadTokenException {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Init variable
-               boolean isAdded = false;
-
-               try {
-                       // Deligate this call to frontend
-                       isAdded = this.getContactDatabase().isOwnContactFound();
-               } catch (final SQLException | IOException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
-                       // Something bad happened
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded)); //NOI18N
-
-               // Return result
-               return isAdded;
-       }
-
-       /**
-        * Adds given contact to address book and flushes all entries to database
-        *
-        * @param contact Contact being added
-        * @todo Add check for book size
-        */
-       @Override
-       public void registerContact (final Contact contact) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
-
-               // Sanity check
-               if (contact == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               }
-
-               // Debug message
-               /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size())); //NOI18N
-               try {
-                       // Check if contact is found
-                       if (this.getContactDatabase().isContactFound(contact)) {
-                               // Contact already added
-                               // @todo Do something here
-                       } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
-                               // Own contact already added
-                               // @todo Do something
-                       }
-
-                       // Add contact to internal list
-                       this.addContact(contact);
-               } catch (final ContactAlreadyAddedException | BadTokenException | SQLException | IOException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
-                       // Abort here
-                       this.abortProgramWithException(ex);
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Getter for size
-        *
-        * @return size of contact "book"
-        */
-       @Override
-       public final int size () {
-               // Init size
-               int size = -1;
-
-               try {
-                       size = this.getContactDatabase().getContactsCount();
-               } catch (final SQLException ex) {
-                       // Something happened
-                       this.abortProgramWithException(ex);
-               }
-
-               // Return amount
-               return size;
-       }
-
-       /**
-        * Fills the column names array with strings from bundle
-        */
-       private void fillColumnNamesFromBundle () {
-               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
-               assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
-
-               // Debug message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // First get an iterator from key set to iterate over
-               Iterator<String> iterator = this.getBundle().keySet().iterator();
-
-               // Then iterate over all
-               while (iterator.hasNext()) {
-                       // Get next element
-                       String key = iterator.next();
-
-                       // Does the key start with AddressbookContactManager.columnName ?
-                       if (key.startsWith("ContactManager.columnName")) { //NOI18N
-                               // This is the wanted entry.
-                               this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N
-
-                               // Convert string to array based on delimiter '.'
-                               String[] tokens = this.getArrayFromString(key, ".", 4);
-
-                               // Token array must contain 4 elements (AddressbookContactManager.columnName.foo.text)
-                               assert(tokens.length == 4) : MessageFormat.format("Array tokens contains not 4 elements: {0}", Arrays.toString(tokens));
-
-                               // Get pre-last element
-                               String columnName = tokens[tokens.length - 2];
-
-                               // Debug message
-                               this.getLogger().debug(MessageFormat.format("columnName={0} - adding ...", columnName));
-
-                               // So add it
-                               this.columnNames.add(columnName);
-                               this.translatedColumnNames.add(this.getBundle().getString(key));
-                       }
-               }
-
-               // Debug message
-               this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N
-       }
-
-       /**
-        * A AddressbookContactFrontend instance
-        *
-        * @return the database
-        */
-       private AddressbookContactFrontend getContactDatabase () {
-               return this.contactDatabase;
-       }
-
-       /**
-        * "Getter" for own contact instance or null if not found
-        *
-        * @return Contact instance or null
-        */
-       private Contact getOwnContact () {
-               // Trace message
-               this.getLogger().trace("CALLED!"); //NOI18N
-
-               // Deligate this call to database frontend
-               Contact contact = this.getContactDatabase().getOwnContact();
-
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
-
-               // Return instance or null
-               return contact;
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java b/Addressbook/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java
deleted file mode 100644 (file)
index 77d39d3..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.manager.contact;
-
-import java.io.IOException;
-import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
-import org.mxchange.jcore.contact.Contact;
-import org.mxchange.jcore.contact.Gender;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.manager.database.ManageableDatabase;
-
-/**
- *
- * @author Roland Haeder
- */
-public interface ManageableAddressbookContact extends ManageableDatabase {
-       /**
-        * Allows the user to enter own cellphone number.
-        *
-        * @return Cellphone number
-        */
-       public String enterOwnCellNumber ();
-
-       /**
-        * Allows the user to enter own city name.
-        *
-        * @return City name
-        */
-       public String enterOwnCity ();
-
-       /**
-        * Allows the user to enter comment for own entry.
-        *
-        * @return Comment
-        */
-       public String enterOwnComment ();
-
-       /**
-        * Allows the user to enter own company name.
-        *
-        * @return Company name
-        */
-       public String enterOwnCompanyName ();
-
-       /**
-        * Allows the user to enter own country code.
-        *
-        * @return Country code
-        */
-       public String enterOwnCountryCode ();
-
-       /**
-        * Allows the user to enter own email address.
-        *
-        * @return Email address
-        */
-       public String enterOwnEmailAddress ();
-
-       /**
-        * Allows the user to enter own family name.
-        *
-        * @return Family name
-        */
-       public String enterOwnFamilyName ();
-
-       /**
-        * Allows the user to enter own fax number.
-        *
-        * @return Fax number
-        */
-       public String enterOwnFaxNumber ();
-
-       /**
-        * Allows the user to enter own gender.
-        *
-        * @return Gender
-        */
-       public Gender enterOwnGender ();
-
-       /**
-        * Allows the user to enter own phone number.
-        *
-        * @return Phone number
-        */
-       public String enterOwnPhoneNumber ();
-
-       /**
-        * Allows the user to enter own street and house number.
-        *
-        * @return Street and house number
-        */
-       public String enterOwnStreet ();
-
-       /**
-        * Allows the user to enter own surname.
-        *
-        * @return Surname
-        */
-       public String enterOwnSurname ();
-
-       /**
-        * Allows the user to enter own ZIP code.
-        *
-        * @return ZIP code
-        */
-       public int enterOwnZipCode ();
-
-       /**
-        * List all contacts
-        */
-       public void doListContacts ();
-
-       /**
-        * Adds given contact to address book
-        *
-        * @param contact Contact being added
-        * @todo Add check for book size
-        */
-       public void registerContact (final Contact contact);
-
-       /**
-        * Adds given Contact instance to list
-        *
-        * @param contact Contact instance to add
-        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added
-        */
-       public void addContact (final Contact contact) throws ContactAlreadyAddedException;
-
-       /**
-        * Let the user add a new other address
-        */
-       public void doAddOtherAddress ();
-
-       /**
-        * The user can change address data, like street, ZIP code, city and country
-        * of given Contact instance.
-        *
-        * @param contact Instance to change data
-        */
-       public void doChangeAddressData (final Contact contact);
-
-       /**
-        * The user can change name data, like gender, surname, family name and
-        * company name (if business contact).
-        *
-        * @param contact Instance to change data
-        */
-       public void doChangeNameData (final Contact contact);
-
-       /**
-        * Let the user change other address
-        */
-       public void doChangeOtherAddress ();
-
-       /**
-        * The user can change other data, like phone numbers or comments.
-        *
-        * @param contact Instance to change data
-        */
-       public void doChangeOtherData (final Contact contact);
-
-       /**
-        * Let the user change own data
-        * @throws java.io.IOException If an IO error was found
-        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
-        */
-       public void doChangeOwnData () throws IOException , BadTokenException;
-
-       /**
-        * Let the user delete other address
-        */
-       public void doDeleteOtherAddress ();
-
-       /**
-        * Asks user for own data
-        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If own contact is already added
-        * @throws java.io.IOException If an IO error was found
-        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
-        */
-       public void doEnterOwnData () throws ContactAlreadyAddedException, IOException , BadTokenException;
-
-       /**
-        * Searches address book for a contact
-        */
-       public void doSearchContacts ();
-
-       /**
-        * Checks whether own contact is already added by checking all entries for
-        * isOwnContact flag
-        *
-        * @return Whether own contact is already added
-        * @throws java.io.IOException If an IO error occurs
-        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
-        */
-       public boolean isOwnContactAdded () throws IOException, BadTokenException;
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/AddressbookMenu.java b/Addressbook/src/org/mxchange/addressbook/menu/AddressbookMenu.java
deleted file mode 100644 (file)
index 12257eb..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu;
-
-import java.text.MessageFormat;
-import java.util.List;
-import org.apache.logging.log4j.Logger;
-import org.mxchange.addressbook.BaseAddressbookSystem;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.jcore.client.Client;
-
-/**
- * Utility class for menu structure
- *
- * @author Roland Haeder
- */
-public class AddressbookMenu extends BaseAddressbookSystem {
-
-       /**
-        * Copies entries for given type into the menu list
-        *
-        * @param menuList Menu list for later showing
-        * @param menuType Type of menu
-        * @param client Client instance to call back
-        */
-       public static void addItemsToList (final List<SelectableMenuItem> menuList, final String menuType, final Client client) {
-               // Get logger
-               Logger log = new AddressbookMenu().getLogger();
-
-               // Trace call
-               log.trace(MessageFormat.format("menuList={0},menuType={1},client={2} - CALLED!", menuList, menuType, client)); //NOI18N
-
-               // Some instances must be set
-               if (menuList == null) {
-                       // Abort here
-                       throw new NullPointerException("menuList is null"); //NOI18N
-               } else if (client == null) {
-                       // Abort here
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (!(client instanceof AddressbookClient)) {
-                       // Not correct instance
-                       throw new IllegalArgumentException(MessageFormat.format("client{0} must implement AddressbookClient", client));
-               }
-
-               // Cast client to proper interface
-               AddressbookClient c = (AddressbookClient) client;
-
-               // Get list size
-               int size = menuList.size();
-
-               // Debug message
-               log.debug(MessageFormat.format("Adding menu for '{0}' (old size: '{1}') ...", menuType, size)); //NOI18N
-
-               // Depends on type
-               switch (menuType) {
-                       case "main": // Main menu //NOI18N
-                               // Enter own data
-                               menuList.add(c.getMenuItem('1', "Eigene Adresse anlegen"));
-
-                               // Change own data
-                               menuList.add(c.getMenuItem('2', "Eigene Adresse ändern"));
-
-                               // Add new addess
-                               menuList.add(c.getMenuItem('3', "Neue Adresse hinzufügen"));
-
-                               // List entries
-                               menuList.add(c.getMenuItem('4', "Adressbuch anzeigen"));
-
-                               // Address search
-                               menuList.add(c.getMenuItem('5', "Adresse suchen"));
-
-                               // Change other address
-                               menuList.add(c.getMenuItem('6', "Adresse ändern"));
-
-                               // Delete other address
-                               menuList.add(c.getMenuItem('7', "Adresse löschen"));
-
-                               // Always last line: Exit program
-                               menuList.add(c.getMenuItem('0', "Programm verlassen"));
-                               break;
-
-                       default: // Not supported
-                               log.error(MessageFormat.format("Menu type '{0}' ont supported", menuType)); //NOI18N
-                               System.exit(1);
-               }
-
-               // Size must have changed to more entries than before
-               assert (menuList.size() > size);
-       }
-
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/BaseMenu.java b/Addressbook/src/org/mxchange/addressbook/menu/BaseMenu.java
deleted file mode 100644 (file)
index f554820..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu;
-
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import org.mxchange.addressbook.BaseAddressbookSystem;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.jcore.client.Client;
-
-/**
- *
- * @author Roland Haeder
- */
-public class BaseMenu extends BaseAddressbookSystem {
-
-       /**
-        * Menu list
-        */
-       private List<SelectableMenuItem> menuList;
-
-       /**
-        * No instance from this object
-        */
-       protected BaseMenu () {
-       }
-
-       /**
-        * Size of menu items
-        *
-        * @return Count of menu items
-        */
-       public int getMenuItemsCount () {
-               return this.menuList.size();
-       }
-
-       /**
-        * "Getter" for an iterator of this menu's items
-        *
-        * @return An iterator of all menu items
-        */
-       public Iterator<SelectableMenuItem> getMenuItemsIterator () {
-               return this.menuList.iterator();
-       }
-
-       /**
-        * Shows this menu
-        *
-        * @param client Client instance to call back
-        */
-       public void show (final Client client) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("client={0} CALLED!", client)); //NOI18N
-
-               // Client must not be null
-               if (client == null) {
-                       // Abort here
-                       throw new NullPointerException("client is null"); //NOI18N
-               }
-
-               // Get values
-               Iterator<SelectableMenuItem> iterator = this.menuList.iterator();
-
-               // Debug message
-               this.getLogger().debug("Showing menu with '" + this.menuList.size() + "' entries.");
-
-               // Output all menus
-               while (iterator.hasNext()) {
-                       // Get item
-                       SelectableMenuItem item = iterator.next();
-
-                       // Show this item
-                       item.show((AddressbookClient) client);
-               }
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-       /**
-        * Getter for menu list
-        *
-        * @return      menuList List of menu entries
-        */
-       protected final List<SelectableMenuItem> getMenuList () {
-               return this.menuList;
-       }
-
-       /**
-        * Initializes menu
-        *
-        * @param menuType      Menu type to initialize
-        * @param client CLient to call back
-        */
-       protected void initMenu (final String menuType, final Client client) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N
-
-               // Init menu list
-               this.menuList = new ArrayList<>(5);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/Menu.java b/Addressbook/src/org/mxchange/addressbook/menu/Menu.java
deleted file mode 100644 (file)
index 78a5fb1..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu;
-
-import java.util.Iterator;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.jcore.client.Client;
-
-/**
- *
- * @author Roland Haeder
- * @todo find better name
- */
-public interface Menu {
-
-       /**
-        * "Getter" for an iterator on all menu items of the current menu
-        *
-        * @return Iterator on all menu items
-        */
-       public Iterator<SelectableMenuItem> getMenuItemsIterator ();
-
-       /**
-        * Shows this menu
-        *
-        * @param client Client instance
-        */
-       public void show (final Client client);
-
-       /**
-        * Size of all menu items
-        *
-        * @return
-        */
-       public int getMenuItemsCount ();
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/MenuTools.java b/Addressbook/src/org/mxchange/addressbook/menu/MenuTools.java
deleted file mode 100644 (file)
index 30d8164..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu;
-
-import java.util.Iterator;
-import java.util.Map;
-import org.apache.logging.log4j.Logger;
-import org.mxchange.addressbook.BaseAddressbookSystem;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-
-/**
- *
- * @author Roland Haeder
- */
-public class MenuTools extends BaseAddressbookSystem {
-
-       /**
-        * Gets an array with all available access keys back from given menu map.
-        * This can later be handle to the client's enterChar() method.
-        *
-        * @param menus A Map with all menus and their entries
-        * @param menuType Menu type
-        * @return An array with available access chars
-        */
-       public static char[] getAccessKeysFromMenuMap (final Map<String, Menu> menus, final String menuType) {
-               // Get logger
-               Logger logger = new MenuTools().getLogger();
-
-               // First search for the proper menu class
-               Menu menu = menus.get(menuType);
-
-               // Is it there?
-               if (!(menu instanceof Menu)) {
-                       // Not found
-                       // @todo Rewrite to exception
-                       logger.error("Menu '" + menuType + "' not found.");
-                       System.exit(1);
-               }
-
-               // Get iterator
-               Iterator<SelectableMenuItem> iterator = menu.getMenuItemsIterator();
-
-               // Init return array and counter 'i'
-               char[] accessKeys = new char[menu.getMenuItemsCount()];
-               int i = 0;
-
-               // Now "walk" through all menu entries
-               while (iterator.hasNext()) {
-                       // Get item
-                       SelectableMenuItem item = iterator.next();
-                       //* NOISY-DEBUG: */ logger.debug("item=" + item);
-
-                       // Get access key from item and add it to the array
-                       accessKeys[i] = item.getAccessKey();
-                       //* NOISY-DEBUG: */ logger.debug("accessKeys[" + i + "]=" + accessKeys[i]);
-
-                       // Increment counter
-                       i++;
-               }
-
-               // Return finished array
-               return accessKeys;
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java b/Addressbook/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java
deleted file mode 100644 (file)
index 965f68a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu.console;
-
-import java.text.MessageFormat;
-import org.mxchange.addressbook.menu.AddressbookMenu;
-import org.mxchange.addressbook.menu.BaseMenu;
-import org.mxchange.addressbook.menu.Menu;
-import org.mxchange.jcore.client.Client;
-
-/**
- *
- * @author Roland Haeder
- */
-public class ConsoleMenu extends BaseMenu implements Menu {
-
-       /**
-        * Constructor for this menu
-        *
-        * @param menuType      Menu type to initialize
-        * @param client CLient to call back
-        */
-       public ConsoleMenu (final String menuType, final Client client) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N
-
-               // Client must not be null
-               if (client == null)  {
-                       // Abort here
-                       throw new NullPointerException("client is null");
-               }
-
-               // Init menu
-               this.initMenu(menuType, client);
-
-               // Add all items
-               AddressbookMenu.addItemsToList(this.getMenuList(), menuType, client);
-       }
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java b/Addressbook/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java
deleted file mode 100644 (file)
index 4bb1cf9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu.item;
-
-import org.mxchange.addressbook.BaseAddressbookSystem;
-
-/**
- *
- * @author Roland Haeder
- */
-public class BaseMenuItem extends BaseAddressbookSystem {
-
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java b/Addressbook/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java
deleted file mode 100644 (file)
index a6de00a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu.item;
-
-import org.mxchange.jcore.client.Client;
-
-/**
- *
- * @author Roland Haeder
- */
-public interface SelectableMenuItem {
-
-       /**
-        * Shows this menu item
-        *
-        * @param client Client instance
-        */
-       public void show (final Client client);
-
-       /**
-        * Access key
-        *
-        * @return the accessKey
-        */
-       public char getAccessKey ();
-
-       /**
-        * Text to user
-        *
-        * @return the text
-        */
-       public String getText ();
-}
diff --git a/Addressbook/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java b/Addressbook/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java
deleted file mode 100644 (file)
index 1090a63..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2015 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.addressbook.menu.item.console;
-
-import java.text.MessageFormat;
-import org.mxchange.addressbook.client.AddressbookClient;
-import org.mxchange.addressbook.menu.item.BaseMenuItem;
-import org.mxchange.addressbook.menu.item.SelectableMenuItem;
-import org.mxchange.jcore.client.Client;
-
-/**
- *
- * @author Roland Haeder
- */
-public class ConsoleMenuItem extends BaseMenuItem implements SelectableMenuItem {
-
-       /**
-        * Access key
-        */
-       private char accessKey;
-
-       /**
-        * Text to user
-        */
-       private String text;
-
-       /**
-        * Constructor for building a console menu with access key and text
-        *
-        * @param accessKey Access key for this menu entry
-        * @param text Text to show to user
-        */
-       public ConsoleMenuItem (final char accessKey, final String text) {
-               this.setAccessKey(accessKey);
-               this.setText(text);
-       }
-
-       /**
-        * Access key
-        *
-        * @return the accessKey
-        */
-       @Override
-       public final char getAccessKey () {
-               return this.accessKey;
-       }
-
-       /**
-        * Access key
-        *
-        * @param accessKey the accessKey to set
-        */
-       private void setAccessKey (char accessKey) {
-               this.accessKey = accessKey;
-       }
-
-       /**
-        * Text to user
-        *
-        * @return the text
-        */
-       @Override
-       public String getText () {
-               return this.text;
-       }
-
-       /**
-        * Text to user
-        *
-        * @param text the text to set
-        */
-       private void setText (String text) {
-               this.text = text;
-       }
-
-       @Override
-       public void show (final Client client) {
-               // Trace message
-               this.getLogger().trace(MessageFormat.format("client={0} - CALLED!", client)); //NOI18N
-
-               // Client must not be null
-               if (client == null) {
-                       // Abort here
-                       throw new NullPointerException("client is null");
-               } else if (!(client instanceof AddressbookClient)) {
-                       // Wrong interface
-                       throw new IllegalArgumentException("client " + client + " must implement AddressbookClient");
-               }
-
-               // Cast it
-               AddressbookClient c = (AddressbookClient) client;
-
-               // Call-back client over menu
-               c.showEntry(this);
-
-               // Trace message
-               this.getLogger().trace("EXIT!"); //NOI18N
-       }
-
-}
diff --git a/Addressbook/src/org/mxchange/localization/bundle_de_DE.properties b/Addressbook/src/org/mxchange/localization/bundle_de_DE.properties
deleted file mode 100644 (file)
index 19ee753..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2015 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/>.
-AddressbookFrame.border.name.title.text=Anrede, Vorname, Nachname:
-AddressbookFrame.border.address.title.text=Anschrift:
-AddressbookFrame.border.other.title.text=Andere Angaben:
-AddressbookFrame.button.addAddress.text=Adresse hinzuf\u00fcgen
-AddressbookFrame.button.cancel.text=Abbrechen
-AddressbookFrame.menu.file.text=Datei
-AddressbookFrame.menu.addressbook.text=Adressbuch
-AddressbookFrame.statusLabel.initializing.text=Initialisiere ...
-AddressbookFrame.statusLabel.done.text=Fertig.
-AddressbookFrame.statusLabel.shutdown.text=Shuttting down ...
-AddressbookFrame.menuItem.exitProgram.text=Programm beenden
-AddressbookFrame.menuItem.exitProgram.toolTipText=Beendet das Programm und speichert alle Einstellungen ab.
-AddressbookFrame.menuItem.addOwnData.text=Eigene Adresse hinzuf\u00fcgen
-AddressbookFrame.menuItem.addOwnData.toolTipText=Erlaubt das Hinzuf\u00fcgen eigener Daten.
-AddressbookFrame.menuItem.editOwnData.text=Eigene Adresse \u00e4ndern
-AddressbookFrame.menuItem.editOwnData.toolTipText=Erlaubt das \u00c4ndern eigener Daten.
-AddressbookFrame.menuItem.addNewContact.text=Neue Adresse hinzuf\u00fcgen
-AddressbookFrame.menuItem.addNewContact.toolTipText=Eine neue Adresse hinzuf\u00fcgen.
-AddressbookFrame.dialog.addContact.title.text=Neue Adresse hinzuf\u00fcgen
-AddressbookFrame.main.title.text=Adressen auflisten
-AddressbookFrame.gender.text=Anrede:
-AddressbookFrame.gender.toolTipText=W\u00e4hlen Sie die Anrede aus.
-AddressbookFrame.surname.text=Vorname:
-AddressbookFrame.surname.toolTipText=Geben Sie den Vornamen ein.
-AddressbookFrame.familyName.text=Nachname:
-AddressbookFrame.familyName.toolTipText=Geben Sie den Nachnamen ein.
-AddressbookFrame.street.text=Stra\u00dfe:
-AddressbookFrame.street.toolTipText=Geben Sie die Stra\u00dfe ein.
-AddressbookFrame.number.text=Hausnummer:
-AddressbookFrame.number.toolTipText=Geben Sie die Hausnummer ein.
-AddressbookFrame.zip.text=PLZ:
-AddressbookFrame.zip.toolTipText=Geben Sie die Postleitzahl ein.
-AddressbookFrame.city.text=Stadt:
-AddressbookFrame.city.toolTipText=Geben Sie die Stadt ein.
-AddressbookFrame.emailAddress.text=Email-Adresse:
-AddressbookFrame.emailAddress.toolTipText=Geben Sie die Email-Adresse ein.
-AddressbookFrame.phoneNumber.text=Telefon:
-AddressbookFrame.phoneNumber.toolTipText=Geben Sie die Telefonnummer ein.
-AddressbookFrame.cellphoneNumber.text=Mobil:
-AddressbookFrame.cellphoneNumber.toolTipText=Geben Sie die Handynummer ein.
-AddressbookFrame.faxNumber.text=Fax:
-AddressbookFrame.faxNumber.toolTipText=Geben Sie die Faxnummer ein.
-AddressbookFrame.comment.text=Anmerkungen:
-AddressbookFrame.comment.toolTipText=Geben Sie eine Anmerkung (Freifeld) ein.
-BaseContact.gender.unknown.text=Unbekannt
-BaseContact.gender.male.text=Herr
-BaseContact.gender.female.text=Frau
-BaseContact.gender.company.text=Firma
-ContactManager.columnName.gender.text=Anrede
-ContactManager.columnName.surname.text=Vorname
-ContactManager.columnName.familyName.text=Nachname
-ContactManager.columnName.street.text=Strasse
-ContactManager.columnName.houseNumber.text=Hausnummer
-ContactManager.columnName.zipCode.text=Postleitzahl
-ContactManager.columnName.city.text=Stadt
diff --git a/Addressbook/src/org/mxchange/localization/bundle_en_US.properties b/Addressbook/src/org/mxchange/localization/bundle_en_US.properties
deleted file mode 100644 (file)
index 5b2c4d2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2015 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/>.
-AddressbookFrame.border.name.title.text=Gender, surname, family name:
-AddressbookFrame.border.address.title.text=Address:
-AddressbookFrame.border.other.title.text=Other data:
-AddressbookFrame.button.addAddress.text=Add address
-AddressbookFrame.button.cancel.text=Cancel
-AddressbookFrame.menu.file.text=File
-AddressbookFrame.menu.addressbook.text=Addressbook
-AddressbookFrame.statusLabel.initializing.text=Initializing ...
-AddressbookFrame.statusLabel.done.text=Done.
-AddressbookFrame.statusLabel.shutdown.text=Shuttting down ...
-AddressbookFrame.menuItem.exitProgram.toolTipText=Exits the program and saves all data.
-AddressbookFrame.menuItem.exitProgram.text=Exit program
-AddressbookFrame.menuItem.addOwnData.text=Add own address
-AddressbookFrame.menuItem.addOwnData.toolTipText=Allows the user to add own address data
-AddressbookFrame.menuItem.editOwnData.text=Edit own data
-AddressbookFrame.menuItem.editOwnData.toolTipText=Allows the user to edit own address data
-AddressbookFrame.menuItem.addNewContact.text=Add new address
-AddressbookFrame.menuItem.addNewContact.toolTipText=Add a new address.
-AddressbookFrame.dialog.addContact.title.text=Add new address
-AddressbookFrame.main.title.text=List addresses
-AddressbookFrame.gender.text=Gender:
-AddressbookFrame.gender.toolTipText=Choose gender.
-AddressbookFrame.surname.text=Surname:
-AddressbookFrame.surname.toolTipText=Enter surname.
-AddressbookFrame.familyName.text=Family name:
-AddressbookFrame.familyName.toolTipText=Enter family name.
-AddressbookFrame.street.text=Street:
-AddressbookFrame.street.toolTipText=Enter street.
-AddressbookFrame.number.text=Number:
-AddressbookFrame.number.toolTipText=Enter number.
-AddressbookFrame.zip.text=ZIP:
-AddressbookFrame.zip.toolTipText=Enter zip code.
-AddressbookFrame.city.text=City:
-AddressbookFrame.city.toolTipText=Enter city.
-AddressbookFrame.emailAddress.text=Email address:
-AddressbookFrame.emailAddress.toolTipText=Enter email address.
-AddressbookFrame.phoneNumber.text=Phone:
-AddressbookFrame.phoneNumber.toolTipText=Enter phone number.
-AddressbookFrame.cellphoneNumber.text=Mobile:
-AddressbookFrame.cellphoneNumber.toolTipText=Enter mobile number.
-AddressbookFrame.faxNumber.text=Fax:
-AddressbookFrame.faxNumber.toolTipText=Enter fax number.
-AddressbookFrame.comment.text=Note:
-AddressbookFrame.comment.toolTipText=Enter a note (free field).
-BaseContact.gender.unknown.text=Unknown
-BaseContact.gender.male.text=Mr.
-BaseContact.gender.female.text=Mrs.
-BaseContact.gender.company.text=Company
-ContactManager.columnName.gender.text=Gender
-ContactManager.columnName.surname.text=Surname
-ContactManager.columnName.familyName.text=Family name
-ContactManager.columnName.street.text=Street
-ContactManager.columnName.houseNumber.text=House number
-ContactManager.columnName.zipCode.text=ZIP code
-ContactManager.columnName.city.text=City
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..20590e3
--- /dev/null
@@ -0,0 +1,30 @@
+How to launch:
+==============
+
+1) Build it: (you need ant tools)
+ant jar
+
+2) Go to dist folder and create "data":
+cd dist
+mkdir data
+
+3) Launch it
+$ java -jar Addressbook.jar
+
+4) The GUI can also be launched:
+$ java -jar Addressbook.jar -gui
+
+If you got an exception, maybe you bumbed into a stub method (unfinished). To reduce possibilities of
+crashes try the usual approach:
+
+$ java -ea -jar Addressbook.jar -gui
+
+Please report any errors back to me. And yes, not all is finished. :)
+
+The file config.properties will be created on first run for you. After that you
+can customize it. Supported database backends are:
+
+base64csv - The default backend, BASE64-encoded CSV strings
+mysql     - The unfinished MySQL backend
+
+Good luck!
diff --git a/VERSIONS.txt b/VERSIONS.txt
new file mode 100644 (file)
index 0000000..9d25667
--- /dev/null
@@ -0,0 +1,85 @@
+============================================
+AddressbookApplication management:
+============================================
+
+Inernet("public" service) and Intranet
+
+Version 1.0+:
+- Single-user local application
+- Fields:
+  + Gender
+  + Surname
+  + Family name
+  + Company name
+  + Street + number
+  + ZIP code
+  + City
+  + Landline number
+  + Fax number
+  + Cell phone number
+  + Email address
+  + Birth day
+  + Comment (?)
+- Edit own data
+- Add new contact
+- Edit contacts
+- Delete contacts
+- Categorization of contacts
+
+Version 1.1+:
+- Permanent storage in database
+
+Version 2.0+:
+- Multi-user web application
+- Local user registration / login / resend confirmation link / password
+  recovery
+- User groups (aka. teams)
+- Administration area (user role)
+  + Create/edit/delete groups
+  + Edit/delete/lock/unlock user
+  + Assign user roles/rights
+- Allow other users / groups to view addressbook
+  + Full addressbook
+  + Only some categories
+- VCard export
+  + Allow users/guests (not recommended)
+- XML export of addressbook and compressable (ZIP)
+- Form to contact other user/group without need of mail program
+  + User can disabled this
+- Directory for ussers/groups (who allowed to be listed)
+  + Simple click to add user to own addressbook
+  + Search form?
+
+Version 2.1+:
+- Multi-language support
+
+Version 2.2+:("socialized")
+- "Social login" (OpenID consumer)
+  + Connect user account to social account
+  + Sync own data?
+- "Social profile"
+  + OpenID provider
+  + RSS/activity feed 
+
+============================================
+Time esitmation:
+============================================
+1.0 (console):
+  + 2 days
+
+1.1 (database):
+  + 2 day
+  + Initial tables: contacts, categories, contact_category
+
+2.0 (web):
+  + 3 days
+  + Additional tables: admins (?), admin_rights, groups,
+   users, user_contacts, user_user_rights, user_category_rights, 
+
+2.1 (language)
+  + 1 day
+  + Additional tables: languages (disable, enable language "pack" ?)
+
+2.2 (social):
+  + 3 days
+  + Additional tables: ???
diff --git a/install/tables.sql b/install/tables.sql
new file mode 100644 (file)
index 0000000..a08e1de
--- /dev/null
@@ -0,0 +1,42 @@
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+DROP TABLE IF EXISTS `contacts`;
+CREATE TABLE IF NOT EXISTS `contacts` (
+`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key',
+  `own_contact` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether own contact',
+  `gender` varchar(10) NOT NULL DEFAULT 'UNKNOWN' COMMENT 'Gender',
+  `surname` varchar(100) NOT NULL COMMENT 'Surname',
+  `family_name` varchar(100) NOT NULL COMMENT 'Family name',
+  `company_name` varchar(255) DEFAULT NULL COMMENT 'Company name',
+  `street` varchar(255) DEFAULT NULL COMMENT 'Street name',
+  `house_number` smallint(5) unsigned DEFAULT NULL COMMENT 'House number',
+  `city` varchar(100) DEFAULT NULL COMMENT 'City name',
+  `zip_code` smallint(5) unsigned DEFAULT NULL COMMENT 'ZIP code',
+  `country_code` char(2) DEFAULT NULL COMMENT 'Country code',
+  `phone_number` varchar(100) DEFAULT NULL COMMENT 'Phone number',
+  `cellphone_number` varchar(100) DEFAULT NULL COMMENT 'Cellphone number',
+  `fax_number` varchar(100) DEFAULT NULL COMMENT 'Fax number',
+  `email_address` varchar(100) DEFAULT NULL COMMENT 'Email addres',
+  `birthday` date DEFAULT NULL COMMENT 'Birth day',
+  `comment` tinytext NOT NULL COMMENT 'Comment',
+  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Entry created',
+  `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Contacts data' AUTO_INCREMENT=1 ;
+
+
+ALTER TABLE `contacts`
+ ADD PRIMARY KEY (`id`);
+
+
+ALTER TABLE `contacts`
+MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key';
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/lib/jcore.jar b/lib/jcore.jar
new file mode 100644 (file)
index 0000000..3593f27
Binary files /dev/null and b/lib/jcore.jar differ
diff --git a/lib/log4j-api-2.3.jar b/lib/log4j-api-2.3.jar
new file mode 100644 (file)
index 0000000..2a61bbe
Binary files /dev/null and b/lib/log4j-api-2.3.jar differ
diff --git a/lib/log4j-core-2.3.jar b/lib/log4j-core-2.3.jar
new file mode 100644 (file)
index 0000000..5438b0b
Binary files /dev/null and b/lib/log4j-core-2.3.jar differ
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
new file mode 100644 (file)
index 0000000..7a1b05a
--- /dev/null
@@ -0,0 +1,1425 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+*** GENERATED FROM project.xml - DO NOT EDIT  ***\r
+***         EDIT ../build.xml INSTEAD         ***\r
+\r
+For the purpose of easier reading the script\r
+is divided into following sections:\r
+\r
+  - initialization\r
+  - compilation\r
+  - jar\r
+  - execution\r
+  - debugging\r
+  - javadoc\r
+  - test compilation\r
+  - test execution\r
+  - test debugging\r
+  - applet\r
+  - cleanup\r
+\r
+        -->\r
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Addressbook-impl">\r
+    <fail message="Please build using Ant 1.8.0 or higher.">\r
+        <condition>\r
+            <not>\r
+                <antversion atleast="1.8.0"/>\r
+            </not>\r
+        </condition>\r
+    </fail>\r
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>\r
+    <!-- \r
+                ======================\r
+                INITIALIZATION SECTION \r
+                ======================\r
+            -->\r
+    <target name="-pre-init">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="-pre-init" name="-init-private">\r
+        <property file="nbproject/private/config.properties"/>\r
+        <property file="nbproject/private/configs/${config}.properties"/>\r
+        <property file="nbproject/private/private.properties"/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private" name="-init-user">\r
+        <property file="${user.properties.file}"/>\r
+        <!-- The two properties below are usually overridden -->\r
+        <!-- by the active platform. Just a fallback. -->\r
+        <property name="default.javac.source" value="1.4"/>\r
+        <property name="default.javac.target" value="1.4"/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">\r
+        <property file="nbproject/configs/${config}.properties"/>\r
+        <property file="nbproject/project.properties"/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">\r
+        <property name="platform.java" value="${java.home}/bin/java"/>\r
+        <available file="${manifest.file}" property="manifest.available"/>\r
+        <condition property="splashscreen.available">\r
+            <and>\r
+                <not>\r
+                    <equals arg1="${application.splash}" arg2="" trim="true"/>\r
+                </not>\r
+                <available file="${application.splash}"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="main.class.available">\r
+            <and>\r
+                <isset property="main.class"/>\r
+                <not>\r
+                    <equals arg1="${main.class}" arg2="" trim="true"/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <condition property="profile.available">\r
+            <and>\r
+                <isset property="javac.profile"/>\r
+                <length length="0" string="${javac.profile}" when="greater"/>\r
+                <matches pattern="1\.[89](\..*)?" string="${javac.source}"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="do.archive">\r
+            <or>\r
+                <not>\r
+                    <istrue value="${jar.archive.disabled}"/>\r
+                </not>\r
+                <istrue value="${not.archive.disabled}"/>\r
+            </or>\r
+        </condition>\r
+        <condition property="do.mkdist">\r
+            <and>\r
+                <isset property="do.archive"/>\r
+                <isset property="libs.CopyLibs.classpath"/>\r
+                <not>\r
+                    <istrue value="${mkdist.disabled}"/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <condition property="do.archive+manifest.available">\r
+            <and>\r
+                <isset property="manifest.available"/>\r
+                <istrue value="${do.archive}"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="do.archive+main.class.available">\r
+            <and>\r
+                <isset property="main.class.available"/>\r
+                <istrue value="${do.archive}"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="do.archive+splashscreen.available">\r
+            <and>\r
+                <isset property="splashscreen.available"/>\r
+                <istrue value="${do.archive}"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="do.archive+profile.available">\r
+            <and>\r
+                <isset property="profile.available"/>\r
+                <istrue value="${do.archive}"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="have.tests">\r
+            <or>\r
+                <available file="${test.src.dir}"/>\r
+            </or>\r
+        </condition>\r
+        <condition property="have.sources">\r
+            <or>\r
+                <available file="${src.dir}"/>\r
+            </or>\r
+        </condition>\r
+        <condition property="netbeans.home+have.tests">\r
+            <and>\r
+                <isset property="netbeans.home"/>\r
+                <isset property="have.tests"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="no.javadoc.preview">\r
+            <and>\r
+                <isset property="javadoc.preview"/>\r
+                <isfalse value="${javadoc.preview}"/>\r
+            </and>\r
+        </condition>\r
+        <property name="run.jvmargs" value=""/>\r
+        <property name="run.jvmargs.ide" value=""/>\r
+        <property name="javac.compilerargs" value=""/>\r
+        <property name="work.dir" value="${basedir}"/>\r
+        <condition property="no.deps">\r
+            <and>\r
+                <istrue value="${no.dependencies}"/>\r
+            </and>\r
+        </condition>\r
+        <property name="javac.debug" value="true"/>\r
+        <property name="javadoc.preview" value="true"/>\r
+        <property name="application.args" value=""/>\r
+        <property name="source.encoding" value="${file.encoding}"/>\r
+        <property name="runtime.encoding" value="${source.encoding}"/>\r
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">\r
+            <and>\r
+                <isset property="javadoc.encoding"/>\r
+                <not>\r
+                    <equals arg1="${javadoc.encoding}" arg2=""/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>\r
+        <property name="includes" value="**"/>\r
+        <property name="excludes" value=""/>\r
+        <property name="do.depend" value="false"/>\r
+        <condition property="do.depend.true">\r
+            <istrue value="${do.depend}"/>\r
+        </condition>\r
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>\r
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">\r
+            <and>\r
+                <isset property="endorsed.classpath"/>\r
+                <not>\r
+                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">\r
+            <isset property="profile.available"/>\r
+        </condition>\r
+        <condition else="false" property="jdkBug6558476">\r
+            <and>\r
+                <matches pattern="1\.[56]" string="${java.specification.version}"/>\r
+                <not>\r
+                    <os family="unix"/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <property name="javac.fork" value="${jdkBug6558476}"/>\r
+        <property name="jar.index" value="false"/>\r
+        <property name="jar.index.metainf" value="${jar.index}"/>\r
+        <property name="copylibs.rebase" value="true"/>\r
+        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>\r
+        <condition property="junit.available">\r
+            <or>\r
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>\r
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>\r
+            </or>\r
+        </condition>\r
+        <condition property="testng.available">\r
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>\r
+        </condition>\r
+        <condition property="junit+testng.available">\r
+            <and>\r
+                <istrue value="${junit.available}"/>\r
+                <istrue value="${testng.available}"/>\r
+            </and>\r
+        </condition>\r
+        <condition else="testng" property="testng.mode" value="mixed">\r
+            <istrue value="${junit+testng.available}"/>\r
+        </condition>\r
+        <condition else="" property="testng.debug.mode" value="-mixed">\r
+            <istrue value="${junit+testng.available}"/>\r
+        </condition>\r
+    </target>\r
+    <target name="-post-init">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">\r
+        <fail unless="src.dir">Must set src.dir</fail>\r
+        <fail unless="test.src.dir">Must set test.src.dir</fail>\r
+        <fail unless="build.dir">Must set build.dir</fail>\r
+        <fail unless="dist.dir">Must set dist.dir</fail>\r
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>\r
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>\r
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>\r
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>\r
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>\r
+        <fail unless="dist.jar">Must set dist.jar</fail>\r
+    </target>\r
+    <target name="-init-macrodef-property">\r
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute name="name"/>\r
+            <attribute name="value"/>\r
+            <sequential>\r
+                <property name="@{name}" value="${@{value}}"/>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">\r
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${src.dir}" name="srcdir"/>\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <attribute default="${javac.classpath}" name="classpath"/>\r
+            <attribute default="${javac.processorpath}" name="processorpath"/>\r
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="${javac.debug}" name="debug"/>\r
+            <attribute default="${empty.dir}" name="sourcepath"/>\r
+            <attribute default="${empty.dir}" name="gensrcdir"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property location="${build.dir}/empty" name="empty.dir"/>\r
+                <mkdir dir="${empty.dir}"/>\r
+                <mkdir dir="@{apgeneratedsrcdir}"/>\r
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">\r
+                    <src>\r
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
+                            <include name="*"/>\r
+                        </dirset>\r
+                    </src>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>\r
+                    <compilerarg line="${javac.compilerargs}"/>\r
+                    <compilerarg value="-processorpath"/>\r
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>\r
+                    <compilerarg line="${ap.processors.internal}"/>\r
+                    <compilerarg line="${annotation.processing.processor.options}"/>\r
+                    <compilerarg value="-s"/>\r
+                    <compilerarg path="@{apgeneratedsrcdir}"/>\r
+                    <compilerarg line="${ap.proc.none.internal}"/>\r
+                    <customize/>\r
+                </javac>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">\r
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${src.dir}" name="srcdir"/>\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <attribute default="${javac.classpath}" name="classpath"/>\r
+            <attribute default="${javac.processorpath}" name="processorpath"/>\r
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="${javac.debug}" name="debug"/>\r
+            <attribute default="${empty.dir}" name="sourcepath"/>\r
+            <attribute default="${empty.dir}" name="gensrcdir"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property location="${build.dir}/empty" name="empty.dir"/>\r
+                <mkdir dir="${empty.dir}"/>\r
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">\r
+                    <src>\r
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
+                            <include name="*"/>\r
+                        </dirset>\r
+                    </src>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>\r
+                    <compilerarg line="${javac.compilerargs}"/>\r
+                    <customize/>\r
+                </javac>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">\r
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${src.dir}" name="srcdir"/>\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <attribute default="${javac.classpath}" name="classpath"/>\r
+            <sequential>\r
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                </depend>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <sequential>\r
+                <fail unless="javac.includes">Must set javac.includes</fail>\r
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">\r
+                    <path>\r
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>\r
+                    </path>\r
+                    <globmapper from="*.java" to="*.class"/>\r
+                </pathconvert>\r
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>\r
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>\r
+                <delete>\r
+                    <files includesfile="${javac.includesfile.binary}"/>\r
+                </delete>\r
+                <delete>\r
+                    <fileset file="${javac.includesfile.binary}"/>\r
+                </delete>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target if="${junit.available}" name="-init-macrodef-junit-init">\r
+        <condition else="false" property="nb.junit.batch" value="true">\r
+            <and>\r
+                <istrue value="${junit.available}"/>\r
+                <not>\r
+                    <isset property="test.method"/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <condition else="false" property="nb.junit.single" value="true">\r
+            <and>\r
+                <istrue value="${junit.available}"/>\r
+                <isset property="test.method"/>\r
+            </and>\r
+        </condition>\r
+    </target>\r
+    <target name="-init-test-properties">\r
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>\r
+        <property name="test.binarytestincludes" value=""/>\r
+        <property name="test.binaryexcludes" value=""/>\r
+    </target>\r
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">\r
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property name="junit.forkmode" value="perTest"/>\r
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="test-sys-prop."/>\r
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <formatter type="brief" usefile="false"/>\r
+                    <formatter type="xml"/>\r
+                    <jvmarg value="-ea"/>\r
+                    <customize/>\r
+                </junit>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">\r
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property name="junit.forkmode" value="perTest"/>\r
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
+                    <batchtest todir="${build.test.results.dir}">\r
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">\r
+                            <filename name="@{testincludes}"/>\r
+                        </fileset>\r
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">\r
+                            <filename name="${test.binarytestincludes}"/>\r
+                        </fileset>\r
+                    </batchtest>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="test-sys-prop."/>\r
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <formatter type="brief" usefile="false"/>\r
+                    <formatter type="xml"/>\r
+                    <jvmarg value="-ea"/>\r
+                    <customize/>\r
+                </junit>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>\r
+    <target if="${testng.available}" name="-init-macrodef-testng">\r
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">\r
+                    <isset property="test.method"/>\r
+                </condition>\r
+                <union id="test.set">\r
+                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">\r
+                        <filename name="@{testincludes}"/>\r
+                    </fileset>\r
+                </union>\r
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>\r
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="Addressbook" testname="TestNG tests" workingDir="${work.dir}">\r
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>\r
+                    <propertyset>\r
+                        <propertyref prefix="test-sys-prop."/>\r
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                    </propertyset>\r
+                    <customize/>\r
+                </testng>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-macrodef-test-impl">\r
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element implicit="true" name="customize" optional="true"/>\r
+            <sequential>\r
+                <echo>No tests executed.</echo>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">\r
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element implicit="true" name="customize" optional="true"/>\r
+            <sequential>\r
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
+                    <customize/>\r
+                </j2seproject3:junit>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">\r
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element implicit="true" name="customize" optional="true"/>\r
+            <sequential>\r
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
+                    <customize/>\r
+                </j2seproject3:testng>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">\r
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <sequential>\r
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
+                    <customize>\r
+                        <classpath>\r
+                            <path path="${run.test.classpath}"/>\r
+                        </classpath>\r
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                        <jvmarg line="${run.jvmargs}"/>\r
+                        <jvmarg line="${run.jvmargs.ide}"/>\r
+                    </customize>\r
+                </j2seproject3:test-impl>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">\r
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property name="junit.forkmode" value="perTest"/>\r
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="test-sys-prop."/>\r
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <formatter type="brief" usefile="false"/>\r
+                    <formatter type="xml"/>\r
+                    <jvmarg value="-ea"/>\r
+                    <jvmarg line="${debug-args-line}"/>\r
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
+                    <customize/>\r
+                </junit>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">\r
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property name="junit.forkmode" value="perTest"/>\r
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">\r
+                    <batchtest todir="${build.test.results.dir}">\r
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">\r
+                            <filename name="@{testincludes}"/>\r
+                        </fileset>\r
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">\r
+                            <filename name="${test.binarytestincludes}"/>\r
+                        </fileset>\r
+                    </batchtest>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="test-sys-prop."/>\r
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <formatter type="brief" usefile="false"/>\r
+                    <formatter type="xml"/>\r
+                    <jvmarg value="-ea"/>\r
+                    <jvmarg line="${debug-args-line}"/>\r
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
+                    <customize/>\r
+                </junit>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">\r
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <element implicit="true" name="customize" optional="true"/>\r
+            <sequential>\r
+                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
+                    <customize/>\r
+                </j2seproject3:junit-debug>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">\r
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${main.class}" name="testClass"/>\r
+            <attribute default="" name="testMethod"/>\r
+            <element name="customize2" optional="true"/>\r
+            <sequential>\r
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">\r
+                    <isset property="test.method"/>\r
+                </condition>\r
+                <condition else="-suitename Addressbook -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">\r
+                    <matches pattern=".*\.xml" string="@{testClass}"/>\r
+                </condition>\r
+                <delete dir="${build.test.results.dir}" quiet="true"/>\r
+                <mkdir dir="${build.test.results.dir}"/>\r
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">\r
+                    <customize>\r
+                        <customize2/>\r
+                        <jvmarg value="-ea"/>\r
+                        <arg line="${testng.debug.mode}"/>\r
+                        <arg line="-d ${build.test.results.dir}"/>\r
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>\r
+                        <arg line="${testng.cmd.args}"/>\r
+                    </customize>\r
+                </j2seproject3:debug>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">\r
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${main.class}" name="testClass"/>\r
+            <attribute default="" name="testMethod"/>\r
+            <element implicit="true" name="customize2" optional="true"/>\r
+            <sequential>\r
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">\r
+                    <customize2/>\r
+                </j2seproject3:testng-debug>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">\r
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <attribute default="${main.class}" name="testClass"/>\r
+            <attribute default="" name="testMethod"/>\r
+            <sequential>\r
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">\r
+                    <customize>\r
+                        <classpath>\r
+                            <path path="${run.test.classpath}"/>\r
+                        </classpath>\r
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                        <jvmarg line="${run.jvmargs}"/>\r
+                        <jvmarg line="${run.jvmargs.ide}"/>\r
+                    </customize>\r
+                </j2seproject3:test-debug-impl>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">\r
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <attribute default="" name="testmethods"/>\r
+            <attribute default="${main.class}" name="testClass"/>\r
+            <attribute default="" name="testMethod"/>\r
+            <sequential>\r
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">\r
+                    <customize2>\r
+                        <syspropertyset>\r
+                            <propertyref prefix="test-sys-prop."/>\r
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                        </syspropertyset>\r
+                    </customize2>\r
+                </j2seproject3:testng-debug-impl>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>\r
+    <!--\r
+                pre NB7.2 profiling section; consider it deprecated\r
+            -->\r
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>\r
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">\r
+        <macrodef name="resolve">\r
+            <attribute name="name"/>\r
+            <attribute name="value"/>\r
+            <sequential>\r
+                <property name="@{name}" value="${env.@{value}}"/>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="profile">\r
+            <attribute default="${main.class}" name="classname"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property environment="env"/>\r
+                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>\r
+                <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">\r
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                    <jvmarg value="${profiler.info.jvmargs.agent}"/>\r
+                    <jvmarg line="${profiler.info.jvmargs}"/>\r
+                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>\r
+                    <arg line="${application.args}"/>\r
+                    <classpath>\r
+                        <path path="${run.classpath}"/>\r
+                    </classpath>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="run-sys-prop."/>\r
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <customize/>\r
+                </java>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">\r
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>\r
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>\r
+    </target>\r
+    <!--\r
+                end of pre NB7.2 profiling section\r
+            -->\r
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">\r
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute default="${main.class}" name="name"/>\r
+            <attribute default="${debug.classpath}" name="classpath"/>\r
+            <attribute default="" name="stopclassname"/>\r
+            <sequential>\r
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                </nbjpdastart>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute default="${build.classes.dir}" name="dir"/>\r
+            <sequential>\r
+                <nbjpdareload>\r
+                    <fileset dir="@{dir}" includes="${fix.classes}">\r
+                        <include name="${fix.includes}*.class"/>\r
+                    </fileset>\r
+                </nbjpdareload>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-debug-args">\r
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>\r
+        <condition property="have-jdk-older-than-1.4">\r
+            <or>\r
+                <contains string="${version-output}" substring="java version &quot;1.0"/>\r
+                <contains string="${version-output}" substring="java version &quot;1.1"/>\r
+                <contains string="${version-output}" substring="java version &quot;1.2"/>\r
+                <contains string="${version-output}" substring="java version &quot;1.3"/>\r
+            </or>\r
+        </condition>\r
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">\r
+            <istrue value="${have-jdk-older-than-1.4}"/>\r
+        </condition>\r
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">\r
+            <os family="windows"/>\r
+        </condition>\r
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">\r
+            <isset property="debug.transport"/>\r
+        </condition>\r
+    </target>\r
+    <target depends="-init-debug-args" name="-init-macrodef-debug">\r
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${main.class}" name="classname"/>\r
+            <attribute default="${debug.classpath}" name="classpath"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <java classname="@{classname}" dir="${work.dir}" fork="true">\r
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                    <jvmarg line="${debug-args-line}"/>\r
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>\r
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>\r
+                    <jvmarg line="${run.jvmargs}"/>\r
+                    <jvmarg line="${run.jvmargs.ide}"/>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="run-sys-prop."/>\r
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <customize/>\r
+                </java>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-macrodef-java">\r
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute default="${main.class}" name="classname"/>\r
+            <attribute default="${run.classpath}" name="classpath"/>\r
+            <attribute default="jvm" name="jvm"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <java classname="@{classname}" dir="${work.dir}" fork="true">\r
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>\r
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>\r
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>\r
+                    <jvmarg line="${run.jvmargs}"/>\r
+                    <jvmarg line="${run.jvmargs.ide}"/>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="run-sys-prop."/>\r
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <customize/>\r
+                </java>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-macrodef-copylibs">\r
+        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${manifest.file}" name="manifest"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
+                <pathconvert property="run.classpath.without.build.classes.dir">\r
+                    <path path="${run.classpath}"/>\r
+                    <map from="${build.classes.dir.resolved}" to=""/>\r
+                </pathconvert>\r
+                <pathconvert pathsep=" " property="jar.classpath">\r
+                    <path path="${run.classpath.without.build.classes.dir}"/>\r
+                    <chainedmapper>\r
+                        <flattenmapper/>\r
+                        <filtermapper>\r
+                            <replacestring from=" " to="%20"/>\r
+                        </filtermapper>\r
+                        <globmapper from="*" to="lib/*"/>\r
+                    </chainedmapper>\r
+                </pathconvert>\r
+                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>\r
+                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">\r
+                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>\r
+                    <manifest>\r
+                        <attribute name="Class-Path" value="${jar.classpath}"/>\r
+                        <customize/>\r
+                    </manifest>\r
+                </copylibs>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-presetdef-jar">\r
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">\r
+                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>\r
+            </jar>\r
+        </presetdef>\r
+    </target>\r
+    <target name="-init-ap-cmdline-properties">\r
+        <property name="annotation.processing.enabled" value="true"/>\r
+        <property name="annotation.processing.processors.list" value=""/>\r
+        <property name="annotation.processing.processor.options" value=""/>\r
+        <property name="annotation.processing.run.all.processors" value="true"/>\r
+        <property name="javac.processorpath" value="${javac.classpath}"/>\r
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>\r
+        <condition property="ap.supported.internal" value="true">\r
+            <not>\r
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>\r
+            </not>\r
+        </condition>\r
+    </target>\r
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">\r
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">\r
+            <isfalse value="${annotation.processing.run.all.processors}"/>\r
+        </condition>\r
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">\r
+            <isfalse value="${annotation.processing.enabled}"/>\r
+        </condition>\r
+    </target>\r
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">\r
+        <property name="ap.cmd.line.internal" value=""/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>\r
+    <!--\r
+                ===================\r
+                COMPILATION SECTION\r
+                ===================\r
+            -->\r
+    <target name="-deps-jar-init" unless="built-jar.properties">\r
+        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>\r
+        <delete file="${built-jar.properties}" quiet="true"/>\r
+    </target>\r
+    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">\r
+        <echo level="warn" message="Cycle detected: Addressbook was already built"/>\r
+    </target>\r
+    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">\r
+        <mkdir dir="${build.dir}"/>\r
+        <touch file="${built-jar.properties}" verbose="false"/>\r
+        <property file="${built-jar.properties}" prefix="already.built.jar."/>\r
+        <antcall target="-warn-already-built-jar"/>\r
+        <propertyfile file="${built-jar.properties}">\r
+            <entry key="${basedir}" value=""/>\r
+        </propertyfile>\r
+        <antcall target="-maybe-call-dep">\r
+            <param name="call.built.properties" value="${built-jar.properties}"/>\r
+            <param name="call.target" value="jar"/>\r
+            <param name="transfer.built-jar.properties" value="${built-jar.properties}"/>\r
+            <param name="transfer.not.archive.disabled" value="true"/>\r
+        </antcall>\r
+    </target>\r
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>\r
+    <target depends="init" name="-check-automatic-build">\r
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>\r
+    </target>\r
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">\r
+        <antcall target="clean"/>\r
+    </target>\r
+    <target depends="init,deps-jar" name="-pre-pre-compile">\r
+        <mkdir dir="${build.classes.dir}"/>\r
+    </target>\r
+    <target name="-pre-compile">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target if="do.depend.true" name="-compile-depend">\r
+        <pathconvert property="build.generated.subdirs">\r
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
+                <include name="*"/>\r
+            </dirset>\r
+        </pathconvert>\r
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>\r
+    </target>\r
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">\r
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>\r
+        <copy todir="${build.classes.dir}">\r
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
+        </copy>\r
+    </target>\r
+    <target if="has.persistence.xml" name="-copy-persistence-xml">\r
+        <mkdir dir="${build.classes.dir}/META-INF"/>\r
+        <copy todir="${build.classes.dir}/META-INF">\r
+            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>\r
+        </copy>\r
+    </target>\r
+    <target name="-post-compile">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>\r
+    <target name="-pre-compile-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">\r
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>\r
+        <j2seproject3:force-recompile/>\r
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>\r
+    </target>\r
+    <target name="-post-compile-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>\r
+    <!--\r
+                ====================\r
+                JAR BUILDING SECTION\r
+                ====================\r
+            -->\r
+    <target depends="init" name="-pre-pre-jar">\r
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>\r
+        <mkdir dir="${dist.jar.dir}"/>\r
+    </target>\r
+    <target name="-pre-jar">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">\r
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>\r
+        <touch file="${tmp.manifest.file}" verbose="false"/>\r
+    </target>\r
+    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">\r
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>\r
+        <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>\r
+    </target>\r
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">\r
+        <manifest file="${tmp.manifest.file}" mode="update">\r
+            <attribute name="Main-Class" value="${main.class}"/>\r
+        </manifest>\r
+    </target>\r
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">\r
+        <manifest file="${tmp.manifest.file}" mode="update">\r
+            <attribute name="Profile" value="${javac.profile}"/>\r
+        </manifest>\r
+    </target>\r
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">\r
+        <basename file="${application.splash}" property="splashscreen.basename"/>\r
+        <mkdir dir="${build.classes.dir}/META-INF"/>\r
+        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>\r
+        <manifest file="${tmp.manifest.file}" mode="update">\r
+            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>\r
+        </manifest>\r
+    </target>\r
+    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">\r
+        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>\r
+        <echo level="info">To run this application from the command line without Ant, try:</echo>\r
+        <property location="${dist.jar}" name="dist.jar.resolved"/>\r
+        <echo level="info">java -jar "${dist.jar.resolved}"</echo>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">\r
+        <j2seproject1:jar manifest="${tmp.manifest.file}"/>\r
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
+        <property location="${dist.jar}" name="dist.jar.resolved"/>\r
+        <pathconvert property="run.classpath.with.dist.jar">\r
+            <path path="${run.classpath}"/>\r
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>\r
+        </pathconvert>\r
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">\r
+            <isset property="main.class.available"/>\r
+        </condition>\r
+        <condition else="debug" property="jar.usage.level" value="info">\r
+            <isset property="main.class.available"/>\r
+        </condition>\r
+        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>\r
+    </target>\r
+    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">\r
+        <delete>\r
+            <fileset file="${tmp.manifest.file}"/>\r
+        </delete>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>\r
+    <target name="-post-jar">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>\r
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>\r
+    <!--\r
+                =================\r
+                EXECUTION SECTION\r
+                =================\r
+            -->\r
+    <target depends="init,compile" description="Run a main class." name="run">\r
+        <j2seproject1:java>\r
+            <customize>\r
+                <arg line="${application.args}"/>\r
+            </customize>\r
+        </j2seproject1:java>\r
+    </target>\r
+    <target name="-do-not-recompile">\r
+        <property name="javac.includes.binary" value=""/>\r
+    </target>\r
+    <target depends="init,compile-single" name="run-single">\r
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
+        <j2seproject1:java classname="${run.class}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single" name="run-test-with-main">\r
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>\r
+    </target>\r
+    <!--\r
+                =================\r
+                DEBUGGING SECTION\r
+                =================\r
+            -->\r
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">\r
+        <j2seproject1:nbjpdastart name="${debug.class}"/>\r
+    </target>\r
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">\r
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>\r
+    </target>\r
+    <target depends="init,compile" name="-debug-start-debuggee">\r
+        <j2seproject3:debug>\r
+            <customize>\r
+                <arg line="${application.args}"/>\r
+            </customize>\r
+        </j2seproject3:debug>\r
+    </target>\r
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>\r
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">\r
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>\r
+    </target>\r
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>\r
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">\r
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>\r
+        <j2seproject3:debug classname="${debug.class}"/>\r
+    </target>\r
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>\r
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">\r
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>\r
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>\r
+    <target depends="init" name="-pre-debug-fix">\r
+        <fail unless="fix.includes">Must set fix.includes</fail>\r
+        <property name="javac.includes" value="${fix.includes}.java"/>\r
+    </target>\r
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">\r
+        <j2seproject1:nbjpdareload/>\r
+    </target>\r
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>\r
+    <!--\r
+                =================\r
+                PROFILING SECTION\r
+                =================\r
+            -->\r
+    <!--\r
+                pre NB7.2 profiler integration\r
+            -->\r
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">\r
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
+        <nbprofiledirect>\r
+            <classpath>\r
+                <path path="${run.classpath}"/>\r
+            </classpath>\r
+        </nbprofiledirect>\r
+        <profile/>\r
+    </target>\r
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">\r
+        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>\r
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
+        <nbprofiledirect>\r
+            <classpath>\r
+                <path path="${run.classpath}"/>\r
+            </classpath>\r
+        </nbprofiledirect>\r
+        <profile classname="${profile.class}"/>\r
+    </target>\r
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">\r
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
+        <nbprofiledirect>\r
+            <classpath>\r
+                <path path="${run.classpath}"/>\r
+            </classpath>\r
+        </nbprofiledirect>\r
+        <profile classname="sun.applet.AppletViewer">\r
+            <customize>\r
+                <arg value="${applet.url}"/>\r
+            </customize>\r
+        </profile>\r
+    </target>\r
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">\r
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>\r
+        <nbprofiledirect>\r
+            <classpath>\r
+                <path path="${run.test.classpath}"/>\r
+            </classpath>\r
+        </nbprofiledirect>\r
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">\r
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>\r
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>\r
+            <jvmarg line="${profiler.info.jvmargs}"/>\r
+            <test name="${profile.class}"/>\r
+            <classpath>\r
+                <path path="${run.test.classpath}"/>\r
+            </classpath>\r
+            <syspropertyset>\r
+                <propertyref prefix="test-sys-prop."/>\r
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+            </syspropertyset>\r
+            <formatter type="brief" usefile="false"/>\r
+            <formatter type="xml"/>\r
+        </junit>\r
+    </target>\r
+    <!--\r
+                end of pre NB72 profiling section\r
+            -->\r
+    <target if="netbeans.home" name="-profile-check">\r
+        <condition property="profiler.configured">\r
+            <or>\r
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>\r
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>\r
+            </or>\r
+        </condition>\r
+    </target>\r
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">\r
+        <startprofiler/>\r
+        <antcall target="run"/>\r
+    </target>\r
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">\r
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
+        <startprofiler/>\r
+        <antcall target="run-single"/>\r
+    </target>\r
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>\r
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">\r
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>\r
+        <startprofiler/>\r
+        <antcall target="test-single"/>\r
+    </target>\r
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">\r
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
+        <startprofiler/>\r
+        <antcal target="run-test-with-main"/>\r
+    </target>\r
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">\r
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
+        <startprofiler/>\r
+        <antcall target="run-applet"/>\r
+    </target>\r
+    <!--\r
+                ===============\r
+                JAVADOC SECTION\r
+                ===============\r
+            -->\r
+    <target depends="init" if="have.sources" name="-javadoc-build">\r
+        <mkdir dir="${dist.javadoc.dir}"/>\r
+        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">\r
+            <and>\r
+                <isset property="endorsed.classpath.cmd.line.arg"/>\r
+                <not>\r
+                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <condition else="" property="bug5101868workaround" value="*.java">\r
+            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>\r
+        </condition>\r
+        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">\r
+            <classpath>\r
+                <path path="${javac.classpath}"/>\r
+            </classpath>\r
+            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">\r
+                <filename name="**/*.java"/>\r
+            </fileset>\r
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
+                <include name="**/*.java"/>\r
+                <exclude name="*.java"/>\r
+            </fileset>\r
+            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>\r
+        </javadoc>\r
+        <copy todir="${dist.javadoc.dir}">\r
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">\r
+                <filename name="**/doc-files/**"/>\r
+            </fileset>\r
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
+                <include name="**/doc-files/**"/>\r
+            </fileset>\r
+        </copy>\r
+    </target>\r
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">\r
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>\r
+    </target>\r
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>\r
+    <!--\r
+                =========================\r
+                TEST COMPILATION SECTION\r
+                =========================\r
+            -->\r
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">\r
+        <mkdir dir="${build.test.classes.dir}"/>\r
+    </target>\r
+    <target name="-pre-compile-test">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target if="do.depend.true" name="-compile-test-depend">\r
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>\r
+    </target>\r
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">\r
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>\r
+        <copy todir="${build.test.classes.dir}">\r
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
+        </copy>\r
+    </target>\r
+    <target name="-post-compile-test">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>\r
+    <target name="-pre-compile-test-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">\r
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>\r
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>\r
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>\r
+        <copy todir="${build.test.classes.dir}">\r
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
+        </copy>\r
+    </target>\r
+    <target name="-post-compile-test-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>\r
+    <!--\r
+                =======================\r
+                TEST EXECUTION SECTION\r
+                =======================\r
+            -->\r
+    <target depends="init" if="have.tests" name="-pre-test-run">\r
+        <mkdir dir="${build.test.results.dir}"/>\r
+    </target>\r
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">\r
+        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>\r
+    </target>\r
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">\r
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
+    </target>\r
+    <target depends="init" if="have.tests" name="test-report"/>\r
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>\r
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>\r
+    <target depends="init" if="have.tests" name="-pre-test-run-single">\r
+        <mkdir dir="${build.test.results.dir}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">\r
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>\r
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">\r
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>\r
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">\r
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>\r
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>\r
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">\r
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>\r
+    <!--\r
+                =======================\r
+                TEST DEBUGGING SECTION\r
+                =======================\r
+            -->\r
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">\r
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>\r
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">\r
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>\r
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>\r
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>\r
+    </target>\r
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">\r
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>\r
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>\r
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">\r
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>\r
+    </target>\r
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>\r
+    <!--\r
+                =========================\r
+                APPLET EXECUTION SECTION\r
+                =========================\r
+            -->\r
+    <target depends="init,compile-single" name="run-applet">\r
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
+        <j2seproject1:java classname="sun.applet.AppletViewer">\r
+            <customize>\r
+                <arg value="${applet.url}"/>\r
+            </customize>\r
+        </j2seproject1:java>\r
+    </target>\r
+    <!--\r
+                =========================\r
+                APPLET DEBUGGING  SECTION\r
+                =========================\r
+            -->\r
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">\r
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
+        <j2seproject3:debug classname="sun.applet.AppletViewer">\r
+            <customize>\r
+                <arg value="${applet.url}"/>\r
+            </customize>\r
+        </j2seproject3:debug>\r
+    </target>\r
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>\r
+    <!--\r
+                ===============\r
+                CLEANUP SECTION\r
+                ===============\r
+            -->\r
+    <target name="-deps-clean-init" unless="built-clean.properties">\r
+        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>\r
+        <delete file="${built-clean.properties}" quiet="true"/>\r
+    </target>\r
+    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">\r
+        <echo level="warn" message="Cycle detected: Addressbook was already built"/>\r
+    </target>\r
+    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">\r
+        <mkdir dir="${build.dir}"/>\r
+        <touch file="${built-clean.properties}" verbose="false"/>\r
+        <property file="${built-clean.properties}" prefix="already.built.clean."/>\r
+        <antcall target="-warn-already-built-clean"/>\r
+        <propertyfile file="${built-clean.properties}">\r
+            <entry key="${basedir}" value=""/>\r
+        </propertyfile>\r
+        <antcall target="-maybe-call-dep">\r
+            <param name="call.built.properties" value="${built-clean.properties}"/>\r
+            <param name="call.target" value="clean"/>\r
+            <param name="transfer.built-clean.properties" value="${built-clean.properties}"/>\r
+            <param name="transfer.not.archive.disabled" value="true"/>\r
+        </antcall>\r
+    </target>\r
+    <target depends="init" name="-do-clean">\r
+        <delete dir="${build.dir}"/>\r
+        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>\r
+    </target>\r
+    <target name="-post-clean">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>\r
+    <target name="-check-call-dep">\r
+        <property file="${call.built.properties}" prefix="already.built."/>\r
+        <condition property="should.call.dep">\r
+            <and>\r
+                <not>\r
+                    <isset property="already.built.${call.subproject}"/>\r
+                </not>\r
+                <available file="${call.script}"/>\r
+            </and>\r
+        </condition>\r
+    </target>\r
+    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">\r
+        <ant antfile="${call.script}" inheritall="false" target="${call.target}">\r
+            <propertyset>\r
+                <propertyref prefix="transfer."/>\r
+                <mapper from="transfer.*" to="*" type="glob"/>\r
+            </propertyset>\r
+        </ant>\r
+    </target>\r
+</project>\r
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
new file mode 100644 (file)
index 0000000..5cab81f
--- /dev/null
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=39498655\r
+build.xml.script.CRC32=e7acbc61\r
+build.xml.stylesheet.CRC32=8064a381@1.75.2.48\r
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\r
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\r
+nbproject/build-impl.xml.data.CRC32=b3f3ee43\r
+nbproject/build-impl.xml.script.CRC32=96150614\r
+nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48\r
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644 (file)
index 0000000..d1a9fce
--- /dev/null
@@ -0,0 +1,84 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=Addressbook
+application.vendor=Roland Haeder
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/Addressbook.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+file.reference.log4j-api-2.3.jar=lib/log4j-api-2.3.jar
+file.reference.log4j-core-2.3.jar=lib/log4j-core-2.3.jar
+file.reference.jcore.jar=./lib/jcore.jar
+includes=**
+jar.compress=false
+javac.classpath=\
+    ${file.reference.log4j-api-2.3.jar}:\
+    ${file.reference.log4j-core-2.3.jar}:\
+    ${file.reference.jcore.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=-Xlint:deprecation -Xlint:unchecked
+javac.deprecation=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.7
+javac.target=1.7
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=org.mxchange.addressbook.application.AddressbookApplication
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+project.license=gpl30
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project.
+# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
+# To set system properties for unit tests define test-sys-prop.name=value:
+run.jvmargs=-ea
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+source.encoding=UTF-8
+source.reference.log4j-api-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-api-2.3-sources.jar
+source.reference.log4j-core-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-core-2.3-sources.jar
+src.dir=src
+test.src.dir=test
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644 (file)
index 0000000..d95b345
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://www.netbeans.org/ns/project/1">\r
+    <type>org.netbeans.modules.java.j2seproject</type>\r
+    <configuration>\r
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">\r
+            <name>Addressbook</name>\r
+            <source-roots>\r
+                <root id="src.dir"/>\r
+            </source-roots>\r
+            <test-roots>\r
+                <root id="test.src.dir"/>\r
+            </test-roots>\r
+        </data>\r
+        <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">\r
+            <reference>\r
+                <artifact-type>jar</artifact-type>\r
+                <script>build.xml</script>\r
+                <target>jar</target>\r
+                <clean-target>clean</clean-target>\r
+                <id>jar</id>\r
+            </reference>\r
+        </references>\r
+    </configuration>\r
+</project>\r
diff --git a/src/log4j2.xml b/src/log4j2.xml
new file mode 100644 (file)
index 0000000..1ebbd9f
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2015 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/>.
+-->
+<Configuration status="INFO">
+       <Appenders>
+               <Console name="STDOUT" target="SYSTEM_OUT">
+                       <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+               </Console>
+       </Appenders>
+       <Loggers>
+               <Root level="trace">
+                       <AppenderRef ref="STDOUT" level="TRACE"/>
+               </Root>
+       </Loggers>
+</Configuration>
diff --git a/src/org/mxchange/addressbook/BaseAddressbookSystem.java b/src/org/mxchange/addressbook/BaseAddressbookSystem.java
new file mode 100644 (file)
index 0000000..aa8c235
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 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.addressbook;
+
+import org.mxchange.jcore.BaseFrameworkSystem;
+
+/**
+ * General class for addressbook application
+ *
+ * @author Roland Haeder
+ */
+public class BaseAddressbookSystem extends BaseFrameworkSystem {
+       /**
+        * No instances can be created of this class
+        */
+       protected BaseAddressbookSystem () {
+       }
+}
diff --git a/src/org/mxchange/addressbook/application/AddressbookApplication.java b/src/org/mxchange/addressbook/application/AddressbookApplication.java
new file mode 100644 (file)
index 0000000..4be3359
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2015 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.addressbook.application;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import org.mxchange.addressbook.BaseAddressbookSystem;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.client.console.ConsoleClient;
+import org.mxchange.addressbook.client.gui.SwingClient;
+import org.mxchange.jcore.BaseFrameworkSystem;
+import org.mxchange.jcore.application.Application;
+import org.mxchange.jcore.client.Client;
+import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
+import org.mxchange.jcore.manager.application.ApplicationManager;
+
+/**
+ * ============================================
+ * AddressbookApplication management:
+ * ============================================
+ * 
+ * Inernet("public" service) and Intranet
+ * 
+ * Version 1.0+:
+ * - Single-user local application
+ * - Fields:
+ *   + Gender
+ *   + Surname
+ *   + Family name
+ *   + Company name
+ *   + Street + number
+ *   + ZIP code
+ *   + City
+ *   + Landline number
+ *   + Fax number
+ *   + Cell phone number
+ *   + Email address
+ *   + Birth day
+ *   + Comment (?)
+ * - Edit own data
+ * - Add new contact
+ * - Edit contacts
+ * - Delete contacts
+ * - Categorization of contacts
+ * 
+ * Version 1.1+:
+ * - Permanent storage in database
+ * 
+ * Version 2.0+:
+ * - Multi-user web application
+ * - Local user registration / login / resend confirmation link / password
+ *   recovery
+ * - User groups (aka. teams)
+ * - Administration area (user role)
+ *   + Create/edit/delete groups
+ *   + Edit/delete/lock/unlock user
+ *   + Assign user roles/rights
+ * - Allow other users / groups to view addressbook
+ *   + Full addressbook
+ *   + Only some categories
+ * - VCard export
+ *   + Allow users/guests (not recommended)
+ * - XML export of addressbook and compressable (ZIP)
+ * - Form to contact other user/group without need of mail program
+ *   + User can disabled this
+ * - Directory for ussers/groups (who allowed to be listed)
+ *   + Simple click to add user to own addressbook
+ *   + Search form?
+ * 
+ * Version 2.1+:
+ * - Multi-language support
+ * 
+ * Version 2.2+:("socialized")
+ * - "Social login" (OpenID consumer)
+ *   + Connect user account to social account
+ *   + Sync own data?
+ * - "Social profile"
+ *   + OpenID provider
+ *   + RSS/activity feed 
+ * 
+ * ============================================
+ * Time esitmation:
+ * ============================================
+ * 1.0 (console):
+ *   + 2 days
+ * 
+ * 1.1 (database):
+ *   + 2 day
+ *   + Initial tables: contacts, categories, contact_category
+ * 
+ * 2.0 (web):
+ *   + 3 days
+ *   + Additional tables: admins (?), admin_rights, groups,
+ *    users, user_contacts, user_user_rights, user_category_rights, 
+ * 
+ * 2.1 (language)
+ *   + 1 day
+ *   + Additional tables: languages (disable, enable language "pack" ?)
+ * 
+ * 2.2 (social):
+ *   + 3 days
+ *   + Additional tables: ???
+*
+ * @author Roland Haeder
+ * @version 0.0
+ */
+public class AddressbookApplication extends BaseAddressbookSystem implements Application {
+
+       /**
+        * Application title
+        */
+       public static final String APP_TITLE = "Adressbuch"; //NOI18N
+
+       /**
+        * Application version
+        */
+       public static final String APP_VERSION = "0.0"; //NOI18N
+
+       /**
+        * Console client is enabled by default
+        */
+       private boolean consoleClient = true;
+
+       /**
+        * GUI client is disabled by default
+        */
+       private boolean guiClient = false;
+
+       /**
+        * Protected constructor
+        * @throws java.io.IOException If any IO error occurs
+        */
+       protected AddressbookApplication () throws IOException {
+               // Init properties file
+               this.initProperties();
+
+               // Init bundle
+               this.initBundle();
+       }
+
+       /**
+        * Bootstraps application
+        */
+       @Override
+       public void doBootstrap () {
+               this.getLogger().debug("Initializing application ..."); //NOI18N
+
+               // Init client variable
+               Client client = null;
+
+               // Is console or Swing choosen?
+               if (this.isConsole()) {
+                       // Debug message
+                       this.getLogger().debug("Initializing console client ..."); //NOI18N
+
+                       // Init console client instance
+                       client = new ConsoleClient(this);
+               } else if (this.isGui()) {
+                       // Debug message
+                       this.getLogger().debug("Initializing GUI (Swing) client ..."); //NOI18N
+
+                       // Init console instance
+                       client = new SwingClient(this);
+               } else {
+                       // Not client choosen
+                       this.getLogger().error("No client choosen. Cannot launch."); //NOI18N
+                       System.exit(1);
+               }
+
+               // Init client
+               client.init();
+
+               // Set client instance
+               this.setClient(client);
+
+               // The application is running at this point
+               this.getClient().enableIsRunning();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Main loop of the application
+        */
+       @Override
+       public void doMainLoop () {
+               // Get client and cast it
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // @TODO The application should be running now
+               // Output introduction
+               this.showIntro();
+
+               // Set current menu to main
+               client.setCurrentMenu("main"); //NOI18N
+
+               // --- Main loop starts here ---
+               while (this.getClient().isRunning()) {
+                       // The application is still active, show menu selection
+                       client.showCurrentMenu();
+
+                       try {
+                               // Ask for user input and run proper method
+                               client.doUserMenuChoice();
+                       } catch (final UnhandledUserChoiceException ex) {
+                               this.getLogger().catching(ex);
+                       }
+
+                       try {
+                               // Sleep a little to reduce system load
+                               Thread.sleep(100);
+                       } catch (final InterruptedException ex) {
+                               // Ignore it
+                       }
+               }
+               // --- Main loop ends here ---
+
+               // Debug message
+               this.getLogger().debug("Main loop exit - shutting down ..."); //NOI18N
+       }
+
+       /**
+        * Shuts down the application.
+        */
+       @Override
+       public void doShutdown () throws SQLException, IOException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+               
+               // Shutdown client
+               this.getClient().doShutdown();
+               
+               this.getLogger().info("End of program (last line)"); //NOI18N
+               System.exit(0);
+       }
+
+       /**
+        * Enables console client by setting propper flag
+        */
+       private void enableConsoleClient () {
+               this.getLogger().debug("Enabling console client (may become optional client) ..."); //NOI18N
+               this.consoleClient = true;
+               this.guiClient = false;
+       }
+
+       /**
+        * Enables GUI client by setting propper flag
+        */
+       private void enableGuiClient () {
+               this.getLogger().debug("Enabling GUI client (may become new default client) ..."); //NOI18N
+               this.consoleClient = false;
+               this.guiClient = true;
+       }
+
+       /**
+        * Checks whether the client shoule be console client should be launched by
+        * checking if -console is set.
+        *
+        * @return Whether console client should be taken
+        */
+       private boolean isConsole () {
+               return this.consoleClient;
+       }
+
+       /**
+        * Checks whether the client shoule be GUI client should be launched by
+        * checking if -gui is set.
+        *
+        * @return Whether GUI client should be taken
+        */
+       private boolean isGui () {
+               return this.guiClient;
+       }
+
+       /**
+        * Parses all given arguments
+        *
+        * @param args Arguments from program launch
+        */
+       private void parseArguments (final String[] args) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("args()={0} - CALLED!", args.length)); //NOI18N
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("Parsing {0} arguments ...", args.length)); //NOI18N
+
+               for (final String arg : args) {
+                       // Switch on it
+                       switch (arg) {
+                               case "-console": //NOI18N
+                                       enableConsoleClient();
+                                       break;
+
+                               case "-gui": //NOI18N
+                                       enableGuiClient();
+                                       break;
+                       }
+               }
+       }
+
+       /**
+        * Show introduction which depends on client
+        */
+       private void showIntro () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Let the client show it
+               this.getClient().showWelcome();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Launches the application
+        *
+        * @param args Arguments handled to program
+        */
+       private void start (final String args[]) {
+               this.getLogger().info("Program is started."); //NOI18N
+               try {
+                       // Init properties file
+                       this.initProperties();
+               } catch (final IOException ex) {
+                       // Something bad happened
+                       this.abortProgramWithException(ex);
+               }
+
+               // Parse arguments
+               this.parseArguments(args);
+
+               // Launch application
+               ApplicationManager.getManager(this).start();
+
+               // Good bye, but this should not be reached ...
+               this.getLogger().warn("Unusual exit reached."); //NOI18N
+               try {
+                       this.doShutdown();
+               } catch (final SQLException | IOException ex) {
+                       this.abortProgramWithException(ex);
+               }
+       }
+
+       /**
+        * Main method (entry point)
+        *
+        * @param args the command line arguments
+        */
+       public static void main (String[] args) {
+               try {
+                       // Start application
+                       new AddressbookApplication().start(args);
+               } catch (final IOException ex) {
+                       // Get instance
+                       BaseFrameworkSystem.getInstance().getLogger().catching(ex);
+                       System.exit(1);
+               }
+       }
+
+       /**
+        * Getter for printable application name
+        *
+        * @return A printable name
+        */
+       public static String printableTitle () {
+               return MessageFormat.format("{0} v{1}", APP_TITLE, APP_VERSION); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/addressbook/client/AddressbookClient.java b/src/org/mxchange/addressbook/client/AddressbookClient.java
new file mode 100644 (file)
index 0000000..dde3c17
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2015 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.addressbook.client;
+
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.jcore.client.Client;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
+
+/**
+ * A special client interface for addressbook applications.
+ * 
+ * @author Roland Haeder
+ */
+public interface AddressbookClient extends Client {
+
+       /**
+        * The user changes own name data
+        *
+        * @param contact
+        */
+       public void doChangeOwnNameData (final Contact contact);
+
+       /**
+        * The user changes own address data
+        *
+        * @param contact Contact instance to change
+        */
+       public void doChangeOwnAddressData (final Contact contact);
+
+       /**
+        * The user changes own other data
+        *
+        * @param contact Constact instance to change
+        */
+       public void doChangeOwnOtherData (final Contact contact);
+
+       /**
+        * Allows the user to enter own data
+        *
+        * @return Finished Contact instance
+        */
+       public Contact doEnterOwnData ();
+
+       /**
+        * Asks the user to enter his/her gender (M=Male, F=Female, C=Company)
+        *
+        * @param message Message to output
+        * @return Gender enum
+        */
+       public Gender enterGender (final String message);
+
+       /**
+        * Let the user choose what to change on the address: [n]ame, [a]ddress,
+        * [o]ther
+        *
+        * @param contact Contact instance to let the user change data
+        * @throws UnhandledUserChoiceException If choice is not supported
+        */
+       public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException;
+
+       /**
+        * Asks the user for a choice and proceeds accordingly
+        *
+        * @throws UnhandledUserChoiceException If choice is not supported
+        */
+       public void doUserMenuChoice () throws UnhandledUserChoiceException;
+
+       /**
+        * Asks the the user to enter a single character which must match validChars
+        *
+        * @param       validChars Valid chars that are accepted
+        * @param       message Message to user
+        * @return      Allowed character
+        */
+       public char enterChar (final char[] validChars, final String message);
+
+       /**
+        * Reads a string of minimum and maximum length from the user. An empty
+        * string should be generally not allowed, but might be okay for e.g.
+        * company name.
+        *
+        * @param minLength     Minimum length of the string to read
+        * @param maxLength     Maximum length of the string to read
+        * @param message       Message to user
+        * @param allowEmpty Whether empty strings are allowed
+        * @return Entered string by user or null if empty string is allowed
+        */
+       public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty);
+
+       /**
+        * Reads an integer (int) from the user
+        *
+        * @param minimum Minimum allowed number
+        * @param maximum Maximum allowed number
+        * @param message       Message to user
+        * @return Entered string by user or null if empty string is allowed
+        */
+       public int enterInt (final int minimum, final int maximum, final String message);
+
+       /**
+        * Setter for current menu choice
+        *
+        * @param currentMenu Current menu choice
+        */
+       public void setCurrentMenu (final String currentMenu);
+
+       /**
+        * Some "Getter" for menu item
+        *
+        * @param accessKey Key to press to access this menu
+        * @param text Text to show to user
+        * @return
+        */
+       public SelectableMenuItem getMenuItem (final char accessKey, final String text);
+
+       /**
+        * Shows given menu entry in client
+        *
+        * @param item Menu item to show
+        */
+       public void showEntry (final SelectableMenuItem item);
+
+       /**
+        * Shows current menu selection to the user
+        */
+       public void showCurrentMenu ();
+}
diff --git a/src/org/mxchange/addressbook/client/BaseAddressbookClient.java b/src/org/mxchange/addressbook/client/BaseAddressbookClient.java
new file mode 100644 (file)
index 0000000..2f2e2aa
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2015 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.addressbook.client;
+
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import org.mxchange.addressbook.manager.contact.AddressbookContactManager;
+import org.mxchange.addressbook.menu.Menu;
+import org.mxchange.jcore.client.BaseClient;
+import org.mxchange.jcore.client.Client;
+import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
+import org.mxchange.jcore.manager.database.ManageableDatabase;
+
+/**
+ * A general addressbook client
+ *
+ * @author Roland Haeder
+ */
+public abstract class BaseAddressbookClient extends BaseClient {
+
+       /**
+        * Current menu choice
+        */
+       private String currentMenu;
+
+       /**
+        * Menu system
+        */
+       private final Map<String, Menu> menus;
+
+       /**
+        * No instances can be created of this class
+        */
+       protected BaseAddressbookClient () {
+               // Init menu map
+               this.menus = new HashMap<>(10);
+       }
+
+       /**
+        * Current menu choice
+        *
+        * @return the currentMenu
+        */
+       public final String getCurrentMenu () {
+               return this.currentMenu;
+       }
+
+       /**
+        * Current menu choice
+        *
+        * @param currentMenu the currentMenu to set
+        */
+       public final void setCurrentMenu (final String currentMenu) {
+               this.currentMenu = currentMenu;
+       }
+
+       /**
+        * "Getter" for given menu type
+        *
+        * @param menuType Menu type instance to return
+        * @return Menu or null if not found
+        */
+       public Menu getMenu (final String menuType) {
+               // Default is not found
+               Menu menu = null;
+
+               // Check array
+               if (this.getMenus().containsKey(menuType)) {
+                       // Found!
+                       menu = this.getMenus().get(menuType);
+               }
+
+               // Return it
+               return menu;
+       }
+
+       /**
+        * Fills menu map with swing menus
+        */
+       protected abstract void fillMenuMap ();
+
+       /**
+        * Getter for menus map
+        *
+        * @return Map of all menus
+        */
+       protected final Map<String, Menu> getMenus () {
+               return this.menus;
+       }
+
+       /**
+        * Initializes contact manager
+        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported
+        * @throws java.sql.SQLException If any SQL error occurs
+        */
+       protected void initContactManager () throws UnsupportedDatabaseBackendException, SQLException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+               
+               // Debug message
+               this.getLogger().debug("Initializing contact manager ..."); //NOI18N
+               
+               // Init contact manager with console client
+               // @TODO Static initial amount of contacts
+               ManageableDatabase manager = new AddressbookContactManager((Client) this);
+               
+               // Set it here
+               this.setContactManager(manager);
+               
+               // Debug message
+               this.getLogger().debug("Contact manager has been initialized."); //NOI18N
+               
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Shows given menu
+        *
+        * @param menuType Given menu to show
+        */
+       protected void showMenu (final String menuType) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("menuType={0} - CALLED!", menuType)); //NOI18N
+
+               Menu menu = this.getMenu(menuType);
+
+               // Is the menu set?
+               if (!(menu instanceof Menu)) {
+                       // Not found
+                       // @todo Own exception?
+                       throw new NullPointerException(MessageFormat.format("Menu '{0}' not found.", menuType)); //NOI18N
+               }
+
+               // Show menu
+               menu.show(this);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/addressbook/client/console/ConsoleClient.java b/src/org/mxchange/addressbook/client/console/ConsoleClient.java
new file mode 100644 (file)
index 0000000..6ed15fb
--- /dev/null
@@ -0,0 +1,753 @@
+/*
+ * Copyright (C) 2015 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.addressbook.client.console;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Scanner;
+import org.mxchange.addressbook.application.AddressbookApplication;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.client.BaseAddressbookClient;
+import org.mxchange.addressbook.contact.user.UserContact;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact;
+import org.mxchange.addressbook.menu.Menu;
+import org.mxchange.addressbook.menu.MenuTools;
+import org.mxchange.addressbook.menu.console.ConsoleMenu;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.addressbook.menu.item.console.ConsoleMenuItem;
+import org.mxchange.jcore.application.Application;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
+import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
+
+/**
+ * A client for the console
+ *
+ * @author Roland Haeder
+ */
+public class ConsoleClient extends BaseAddressbookClient implements AddressbookClient {
+
+       /**
+        * Scanner instance for reading data from console input
+        */
+       private final Scanner scanner;
+
+       /**
+        * Parameterless constructor
+        *
+        * @param application An instance of an Application class
+        */
+       public ConsoleClient (final Application application) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("application={0} - CALLED!", application)); //NOI18N
+
+               // Set application instance
+               this.setApplication(application);
+
+               // Init scanner instance
+               this.scanner = new Scanner(System.in, "UTF-8"); //NOI18N
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Displays a textual address "box" of given contact
+        *
+        * @param contact Contact to show address for
+        */
+       @Override
+       public void displayAddressBox (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Is it null?
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Simple display ...
+               this.outputMessage(MessageFormat.format("Strasse, PLZ Ort, Land: {0}\n{1} {2}\n{3}", contact.getStreet(), contact.getZipCode(), contact.getCity(), contact.getCountryCode()));
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Displays a textual name "box" of given contact
+        *
+        * @param contact Contact to show name for
+        */
+       @Override
+       public void displayNameBox (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Is it null?
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get translated gender as the user may want to see "Mr.", "Mrs."
+               String gender = contact.getTranslatedGender();
+
+               // Get company name
+               String companyName = contact.getCompanyName();
+
+               // If it is empty/null, then assume private contact
+               if ((companyName == null) || (companyName.isEmpty())) {
+                       // Now put all together: gender, surname, family name
+                       // @todo Use mask
+                       this.outputMessage(MessageFormat.format("Anrede, Vorname, Name: {0} {1} {2}", gender, contact.getSurname(), contact.getFamilyName()));
+               } else {
+                       // Company contact
+                       this.outputMessage(MessageFormat.format("Firma: {0}\nAnsprechpartner: {1} {2} {3}", companyName, gender, contact.getSurname(), contact.getFamilyName()));
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Displays a textual other data "box" of given contact
+        *
+        * @param contact Contact to show other data for
+        */
+       @Override
+       public void displayOtherDataBox (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Is it null?
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Cellphone and such ...
+               this.outputMessage(MessageFormat.format("Telefonnumer: {0}\nFaxnummer: {1}\nHandy: {2}\nKommentar:\n{3}", contact.getPhoneNumber(), contact.getFaxNumber(), contact.getCellphoneNumber(), contact.getComment()));
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doChangeOwnAddressData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Is it null?
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Make sure it is own contact
+               if (!contact.isOwnContact()) {
+                       // Not own contact
+                       throw new IllegalArgumentException("Contact is not own data."); //NOI18N
+               }
+
+               // Get manager and cast it
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
+
+               // Own street and number
+               String streetNumber = manager.enterOwnStreet();
+
+               // Get zip code
+               Long zipCode = (long) manager.enterOwnZipCode();
+
+               // Get city name
+               String city = manager.enterOwnCity();
+
+               // Get country code
+               String countryCode = manager.enterOwnCountryCode();
+
+               // Update address data
+               contact.setStreet(streetNumber);
+               contact.setZipCode(zipCode);
+               contact.setCity(city);
+               contact.setCountryCode(countryCode);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doChangeOwnNameData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Is it null?
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Make sure it is own contact
+               if (!contact.isOwnContact()) {
+                       // Not own contact
+                       throw new IllegalArgumentException("Contact is not own data."); //NOI18N
+               }
+
+               // Get manager and cast it
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
+
+               // Gender:
+               Gender gender = manager.enterOwnGender();
+
+               // Surname
+               String surname = manager.enterOwnSurname();
+
+               // Family name
+               String familyName = manager.enterOwnFamilyName();
+
+               // And company
+               String companyName = manager.enterOwnCompanyName();
+
+               // Update contact instance
+               contact.setGender(gender);
+               contact.setSurname(surname);
+               contact.setFamilyName(familyName);
+               contact.setCompanyName(companyName);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doChangeOwnOtherData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Is it null?
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Make sure it is own contact
+               if (!contact.isOwnContact()) {
+                       // Not own contact
+                       throw new IllegalArgumentException("Contact is not own data."); //NOI18N
+               }
+
+               // Get manager and cast it
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
+
+               // Phone number
+               String phoneNumber = manager.enterOwnPhoneNumber();
+
+               // Phone number
+               String cellphonePhoneNumber = manager.enterOwnCellNumber();
+
+               // Fax number
+               String faxNumber = manager.enterOwnFaxNumber();
+
+               // Email address
+               String email = manager.enterOwnEmailAddress();
+
+               // Comment
+               String comment = manager.enterOwnComment();
+
+               // Update contact instance
+               contact.setPhoneNumber(phoneNumber);
+               contact.setCellphoneNumber(cellphonePhoneNumber);
+               contact.setFaxNumber(faxNumber);
+               contact.setEmailAddress(email);
+               contact.setComment(comment);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public Contact doEnterOwnData () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get manager and cast it
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
+
+               // First ask for gender
+               Gender gender = manager.enterOwnGender();
+
+               // 2nd for surname
+               String surname = manager.enterOwnSurname();
+
+               // And 3rd for family name
+               String familyName = manager.enterOwnFamilyName();
+
+               // Company name ...
+               String companyName = manager.enterOwnCompanyName();
+
+               // Construct UserContact instance
+               Contact contact = new UserContact(gender, surname, familyName, companyName);
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
+
+               // And return object
+               return contact;
+       }
+
+       /**
+        * Shutdown this client
+        */
+       @Override
+       public void doShutdown () throws SQLException, IOException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Parent call
+               super.doShutdown();
+
+               // @TODO Add other shutdown stuff
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doUserMenuChoice () throws UnhandledUserChoiceException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get all access keys from menu
+               char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.getMenus(), this.getCurrentMenu());
+
+               // Output textural message and ask for a char as input
+               char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Programm beenden): ");
+
+               // Get manager and cast it
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
+
+               // Try it!
+               try {
+                       // @TODO Rewrite this ugly switch() block
+                       switch (choice) {
+                               case '1':
+                                       try {
+                                               // Enter/add own data
+                                               manager.doEnterOwnData();
+                                       } catch (final ContactAlreadyAddedException ex) {
+                                               // Already added
+                                               this.outputMessage("Sie haben bereits Ihre eigenen Daten eingegeben.");
+                                       }
+                                       break;
+
+                               case '2': // Change own data
+                                       manager.doChangeOwnData();
+                                       break;
+
+                               case '3': // Add new addess
+                                       manager.doAddOtherAddress();
+                                       break;
+
+                               case '4': // List contacts
+                                       manager.doListContacts();
+                                       break;
+
+                               case '5': // Search addresses
+                                       manager.doSearchContacts();
+                                       break;
+
+                               case '6': // Change other addess
+                                       manager.doChangeOtherAddress();
+                                       break;
+
+                               case '7': // Delete other address
+                                       manager.doDeleteOtherAddress();
+                                       break;
+
+                       case '0': {
+                       try {
+                               // Program exit
+                               this.getApplication().doShutdown();
+                       } catch (final SQLException | IOException ex) {
+                               this.abortProgramWithException(ex);
+                       }
+               }
+                               break;
+
+                               default:
+                                       // @TODO throw own exception
+                                       throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N
+                       }
+               } catch (final IOException | BadTokenException ex) {
+                       // Something bad happened
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Asks the the user to enter a single character which must match validChars
+        *
+        * @param       validChars Valid chars that are accepted
+        * @param       message Message to user
+        * @return      Allowed character
+        */
+       @Override
+       public char enterChar (final char[] validChars, final String message) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("validChars={0},message={1} - CALLED!", Arrays.toString(validChars), message)); //NOI18N
+
+               // The validChars must not null be null and filled with at least one char
+               if (validChars == null) {
+                       // Is null
+                       throw new NullPointerException("validChars is null"); //NOI18N
+               } else if (validChars.length == 0) {
+                       // Is not filled
+                       throw new IllegalArgumentException("validChars is not filled."); //NOI18N
+               }
+
+               char input = 0;
+
+               // Sort array, else binarySearch() won't work
+               Arrays.sort(validChars);
+
+               // Keep asking until valid char has been entered
+               while (Arrays.binarySearch(validChars, input) < 0) {
+                       // Output message
+                       System.out.print(message);
+
+                       // Read char
+                       input = this.readChar();
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
+
+               // Return read char
+               return input;
+       }
+
+       /**
+        * Asks the user to enter his/her gender
+        *
+        * @param message Message to the user
+        * @return Gender enum
+        */
+       @Override
+       public Gender enterGender (final String message) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("message={0} - CALLED!", message)); //NOI18N
+
+               // Get valid chars
+               char[] validChars = Gender.validChars();
+
+               // Debug message
+               //* NOISY-DEBUG: */ System.out.println(validChars);
+               // Call inner method
+               char gender = this.enterChar(validChars, message);
+
+               // Now get a Gender instance back
+               Gender g = Gender.fromChar(gender);
+
+               // g must not be null
+               assert(g instanceof Gender) : "g is not set."; //NOI18N
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("g={0} - EXIT!", g)); //NOI18N
+
+               // Return it
+               return g;
+       }
+
+       /**
+        * Reads an integer (int) with a textural message from the user
+        *
+        * @param minimum Minimum allowed number
+        * @param maximum Maximum allowed number
+        * @param message Messager to display in console
+        * @return
+        */
+       @Override
+       public int enterInt (final int minimum, final int maximum, final String message) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("minimum={0},maximum={1},message={2} - CALLED!", minimum, maximum, message)); //NOI18N
+
+               // Minimum should not be below zero
+               assert (minimum >= 0);
+               assert (maximum > minimum);
+
+               // Init input
+               int input = -1;
+
+               while ((input < minimum) || (input > maximum)) {
+                       // Output message
+                       System.out.print(message);
+
+                       // Read integer from user
+                       input = this.readInt();
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
+
+               // Return it
+               return input;
+       }
+
+       /**
+        * Reads a string of minimum and maximum length from the user
+        *
+        * @param minLength     Minimum length of the string to read
+        * @param maxLength     Maximum length of the string to read
+        * @param message       Message to user
+        * @param allowEmpty Whether to allow empty string
+        * @return Entered string by user or null for empty strings
+        */
+       @Override
+       public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("minLength={0},maxLength={1},message={2}allowEmpty={3} - CALLED!", minLength, maxLength, message, allowEmpty)); //NOI18N
+
+               // Check on length, e.g. country codes are excactly 2 chars long
+               assert (maxLength >= minLength);
+
+               // Init input
+               String input = null;
+
+               // Check if it is to short or to long
+               while (((input == null) || ((input.length() < minLength) && (!allowEmpty))) || ((input.length() > 0) && (input.length() < minLength) && (allowEmpty)) || ((input instanceof String) && (input.length() > maxLength))) {
+                       // Output message
+                       System.out.print(message);
+
+                       // Read line
+                       input = this.readString();
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
+
+               // Return it
+               return input;
+       }
+
+       /**
+        * Returns a console menu item
+        *
+        * @param accessKey Key to access the menu
+        * @param text Text to show to user
+        * @return A SelectableMenuItem
+        * @todo Make sure the access key is unique
+        */
+       @Override
+       public SelectableMenuItem getMenuItem (final char accessKey, final String text) {
+               // Return a new console menu item
+               return new ConsoleMenuItem(accessKey, text);
+       }
+
+       /**
+        * Initializes this client
+        */
+       @Override
+       public void init () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init contact manager here
+               try {
+                       this.initContactManager();
+               } catch (final UnsupportedDatabaseBackendException | SQLException ex) {
+                       // End here
+                       this.abortProgramWithException(ex);
+               }
+
+               // Fill menu map
+               this.fillMenuMap();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Displays textural message to the user
+        *
+        * @param message
+        */
+       @Override
+       public void outputMessage (final String message) {
+               System.out.println(message);
+       }
+
+       /**
+        * Shows textural menu on console
+        */
+       @Override
+       public void showCurrentMenu () {
+               this.showMenu(this.getCurrentMenu());
+       }
+
+       /**
+        * Shows given menu entry to user
+        *
+        * @param item Menu entry
+        */
+       @Override
+       public void showEntry (final SelectableMenuItem item) {
+               // Access key then text
+               this.outputMessage(MessageFormat.format("[{0}] {1}", item.getAccessKey(), item.getText()));
+       }
+
+       /**
+        * Shows a textural message to the user
+        */
+       @Override
+       public void showWelcome () {
+               this.outputMessage(MessageFormat.format("Welcome to {0}", AddressbookApplication.printableTitle()));
+               this.outputMessage("");
+               this.outputMessage("Copyright(c) 2015 by Roland Haeder, this is free software");
+
+               // Debug message
+               this.getLogger().debug("Intro shown to user"); //NOI18N
+       }
+
+       @Override
+       public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Ask the user for editing [name], [a]ddress or [other] data
+               char choice = this.enterChar(new char[] {'n', 'a', 'o', 'x'}, "Welchen Daten möchten Sie ändern? (n=Namensdaten, a=Anschriftsdaten, o=Andere, x=Zurück zur Hauptauswahl) ");
+
+               // Get manager and cast it
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager();
+
+               // @TODO Get rid of this ugly switch block, too
+               switch (choice) {
+                       case 'n': // Name data
+                               manager.doChangeNameData(contact);
+                               break;
+
+                       case 'a': // Address data
+                               manager.doChangeAddressData(contact);
+                               break;
+
+                       case 'o': // Other data
+                               manager.doChangeOtherData(contact);
+                               break;
+
+                       case 'x': // Exit this menu
+                               // Ignored as it should go back
+                               break;
+
+                       default:
+                               // @TODO throw own exception
+                               throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Reads one character
+        *
+        * @return A single character
+        */
+       private char readChar () {
+               // Read line
+               String input = this.readString();
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N
+
+               // This must be only one character
+               if (input.length() != 1) {
+                       // Return zero
+                       return 0;
+               }
+
+               // Get char from first (and only) position
+               return input.charAt(0);
+       }
+
+       /**
+        * Reads an integer (int) from user
+        *
+        * @return An integer number
+        */
+       private int readInt () {
+               // First read a string
+               String input = this.readString();
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N
+
+               // Init number with invalid value
+               int num = -1;
+
+               // Parse number, this can be risky
+               try {
+                       num = Integer.parseInt(input);
+               } catch (final NumberFormatException e) {
+                       this.outputMessage("Bitte geben Sie nur Zahlen ein!");
+                       this.getLogger().warn(MessageFormat.format("No numbers-only entered. input={0},message={1}", input, e.getMessage())); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("num={0} - EXIT!", num)); //NOI18N
+
+               // Return read number
+               return num;
+       }
+
+       /**
+        * Reads a string from a scanner until RETURN is pressed
+        *
+        * @return Read string from scanner
+        */
+       private String readString () {
+               return this.scanner.nextLine();
+       }
+
+       /**
+        * Fills menu map with menu entries
+        */
+       @Override
+       protected final void fillMenuMap () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Initialize first (main) menu
+               Menu menu = new ConsoleMenu("main", this); //NOI18N
+
+               // Add it
+               this.getMenus().put("main", menu); //NOI18N
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java b/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
new file mode 100644 (file)
index 0000000..4bdb6e9
--- /dev/null
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (C) 2015 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.addressbook.client.gui;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFormattedTextField;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.border.TitledBorder;
+import javax.swing.table.TableModel;
+import org.mxchange.addressbook.BaseAddressbookSystem;
+import org.mxchange.addressbook.application.AddressbookApplication;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact;
+import org.mxchange.jcore.client.Client;
+import org.mxchange.jcore.client.gui.ClientFrame;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException;
+import org.mxchange.jcore.model.swing.contact.ContactTableModel;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class AddressbookFrame extends BaseAddressbookSystem implements ClientFrame {
+
+       /**
+        * Own instance
+        */
+       private static ClientFrame self;
+
+       /**
+        * Singelton getter for this frame instance.
+        *
+        * @param client Client instance
+        * @return Returns a singelton instance of this frame
+        */
+       public static final ClientFrame getSelfInstance (final Client client) {
+               // Is it set?
+               if (!(self instanceof ClientFrame)) {
+                       // Create new instance
+                       self = new AddressbookFrame(client);
+               }
+
+               // Return instance
+               return self;
+       }
+
+       /**
+        * Dialog box "add contact"
+        */
+       private JDialog addContact;
+
+       /**
+        * Frame instance for "add own data"
+        */
+       private JMenuItem addOwnItem;
+
+       /**
+        * Instance to table model
+        */
+       private TableModel dataModel;
+
+       /**
+        * Table instance
+        */
+       private JTable dataTable;
+
+       /**
+        * Frame instance for "edit own data"
+        */
+       private JMenuItem editOwnItem;
+
+       /**
+        * Frame instance
+        */
+       private final JFrame frame;
+
+       /**
+        * Whether this frame has been initialized
+        */
+       private boolean initialized;
+
+       /**
+        * Status label needs to be updated
+        */
+       private JLabel statusLabel;
+
+       /**
+        * Creates an instance of this frame with a client instance
+        *
+        * @param client
+        */
+       private AddressbookFrame (final Client client) {
+               // Debug line
+               this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
+
+               // Set frame instance
+               this.frame = new JFrame();
+               this.frame.setTitle(this.generateFrameTitle("main")); //NOI18N
+
+               // Set client here
+               this.setClient(client);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public Contact doEnterOwnData () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Is the "add contact" window visible?
+               if (this.addContact.isVisible()) {
+                       // Something bad happened
+                       throw new IllegalStateException("Window addContact is already visible."); //NOI18N
+               }
+
+               // Disable main window
+               this.frame.setEnabled(false);
+
+               // Make other window visible
+               this.addContact.setVisible(true);
+
+               // Trace message
+               this.getLogger().trace("Returning null : EXIT!"); //NOI18N
+
+               // Return value is not supported
+               return null;
+       }
+
+       /**
+        * Shutdown this frame
+        */
+       @Override
+       public void doShutdown () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // First only show shutdown status
+               this.updateStatus("shutdown"); //NOI18N
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+
+       /**
+        * Enables main window (frame)
+        */
+       @Override
+       public void enableMainWindow () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Enable it again
+               this.frame.setEnabled(true);
+
+               // Request focus for this window
+               this.frame.requestFocus();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Setups the frame, do not set isInitialized here
+        *
+        * @param client Client instance
+        */
+       @Override
+       public void setupFrame (final Client client) throws IOException, BadTokenException {
+               // Debug line
+               this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
+
+               // Get and cast manager instance
+               ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getClient().getManager();
+
+               // Has the user entered own data?
+               if (manager.isOwnContactAdded()) {
+                       // Debug message
+                       this.getLogger().debug("Disabling menus: isOwnContactAdded()=false"); //NOI18N
+
+                       // Not entered yet, so disable "add" menu
+                       this.addOwnItem.setEnabled(false);
+               } else {
+                       // Disable "edit"
+                       this.editOwnItem.setEnabled(false);
+               }
+
+               // Make the frame visible
+               this.frame.setVisible(true);
+
+               // All done here
+               this.updateStatus("done"); //NOI18N
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initalizes this frame. Having initComponents() exposed (publicly
+        * accessible) means that any other object can initialize components which
+        * you may not want.
+        *
+        * @throws
+        * org.mxchange.jcore.exceptions.FrameAlreadyInitializedException If
+        * this method has been called twice
+        */
+       @Override
+       public void init () throws FrameAlreadyInitializedException {
+               // Debug line
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Has this frame been initialized?
+               if (this.isInitialized()) {
+                       // Throw exception
+                       throw new FrameAlreadyInitializedException();
+               }
+
+               // Init components
+               this.initComponents();
+
+               // Set flag
+               this.initialized = true;
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Returns field isInitialized. This flag indicates whether this frame has
+        * been initialized or not.
+        *
+        * @return Field isInitialized
+        */
+       @Override
+       public final boolean isInitialized () {
+               return this.initialized;
+       }
+
+       /**
+        * Shuts down the application.
+        */
+       @Override
+       public void shutdownApplication () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // To do this, the frame must be initialized
+               if (!this.isInitialized()) {
+                       // Not initalized, so bad call
+                       this.getLogger().fatal("Bad call of shutdownApplication(). Please report this."); //NOI18N
+                       return;
+               }
+
+               // Call shutdown method
+               try {
+                       this.getClient().getApplication().doShutdown();
+               } catch (final SQLException | IOException ex) {
+                       // Abort here
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Adds a new menu item with given key to menu instance
+        *
+        * @param menu Menu instance to add item to
+        * @param key Message key part
+        * @param listener Listener instance
+        */
+       private void addMenuItem (final JMenu menu, final String key, final ActionListener listener) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("menu={0},key={1},listener={2} - CALLED!", menu, key, listener)); //NOI18N
+               
+               // New instance
+               JMenuItem item = this.initMenuItemWithTooltip(key);
+               
+               // Add listener
+               item.addActionListener(listener);
+               
+               // Add item -> menu
+               menu.add(item);
+               
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Adds a JTextField with label and tool tip to given panel
+        *
+        * @param panel Panel instance to add text field
+        * @param key Part of message key from resource bundle
+        * @param fieldLength Length of text field
+        */
+       private void addTextFieldWithLabelToPanel (final JPanel panel, final String key, final int fieldLength) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("panel={0},key={1},fieldLength={2} - CALLED!", panel, key, fieldLength)); //NOI18N
+               
+               // Init label for given key
+               JLabel label = new JLabel(this.getBundle().getString(String.format("AddressbookFrame.%s.text", key))); //NOI18N
+               
+               // And input box wih tool tip
+               JTextField field = new JTextField(fieldLength);
+               field.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.%s.toolTipText", key))); //NOI18N
+               
+               // Add both to panel
+               panel.add(label);
+               panel.add(field);
+               
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Generates a title for borders
+        *
+        * @param key Key part to look for
+        * @return Human-readable title
+        */
+       private String generateBorderTitle (final String key) {
+               // Call bundle instance
+               return this.getBundle().getString(String.format("AddressbookFrame.border.%s.title.text", key)); //NOI18N
+       }
+
+       /**
+        * Generates a title for all frames based on given sub title key. If null is
+        * given, the sub title is not generated.
+        *
+        * @param subKey Key for sub title resource
+        * @return A full application title
+        */
+       private String generateFrameTitle (final String subKey) {
+               // Base title
+               String title = AddressbookApplication.printableTitle();
+
+               // Is key given?
+               if (subKey != null) {
+                       // Add sub title
+                       title = String.format("%s - %s", title, this.getBundle().getString(String.format("AddressbookFrame.%s.title.text", subKey))); //NOI18N
+               }
+
+               // Return it
+               return title;
+       }
+
+       /**
+        * Initializes "add" and "cancel" buttons
+        */
+       private void initAddCancelButtons () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init panel
+               JPanel panel = new JPanel();
+               panel.setLayout(new GridLayout(1, 2, 10, 10));
+
+               // Generate "add" button
+               JButton addButton = new JButton(this.getBundle().getString("AddressbookFrame.button.addAddress.text"));
+
+               // Add listener
+               addButton.addActionListener(new AddActionListener(this.addContact, this));
+
+               // Add button to panel
+               panel.add(addButton);
+
+               // Generate "cancel" button
+               JButton cancelButton = new JButton(this.getBundle().getString("AddressbookFrame.button.cancel.text"));
+
+               // Add listener
+               cancelButton.addActionListener(new CancelActionListener(this.addContact, this));
+
+               // Add button to panel
+               panel.add(cancelButton);
+
+               // Add panel to main panel
+               this.addContact.add(panel);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes "add contact" dialog
+        */
+       private void initAddContactDialog () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Instance dialog and set title
+               this.addContact = new JDialog();
+               this.addContact.setTitle(this.generateFrameTitle("dialog.addContact")); //NOI18N
+
+               // Set layout
+               this.addContact.setLayout(new GridLayout(0, 1, 2, 2));
+
+               // Only hide it on close and make it appear in middle of screen
+               this.addContact.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
+               this.addContact.setLocationRelativeTo(this.frame);
+
+               // Set always on top and auto-focus
+               this.addContact.setAlwaysOnTop(true);
+               this.addContact.setAutoRequestFocus(true);
+
+               // Initial dimension
+               this.addContact.setSize(500, 500);
+
+               // And it is not resizeable
+               this.addContact.setResizable(false);
+
+               /*
+                * Add listener which asks for confirmation, if data has been entered
+                * but not saved yet. The user may appriciate this ... ;-)
+                *
+                * @TODO Unfinished
+                */
+               this.addContact.addWindowListener(new WindowAdapter() {
+                       /**
+                        * Invoked when a window has been closed.
+                        */
+                       @Override
+                       public void windowClosed (final WindowEvent e) {
+                               // Enable main window again
+                               AddressbookFrame.getSelfInstance(null).enableMainWindow();
+                       }
+
+                       /**
+                        * Invoked when a window is in the process of being closed. The
+                        * close operation can be overridden at this point.
+                        */
+                       @Override
+                       public void windowClosing (final WindowEvent e) {
+                               e.getWindow().dispose();
+                       }
+               });
+
+               // Init 3 panels:
+               // 1) "name" panel
+               initNameDataPanel(this.addContact);
+
+               // 2) "address" panel
+               initAddressDataPanel(this.addContact);
+
+               // 3) "other" panel
+               initOtherDataPanel(this.addContact);
+
+               // 4) "Add" and "Cancel" buttons, combined they are unique for this dialog
+               initAddCancelButtons();
+
+               // x)Only for developing:
+               /* DEBUG: */ this.addContact.setVisible(true);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes address panel
+        *
+        * @param dialog A JDialog instance to this components to
+        */
+       private void initAddressDataPanel (final JDialog dialog) {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Panel "address" input boxes
+               JPanel addressPanel = new JPanel();
+               addressPanel.setLayout(new GridLayout(0, 4, 3, 3));
+
+               // Set border to titled version
+               addressPanel.setBorder(new TitledBorder(this.generateBorderTitle("address"))); //NOI18N
+
+               // Add text field for street
+               this.addTextFieldWithLabelToPanel(addressPanel, "street", 20); //NOI18N
+
+               // Number label
+               JLabel numberLabel = new JLabel(this.getBundle().getString("AddressbookFrame.number.text"));
+
+               // And text field, but only accept numbers
+               JFormattedTextField number = new JFormattedTextField();
+               number.setToolTipText(this.getBundle().getString("AddressbookFrame.number.toolTipText"));
+
+               // Add both to street panel
+               addressPanel.add(numberLabel);
+               addressPanel.add(number);
+
+               // Label for ZIP code, again numbers only
+               JLabel zipLabel = new JLabel(this.getBundle().getString("AddressbookFrame.zip.text"));
+
+               // Init text field with label
+               JFormattedTextField zip = new JFormattedTextField();
+               zip.setToolTipText(this.getBundle().getString("AddressbookFrame.zip.toolTipText"));
+
+               // Add both to street panel
+               addressPanel.add(zipLabel);
+               addressPanel.add(zip);
+
+               // Add text field for city name
+               this.addTextFieldWithLabelToPanel(addressPanel, "city", 20); //NOI18N
+
+               // Add panel to dialog
+               dialog.add(addressPanel);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initialize components
+        */
+       private void initComponents () {
+               // Debug line
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Set default close operation
+               this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+               // Register shutdown listener
+               this.frame.addWindowListener(new WindowAdapter() {
+                       /**
+                        * Invoked when a window has been closed.
+                        */
+                       @Override
+                       public void windowClosed (final WindowEvent e) {
+                               // Shutdown application cleanly
+                               self.shutdownApplication();
+                       }
+
+                       /**
+                        * Invoked when a window is in the process of being closed. The
+                        * close operation can be overridden at this point.
+                        */
+                       @Override
+                       public void windowClosing (final WindowEvent e) {
+                               // Also shutdown cleanly here
+                               self.shutdownApplication();
+                       }
+               });
+
+               // Setup layout manager
+               this.frame.setLayout(new BorderLayout(2, 2));
+
+               // Set window size
+               this.frame.setSize(700, 400);
+
+               // Center window in middle of screen, instead of top-left corner
+               this.frame.setLocationRelativeTo(null);
+
+               // Init menu system
+               initMenuSystem();
+
+               // Init table
+               initTable();
+
+               // Init status panel
+               initStatusPanel();
+
+               // Init other windows
+               initOtherDialogs();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes a menu item instance with tool tip
+        * 
+        * @param key Message key part
+        * @return A finished JMenuItem instance
+        */
+       private JMenuItem initMenuItemWithTooltip (final String key) {
+               // Debug line
+               this.getLogger().trace(MessageFormat.format("key={0} - CALLED!", key)); //NOI18N
+
+               JMenuItem item = new JMenuItem(this.getBundle().getString(String.format("AddressbookFrame.menuItem.%s.text", key))); //NOI18N
+               item.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.menuItem.%s.toolTipText", key))); //NOI18N
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("item={0} - EXIT!", item)); //NOI18N
+
+               // Return it
+               return item;
+       }
+
+       /**
+        * Initializes the menu system
+        */
+       private void initMenuSystem () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init menu bar, menu and item instances
+               JMenuBar menuBar = new JMenuBar();
+               JMenu menu;
+               JMenuItem item;
+
+               // Init some menus:
+               // 1) File menu
+               menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
+
+               // Add menu items:
+               // 1.x) Exit program (should be last)
+               this.addMenuItem(menu, "exitProgram", new ActionListener() { //NOI18N
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               self.shutdownApplication();
+                       }
+               });
+
+               // Add menu -> menu bar
+               menuBar.add(menu);
+
+               // Init some menus:
+               // 2) Addressbook menu
+               menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
+
+               // 2.1) Add own data
+               this.addOwnItem = this.initMenuItemWithTooltip("addOwnData"); //NOI18N
+
+               // Add listener to exit menu
+               this.addOwnItem.addActionListener(new ActionListener() {
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               try {
+                                       ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
+                                       manager.doEnterOwnData();
+                               } catch (final ContactAlreadyAddedException ex) {
+                                       // Already added, log away
+                                       // @TODO maybe output message here?
+                                       self.logException(ex);
+                               } catch (final IOException | BadTokenException ex) {
+                                       // Somethind bad happened here
+                                       // @TODO Output error message here?
+                               }
+                       }
+               });
+
+               // Add item -> menu
+               menu.add(this.addOwnItem);
+
+               // 2.2) Edit own data
+               this.editOwnItem = this.initMenuItemWithTooltip("editOwnData"); //NOI18N
+
+               // Add listener to exit menu
+               this.editOwnItem.addActionListener(new ActionListener() {
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
+                               try {
+                                       manager.doChangeOwnData();
+                               } catch (final IOException | BadTokenException ex) {
+                                       self.logException(ex);
+                               }
+                       }
+               });
+
+               // Add item -> menu
+               menu.add(this.editOwnItem);
+
+               // Init more menus:
+               // 1) Add new contact
+               this.addMenuItem(menu, "addNewContact", new ActionListener() { //NOI18N
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
+                               manager.doAddOtherAddress();
+                       }
+               });
+
+               // Add menu -> menu bar
+               menuBar.add(menu);
+
+               // Add menu bar -> frame
+               this.frame.add(menuBar, BorderLayout.NORTH);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes name panel
+        *
+        * @param dialog A JDialog instance to this components to
+        */
+       private void initNameDataPanel (final JDialog dialog) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N
+
+               // Panel "name" input boxes
+               JPanel namePanel = new JPanel();
+               namePanel.setLayout(new GridLayout(0, 2, 3, 3));
+
+               // Set border to titled version
+               namePanel.setBorder(new TitledBorder(this.generateBorderTitle("name"))); //NOI18N
+
+               // Gender text field
+               JLabel gLabel = new JLabel(this.getBundle().getString("AddressbookFrame.gender.text"));
+
+               // Get all genders
+               Gender[] genders = Gender.values();
+
+               // Init gender combo box with tool tip
+               JComboBox<Gender> gender = new JComboBox<>(new DefaultComboBoxModel<>(genders));
+               gender.setToolTipText(this.getBundle().getString("AddressbookFrame.gender.toolTipText"));
+
+               // Add both to gender panel
+               namePanel.add(gLabel);
+               namePanel.add(gender);
+
+               // Add text field for surname
+               this.addTextFieldWithLabelToPanel(namePanel, "surname", 20); //NOI18N
+
+               // Add text field for family name
+               this.addTextFieldWithLabelToPanel(namePanel, "familyName", 20); //NOI18N
+
+               // Finally add panel to dialog
+               dialog.add(namePanel);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes "other" data panel
+        *
+        * @param dialog A JDialog instance to this components to
+        * @todo Fill this with life
+        */
+       private void initOtherDataPanel (final JDialog dialog) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N
+
+               // Panel "other" input boxes
+               JPanel otherPanel = new JPanel();
+               otherPanel.setLayout(new GridLayout(0, 2, 3, 3));
+               otherPanel.setBorder(new TitledBorder(this.generateBorderTitle("other"))); //NOI18N
+
+               // Add text field for email address
+               this.addTextFieldWithLabelToPanel(otherPanel, "emailAddress", 20); //NOI18N
+
+               // Add text field for phone number
+               this.addTextFieldWithLabelToPanel(otherPanel, "phoneNumber", 20); //NOI18N
+
+               // Add text field for cellphone number
+               this.addTextFieldWithLabelToPanel(otherPanel, "cellphoneNumber", 20); //NOI18N
+
+               // Add text field for fax number
+               this.addTextFieldWithLabelToPanel(otherPanel, "faxNumber", 20); //NOI18N
+
+               // Init label
+               JLabel commentLabel = new JLabel(this.getBundle().getString("AddressbookFrame.comment.text"));
+
+               // Init text area with tool tip
+               JTextArea comment = new JTextArea(5, 20);
+               comment.setToolTipText(this.getBundle().getString("AddressbookFrame.comment.toolTipText"));
+
+               // Add both to panel
+               otherPanel.add(commentLabel);
+               otherPanel.add(comment);
+
+               // Finally add panel to dialog
+               dialog.add(otherPanel);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initialize other dialogs (e.g. "Add contact")
+        */
+       private void initOtherDialogs () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init other windows:
+               // 1) Add contact
+               initAddContactDialog();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes status panel
+        */
+       private void initStatusPanel () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init status label (which needs to be updated
+               this.statusLabel = new JLabel();
+               this.updateStatus("initializing"); //NOI18N
+
+               // Init status bar in south
+               JPanel panel = new JPanel();
+               panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
+               panel.add(this.statusLabel);
+               panel.setBorder(BorderFactory.createEtchedBorder());
+
+               // Add panel to frame
+               this.frame.add(panel, BorderLayout.SOUTH);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Initializes the table which will show all contacts
+        */
+       private void initTable () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Instance table model
+               this.dataModel = new ContactTableModel(this.getClient());
+
+               // Instance table
+               this.dataTable = new JTable(this.dataModel);
+
+               // Add mouse listener
+               this.dataTable.addMouseListener(new MouseAdapter() {
+                       /**
+                        * If the user peformed a click on a cell
+                        *
+                        * @param e Mouse event instance
+                        */
+                       @Override
+                       public void mouseClicked (final MouseEvent e) {
+                               throw new UnsupportedOperationException("Unfinished."); //NOI18N
+                       }
+               });
+
+               // Instance scroll pane
+               JScrollPane scroller = new JScrollPane();
+
+               // Add table to scroll pane
+               scroller.setViewportView(this.dataTable);
+               scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+               scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+
+               // Add pane to frame
+               this.frame.add(scroller, BorderLayout.CENTER);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Updates status to given type
+        *
+        * @param type Status type
+        */
+       private void updateStatus (final String type) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("type={0} - CALLED!", type)); //NOI18N
+
+               // Set status message
+               this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type))); //NOI18N
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Class for "add address" button
+        */
+       private static class AddActionListener extends BaseAddressbookSystem implements ActionListener {
+               /**
+                * Dialog instance
+                */
+               private final JDialog dialog;
+
+               /**
+                * Frame (not JFrame) instance
+                */
+               private final ClientFrame frame;
+
+               /**
+                * Constructor for action listener
+                * 
+                * @param dialog Dialog instance to call back
+                * @param frame Frame instance (not JFrame)
+                */
+               protected AddActionListener (final JDialog dialog, final ClientFrame frame) {
+                       // Set dialog and frame here
+                       this.dialog = dialog;
+                       this.frame = frame;
+               }
+
+               /**
+                * If the action has been performed
+                *
+                * @param e The performed action event
+                */
+               @Override
+               public void actionPerformed (final ActionEvent e) {
+                       throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+               }
+       }
+
+       /**
+        * Class for "cancel address" button
+        */
+       private static class CancelActionListener extends BaseAddressbookSystem implements ActionListener {
+               /**
+                * Dialog instance
+                */
+               private final JDialog dialog;
+
+               /**
+                * Frame (not JFrame) instance
+                */
+               private final ClientFrame frame;
+
+               /**
+                * Constructor for action listener
+                * 
+                * @param dialog Dialog instance to call back
+                * @param frame Frame instance (not JFrame)
+                */
+               protected CancelActionListener (final JDialog dialog, final ClientFrame frame) {
+                       // Set dialog and frame here
+                       this.dialog = dialog;
+                       this.frame = frame;
+               }
+
+               /**
+                * If the action has been performed
+                *
+                * @param e The performed action event
+                */
+               @Override
+               public void actionPerformed (final ActionEvent e) {
+                       throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+               }
+       }
+}
diff --git a/src/org/mxchange/addressbook/client/gui/SwingClient.java b/src/org/mxchange/addressbook/client/gui/SwingClient.java
new file mode 100644 (file)
index 0000000..4c7cb13
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2015 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.addressbook.client.gui;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.client.BaseAddressbookClient;
+import org.mxchange.addressbook.menu.Menu;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.jcore.application.Application;
+import org.mxchange.jcore.client.gui.ClientFrame;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException;
+import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
+import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class SwingClient extends BaseAddressbookClient implements AddressbookClient {
+
+       /**
+        * Swing frame instance
+        */
+       private final ClientFrame frame;
+
+       /**
+        * Constructor with an Application instance.
+        *
+        * @param application Application instance
+        */
+       public SwingClient (final Application application) {
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Set application instance
+               this.setApplication(application);
+
+               // Init frame instance
+               this.frame = AddressbookFrame.getSelfInstance(this);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void displayAddressBox (final Contact contact) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void displayNameBox (final Contact contact) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void displayOtherDataBox (final Contact contact) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void doChangeOwnAddressData (Contact contact) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void doChangeOwnNameData (Contact contact) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void doChangeOwnOtherData (Contact contact) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       /**
+        * Shows dialog to enter new contact
+        *
+        * @return Returns finished Contact instance
+        */
+       @Override
+       public Contact doEnterOwnData () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Deligate this call to the frame
+               return this.frame.doEnterOwnData();
+       }
+
+       /**
+        * Shuts down this client
+        */
+       @Override
+       public void doShutdown () throws SQLException, IOException {
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Parent call
+               super.doShutdown();
+
+               // Shutdown frame
+               this.frame.doShutdown();
+
+               // @TODO Add other shutdown stuff
+               // Debug message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doUserMenuChoice () throws UnhandledUserChoiceException {
+               // Debug message
+               //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!");
+
+               // Not implemented here
+       }
+
+       @Override
+       public char enterChar (final char[] validChars, String message) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public Gender enterGender (final String message) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public int enterInt (final int minimum, final int maximum, final String message) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public Menu getMenu (final String menuType) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       /**
+        * Returns a Swing menu item
+        *
+        * @param accessKey Key to access the menu
+        * @param text Text to show to user
+        * @return A SelectableMenuItem
+        */
+       @Override
+       public SelectableMenuItem getMenuItem (final char accessKey, final String text) {
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Returns null as the menu is now no longer controlled here.
+               return null;
+       }
+
+       /**
+        * Inizializes this client
+        */
+       @Override
+       public void init () {
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               try {
+                       // Init contact manager here
+                       this.initContactManager();
+
+                       // Init frame
+                       this.frame.init();
+
+                       // Now start the frame
+                       this.frame.setupFrame(this);
+               } catch (final FrameAlreadyInitializedException | UnsupportedDatabaseBackendException | IOException | BadTokenException | SQLException ex) {
+                       // Abort program
+                       this.abortProgramWithException(ex);
+               }
+
+               // Debug message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void outputMessage (final String message) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void showCurrentMenu () {
+               // Debug message
+               //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!");
+
+               // Not implemented here
+       }
+
+       @Override
+       public void showEntry (final SelectableMenuItem item) {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       @Override
+       public void showWelcome () {
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Not implemented here
+       }
+
+       @Override
+       public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException {
+               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N
+       }
+
+       /**
+        * Fills menu map with swing menus
+        */
+       @Override
+       protected final void fillMenuMap () {
+               // Nothing to fill here as the Swing frame is handling this all
+               throw new UnsupportedOperationException("Not implemented."); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/addressbook/contact/book/BookContact.java b/src/org/mxchange/addressbook/contact/book/BookContact.java
new file mode 100644 (file)
index 0000000..d4f4bf1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.addressbook.contact.book;
+
+import org.mxchange.jcore.contact.BaseContact;
+import org.mxchange.jcore.contact.Contact;
+
+/**
+ * A contact that can be placed into "contact books"
+ *
+ * @author Roland Haeder
+ * @version 0.0
+ */
+public class BookContact extends BaseContact implements Contact {
+
+       /**
+        * Default constructor, may only be used from database backend
+        */
+       public BookContact () {
+       }
+
+}
diff --git a/src/org/mxchange/addressbook/contact/user/UserContact.java b/src/org/mxchange/addressbook/contact/user/UserContact.java
new file mode 100644 (file)
index 0000000..1ca7f89
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 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.addressbook.contact.user;
+
+import java.text.MessageFormat;
+import org.mxchange.addressbook.contact.book.BookContact;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+
+/**
+ *
+ * @author Roland Haeder
+ * @todo After a Collection has been used in ContactManager, change to
+ * BaseContact
+ */
+public class UserContact extends BookContact implements Contact {
+
+       /**
+        * Creates own contact entry
+        *
+        * @param gender Gender to be set
+        * @param surname Surname to be set
+        * @param familyName Family name to be set
+        * @param companyName Company name
+        * @todo Add validation of data
+        */
+       public UserContact (final Gender gender, final String surname, final String familyName, final String companyName) {
+               // Make sure all constructors are called
+               this();
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("gender={0},surname={1},familyName={2},companyName={3} - CALLED!", gender, surname, familyName, companyName)); //NOI18N
+
+               // Update all data
+               this.setGender(gender);
+               this.setSurname(surname);
+               this.setFamilyName(familyName);
+               this.setCompanyName(companyName);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Default constructor, may only be used from database backend
+        */
+       public UserContact () {
+               this.enableFlagOwnContact();
+       }
+}
diff --git a/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java b/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java
new file mode 100644 (file)
index 0000000..4596c57
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.addressbook.database.contact;
+
+/**
+ * A class holding constants for contact table
+ *
+ * @author Roland Haeder
+ */
+public final class AddressbookContactDatabaseConstants {
+       /**
+        * Column own_contact
+        */
+       public static final String COLUMN_OWN_CONTACT = "own_contact"; //NOI18N
+
+       /**
+        * Column id
+        */
+       public static final String COLUMN_ID = "id";
+
+       /**
+        * No instances are allowed as this class only holds static attributes
+        */
+       private AddressbookContactDatabaseConstants () {
+       }
+}
diff --git a/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java b/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java
new file mode 100644 (file)
index 0000000..89802a8
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2015 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.addressbook.database.frontend.contact;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import org.mxchange.addressbook.contact.book.BookContact;
+import org.mxchange.addressbook.contact.user.UserContact;
+import org.mxchange.addressbook.database.contact.AddressbookContactDatabaseConstants;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.addressbook.manager.contact.AddressbookContactManager;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.criteria.searchable.SearchCriteria;
+import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
+import org.mxchange.jcore.database.frontend.BaseDatabaseFrontend;
+import org.mxchange.jcore.database.result.Result;
+import org.mxchange.jcore.database.storage.Storeable;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
+import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
+
+/**
+ * Stores and retrieves Contact instances
+ *
+ * @author Roland Haeder
+ */
+public class AddressbookContactDatabaseFrontend extends BaseDatabaseFrontend implements AddressbookContactFrontend {
+
+       /**
+        * Constructor which accepts a contact manager
+        *
+        * @param manager Manager instance
+        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported
+        * @throws java.sql.SQLException If an SQL error occurs
+        */
+       public AddressbookContactDatabaseFrontend (final AddressbookContactManager manager) throws UnsupportedDatabaseBackendException, SQLException {
+               // Call own constructor
+               this();
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("manager={0} - CALLED!", manager)); //NOI18N
+
+               // Manager instance must not be null
+               if (manager == null) {
+                       // Abort here
+                       throw new NullPointerException("manager is null"); //NOI18N
+               }
+
+               // Set contact manager
+               this.setContactManager(manager);
+       }
+
+       /**
+        * Default but protected constructor
+        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported
+        * @throws java.sql.SQLException Any SQL exception from e.g. MySQL connector
+        */
+       protected AddressbookContactDatabaseFrontend () throws UnsupportedDatabaseBackendException, SQLException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Set "table" name
+               this.setTableName("contacts"); //NOI18N
+
+               // Initalize backend
+               this.initBackend();
+       }
+
+       /**
+        * Adds given contact instance to database
+        *
+        * @param contact Contact instance
+        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact instance is already found
+        */
+       @Override
+       public void addContact (final Contact contact) throws ContactAlreadyAddedException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Make sure the contact is set
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               try {
+                       // First check if the contact is there
+                       if (this.isContactFound(contact)) {
+                               // Already there
+                               throw new ContactAlreadyAddedException(contact);
+                       }
+
+                       // Then add it
+                       this.getBackend().store((Storeable) contact);
+               } catch (final IOException | BadTokenException ex) {
+                       // Abort here
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+       }
+
+       /**
+        * Shuts down the database layer
+        */
+       @Override
+       public void doShutdown () throws SQLException, IOException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Shutdown backend
+               this.getBackend().doShutdown();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public Object emptyStringToNull (final String key, final Object value) {
+               throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: key={0},value={1}", key, value));
+       }
+
+       /**
+        * Some "getter" for total contact count
+        *
+        * @return Total contact count
+        */
+       @Override
+       public int getContactsCount () throws SQLException {
+               // And deligate to backend
+               return this.getBackend().getTotalCount(); //NOI18N
+       }
+
+       /**
+        * Some "getter" for own contact instance
+        *
+        * @return Own contact instance
+        */
+       @Override
+       public Contact getOwnContact () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get row index back from backend
+               int rowIndex = this.getBackend().getRowIndexFromColumn(AddressbookContactDatabaseConstants.COLUMN_OWN_CONTACT, true);
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("rowIndex={0}", rowIndex));
+
+               // Init instance
+               Contact contact = null;
+
+               try {
+                       // Now simply read the row
+                       contact = (Contact) this.getBackend().readRow(rowIndex);
+               } catch (final BadTokenException ex) {
+                       // Bad token found
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact));
+
+               // Return it
+               return contact;
+       }
+
+       /**
+        * Checks if given Contact is found
+        * 
+        * @param contact Contact instance to check
+        * @return Whether the given Contact instance is found
+        */
+       @Override
+       public boolean isContactFound (final Contact contact) throws BadTokenException {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // contact should not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Default is not found
+               boolean isFound = false;
+
+               // Start iteration
+               Iterator<? extends Storeable> iterator = this.getBackend().iterator();
+
+               // Check all entries
+               while (iterator.hasNext()) {
+                       // Get next element
+                       Contact c = (Contact) iterator.next();
+
+                       // Debug message
+                       this.getLogger().debug(MessageFormat.format("c={0},contact={1}", c, contact)); //NOI18N
+
+                       // Is it added?
+                       if (c.equals(contact)) {
+                               // Is found
+                               isFound = true;
+                               break;
+                       }
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("isFound={0} - EXIT!", isFound)); //NOI18N
+
+               // Return it
+               return isFound;
+       }
+
+       /**
+        * Checks whether own contact is found in database
+        *
+        * @return Whether own contact is found
+        * @throws org.mxchange.jcore.exceptions.BadTokenException Continued throw
+        * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
+        * @throws java.lang.NoSuchMethodException If a method cannot be found
+        * @throws java.lang.IllegalAccessException If a method is not accessible
+        * @throws java.lang.reflect.InvocationTargetException Any other problems?
+        */
+       @Override
+       public boolean isOwnContactFound () throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+               // Get search criteria instance
+               SearchableCriteria critera = new SearchCriteria();
+
+               // Add condition
+               critera.addCriteria(AddressbookContactDatabaseConstants.COLUMN_OWN_CONTACT, true);
+
+               // Get result
+               Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(critera);
+
+               // Deligate this call to backend
+               return result.hasNext();
+       }
+
+       /**
+        * Reads a single row and parses it to a contact instance
+        *
+        * @param rowIndex Row index (also how much to skip)
+        * @return Contact instance
+        */
+       @Override
+       public Contact readSingleContact (final int rowIndex) {
+               try {
+                       // Deligate this to backend instance
+                       return (Contact) this.getBackend().readRow(rowIndex);
+               } catch (final BadTokenException ex) {
+                       // Bad token found
+                       this.abortProgramWithException(ex);
+               }
+
+               // Bad state, should not be reached
+               throw new IllegalStateException("This should not be reached");
+       }
+
+       @Override
+       public Storeable toStoreable (final Map<String, String> map) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               throw new UnsupportedOperationException("Not supported yet: map=" + map);
+       }
+
+       @Override
+       public String getIdName () {
+               // Return id column
+               return AddressbookContactDatabaseConstants.COLUMN_ID;
+       }
+}
diff --git a/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java b/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java
new file mode 100644 (file)
index 0000000..213575e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 Roland Häder
+ *
+ * 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.addressbook.database.frontend.contact;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.database.frontend.DatabaseFrontend;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
+
+/**
+ * An interface for addressbook contact database frontends
+ *
+ * @author Roland Häder
+ */
+public interface AddressbookContactFrontend extends DatabaseFrontend {
+
+       /**
+        * Adds given contact instance to database
+        *
+        * @param contact Contact instance to add
+        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added
+        */
+       public void addContact (final Contact contact) throws ContactAlreadyAddedException;
+
+       /**
+        * Some "getter" for total contacts count
+        *
+        * @return Total contacts count
+        * @throws java.sql.SQLException If any SQL error occurs
+        */
+       public int getContactsCount () throws SQLException;
+
+       /**
+        * Checks if given Contact is found
+        * 
+        * @param contact Contact instance to check
+        * @return Whether the given Contact instance is found
+        * @throws java.sql.SQLException If an SQL error occurs
+        * @throws java.io.IOException If an IO error occurs
+        * @throws org.mxchange.jcore.exceptions.BadTokenException Continued throw
+        * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
+        * @throws java.lang.NoSuchMethodException If a method cannot be found
+        * @throws java.lang.IllegalAccessException If a method is not accessible
+        * @throws java.lang.reflect.InvocationTargetException Any other problems?
+        */
+       public boolean isContactFound (final Contact contact) throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
+
+       /**
+        * Some "getter" for own contact instance
+        *
+        * @return Own contact instance
+        */
+       public Contact getOwnContact ();
+
+       /**
+        * Checks whether own contact is found
+        * 
+        * @return Whether own contact is found
+        * @throws java.sql.SQLException If any SQL error occurs
+        * @throws java.io.IOException If an IO error occurs
+        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
+        * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged
+        * @throws java.lang.NoSuchMethodException If a method cannot be found
+        * @throws java.lang.IllegalAccessException If a method is not accessible
+        * @throws java.lang.reflect.InvocationTargetException Any other problems?
+        */
+       public boolean isOwnContactFound () throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
+
+       /**
+        * Reads a single row and parses it to a contact instance
+        *
+        * @param rowIndex Row index (also how much to skip)
+        * @return Contact instance
+        */
+       public Contact readSingleContact (final int rowIndex);
+}
diff --git a/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java b/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java
new file mode 100644 (file)
index 0000000..634f4b4
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 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.addressbook.exceptions;
+
+import java.text.MessageFormat;
+import org.mxchange.jcore.contact.Contact;
+
+/**
+ * Thrown if the given Contact instance is already added
+ * 
+ * @author Roland Haeder
+ */
+public class ContactAlreadyAddedException extends Exception {
+
+       /**
+        * Constructor with a Contact instance
+        *
+        * @param contact Contact that is already added
+        */
+       public ContactAlreadyAddedException (final Contact contact) {
+               super(MessageFormat.format("Contact with gender={0}, surname={1} and familyName={2} already added.", contact.getGender(), contact.getSurname(), contact.getFamilyName()));
+       }
+
+       /**
+        * Default constructor, may be used if no contact instance is available
+        */
+       public ContactAlreadyAddedException () {
+               super("Contact already added");
+       }
+       
+}
diff --git a/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java b/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java
new file mode 100644 (file)
index 0000000..ef41687
--- /dev/null
@@ -0,0 +1,803 @@
+/*
+ * Copyright (C) 2015 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.addressbook.manager.contact;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.database.frontend.contact.AddressbookContactDatabaseFrontend;
+import org.mxchange.addressbook.database.frontend.contact.AddressbookContactFrontend;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.jcore.client.Client;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
+import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
+import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
+import org.mxchange.jcore.manager.BaseManager;
+
+/**
+ * A manager for contacts.
+ *
+ * @author Roland Haeder
+ * @version 0.0
+ */
+public class AddressbookContactManager extends BaseManager implements ManageableAddressbookContact {
+
+       /**
+        * Column name list
+        */
+       private final List<String> columnNames;
+
+       /**
+        * A AddressbookContactFrontend instance
+        */
+       private final AddressbookContactFrontend contactDatabase;
+
+       /**
+        * Translated column name list
+        */
+       private final List<String> translatedColumnNames;
+
+       /**
+        * Constructor which accepts maxContacts for maximum (initial) contacts and
+        * a client instance.
+        *
+        * @param client Client instance to use
+        * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the configured database backend is not supported
+        * @throws java.sql.SQLException If an SQL error occurs
+        */
+       public AddressbookContactManager (final Client client) throws UnsupportedDatabaseBackendException, SQLException {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("client={1} - CALLED!", client)); //NOI18N
+
+               // Make sure all parameters are set correctly
+               if (client == null) {
+                       // Abort here
+                       throw new NullPointerException("client is null"); //NOI18N
+               }
+
+               // Set client instance
+               this.setClient(client);
+
+               // Init database connection
+               this.contactDatabase = new AddressbookContactDatabaseFrontend(this);
+
+               // Initialize list
+               this.columnNames = new ArrayList<>(15);
+               this.translatedColumnNames = new ArrayList<>(15);
+
+               // And fill it
+               this.fillColumnNamesFromBundle();
+
+               // Debug message
+               //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
+       }
+
+       /**
+        * Adds given Contact instance to list
+        *
+        * @param contact Contact instance to add
+        */
+       @Override
+       public void addContact (final Contact contact)  throws ContactAlreadyAddedException {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Contact instance must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Add it
+               this.getContactDatabase().addContact(contact);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user add a new other address
+        */
+       @Override
+       public void doAddOtherAddress () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Let the user change address data
+        *
+        * @param contact Instance to change data
+        */
+       @Override
+       public void doChangeAddressData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // First display it again
+               client.displayAddressBox(contact);
+
+               // Is it own data?
+               if (contact.isOwnContact()) {
+                       // Deligate to client
+                       client.doChangeOwnAddressData(contact);
+               } else {
+                       // Other contact's address data to change
+                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user change "name data"
+        *
+        * @param contact Instance to change data
+        */
+       @Override
+       public void doChangeNameData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // First display them again
+               client.displayNameBox(contact);
+
+               // Is this own data?
+               if (contact.isOwnContact()) {
+                       // Re-ask own data
+                       client.doChangeOwnNameData(contact);
+               } else {
+                       // Then re-ask them ...
+                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user change other address
+        */
+       @Override
+       public void doChangeOtherAddress () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Let the user change other data
+        *
+        * @param contact Instance to change data
+        * @todo Didn't handle birthday
+        */
+       @Override
+       public void doChangeOtherData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // First display them again
+               client.displayOtherDataBox(contact);
+
+               // Is this own data?
+               if (contact.isOwnContact()) {
+                       // Re-ask own data
+                       client.doChangeOwnOtherData(contact);
+               } else {
+                       // Then re-ask them ...
+                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Allows the user to change his/her own data
+        */
+       @Override
+       public void doChangeOwnData () throws IOException , BadTokenException{
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               /*
+                * First check if the user has registered own contact, before that
+                * nothing can be changed.
+                */
+               if (!this.isOwnContactAdded()) {
+                       // Not added
+                       this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben."); //NOI18N
+
+                       // Skip any below code
+                       return;
+               }
+
+               // Instance
+               Contact contact = this.getOwnContact();
+
+               // It must be found
+               assert (contact instanceof Contact);
+
+               // Display contact
+               contact.show(this.getClient());
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               try {
+                       // Ask user what to change
+                       client.userChooseChangeContactData(contact);
+               } catch (final UnhandledUserChoiceException ex) {
+                       this.getLogger().catching(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user delete other address
+        */
+       @Override
+       public void doDeleteOtherAddress () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Asks user for own data
+        */
+       @Override
+       public void doEnterOwnData () throws ContactAlreadyAddedException, IOException , BadTokenException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Is own contact already added?
+               if (this.isOwnContactAdded()) {
+                       // Don't continue here
+                       throw new ContactAlreadyAddedException();
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // Deligate this call to the client
+               Contact contact = client.doEnterOwnData();
+
+               // Is it set?
+               if (contact instanceof Contact) {
+                       // Add it to contact "book"
+                       this.registerContact(contact);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doListContacts () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       @Override
+       public void doSearchContacts () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Shuts down this contact manager
+        * 
+        * @throws java.sql.SQLException If an SQL error occurs
+        * @throws java.io.IOException If an IO error occurs
+        */
+       @Override
+       public void doShutdown () throws SQLException, IOException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Shut down the database layer
+               this.getContactDatabase().doShutdown();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Asks the user for his/her cellphone number
+        *
+        * @return User's cellphone number
+        */
+       @Override
+       public String enterOwnCellNumber () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
+       }
+
+       /**
+        * Asks the user for his/her city's name
+        *
+        * @return City's name of the user
+        */
+       @Override
+       public String enterOwnCity () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
+       }
+
+       /**
+        * Asks the user for his/her city's name
+        *
+        * @return City's name of the user
+        */
+       @Override
+       public String enterOwnComment () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
+       }
+
+       /**
+        * Asks the user for his/her company name
+        *
+        * @return User's company name
+        */
+       @Override
+       public String enterOwnCompanyName () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
+       }
+
+       /**
+        * Asks user for his/her own country code
+        *
+        * @return User's own country code
+        */
+       @Override
+       public String enterOwnCountryCode () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
+       }
+
+       /**
+        * Asks user for his/her own country code
+        *
+        * @return User's own country code
+        */
+       @Override
+       public String enterOwnEmailAddress () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
+       }
+
+       /**
+        * Asks the user for family name
+        *
+        * @return Family name of the user
+        */
+       @Override
+       public String enterOwnFamilyName () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
+       }
+
+       /**
+        * Asks the user for family name
+        *
+        * @return Family name of the user
+        */
+       @Override
+       public String enterOwnFaxNumber () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
+       }
+
+       /**
+        * Asks the user for gender, until a valid has been entered
+        *
+        * @return Gender of the user
+        */
+       @Override
+       public Gender enterOwnGender () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
+       }
+
+       /**
+        * Asks the user for phone number
+        *
+        * @return Phone number of the user
+        */
+       @Override
+       public String enterOwnPhoneNumber () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
+       }
+
+       /**
+        * Asks the user for own street (including number)
+        *
+        * @return Own street an number
+        */
+       @Override
+       public String enterOwnStreet () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
+       }
+
+       /**
+        * Asks the user for surname
+        *
+        * @return Surname of the user
+        */
+       @Override
+       public String enterOwnSurname () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
+       }
+
+       /**
+        * Asks the user for own ZIP code
+        *
+        * @return ZIP code
+        */
+       @Override
+       public int enterOwnZipCode () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
+       }
+
+       @Override
+       public final int getColumnCount () {
+               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
+
+               return this.columnNames.size();
+       }
+
+       /**
+        * Getter for column name at given index.
+        *
+        * @param columnIndex Column index
+        * @return Database column name
+        */
+       @Override
+       public String getColumnName (final int columnIndex) {
+               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
+
+               // Get column name at index
+               return this.columnNames.get(columnIndex);
+       }
+
+       /**
+        * Getter for translated column name at given index.
+        *
+        * @param columnIndex Column index
+        * @return Human-readable column name
+        */
+       @Override
+       public String getTranslatedColumnName (final int columnIndex) {
+               assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
+
+               // Get column name at index
+               return this.translatedColumnNames.get(columnIndex);
+       }
+
+       /**
+        * Somewhat "getter" for value from given row and column index
+        *
+        * @param rowIndex Row index
+        * @param columnIndex Column index
+        * @return Value from given row/column
+        */
+       @Override
+       public Object getValueFromRowColumn (final int rowIndex, final int columnIndex) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("rowIndex={0},columnIndex={1} CALLED!", rowIndex, columnIndex));
+
+               // Then get specific row from database which is a Contact instance
+               Contact contact = this.getContactDatabase().readSingleContact(rowIndex);
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("contact={0}", contact));
+
+               // It may return null
+               if (contact == null) {
+                       // Nothing found
+                       this.getLogger().warn("contact is null - returning null ...");
+                       return null;
+               }
+
+               // Convert column index -> name
+               String columnName = this.getColumnName(columnIndex);
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("columnName={0}", columnName));
+
+               // Now get that column
+               Object value = null;
+               try {
+                       value = contact.getValueFromColumn(columnName);
+               } catch (final IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value));
+
+               // Return it
+               return value;
+       }
+
+       /**
+        * Checks whether own contact is already added by checking all entries for
+        * isOwnContact flag
+        *
+        * @return Whether own contact is already added
+        */
+       @Override
+       public boolean isOwnContactAdded () throws IOException, BadTokenException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init variable
+               boolean isAdded = false;
+
+               try {
+                       // Deligate this call to frontend
+                       isAdded = this.getContactDatabase().isOwnContactFound();
+               } catch (final SQLException | IOException | BadTokenException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
+                       // Something bad happened
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded)); //NOI18N
+
+               // Return result
+               return isAdded;
+       }
+
+       /**
+        * Adds given contact to address book and flushes all entries to database
+        *
+        * @param contact Contact being added
+        * @todo Add check for book size
+        */
+       @Override
+       public void registerContact (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Sanity check
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Debug message
+               /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size())); //NOI18N
+               try {
+                       // Check if contact is found
+                       if (this.getContactDatabase().isContactFound(contact)) {
+                               // Contact already added
+                               // @todo Do something here
+                       } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
+                               // Own contact already added
+                               // @todo Do something
+                       }
+
+                       // Add contact to internal list
+                       this.addContact(contact);
+               } catch (final ContactAlreadyAddedException | BadTokenException | SQLException | IOException | CorruptedDatabaseFileException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
+                       // Abort here
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Getter for size
+        *
+        * @return size of contact "book"
+        */
+       @Override
+       public final int size () {
+               // Init size
+               int size = -1;
+
+               try {
+                       size = this.getContactDatabase().getContactsCount();
+               } catch (final SQLException ex) {
+                       // Something happened
+                       this.abortProgramWithException(ex);
+               }
+
+               // Return amount
+               return size;
+       }
+
+       /**
+        * Fills the column names array with strings from bundle
+        */
+       private void fillColumnNamesFromBundle () {
+               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
+               assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
+
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // First get an iterator from key set to iterate over
+               Iterator<String> iterator = this.getBundle().keySet().iterator();
+
+               // Then iterate over all
+               while (iterator.hasNext()) {
+                       // Get next element
+                       String key = iterator.next();
+
+                       // Does the key start with AddressbookContactManager.columnName ?
+                       if (key.startsWith("ContactManager.columnName")) { //NOI18N
+                               // This is the wanted entry.
+                               this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N
+
+                               // Convert string to array based on delimiter '.'
+                               String[] tokens = this.getArrayFromString(key, ".", 4);
+
+                               // Token array must contain 4 elements (AddressbookContactManager.columnName.foo.text)
+                               assert(tokens.length == 4) : MessageFormat.format("Array tokens contains not 4 elements: {0}", Arrays.toString(tokens));
+
+                               // Get pre-last element
+                               String columnName = tokens[tokens.length - 2];
+
+                               // Debug message
+                               this.getLogger().debug(MessageFormat.format("columnName={0} - adding ...", columnName));
+
+                               // So add it
+                               this.columnNames.add(columnName);
+                               this.translatedColumnNames.add(this.getBundle().getString(key));
+                       }
+               }
+
+               // Debug message
+               this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N
+       }
+
+       /**
+        * A AddressbookContactFrontend instance
+        *
+        * @return the database
+        */
+       private AddressbookContactFrontend getContactDatabase () {
+               return this.contactDatabase;
+       }
+
+       /**
+        * "Getter" for own contact instance or null if not found
+        *
+        * @return Contact instance or null
+        */
+       private Contact getOwnContact () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Deligate this call to database frontend
+               Contact contact = this.getContactDatabase().getOwnContact();
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
+
+               // Return instance or null
+               return contact;
+       }
+}
diff --git a/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java b/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java
new file mode 100644 (file)
index 0000000..77d39d3
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2015 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.addressbook.manager.contact;
+
+import java.io.IOException;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.jcore.contact.Contact;
+import org.mxchange.jcore.contact.Gender;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.manager.database.ManageableDatabase;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public interface ManageableAddressbookContact extends ManageableDatabase {
+       /**
+        * Allows the user to enter own cellphone number.
+        *
+        * @return Cellphone number
+        */
+       public String enterOwnCellNumber ();
+
+       /**
+        * Allows the user to enter own city name.
+        *
+        * @return City name
+        */
+       public String enterOwnCity ();
+
+       /**
+        * Allows the user to enter comment for own entry.
+        *
+        * @return Comment
+        */
+       public String enterOwnComment ();
+
+       /**
+        * Allows the user to enter own company name.
+        *
+        * @return Company name
+        */
+       public String enterOwnCompanyName ();
+
+       /**
+        * Allows the user to enter own country code.
+        *
+        * @return Country code
+        */
+       public String enterOwnCountryCode ();
+
+       /**
+        * Allows the user to enter own email address.
+        *
+        * @return Email address
+        */
+       public String enterOwnEmailAddress ();
+
+       /**
+        * Allows the user to enter own family name.
+        *
+        * @return Family name
+        */
+       public String enterOwnFamilyName ();
+
+       /**
+        * Allows the user to enter own fax number.
+        *
+        * @return Fax number
+        */
+       public String enterOwnFaxNumber ();
+
+       /**
+        * Allows the user to enter own gender.
+        *
+        * @return Gender
+        */
+       public Gender enterOwnGender ();
+
+       /**
+        * Allows the user to enter own phone number.
+        *
+        * @return Phone number
+        */
+       public String enterOwnPhoneNumber ();
+
+       /**
+        * Allows the user to enter own street and house number.
+        *
+        * @return Street and house number
+        */
+       public String enterOwnStreet ();
+
+       /**
+        * Allows the user to enter own surname.
+        *
+        * @return Surname
+        */
+       public String enterOwnSurname ();
+
+       /**
+        * Allows the user to enter own ZIP code.
+        *
+        * @return ZIP code
+        */
+       public int enterOwnZipCode ();
+
+       /**
+        * List all contacts
+        */
+       public void doListContacts ();
+
+       /**
+        * Adds given contact to address book
+        *
+        * @param contact Contact being added
+        * @todo Add check for book size
+        */
+       public void registerContact (final Contact contact);
+
+       /**
+        * Adds given Contact instance to list
+        *
+        * @param contact Contact instance to add
+        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added
+        */
+       public void addContact (final Contact contact) throws ContactAlreadyAddedException;
+
+       /**
+        * Let the user add a new other address
+        */
+       public void doAddOtherAddress ();
+
+       /**
+        * The user can change address data, like street, ZIP code, city and country
+        * of given Contact instance.
+        *
+        * @param contact Instance to change data
+        */
+       public void doChangeAddressData (final Contact contact);
+
+       /**
+        * The user can change name data, like gender, surname, family name and
+        * company name (if business contact).
+        *
+        * @param contact Instance to change data
+        */
+       public void doChangeNameData (final Contact contact);
+
+       /**
+        * Let the user change other address
+        */
+       public void doChangeOtherAddress ();
+
+       /**
+        * The user can change other data, like phone numbers or comments.
+        *
+        * @param contact Instance to change data
+        */
+       public void doChangeOtherData (final Contact contact);
+
+       /**
+        * Let the user change own data
+        * @throws java.io.IOException If an IO error was found
+        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
+        */
+       public void doChangeOwnData () throws IOException , BadTokenException;
+
+       /**
+        * Let the user delete other address
+        */
+       public void doDeleteOtherAddress ();
+
+       /**
+        * Asks user for own data
+        * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If own contact is already added
+        * @throws java.io.IOException If an IO error was found
+        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
+        */
+       public void doEnterOwnData () throws ContactAlreadyAddedException, IOException , BadTokenException;
+
+       /**
+        * Searches address book for a contact
+        */
+       public void doSearchContacts ();
+
+       /**
+        * Checks whether own contact is already added by checking all entries for
+        * isOwnContact flag
+        *
+        * @return Whether own contact is already added
+        * @throws java.io.IOException If an IO error occurs
+        * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
+        */
+       public boolean isOwnContactAdded () throws IOException, BadTokenException;
+}
diff --git a/src/org/mxchange/addressbook/menu/AddressbookMenu.java b/src/org/mxchange/addressbook/menu/AddressbookMenu.java
new file mode 100644 (file)
index 0000000..12257eb
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu;
+
+import java.text.MessageFormat;
+import java.util.List;
+import org.apache.logging.log4j.Logger;
+import org.mxchange.addressbook.BaseAddressbookSystem;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.jcore.client.Client;
+
+/**
+ * Utility class for menu structure
+ *
+ * @author Roland Haeder
+ */
+public class AddressbookMenu extends BaseAddressbookSystem {
+
+       /**
+        * Copies entries for given type into the menu list
+        *
+        * @param menuList Menu list for later showing
+        * @param menuType Type of menu
+        * @param client Client instance to call back
+        */
+       public static void addItemsToList (final List<SelectableMenuItem> menuList, final String menuType, final Client client) {
+               // Get logger
+               Logger log = new AddressbookMenu().getLogger();
+
+               // Trace call
+               log.trace(MessageFormat.format("menuList={0},menuType={1},client={2} - CALLED!", menuList, menuType, client)); //NOI18N
+
+               // Some instances must be set
+               if (menuList == null) {
+                       // Abort here
+                       throw new NullPointerException("menuList is null"); //NOI18N
+               } else if (client == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (!(client instanceof AddressbookClient)) {
+                       // Not correct instance
+                       throw new IllegalArgumentException(MessageFormat.format("client{0} must implement AddressbookClient", client));
+               }
+
+               // Cast client to proper interface
+               AddressbookClient c = (AddressbookClient) client;
+
+               // Get list size
+               int size = menuList.size();
+
+               // Debug message
+               log.debug(MessageFormat.format("Adding menu for '{0}' (old size: '{1}') ...", menuType, size)); //NOI18N
+
+               // Depends on type
+               switch (menuType) {
+                       case "main": // Main menu //NOI18N
+                               // Enter own data
+                               menuList.add(c.getMenuItem('1', "Eigene Adresse anlegen"));
+
+                               // Change own data
+                               menuList.add(c.getMenuItem('2', "Eigene Adresse ändern"));
+
+                               // Add new addess
+                               menuList.add(c.getMenuItem('3', "Neue Adresse hinzufügen"));
+
+                               // List entries
+                               menuList.add(c.getMenuItem('4', "Adressbuch anzeigen"));
+
+                               // Address search
+                               menuList.add(c.getMenuItem('5', "Adresse suchen"));
+
+                               // Change other address
+                               menuList.add(c.getMenuItem('6', "Adresse ändern"));
+
+                               // Delete other address
+                               menuList.add(c.getMenuItem('7', "Adresse löschen"));
+
+                               // Always last line: Exit program
+                               menuList.add(c.getMenuItem('0', "Programm verlassen"));
+                               break;
+
+                       default: // Not supported
+                               log.error(MessageFormat.format("Menu type '{0}' ont supported", menuType)); //NOI18N
+                               System.exit(1);
+               }
+
+               // Size must have changed to more entries than before
+               assert (menuList.size() > size);
+       }
+
+}
diff --git a/src/org/mxchange/addressbook/menu/BaseMenu.java b/src/org/mxchange/addressbook/menu/BaseMenu.java
new file mode 100644 (file)
index 0000000..f554820
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.mxchange.addressbook.BaseAddressbookSystem;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.jcore.client.Client;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class BaseMenu extends BaseAddressbookSystem {
+
+       /**
+        * Menu list
+        */
+       private List<SelectableMenuItem> menuList;
+
+       /**
+        * No instance from this object
+        */
+       protected BaseMenu () {
+       }
+
+       /**
+        * Size of menu items
+        *
+        * @return Count of menu items
+        */
+       public int getMenuItemsCount () {
+               return this.menuList.size();
+       }
+
+       /**
+        * "Getter" for an iterator of this menu's items
+        *
+        * @return An iterator of all menu items
+        */
+       public Iterator<SelectableMenuItem> getMenuItemsIterator () {
+               return this.menuList.iterator();
+       }
+
+       /**
+        * Shows this menu
+        *
+        * @param client Client instance to call back
+        */
+       public void show (final Client client) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("client={0} CALLED!", client)); //NOI18N
+
+               // Client must not be null
+               if (client == null) {
+                       // Abort here
+                       throw new NullPointerException("client is null"); //NOI18N
+               }
+
+               // Get values
+               Iterator<SelectableMenuItem> iterator = this.menuList.iterator();
+
+               // Debug message
+               this.getLogger().debug("Showing menu with '" + this.menuList.size() + "' entries.");
+
+               // Output all menus
+               while (iterator.hasNext()) {
+                       // Get item
+                       SelectableMenuItem item = iterator.next();
+
+                       // Show this item
+                       item.show((AddressbookClient) client);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Getter for menu list
+        *
+        * @return      menuList List of menu entries
+        */
+       protected final List<SelectableMenuItem> getMenuList () {
+               return this.menuList;
+       }
+
+       /**
+        * Initializes menu
+        *
+        * @param menuType      Menu type to initialize
+        * @param client CLient to call back
+        */
+       protected void initMenu (final String menuType, final Client client) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N
+
+               // Init menu list
+               this.menuList = new ArrayList<>(5);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+}
diff --git a/src/org/mxchange/addressbook/menu/Menu.java b/src/org/mxchange/addressbook/menu/Menu.java
new file mode 100644 (file)
index 0000000..78a5fb1
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu;
+
+import java.util.Iterator;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.jcore.client.Client;
+
+/**
+ *
+ * @author Roland Haeder
+ * @todo find better name
+ */
+public interface Menu {
+
+       /**
+        * "Getter" for an iterator on all menu items of the current menu
+        *
+        * @return Iterator on all menu items
+        */
+       public Iterator<SelectableMenuItem> getMenuItemsIterator ();
+
+       /**
+        * Shows this menu
+        *
+        * @param client Client instance
+        */
+       public void show (final Client client);
+
+       /**
+        * Size of all menu items
+        *
+        * @return
+        */
+       public int getMenuItemsCount ();
+}
diff --git a/src/org/mxchange/addressbook/menu/MenuTools.java b/src/org/mxchange/addressbook/menu/MenuTools.java
new file mode 100644 (file)
index 0000000..30d8164
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu;
+
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.logging.log4j.Logger;
+import org.mxchange.addressbook.BaseAddressbookSystem;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class MenuTools extends BaseAddressbookSystem {
+
+       /**
+        * Gets an array with all available access keys back from given menu map.
+        * This can later be handle to the client's enterChar() method.
+        *
+        * @param menus A Map with all menus and their entries
+        * @param menuType Menu type
+        * @return An array with available access chars
+        */
+       public static char[] getAccessKeysFromMenuMap (final Map<String, Menu> menus, final String menuType) {
+               // Get logger
+               Logger logger = new MenuTools().getLogger();
+
+               // First search for the proper menu class
+               Menu menu = menus.get(menuType);
+
+               // Is it there?
+               if (!(menu instanceof Menu)) {
+                       // Not found
+                       // @todo Rewrite to exception
+                       logger.error("Menu '" + menuType + "' not found.");
+                       System.exit(1);
+               }
+
+               // Get iterator
+               Iterator<SelectableMenuItem> iterator = menu.getMenuItemsIterator();
+
+               // Init return array and counter 'i'
+               char[] accessKeys = new char[menu.getMenuItemsCount()];
+               int i = 0;
+
+               // Now "walk" through all menu entries
+               while (iterator.hasNext()) {
+                       // Get item
+                       SelectableMenuItem item = iterator.next();
+                       //* NOISY-DEBUG: */ logger.debug("item=" + item);
+
+                       // Get access key from item and add it to the array
+                       accessKeys[i] = item.getAccessKey();
+                       //* NOISY-DEBUG: */ logger.debug("accessKeys[" + i + "]=" + accessKeys[i]);
+
+                       // Increment counter
+                       i++;
+               }
+
+               // Return finished array
+               return accessKeys;
+       }
+}
diff --git a/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java b/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java
new file mode 100644 (file)
index 0000000..965f68a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu.console;
+
+import java.text.MessageFormat;
+import org.mxchange.addressbook.menu.AddressbookMenu;
+import org.mxchange.addressbook.menu.BaseMenu;
+import org.mxchange.addressbook.menu.Menu;
+import org.mxchange.jcore.client.Client;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class ConsoleMenu extends BaseMenu implements Menu {
+
+       /**
+        * Constructor for this menu
+        *
+        * @param menuType      Menu type to initialize
+        * @param client CLient to call back
+        */
+       public ConsoleMenu (final String menuType, final Client client) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N
+
+               // Client must not be null
+               if (client == null)  {
+                       // Abort here
+                       throw new NullPointerException("client is null");
+               }
+
+               // Init menu
+               this.initMenu(menuType, client);
+
+               // Add all items
+               AddressbookMenu.addItemsToList(this.getMenuList(), menuType, client);
+       }
+}
diff --git a/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java b/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java
new file mode 100644 (file)
index 0000000..4bb1cf9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu.item;
+
+import org.mxchange.addressbook.BaseAddressbookSystem;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class BaseMenuItem extends BaseAddressbookSystem {
+
+}
diff --git a/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java b/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java
new file mode 100644 (file)
index 0000000..a6de00a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu.item;
+
+import org.mxchange.jcore.client.Client;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public interface SelectableMenuItem {
+
+       /**
+        * Shows this menu item
+        *
+        * @param client Client instance
+        */
+       public void show (final Client client);
+
+       /**
+        * Access key
+        *
+        * @return the accessKey
+        */
+       public char getAccessKey ();
+
+       /**
+        * Text to user
+        *
+        * @return the text
+        */
+       public String getText ();
+}
diff --git a/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java b/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java
new file mode 100644 (file)
index 0000000..1090a63
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015 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.addressbook.menu.item.console;
+
+import java.text.MessageFormat;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.menu.item.BaseMenuItem;
+import org.mxchange.addressbook.menu.item.SelectableMenuItem;
+import org.mxchange.jcore.client.Client;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class ConsoleMenuItem extends BaseMenuItem implements SelectableMenuItem {
+
+       /**
+        * Access key
+        */
+       private char accessKey;
+
+       /**
+        * Text to user
+        */
+       private String text;
+
+       /**
+        * Constructor for building a console menu with access key and text
+        *
+        * @param accessKey Access key for this menu entry
+        * @param text Text to show to user
+        */
+       public ConsoleMenuItem (final char accessKey, final String text) {
+               this.setAccessKey(accessKey);
+               this.setText(text);
+       }
+
+       /**
+        * Access key
+        *
+        * @return the accessKey
+        */
+       @Override
+       public final char getAccessKey () {
+               return this.accessKey;
+       }
+
+       /**
+        * Access key
+        *
+        * @param accessKey the accessKey to set
+        */
+       private void setAccessKey (char accessKey) {
+               this.accessKey = accessKey;
+       }
+
+       /**
+        * Text to user
+        *
+        * @return the text
+        */
+       @Override
+       public String getText () {
+               return this.text;
+       }
+
+       /**
+        * Text to user
+        *
+        * @param text the text to set
+        */
+       private void setText (String text) {
+               this.text = text;
+       }
+
+       @Override
+       public void show (final Client client) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("client={0} - CALLED!", client)); //NOI18N
+
+               // Client must not be null
+               if (client == null) {
+                       // Abort here
+                       throw new NullPointerException("client is null");
+               } else if (!(client instanceof AddressbookClient)) {
+                       // Wrong interface
+                       throw new IllegalArgumentException("client " + client + " must implement AddressbookClient");
+               }
+
+               // Cast it
+               AddressbookClient c = (AddressbookClient) client;
+
+               // Call-back client over menu
+               c.showEntry(this);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+}
diff --git a/src/org/mxchange/localization/bundle_de_DE.properties b/src/org/mxchange/localization/bundle_de_DE.properties
new file mode 100644 (file)
index 0000000..19ee753
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright (C) 2015 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/>.
+AddressbookFrame.border.name.title.text=Anrede, Vorname, Nachname:
+AddressbookFrame.border.address.title.text=Anschrift:
+AddressbookFrame.border.other.title.text=Andere Angaben:
+AddressbookFrame.button.addAddress.text=Adresse hinzuf\u00fcgen
+AddressbookFrame.button.cancel.text=Abbrechen
+AddressbookFrame.menu.file.text=Datei
+AddressbookFrame.menu.addressbook.text=Adressbuch
+AddressbookFrame.statusLabel.initializing.text=Initialisiere ...
+AddressbookFrame.statusLabel.done.text=Fertig.
+AddressbookFrame.statusLabel.shutdown.text=Shuttting down ...
+AddressbookFrame.menuItem.exitProgram.text=Programm beenden
+AddressbookFrame.menuItem.exitProgram.toolTipText=Beendet das Programm und speichert alle Einstellungen ab.
+AddressbookFrame.menuItem.addOwnData.text=Eigene Adresse hinzuf\u00fcgen
+AddressbookFrame.menuItem.addOwnData.toolTipText=Erlaubt das Hinzuf\u00fcgen eigener Daten.
+AddressbookFrame.menuItem.editOwnData.text=Eigene Adresse \u00e4ndern
+AddressbookFrame.menuItem.editOwnData.toolTipText=Erlaubt das \u00c4ndern eigener Daten.
+AddressbookFrame.menuItem.addNewContact.text=Neue Adresse hinzuf\u00fcgen
+AddressbookFrame.menuItem.addNewContact.toolTipText=Eine neue Adresse hinzuf\u00fcgen.
+AddressbookFrame.dialog.addContact.title.text=Neue Adresse hinzuf\u00fcgen
+AddressbookFrame.main.title.text=Adressen auflisten
+AddressbookFrame.gender.text=Anrede:
+AddressbookFrame.gender.toolTipText=W\u00e4hlen Sie die Anrede aus.
+AddressbookFrame.surname.text=Vorname:
+AddressbookFrame.surname.toolTipText=Geben Sie den Vornamen ein.
+AddressbookFrame.familyName.text=Nachname:
+AddressbookFrame.familyName.toolTipText=Geben Sie den Nachnamen ein.
+AddressbookFrame.street.text=Stra\u00dfe:
+AddressbookFrame.street.toolTipText=Geben Sie die Stra\u00dfe ein.
+AddressbookFrame.number.text=Hausnummer:
+AddressbookFrame.number.toolTipText=Geben Sie die Hausnummer ein.
+AddressbookFrame.zip.text=PLZ:
+AddressbookFrame.zip.toolTipText=Geben Sie die Postleitzahl ein.
+AddressbookFrame.city.text=Stadt:
+AddressbookFrame.city.toolTipText=Geben Sie die Stadt ein.
+AddressbookFrame.emailAddress.text=Email-Adresse:
+AddressbookFrame.emailAddress.toolTipText=Geben Sie die Email-Adresse ein.
+AddressbookFrame.phoneNumber.text=Telefon:
+AddressbookFrame.phoneNumber.toolTipText=Geben Sie die Telefonnummer ein.
+AddressbookFrame.cellphoneNumber.text=Mobil:
+AddressbookFrame.cellphoneNumber.toolTipText=Geben Sie die Handynummer ein.
+AddressbookFrame.faxNumber.text=Fax:
+AddressbookFrame.faxNumber.toolTipText=Geben Sie die Faxnummer ein.
+AddressbookFrame.comment.text=Anmerkungen:
+AddressbookFrame.comment.toolTipText=Geben Sie eine Anmerkung (Freifeld) ein.
+BaseContact.gender.unknown.text=Unbekannt
+BaseContact.gender.male.text=Herr
+BaseContact.gender.female.text=Frau
+BaseContact.gender.company.text=Firma
+ContactManager.columnName.gender.text=Anrede
+ContactManager.columnName.surname.text=Vorname
+ContactManager.columnName.familyName.text=Nachname
+ContactManager.columnName.street.text=Strasse
+ContactManager.columnName.houseNumber.text=Hausnummer
+ContactManager.columnName.zipCode.text=Postleitzahl
+ContactManager.columnName.city.text=Stadt
diff --git a/src/org/mxchange/localization/bundle_en_US.properties b/src/org/mxchange/localization/bundle_en_US.properties
new file mode 100644 (file)
index 0000000..5b2c4d2
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright (C) 2015 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/>.
+AddressbookFrame.border.name.title.text=Gender, surname, family name:
+AddressbookFrame.border.address.title.text=Address:
+AddressbookFrame.border.other.title.text=Other data:
+AddressbookFrame.button.addAddress.text=Add address
+AddressbookFrame.button.cancel.text=Cancel
+AddressbookFrame.menu.file.text=File
+AddressbookFrame.menu.addressbook.text=Addressbook
+AddressbookFrame.statusLabel.initializing.text=Initializing ...
+AddressbookFrame.statusLabel.done.text=Done.
+AddressbookFrame.statusLabel.shutdown.text=Shuttting down ...
+AddressbookFrame.menuItem.exitProgram.toolTipText=Exits the program and saves all data.
+AddressbookFrame.menuItem.exitProgram.text=Exit program
+AddressbookFrame.menuItem.addOwnData.text=Add own address
+AddressbookFrame.menuItem.addOwnData.toolTipText=Allows the user to add own address data
+AddressbookFrame.menuItem.editOwnData.text=Edit own data
+AddressbookFrame.menuItem.editOwnData.toolTipText=Allows the user to edit own address data
+AddressbookFrame.menuItem.addNewContact.text=Add new address
+AddressbookFrame.menuItem.addNewContact.toolTipText=Add a new address.
+AddressbookFrame.dialog.addContact.title.text=Add new address
+AddressbookFrame.main.title.text=List addresses
+AddressbookFrame.gender.text=Gender:
+AddressbookFrame.gender.toolTipText=Choose gender.
+AddressbookFrame.surname.text=Surname:
+AddressbookFrame.surname.toolTipText=Enter surname.
+AddressbookFrame.familyName.text=Family name:
+AddressbookFrame.familyName.toolTipText=Enter family name.
+AddressbookFrame.street.text=Street:
+AddressbookFrame.street.toolTipText=Enter street.
+AddressbookFrame.number.text=Number:
+AddressbookFrame.number.toolTipText=Enter number.
+AddressbookFrame.zip.text=ZIP:
+AddressbookFrame.zip.toolTipText=Enter zip code.
+AddressbookFrame.city.text=City:
+AddressbookFrame.city.toolTipText=Enter city.
+AddressbookFrame.emailAddress.text=Email address:
+AddressbookFrame.emailAddress.toolTipText=Enter email address.
+AddressbookFrame.phoneNumber.text=Phone:
+AddressbookFrame.phoneNumber.toolTipText=Enter phone number.
+AddressbookFrame.cellphoneNumber.text=Mobile:
+AddressbookFrame.cellphoneNumber.toolTipText=Enter mobile number.
+AddressbookFrame.faxNumber.text=Fax:
+AddressbookFrame.faxNumber.toolTipText=Enter fax number.
+AddressbookFrame.comment.text=Note:
+AddressbookFrame.comment.toolTipText=Enter a note (free field).
+BaseContact.gender.unknown.text=Unknown
+BaseContact.gender.male.text=Mr.
+BaseContact.gender.female.text=Mrs.
+BaseContact.gender.company.text=Company
+ContactManager.columnName.gender.text=Gender
+ContactManager.columnName.surname.text=Surname
+ContactManager.columnName.familyName.text=Family name
+ContactManager.columnName.street.text=Street
+ContactManager.columnName.houseNumber.text=House number
+ContactManager.columnName.zipCode.text=ZIP code
+ContactManager.columnName.city.text=City