-/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
+++ /dev/null
-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!
+++ /dev/null
-============================================
-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: ???
+++ /dev/null
-<?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>
+++ /dev/null
-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 */;
+++ /dev/null
-<?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="<nothing>"/>\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 "${ant.java.version}"/>\r
- <condition property="have-jdk-older-than-1.4">\r
- <or>\r
- <contains string="${version-output}" substring="java version "1.0"/>\r
- <contains string="${version-output}" substring="java version "1.1"/>\r
- <contains string="${version-output}" substring="java version "1.2"/>\r
- <contains string="${version-output}" substring="java version "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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-<?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
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- * 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 () {
- }
-}
+++ /dev/null
-/*
- * 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
- }
-}
+++ /dev/null
-/*
- * 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 ();
-}
+++ /dev/null
-/*
- * 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
- }
-}
+++ /dev/null
-/*
- * 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
- }
-}
+++ /dev/null
-/*
- * 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.
- }
- }
-}
+++ /dev/null
-/*
- * 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
- }
-}
+++ /dev/null
-/*
- * 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 () {
- }
-
-}
+++ /dev/null
-/*
- * 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();
- }
-}
+++ /dev/null
-/*
- * 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 () {
- }
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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");
- }
-
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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);
- }
-
-}
+++ /dev/null
-/*
- * 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
- }
-}
+++ /dev/null
-/*
- * 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 ();
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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 {
-
-}
+++ /dev/null
-/*
- * 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 ();
-}
+++ /dev/null
-/*
- * 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
- }
-
-}
+++ /dev/null
-# 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
+++ /dev/null
-# 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
--- /dev/null
+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!
--- /dev/null
+============================================
+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: ???
--- /dev/null
+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 */;
--- /dev/null
+<?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="<nothing>"/>\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 "${ant.java.version}"/>\r
+ <condition property="have-jdk-older-than-1.4">\r
+ <or>\r
+ <contains string="${version-output}" substring="java version "1.0"/>\r
+ <contains string="${version-output}" substring="java version "1.1"/>\r
+ <contains string="${version-output}" substring="java version "1.2"/>\r
+ <contains string="${version-output}" substring="java version "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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+<?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
--- /dev/null
+<?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>
--- /dev/null
+/*
+ * 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 () {
+ }
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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 ();
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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.
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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 () {
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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 () {
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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");
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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 ();
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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 {
+
+}
--- /dev/null
+/*
+ * 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 ();
+}
--- /dev/null
+/*
+ * 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
+ }
+
+}
--- /dev/null
+# 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
--- /dev/null
+# 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