From: Roland Haeder Date: Mon, 17 Aug 2015 15:29:30 +0000 (+0200) Subject: Moved project files again + lib/jcore.jar added. This makes jcore more decentralized... X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;ds=inline;h=f2010ed4e24bb3e08ee7884184ee23f35193200d;p=addressbook-swing.git Moved project files again + lib/jcore.jar added. This makes jcore more decentralized than before it was. Signed-off-by: Roland Häder --- diff --git a/.gitignore b/.gitignore index 3d96b71..8f32b37 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -/Addressbook/nbproject/private/ -/Addressbook/manifest.mf -/Addressbook/build/ -/Addressbook/data/*.* -/Addressbook/dist/ -/Addressbook/*.properties +/nbproject/private/ +/manifest.mf +/build/ +/data/*.* +/dist/ +/*.properties diff --git a/Addressbook/README.txt b/Addressbook/README.txt deleted file mode 100644 index 20590e3..0000000 --- a/Addressbook/README.txt +++ /dev/null @@ -1,30 +0,0 @@ -How to launch: -============== - -1) Build it: (you need ant tools) -ant jar - -2) Go to dist folder and create "data": -cd dist -mkdir data - -3) Launch it -$ java -jar Addressbook.jar - -4) The GUI can also be launched: -$ java -jar Addressbook.jar -gui - -If you got an exception, maybe you bumbed into a stub method (unfinished). To reduce possibilities of -crashes try the usual approach: - -$ java -ea -jar Addressbook.jar -gui - -Please report any errors back to me. And yes, not all is finished. :) - -The file config.properties will be created on first run for you. After that you -can customize it. Supported database backends are: - -base64csv - The default backend, BASE64-encoded CSV strings -mysql - The unfinished MySQL backend - -Good luck! diff --git a/Addressbook/VERSIONS.txt b/Addressbook/VERSIONS.txt deleted file mode 100644 index 9d25667..0000000 --- a/Addressbook/VERSIONS.txt +++ /dev/null @@ -1,85 +0,0 @@ -============================================ -AddressbookApplication management: -============================================ - -Inernet("public" service) and Intranet - -Version 1.0+: -- Single-user local application -- Fields: - + Gender - + Surname - + Family name - + Company name - + Street + number - + ZIP code - + City - + Landline number - + Fax number - + Cell phone number - + Email address - + Birth day - + Comment (?) -- Edit own data -- Add new contact -- Edit contacts -- Delete contacts -- Categorization of contacts - -Version 1.1+: -- Permanent storage in database - -Version 2.0+: -- Multi-user web application -- Local user registration / login / resend confirmation link / password - recovery -- User groups (aka. teams) -- Administration area (user role) - + Create/edit/delete groups - + Edit/delete/lock/unlock user - + Assign user roles/rights -- Allow other users / groups to view addressbook - + Full addressbook - + Only some categories -- VCard export - + Allow users/guests (not recommended) -- XML export of addressbook and compressable (ZIP) -- Form to contact other user/group without need of mail program - + User can disabled this -- Directory for ussers/groups (who allowed to be listed) - + Simple click to add user to own addressbook - + Search form? - -Version 2.1+: -- Multi-language support - -Version 2.2+:("socialized") -- "Social login" (OpenID consumer) - + Connect user account to social account - + Sync own data? -- "Social profile" - + OpenID provider - + RSS/activity feed - -============================================ -Time esitmation: -============================================ -1.0 (console): - + 2 days - -1.1 (database): - + 2 day - + Initial tables: contacts, categories, contact_category - -2.0 (web): - + 3 days - + Additional tables: admins (?), admin_rights, groups, - users, user_contacts, user_user_rights, user_category_rights, - -2.1 (language) - + 1 day - + Additional tables: languages (disable, enable language "pack" ?) - -2.2 (social): - + 3 days - + Additional tables: ??? diff --git a/Addressbook/build.xml b/Addressbook/build.xml deleted file mode 100644 index b72f99d..0000000 --- a/Addressbook/build.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - Builds, tests, and runs the project Addressbook. - - - diff --git a/Addressbook/install/tables.sql b/Addressbook/install/tables.sql deleted file mode 100644 index a08e1de..0000000 --- a/Addressbook/install/tables.sql +++ /dev/null @@ -1,42 +0,0 @@ -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - - -DROP TABLE IF EXISTS `contacts`; -CREATE TABLE IF NOT EXISTS `contacts` ( -`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key', - `own_contact` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether own contact', - `gender` varchar(10) NOT NULL DEFAULT 'UNKNOWN' COMMENT 'Gender', - `surname` varchar(100) NOT NULL COMMENT 'Surname', - `family_name` varchar(100) NOT NULL COMMENT 'Family name', - `company_name` varchar(255) DEFAULT NULL COMMENT 'Company name', - `street` varchar(255) DEFAULT NULL COMMENT 'Street name', - `house_number` smallint(5) unsigned DEFAULT NULL COMMENT 'House number', - `city` varchar(100) DEFAULT NULL COMMENT 'City name', - `zip_code` smallint(5) unsigned DEFAULT NULL COMMENT 'ZIP code', - `country_code` char(2) DEFAULT NULL COMMENT 'Country code', - `phone_number` varchar(100) DEFAULT NULL COMMENT 'Phone number', - `cellphone_number` varchar(100) DEFAULT NULL COMMENT 'Cellphone number', - `fax_number` varchar(100) DEFAULT NULL COMMENT 'Fax number', - `email_address` varchar(100) DEFAULT NULL COMMENT 'Email addres', - `birthday` date DEFAULT NULL COMMENT 'Birth day', - `comment` tinytext NOT NULL COMMENT 'Comment', - `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Entry created', - `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Contacts data' AUTO_INCREMENT=1 ; - - -ALTER TABLE `contacts` - ADD PRIMARY KEY (`id`); - - -ALTER TABLE `contacts` -MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key'; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/Addressbook/lib/log4j-api-2.3.jar b/Addressbook/lib/log4j-api-2.3.jar deleted file mode 100644 index 2a61bbe..0000000 Binary files a/Addressbook/lib/log4j-api-2.3.jar and /dev/null differ diff --git a/Addressbook/lib/log4j-core-2.3.jar b/Addressbook/lib/log4j-core-2.3.jar deleted file mode 100644 index 5438b0b..0000000 Binary files a/Addressbook/lib/log4j-core-2.3.jar and /dev/null differ diff --git a/Addressbook/nbproject/build-impl.xml b/Addressbook/nbproject/build-impl.xml deleted file mode 100644 index 4c95079..0000000 --- a/Addressbook/nbproject/build-impl.xml +++ /dev/null @@ -1,1429 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No tests executed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set JVM to use for profiling in profiler.info.jvm - Must set profiler agent JVM arguments in profiler.info.jvmargs.agent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - Must select one file in the IDE or set profile.class - This target only works when run from inside the NetBeans IDE. - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - - - Must select some files in the IDE or set test.includes - - - - - Must select one file in the IDE or set run.class - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - Must select some files in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - Must select one file in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Addressbook/nbproject/genfiles.properties b/Addressbook/nbproject/genfiles.properties deleted file mode 100644 index 5cab81f..0000000 --- a/Addressbook/nbproject/genfiles.properties +++ /dev/null @@ -1,8 +0,0 @@ -build.xml.data.CRC32=39498655 -build.xml.script.CRC32=e7acbc61 -build.xml.stylesheet.CRC32=8064a381@1.75.2.48 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=b3f3ee43 -nbproject/build-impl.xml.script.CRC32=96150614 -nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/Addressbook/nbproject/project.properties b/Addressbook/nbproject/project.properties deleted file mode 100644 index 7cc6fa2..0000000 --- a/Addressbook/nbproject/project.properties +++ /dev/null @@ -1,87 +0,0 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=Addressbook -application.vendor=Roland Haeder -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# Files in build.classes.dir which should be excluded from distribution jar -dist.archive.excludes= -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/Addressbook.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.log4j-api-2.3.jar=C:\\Users\\KLC\\Documents\\NetBeansProjects\\jcore\\lib\\log4j-api-2.3.jar -file.reference.log4j-core-2.3.jar=C:\\Users\\KLC\\Documents\\NetBeansProjects\\jcore\\lib\\log4j-core-2.3.jar -includes=** -jar.compress=false -javac.classpath=\ - ${file.reference.log4j-api-2.3.jar}:\ - ${file.reference.log4j-core-2.3.jar}:\ - ${reference.jcore.jar} -# Space-separated list of extra javac options -javac.compilerargs=-Xlint:deprecation -Xlint:unchecked -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.7 -javac.target=1.7 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.reference.log4j-api-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-api-2.3-javadoc.jar -javadoc.reference.log4j-core-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-core-2.3-javadoc.jar -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class=org.mxchange.addressbook.application.AddressbookApplication -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -project.jcore=../../jcore -project.license=gpl30 -reference.jcore.jar=${project.jcore}/dist/jcore.jar -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs=-ea -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -source.reference.log4j-api-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-api-2.3-sources.jar -source.reference.log4j-core-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-core-2.3-sources.jar -src.dir=src -test.src.dir=test diff --git a/Addressbook/nbproject/project.xml b/Addressbook/nbproject/project.xml deleted file mode 100644 index 6b25f3e..0000000 --- a/Addressbook/nbproject/project.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - org.netbeans.modules.java.j2seproject - - - Addressbook - - - - - - - - - - jcore - jar - - jar - clean - jar - - - - diff --git a/Addressbook/src/log4j2.xml b/Addressbook/src/log4j2.xml deleted file mode 100644 index 1ebbd9f..0000000 --- a/Addressbook/src/log4j2.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - diff --git a/Addressbook/src/org/mxchange/addressbook/BaseAddressbookSystem.java b/Addressbook/src/org/mxchange/addressbook/BaseAddressbookSystem.java deleted file mode 100644 index aa8c235..0000000 --- a/Addressbook/src/org/mxchange/addressbook/BaseAddressbookSystem.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook; - -import org.mxchange.jcore.BaseFrameworkSystem; - -/** - * General class for addressbook application - * - * @author Roland Haeder - */ -public class BaseAddressbookSystem extends BaseFrameworkSystem { - /** - * No instances can be created of this class - */ - protected BaseAddressbookSystem () { - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/application/AddressbookApplication.java b/Addressbook/src/org/mxchange/addressbook/application/AddressbookApplication.java deleted file mode 100644 index 4be3359..0000000 --- a/Addressbook/src/org/mxchange/addressbook/application/AddressbookApplication.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.application; - -import java.io.IOException; -import java.sql.SQLException; -import java.text.MessageFormat; -import org.mxchange.addressbook.BaseAddressbookSystem; -import org.mxchange.addressbook.client.AddressbookClient; -import org.mxchange.addressbook.client.console.ConsoleClient; -import org.mxchange.addressbook.client.gui.SwingClient; -import org.mxchange.jcore.BaseFrameworkSystem; -import org.mxchange.jcore.application.Application; -import org.mxchange.jcore.client.Client; -import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; -import org.mxchange.jcore.manager.application.ApplicationManager; - -/** - * ============================================ - * AddressbookApplication management: - * ============================================ - * - * Inernet("public" service) and Intranet - * - * Version 1.0+: - * - Single-user local application - * - Fields: - * + Gender - * + Surname - * + Family name - * + Company name - * + Street + number - * + ZIP code - * + City - * + Landline number - * + Fax number - * + Cell phone number - * + Email address - * + Birth day - * + Comment (?) - * - Edit own data - * - Add new contact - * - Edit contacts - * - Delete contacts - * - Categorization of contacts - * - * Version 1.1+: - * - Permanent storage in database - * - * Version 2.0+: - * - Multi-user web application - * - Local user registration / login / resend confirmation link / password - * recovery - * - User groups (aka. teams) - * - Administration area (user role) - * + Create/edit/delete groups - * + Edit/delete/lock/unlock user - * + Assign user roles/rights - * - Allow other users / groups to view addressbook - * + Full addressbook - * + Only some categories - * - VCard export - * + Allow users/guests (not recommended) - * - XML export of addressbook and compressable (ZIP) - * - Form to contact other user/group without need of mail program - * + User can disabled this - * - Directory for ussers/groups (who allowed to be listed) - * + Simple click to add user to own addressbook - * + Search form? - * - * Version 2.1+: - * - Multi-language support - * - * Version 2.2+:("socialized") - * - "Social login" (OpenID consumer) - * + Connect user account to social account - * + Sync own data? - * - "Social profile" - * + OpenID provider - * + RSS/activity feed - * - * ============================================ - * Time esitmation: - * ============================================ - * 1.0 (console): - * + 2 days - * - * 1.1 (database): - * + 2 day - * + Initial tables: contacts, categories, contact_category - * - * 2.0 (web): - * + 3 days - * + Additional tables: admins (?), admin_rights, groups, - * users, user_contacts, user_user_rights, user_category_rights, - * - * 2.1 (language) - * + 1 day - * + Additional tables: languages (disable, enable language "pack" ?) - * - * 2.2 (social): - * + 3 days - * + Additional tables: ??? -* - * @author Roland Haeder - * @version 0.0 - */ -public class AddressbookApplication extends BaseAddressbookSystem implements Application { - - /** - * Application title - */ - public static final String APP_TITLE = "Adressbuch"; //NOI18N - - /** - * Application version - */ - public static final String APP_VERSION = "0.0"; //NOI18N - - /** - * Console client is enabled by default - */ - private boolean consoleClient = true; - - /** - * GUI client is disabled by default - */ - private boolean guiClient = false; - - /** - * Protected constructor - * @throws java.io.IOException If any IO error occurs - */ - protected AddressbookApplication () throws IOException { - // Init properties file - this.initProperties(); - - // Init bundle - this.initBundle(); - } - - /** - * Bootstraps application - */ - @Override - public void doBootstrap () { - this.getLogger().debug("Initializing application ..."); //NOI18N - - // Init client variable - Client client = null; - - // Is console or Swing choosen? - if (this.isConsole()) { - // Debug message - this.getLogger().debug("Initializing console client ..."); //NOI18N - - // Init console client instance - client = new ConsoleClient(this); - } else if (this.isGui()) { - // Debug message - this.getLogger().debug("Initializing GUI (Swing) client ..."); //NOI18N - - // Init console instance - client = new SwingClient(this); - } else { - // Not client choosen - this.getLogger().error("No client choosen. Cannot launch."); //NOI18N - System.exit(1); - } - - // Init client - client.init(); - - // Set client instance - this.setClient(client); - - // The application is running at this point - this.getClient().enableIsRunning(); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Main loop of the application - */ - @Override - public void doMainLoop () { - // Get client and cast it - AddressbookClient client = (AddressbookClient) this.getClient(); - - // Debug message - this.getLogger().trace("CALLED!"); //NOI18N - - // @TODO The application should be running now - // Output introduction - this.showIntro(); - - // Set current menu to main - client.setCurrentMenu("main"); //NOI18N - - // --- Main loop starts here --- - while (this.getClient().isRunning()) { - // The application is still active, show menu selection - client.showCurrentMenu(); - - try { - // Ask for user input and run proper method - client.doUserMenuChoice(); - } catch (final UnhandledUserChoiceException ex) { - this.getLogger().catching(ex); - } - - try { - // Sleep a little to reduce system load - Thread.sleep(100); - } catch (final InterruptedException ex) { - // Ignore it - } - } - // --- Main loop ends here --- - - // Debug message - this.getLogger().debug("Main loop exit - shutting down ..."); //NOI18N - } - - /** - * Shuts down the application. - */ - @Override - public void doShutdown () throws SQLException, IOException { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Shutdown client - this.getClient().doShutdown(); - - this.getLogger().info("End of program (last line)"); //NOI18N - System.exit(0); - } - - /** - * Enables console client by setting propper flag - */ - private void enableConsoleClient () { - this.getLogger().debug("Enabling console client (may become optional client) ..."); //NOI18N - this.consoleClient = true; - this.guiClient = false; - } - - /** - * Enables GUI client by setting propper flag - */ - private void enableGuiClient () { - this.getLogger().debug("Enabling GUI client (may become new default client) ..."); //NOI18N - this.consoleClient = false; - this.guiClient = true; - } - - /** - * Checks whether the client shoule be console client should be launched by - * checking if -console is set. - * - * @return Whether console client should be taken - */ - private boolean isConsole () { - return this.consoleClient; - } - - /** - * Checks whether the client shoule be GUI client should be launched by - * checking if -gui is set. - * - * @return Whether GUI client should be taken - */ - private boolean isGui () { - return this.guiClient; - } - - /** - * Parses all given arguments - * - * @param args Arguments from program launch - */ - private void parseArguments (final String[] args) { - // Trace message - this.getLogger().trace(MessageFormat.format("args()={0} - CALLED!", args.length)); //NOI18N - - // Debug message - this.getLogger().debug(MessageFormat.format("Parsing {0} arguments ...", args.length)); //NOI18N - - for (final String arg : args) { - // Switch on it - switch (arg) { - case "-console": //NOI18N - enableConsoleClient(); - break; - - case "-gui": //NOI18N - enableGuiClient(); - break; - } - } - } - - /** - * Show introduction which depends on client - */ - private void showIntro () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Let the client show it - this.getClient().showWelcome(); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Launches the application - * - * @param args Arguments handled to program - */ - private void start (final String args[]) { - this.getLogger().info("Program is started."); //NOI18N - try { - // Init properties file - this.initProperties(); - } catch (final IOException ex) { - // Something bad happened - this.abortProgramWithException(ex); - } - - // Parse arguments - this.parseArguments(args); - - // Launch application - ApplicationManager.getManager(this).start(); - - // Good bye, but this should not be reached ... - this.getLogger().warn("Unusual exit reached."); //NOI18N - try { - this.doShutdown(); - } catch (final SQLException | IOException ex) { - this.abortProgramWithException(ex); - } - } - - /** - * Main method (entry point) - * - * @param args the command line arguments - */ - public static void main (String[] args) { - try { - // Start application - new AddressbookApplication().start(args); - } catch (final IOException ex) { - // Get instance - BaseFrameworkSystem.getInstance().getLogger().catching(ex); - System.exit(1); - } - } - - /** - * Getter for printable application name - * - * @return A printable name - */ - public static String printableTitle () { - return MessageFormat.format("{0} v{1}", APP_TITLE, APP_VERSION); //NOI18N - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/client/AddressbookClient.java b/Addressbook/src/org/mxchange/addressbook/client/AddressbookClient.java deleted file mode 100644 index dde3c17..0000000 --- a/Addressbook/src/org/mxchange/addressbook/client/AddressbookClient.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.client; - -import org.mxchange.addressbook.menu.item.SelectableMenuItem; -import org.mxchange.jcore.client.Client; -import org.mxchange.jcore.contact.Contact; -import org.mxchange.jcore.contact.Gender; -import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; - -/** - * A special client interface for addressbook applications. - * - * @author Roland Haeder - */ -public interface AddressbookClient extends Client { - - /** - * The user changes own name data - * - * @param contact - */ - public void doChangeOwnNameData (final Contact contact); - - /** - * The user changes own address data - * - * @param contact Contact instance to change - */ - public void doChangeOwnAddressData (final Contact contact); - - /** - * The user changes own other data - * - * @param contact Constact instance to change - */ - public void doChangeOwnOtherData (final Contact contact); - - /** - * Allows the user to enter own data - * - * @return Finished Contact instance - */ - public Contact doEnterOwnData (); - - /** - * Asks the user to enter his/her gender (M=Male, F=Female, C=Company) - * - * @param message Message to output - * @return Gender enum - */ - public Gender enterGender (final String message); - - /** - * Let the user choose what to change on the address: [n]ame, [a]ddress, - * [o]ther - * - * @param contact Contact instance to let the user change data - * @throws UnhandledUserChoiceException If choice is not supported - */ - public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException; - - /** - * Asks the user for a choice and proceeds accordingly - * - * @throws UnhandledUserChoiceException If choice is not supported - */ - public void doUserMenuChoice () throws UnhandledUserChoiceException; - - /** - * Asks the the user to enter a single character which must match validChars - * - * @param validChars Valid chars that are accepted - * @param message Message to user - * @return Allowed character - */ - public char enterChar (final char[] validChars, final String message); - - /** - * Reads a string of minimum and maximum length from the user. An empty - * string should be generally not allowed, but might be okay for e.g. - * company name. - * - * @param minLength Minimum length of the string to read - * @param maxLength Maximum length of the string to read - * @param message Message to user - * @param allowEmpty Whether empty strings are allowed - * @return Entered string by user or null if empty string is allowed - */ - public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty); - - /** - * Reads an integer (int) from the user - * - * @param minimum Minimum allowed number - * @param maximum Maximum allowed number - * @param message Message to user - * @return Entered string by user or null if empty string is allowed - */ - public int enterInt (final int minimum, final int maximum, final String message); - - /** - * Setter for current menu choice - * - * @param currentMenu Current menu choice - */ - public void setCurrentMenu (final String currentMenu); - - /** - * Some "Getter" for menu item - * - * @param accessKey Key to press to access this menu - * @param text Text to show to user - * @return - */ - public SelectableMenuItem getMenuItem (final char accessKey, final String text); - - /** - * Shows given menu entry in client - * - * @param item Menu item to show - */ - public void showEntry (final SelectableMenuItem item); - - /** - * Shows current menu selection to the user - */ - public void showCurrentMenu (); -} diff --git a/Addressbook/src/org/mxchange/addressbook/client/BaseAddressbookClient.java b/Addressbook/src/org/mxchange/addressbook/client/BaseAddressbookClient.java deleted file mode 100644 index 2f2e2aa..0000000 --- a/Addressbook/src/org/mxchange/addressbook/client/BaseAddressbookClient.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 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 getMenus () { - return this.menus; - } - - /** - * Initializes contact manager - * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported - * @throws java.sql.SQLException If any SQL error occurs - */ - protected void initContactManager () throws UnsupportedDatabaseBackendException, SQLException { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Debug message - this.getLogger().debug("Initializing contact manager ..."); //NOI18N - - // Init contact manager with console client - // @TODO Static initial amount of contacts - ManageableDatabase manager = new AddressbookContactManager((Client) this); - - // Set it here - this.setContactManager(manager); - - // Debug message - this.getLogger().debug("Contact manager has been initialized."); //NOI18N - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Shows given menu - * - * @param menuType Given menu to show - */ - protected void showMenu (final String menuType) { - // Trace message - this.getLogger().trace(MessageFormat.format("menuType={0} - CALLED!", menuType)); //NOI18N - - Menu menu = this.getMenu(menuType); - - // Is the menu set? - if (!(menu instanceof Menu)) { - // Not found - // @todo Own exception? - throw new NullPointerException(MessageFormat.format("Menu '{0}' not found.", menuType)); //NOI18N - } - - // Show menu - menu.show(this); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java b/Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java deleted file mode 100644 index 6ed15fb..0000000 --- a/Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.client.console; - -import java.io.IOException; -import java.sql.SQLException; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.Scanner; -import org.mxchange.addressbook.application.AddressbookApplication; -import org.mxchange.addressbook.client.AddressbookClient; -import org.mxchange.addressbook.client.BaseAddressbookClient; -import org.mxchange.addressbook.contact.user.UserContact; -import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException; -import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact; -import org.mxchange.addressbook.menu.Menu; -import org.mxchange.addressbook.menu.MenuTools; -import org.mxchange.addressbook.menu.console.ConsoleMenu; -import org.mxchange.addressbook.menu.item.SelectableMenuItem; -import org.mxchange.addressbook.menu.item.console.ConsoleMenuItem; -import org.mxchange.jcore.application.Application; -import org.mxchange.jcore.contact.Contact; -import org.mxchange.jcore.contact.Gender; -import org.mxchange.jcore.exceptions.BadTokenException; -import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; -import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; - -/** - * A client for the console - * - * @author Roland Haeder - */ -public class ConsoleClient extends BaseAddressbookClient implements AddressbookClient { - - /** - * Scanner instance for reading data from console input - */ - private final Scanner scanner; - - /** - * Parameterless constructor - * - * @param application An instance of an Application class - */ - public ConsoleClient (final Application application) { - // Trace message - this.getLogger().trace(MessageFormat.format("application={0} - CALLED!", application)); //NOI18N - - // Set application instance - this.setApplication(application); - - // Init scanner instance - this.scanner = new Scanner(System.in, "UTF-8"); //NOI18N - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Displays a textual address "box" of given contact - * - * @param contact Contact to show address for - */ - @Override - public void displayAddressBox (final Contact contact) { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N - - // Is it null? - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Simple display ... - this.outputMessage(MessageFormat.format("Strasse, PLZ Ort, Land: {0}\n{1} {2}\n{3}", contact.getStreet(), contact.getZipCode(), contact.getCity(), contact.getCountryCode())); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Displays a textual name "box" of given contact - * - * @param contact Contact to show name for - */ - @Override - public void displayNameBox (final Contact contact) { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N - - // Is it null? - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Get translated gender as the user may want to see "Mr.", "Mrs." - String gender = contact.getTranslatedGender(); - - // Get company name - String companyName = contact.getCompanyName(); - - // If it is empty/null, then assume private contact - if ((companyName == null) || (companyName.isEmpty())) { - // Now put all together: gender, surname, family name - // @todo Use mask - this.outputMessage(MessageFormat.format("Anrede, Vorname, Name: {0} {1} {2}", gender, contact.getSurname(), contact.getFamilyName())); - } else { - // Company contact - this.outputMessage(MessageFormat.format("Firma: {0}\nAnsprechpartner: {1} {2} {3}", companyName, gender, contact.getSurname(), contact.getFamilyName())); - } - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Displays a textual other data "box" of given contact - * - * @param contact Contact to show other data for - */ - @Override - public void displayOtherDataBox (final Contact contact) { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N - - // Is it null? - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Cellphone and such ... - this.outputMessage(MessageFormat.format("Telefonnumer: {0}\nFaxnummer: {1}\nHandy: {2}\nKommentar:\n{3}", contact.getPhoneNumber(), contact.getFaxNumber(), contact.getCellphoneNumber(), contact.getComment())); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void doChangeOwnAddressData (final Contact contact) { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N - - // Is it null? - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Make sure it is own contact - if (!contact.isOwnContact()) { - // Not own contact - throw new IllegalArgumentException("Contact is not own data."); //NOI18N - } - - // Get manager and cast it - ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); - - // Own street and number - String streetNumber = manager.enterOwnStreet(); - - // Get zip code - Long zipCode = (long) manager.enterOwnZipCode(); - - // Get city name - String city = manager.enterOwnCity(); - - // Get country code - String countryCode = manager.enterOwnCountryCode(); - - // Update address data - contact.setStreet(streetNumber); - contact.setZipCode(zipCode); - contact.setCity(city); - contact.setCountryCode(countryCode); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void doChangeOwnNameData (final Contact contact) { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N - - // Is it null? - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Make sure it is own contact - if (!contact.isOwnContact()) { - // Not own contact - throw new IllegalArgumentException("Contact is not own data."); //NOI18N - } - - // Get manager and cast it - ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); - - // Gender: - Gender gender = manager.enterOwnGender(); - - // Surname - String surname = manager.enterOwnSurname(); - - // Family name - String familyName = manager.enterOwnFamilyName(); - - // And company - String companyName = manager.enterOwnCompanyName(); - - // Update contact instance - contact.setGender(gender); - contact.setSurname(surname); - contact.setFamilyName(familyName); - contact.setCompanyName(companyName); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void doChangeOwnOtherData (final Contact contact) { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N - - // Is it null? - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Make sure it is own contact - if (!contact.isOwnContact()) { - // Not own contact - throw new IllegalArgumentException("Contact is not own data."); //NOI18N - } - - // Get manager and cast it - ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); - - // Phone number - String phoneNumber = manager.enterOwnPhoneNumber(); - - // Phone number - String cellphonePhoneNumber = manager.enterOwnCellNumber(); - - // Fax number - String faxNumber = manager.enterOwnFaxNumber(); - - // Email address - String email = manager.enterOwnEmailAddress(); - - // Comment - String comment = manager.enterOwnComment(); - - // Update contact instance - contact.setPhoneNumber(phoneNumber); - contact.setCellphoneNumber(cellphonePhoneNumber); - contact.setFaxNumber(faxNumber); - contact.setEmailAddress(email); - contact.setComment(comment); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public Contact doEnterOwnData () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Get manager and cast it - ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); - - // First ask for gender - Gender gender = manager.enterOwnGender(); - - // 2nd for surname - String surname = manager.enterOwnSurname(); - - // And 3rd for family name - String familyName = manager.enterOwnFamilyName(); - - // Company name ... - String companyName = manager.enterOwnCompanyName(); - - // Construct UserContact instance - Contact contact = new UserContact(gender, surname, familyName, companyName); - - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N - - // And return object - return contact; - } - - /** - * Shutdown this client - */ - @Override - public void doShutdown () throws SQLException, IOException { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Parent call - super.doShutdown(); - - // @TODO Add other shutdown stuff - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void doUserMenuChoice () throws UnhandledUserChoiceException { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Get all access keys from menu - char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.getMenus(), this.getCurrentMenu()); - - // Output textural message and ask for a char as input - char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Programm beenden): "); - - // Get manager and cast it - ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); - - // Try it! - try { - // @TODO Rewrite this ugly switch() block - switch (choice) { - case '1': - try { - // Enter/add own data - manager.doEnterOwnData(); - } catch (final ContactAlreadyAddedException ex) { - // Already added - this.outputMessage("Sie haben bereits Ihre eigenen Daten eingegeben."); - } - break; - - case '2': // Change own data - manager.doChangeOwnData(); - break; - - case '3': // Add new addess - manager.doAddOtherAddress(); - break; - - case '4': // List contacts - manager.doListContacts(); - break; - - case '5': // Search addresses - manager.doSearchContacts(); - break; - - case '6': // Change other addess - manager.doChangeOtherAddress(); - break; - - case '7': // Delete other address - manager.doDeleteOtherAddress(); - break; - - case '0': { - try { - // Program exit - this.getApplication().doShutdown(); - } catch (final SQLException | IOException ex) { - this.abortProgramWithException(ex); - } - } - break; - - default: - // @TODO throw own exception - throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N - } - } catch (final IOException | BadTokenException ex) { - // Something bad happened - this.abortProgramWithException(ex); - } - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Asks the the user to enter a single character which must match validChars - * - * @param validChars Valid chars that are accepted - * @param message Message to user - * @return Allowed character - */ - @Override - public char enterChar (final char[] validChars, final String message) { - // Trace message - this.getLogger().trace(MessageFormat.format("validChars={0},message={1} - CALLED!", Arrays.toString(validChars), message)); //NOI18N - - // The validChars must not null be null and filled with at least one char - if (validChars == null) { - // Is null - throw new NullPointerException("validChars is null"); //NOI18N - } else if (validChars.length == 0) { - // Is not filled - throw new IllegalArgumentException("validChars is not filled."); //NOI18N - } - - char input = 0; - - // Sort array, else binarySearch() won't work - Arrays.sort(validChars); - - // Keep asking until valid char has been entered - while (Arrays.binarySearch(validChars, input) < 0) { - // Output message - System.out.print(message); - - // Read char - input = this.readChar(); - } - - // Trace message - this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N - - // Return read char - return input; - } - - /** - * Asks the user to enter his/her gender - * - * @param message Message to the user - * @return Gender enum - */ - @Override - public Gender enterGender (final String message) { - // Trace message - this.getLogger().trace(MessageFormat.format("message={0} - CALLED!", message)); //NOI18N - - // Get valid chars - char[] validChars = Gender.validChars(); - - // Debug message - //* NOISY-DEBUG: */ System.out.println(validChars); - // Call inner method - char gender = this.enterChar(validChars, message); - - // Now get a Gender instance back - Gender g = Gender.fromChar(gender); - - // g must not be null - assert(g instanceof Gender) : "g is not set."; //NOI18N - - // Trace message - this.getLogger().trace(MessageFormat.format("g={0} - EXIT!", g)); //NOI18N - - // Return it - return g; - } - - /** - * Reads an integer (int) with a textural message from the user - * - * @param minimum Minimum allowed number - * @param maximum Maximum allowed number - * @param message Messager to display in console - * @return - */ - @Override - public int enterInt (final int minimum, final int maximum, final String message) { - // Trace message - this.getLogger().trace(MessageFormat.format("minimum={0},maximum={1},message={2} - CALLED!", minimum, maximum, message)); //NOI18N - - // Minimum should not be below zero - assert (minimum >= 0); - assert (maximum > minimum); - - // Init input - int input = -1; - - while ((input < minimum) || (input > maximum)) { - // Output message - System.out.print(message); - - // Read integer from user - input = this.readInt(); - } - - // Trace message - this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N - - // Return it - return input; - } - - /** - * Reads a string of minimum and maximum length from the user - * - * @param minLength Minimum length of the string to read - * @param maxLength Maximum length of the string to read - * @param message Message to user - * @param allowEmpty Whether to allow empty string - * @return Entered string by user or null for empty strings - */ - @Override - public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) { - // Trace message - this.getLogger().trace(MessageFormat.format("minLength={0},maxLength={1},message={2}allowEmpty={3} - CALLED!", minLength, maxLength, message, allowEmpty)); //NOI18N - - // Check on length, e.g. country codes are excactly 2 chars long - assert (maxLength >= minLength); - - // Init input - String input = null; - - // Check if it is to short or to long - while (((input == null) || ((input.length() < minLength) && (!allowEmpty))) || ((input.length() > 0) && (input.length() < minLength) && (allowEmpty)) || ((input instanceof String) && (input.length() > maxLength))) { - // Output message - System.out.print(message); - - // Read line - input = this.readString(); - } - - // Trace message - this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N - - // Return it - return input; - } - - /** - * Returns a console menu item - * - * @param accessKey Key to access the menu - * @param text Text to show to user - * @return A SelectableMenuItem - * @todo Make sure the access key is unique - */ - @Override - public SelectableMenuItem getMenuItem (final char accessKey, final String text) { - // Return a new console menu item - return new ConsoleMenuItem(accessKey, text); - } - - /** - * Initializes this client - */ - @Override - public void init () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Init contact manager here - try { - this.initContactManager(); - } catch (final UnsupportedDatabaseBackendException | SQLException ex) { - // End here - this.abortProgramWithException(ex); - } - - // Fill menu map - this.fillMenuMap(); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Displays textural message to the user - * - * @param message - */ - @Override - public void outputMessage (final String message) { - System.out.println(message); - } - - /** - * Shows textural menu on console - */ - @Override - public void showCurrentMenu () { - this.showMenu(this.getCurrentMenu()); - } - - /** - * Shows given menu entry to user - * - * @param item Menu entry - */ - @Override - public void showEntry (final SelectableMenuItem item) { - // Access key then text - this.outputMessage(MessageFormat.format("[{0}] {1}", item.getAccessKey(), item.getText())); - } - - /** - * Shows a textural message to the user - */ - @Override - public void showWelcome () { - this.outputMessage(MessageFormat.format("Welcome to {0}", AddressbookApplication.printableTitle())); - this.outputMessage(""); - this.outputMessage("Copyright(c) 2015 by Roland Haeder, this is free software"); - - // Debug message - this.getLogger().debug("Intro shown to user"); //NOI18N - } - - @Override - public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException { - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N - - // Contact must not be null - if (contact == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } - - // Ask the user for editing [name], [a]ddress or [other] data - char choice = this.enterChar(new char[] {'n', 'a', 'o', 'x'}, "Welchen Daten möchten Sie ändern? (n=Namensdaten, a=Anschriftsdaten, o=Andere, x=Zurück zur Hauptauswahl) "); - - // Get manager and cast it - ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); - - // @TODO Get rid of this ugly switch block, too - switch (choice) { - case 'n': // Name data - manager.doChangeNameData(contact); - break; - - case 'a': // Address data - manager.doChangeAddressData(contact); - break; - - case 'o': // Other data - manager.doChangeOtherData(contact); - break; - - case 'x': // Exit this menu - // Ignored as it should go back - break; - - default: - // @TODO throw own exception - throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N - } - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Reads one character - * - * @return A single character - */ - private char readChar () { - // Read line - String input = this.readString(); - - // Debug message - this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N - - // This must be only one character - if (input.length() != 1) { - // Return zero - return 0; - } - - // Get char from first (and only) position - return input.charAt(0); - } - - /** - * Reads an integer (int) from user - * - * @return An integer number - */ - private int readInt () { - // First read a string - String input = this.readString(); - - // Debug message - this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N - - // Init number with invalid value - int num = -1; - - // Parse number, this can be risky - try { - num = Integer.parseInt(input); - } catch (final NumberFormatException e) { - this.outputMessage("Bitte geben Sie nur Zahlen ein!"); - this.getLogger().warn(MessageFormat.format("No numbers-only entered. input={0},message={1}", input, e.getMessage())); //NOI18N - } - - // Trace message - this.getLogger().trace(MessageFormat.format("num={0} - EXIT!", num)); //NOI18N - - // Return read number - return num; - } - - /** - * Reads a string from a scanner until RETURN is pressed - * - * @return Read string from scanner - */ - private String readString () { - return this.scanner.nextLine(); - } - - /** - * Fills menu map with menu entries - */ - @Override - protected final void fillMenuMap () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Initialize first (main) menu - Menu menu = new ConsoleMenu("main", this); //NOI18N - - // Add it - this.getMenus().put("main", menu); //NOI18N - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java b/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java deleted file mode 100644 index 4bdb6e9..0000000 --- a/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java +++ /dev/null @@ -1,1002 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 = new JComboBox<>(new DefaultComboBoxModel<>(genders)); - gender.setToolTipText(this.getBundle().getString("AddressbookFrame.gender.toolTipText")); - - // Add both to gender panel - namePanel.add(gLabel); - namePanel.add(gender); - - // Add text field for surname - this.addTextFieldWithLabelToPanel(namePanel, "surname", 20); //NOI18N - - // Add text field for family name - this.addTextFieldWithLabelToPanel(namePanel, "familyName", 20); //NOI18N - - // Finally add panel to dialog - dialog.add(namePanel); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Initializes "other" data panel - * - * @param dialog A JDialog instance to this components to - * @todo Fill this with life - */ - private void initOtherDataPanel (final JDialog dialog) { - // Trace message - this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N - - // Panel "other" input boxes - JPanel otherPanel = new JPanel(); - otherPanel.setLayout(new GridLayout(0, 2, 3, 3)); - otherPanel.setBorder(new TitledBorder(this.generateBorderTitle("other"))); //NOI18N - - // Add text field for email address - this.addTextFieldWithLabelToPanel(otherPanel, "emailAddress", 20); //NOI18N - - // Add text field for phone number - this.addTextFieldWithLabelToPanel(otherPanel, "phoneNumber", 20); //NOI18N - - // Add text field for cellphone number - this.addTextFieldWithLabelToPanel(otherPanel, "cellphoneNumber", 20); //NOI18N - - // Add text field for fax number - this.addTextFieldWithLabelToPanel(otherPanel, "faxNumber", 20); //NOI18N - - // Init label - JLabel commentLabel = new JLabel(this.getBundle().getString("AddressbookFrame.comment.text")); - - // Init text area with tool tip - JTextArea comment = new JTextArea(5, 20); - comment.setToolTipText(this.getBundle().getString("AddressbookFrame.comment.toolTipText")); - - // Add both to panel - otherPanel.add(commentLabel); - otherPanel.add(comment); - - // Finally add panel to dialog - dialog.add(otherPanel); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Initialize other dialogs (e.g. "Add contact") - */ - private void initOtherDialogs () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Init other windows: - // 1) Add contact - initAddContactDialog(); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Initializes status panel - */ - private void initStatusPanel () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Init status label (which needs to be updated - this.statusLabel = new JLabel(); - this.updateStatus("initializing"); //NOI18N - - // Init status bar in south - JPanel panel = new JPanel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); - panel.add(this.statusLabel); - panel.setBorder(BorderFactory.createEtchedBorder()); - - // Add panel to frame - this.frame.add(panel, BorderLayout.SOUTH); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Initializes the table which will show all contacts - */ - private void initTable () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Instance table model - this.dataModel = new ContactTableModel(this.getClient()); - - // Instance table - this.dataTable = new JTable(this.dataModel); - - // Add mouse listener - this.dataTable.addMouseListener(new MouseAdapter() { - /** - * If the user peformed a click on a cell - * - * @param e Mouse event instance - */ - @Override - public void mouseClicked (final MouseEvent e) { - throw new UnsupportedOperationException("Unfinished."); //NOI18N - } - }); - - // Instance scroll pane - JScrollPane scroller = new JScrollPane(); - - // Add table to scroll pane - scroller.setViewportView(this.dataTable); - scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - - // Add pane to frame - this.frame.add(scroller, BorderLayout.CENTER); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Updates status to given type - * - * @param type Status type - */ - private void updateStatus (final String type) { - // Trace message - this.getLogger().trace(MessageFormat.format("type={0} - CALLED!", type)); //NOI18N - - // Set status message - this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type))); //NOI18N - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Class for "add address" button - */ - private static class AddActionListener extends BaseAddressbookSystem implements ActionListener { - /** - * Dialog instance - */ - private final JDialog dialog; - - /** - * Frame (not JFrame) instance - */ - private final ClientFrame frame; - - /** - * Constructor for action listener - * - * @param dialog Dialog instance to call back - * @param frame Frame instance (not JFrame) - */ - protected AddActionListener (final JDialog dialog, final ClientFrame frame) { - // Set dialog and frame here - this.dialog = dialog; - this.frame = frame; - } - - /** - * If the action has been performed - * - * @param e The performed action event - */ - @Override - public void actionPerformed (final ActionEvent e) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } - - /** - * Class for "cancel address" button - */ - private static class CancelActionListener extends BaseAddressbookSystem implements ActionListener { - /** - * Dialog instance - */ - private final JDialog dialog; - - /** - * Frame (not JFrame) instance - */ - private final ClientFrame frame; - - /** - * Constructor for action listener - * - * @param dialog Dialog instance to call back - * @param frame Frame instance (not JFrame) - */ - protected CancelActionListener (final JDialog dialog, final ClientFrame frame) { - // Set dialog and frame here - this.dialog = dialog; - this.frame = frame; - } - - /** - * If the action has been performed - * - * @param e The performed action event - */ - @Override - public void actionPerformed (final ActionEvent e) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java b/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java deleted file mode 100644 index 4c7cb13..0000000 --- a/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.client.gui; - -import java.io.IOException; -import java.sql.SQLException; -import org.mxchange.addressbook.client.AddressbookClient; -import org.mxchange.addressbook.client.BaseAddressbookClient; -import org.mxchange.addressbook.menu.Menu; -import org.mxchange.addressbook.menu.item.SelectableMenuItem; -import org.mxchange.jcore.application.Application; -import org.mxchange.jcore.client.gui.ClientFrame; -import org.mxchange.jcore.contact.Contact; -import org.mxchange.jcore.contact.Gender; -import org.mxchange.jcore.exceptions.BadTokenException; -import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException; -import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; -import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; - -/** - * - * @author Roland Haeder - */ -public class SwingClient extends BaseAddressbookClient implements AddressbookClient { - - /** - * Swing frame instance - */ - private final ClientFrame frame; - - /** - * Constructor with an Application instance. - * - * @param application Application instance - */ - public SwingClient (final Application application) { - // Debug message - this.getLogger().trace("CALLED!"); //NOI18N - - // Set application instance - this.setApplication(application); - - // Init frame instance - this.frame = AddressbookFrame.getSelfInstance(this); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void displayAddressBox (final Contact contact) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void displayNameBox (final Contact contact) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void displayOtherDataBox (final Contact contact) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void doChangeOwnAddressData (Contact contact) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void doChangeOwnNameData (Contact contact) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void doChangeOwnOtherData (Contact contact) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - /** - * Shows dialog to enter new contact - * - * @return Returns finished Contact instance - */ - @Override - public Contact doEnterOwnData () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Deligate this call to the frame - return this.frame.doEnterOwnData(); - } - - /** - * Shuts down this client - */ - @Override - public void doShutdown () throws SQLException, IOException { - // Debug message - this.getLogger().trace("CALLED!"); //NOI18N - - // Parent call - super.doShutdown(); - - // Shutdown frame - this.frame.doShutdown(); - - // @TODO Add other shutdown stuff - // Debug message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void doUserMenuChoice () throws UnhandledUserChoiceException { - // Debug message - //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!"); - - // Not implemented here - } - - @Override - public char enterChar (final char[] validChars, String message) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public Gender enterGender (final String message) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public int enterInt (final int minimum, final int maximum, final String message) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public Menu getMenu (final String menuType) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - /** - * Returns a Swing menu item - * - * @param accessKey Key to access the menu - * @param text Text to show to user - * @return A SelectableMenuItem - */ - @Override - public SelectableMenuItem getMenuItem (final char accessKey, final String text) { - // Debug message - this.getLogger().trace("CALLED!"); //NOI18N - - // Returns null as the menu is now no longer controlled here. - return null; - } - - /** - * Inizializes this client - */ - @Override - public void init () { - // Debug message - this.getLogger().trace("CALLED!"); //NOI18N - - try { - // Init contact manager here - this.initContactManager(); - - // Init frame - this.frame.init(); - - // Now start the frame - this.frame.setupFrame(this); - } catch (final FrameAlreadyInitializedException | UnsupportedDatabaseBackendException | IOException | BadTokenException | SQLException ex) { - // Abort program - this.abortProgramWithException(ex); - } - - // Debug message - this.getLogger().trace("EXIT!"); //NOI18N - } - - @Override - public void outputMessage (final String message) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void showCurrentMenu () { - // Debug message - //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!"); - - // Not implemented here - } - - @Override - public void showEntry (final SelectableMenuItem item) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - @Override - public void showWelcome () { - // Debug message - this.getLogger().trace("CALLED!"); //NOI18N - - // Not implemented here - } - - @Override - public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N - } - - /** - * Fills menu map with swing menus - */ - @Override - protected final void fillMenuMap () { - // Nothing to fill here as the Swing frame is handling this all - throw new UnsupportedOperationException("Not implemented."); //NOI18N - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/contact/book/BookContact.java b/Addressbook/src/org/mxchange/addressbook/contact/book/BookContact.java deleted file mode 100644 index d4f4bf1..0000000 --- a/Addressbook/src/org/mxchange/addressbook/contact/book/BookContact.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.contact.book; - -import org.mxchange.jcore.contact.BaseContact; -import org.mxchange.jcore.contact.Contact; - -/** - * A contact that can be placed into "contact books" - * - * @author Roland Haeder - * @version 0.0 - */ -public class BookContact extends BaseContact implements Contact { - - /** - * Default constructor, may only be used from database backend - */ - public BookContact () { - } - -} diff --git a/Addressbook/src/org/mxchange/addressbook/contact/user/UserContact.java b/Addressbook/src/org/mxchange/addressbook/contact/user/UserContact.java deleted file mode 100644 index 1ca7f89..0000000 --- a/Addressbook/src/org/mxchange/addressbook/contact/user/UserContact.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.contact.user; - -import java.text.MessageFormat; -import org.mxchange.addressbook.contact.book.BookContact; -import org.mxchange.jcore.contact.Contact; -import org.mxchange.jcore.contact.Gender; - -/** - * - * @author Roland Haeder - * @todo After a Collection has been used in ContactManager, change to - * BaseContact - */ -public class UserContact extends BookContact implements Contact { - - /** - * Creates own contact entry - * - * @param gender Gender to be set - * @param surname Surname to be set - * @param familyName Family name to be set - * @param companyName Company name - * @todo Add validation of data - */ - public UserContact (final Gender gender, final String surname, final String familyName, final String companyName) { - // Make sure all constructors are called - this(); - - // Trace message - this.getLogger().trace(MessageFormat.format("gender={0},surname={1},familyName={2},companyName={3} - CALLED!", gender, surname, familyName, companyName)); //NOI18N - - // Update all data - this.setGender(gender); - this.setSurname(surname); - this.setFamilyName(familyName); - this.setCompanyName(companyName); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - - /** - * Default constructor, may only be used from database backend - */ - public UserContact () { - this.enableFlagOwnContact(); - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java b/Addressbook/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java deleted file mode 100644 index 4596c57..0000000 --- a/Addressbook/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.database.contact; - -/** - * A class holding constants for contact table - * - * @author Roland Haeder - */ -public final class AddressbookContactDatabaseConstants { - /** - * Column own_contact - */ - public static final String COLUMN_OWN_CONTACT = "own_contact"; //NOI18N - - /** - * Column id - */ - public static final String COLUMN_ID = "id"; - - /** - * No instances are allowed as this class only holds static attributes - */ - private AddressbookContactDatabaseConstants () { - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java b/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java deleted file mode 100644 index 89802a8..0000000 --- a/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 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 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 map) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - throw new UnsupportedOperationException("Not supported yet: map=" + map); - } - - @Override - public String getIdName () { - // Return id column - return AddressbookContactDatabaseConstants.COLUMN_ID; - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java b/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java deleted file mode 100644 index 213575e..0000000 --- a/Addressbook/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2015 Roland Häder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.database.frontend.contact; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.sql.SQLException; -import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException; -import org.mxchange.jcore.contact.Contact; -import org.mxchange.jcore.database.frontend.DatabaseFrontend; -import org.mxchange.jcore.exceptions.BadTokenException; -import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException; - -/** - * An interface for addressbook contact database frontends - * - * @author Roland Häder - */ -public interface AddressbookContactFrontend extends DatabaseFrontend { - - /** - * Adds given contact instance to database - * - * @param contact Contact instance to add - * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added - */ - public void addContact (final Contact contact) throws ContactAlreadyAddedException; - - /** - * Some "getter" for total contacts count - * - * @return Total contacts count - * @throws java.sql.SQLException If any SQL error occurs - */ - public int getContactsCount () throws SQLException; - - /** - * Checks if given Contact is found - * - * @param contact Contact instance to check - * @return Whether the given Contact instance is found - * @throws java.sql.SQLException If an SQL error occurs - * @throws java.io.IOException If an IO error occurs - * @throws org.mxchange.jcore.exceptions.BadTokenException Continued throw - * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged - * @throws java.lang.NoSuchMethodException If a method cannot be found - * @throws java.lang.IllegalAccessException If a method is not accessible - * @throws java.lang.reflect.InvocationTargetException Any other problems? - */ - public boolean isContactFound (final Contact contact) throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException; - - /** - * Some "getter" for own contact instance - * - * @return Own contact instance - */ - public Contact getOwnContact (); - - /** - * Checks whether own contact is found - * - * @return Whether own contact is found - * @throws java.sql.SQLException If any SQL error occurs - * @throws java.io.IOException If an IO error occurs - * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found - * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged - * @throws java.lang.NoSuchMethodException If a method cannot be found - * @throws java.lang.IllegalAccessException If a method is not accessible - * @throws java.lang.reflect.InvocationTargetException Any other problems? - */ - public boolean isOwnContactFound () throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException; - - /** - * Reads a single row and parses it to a contact instance - * - * @param rowIndex Row index (also how much to skip) - * @return Contact instance - */ - public Contact readSingleContact (final int rowIndex); -} diff --git a/Addressbook/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java b/Addressbook/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java deleted file mode 100644 index 634f4b4..0000000 --- a/Addressbook/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.exceptions; - -import java.text.MessageFormat; -import org.mxchange.jcore.contact.Contact; - -/** - * Thrown if the given Contact instance is already added - * - * @author Roland Haeder - */ -public class ContactAlreadyAddedException extends Exception { - - /** - * Constructor with a Contact instance - * - * @param contact Contact that is already added - */ - public ContactAlreadyAddedException (final Contact contact) { - super(MessageFormat.format("Contact with gender={0}, surname={1} and familyName={2} already added.", contact.getGender(), contact.getSurname(), contact.getFamilyName())); - } - - /** - * Default constructor, may be used if no contact instance is available - */ - public ContactAlreadyAddedException () { - super("Contact already added"); - } - -} diff --git a/Addressbook/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java b/Addressbook/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java deleted file mode 100644 index ef41687..0000000 --- a/Addressbook/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 columnNames; - - /** - * A AddressbookContactFrontend instance - */ - private final AddressbookContactFrontend contactDatabase; - - /** - * Translated column name list - */ - private final List 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 iterator = this.getBundle().keySet().iterator(); - - // Then iterate over all - while (iterator.hasNext()) { - // Get next element - String key = iterator.next(); - - // Does the key start with AddressbookContactManager.columnName ? - if (key.startsWith("ContactManager.columnName")) { //NOI18N - // This is the wanted entry. - this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N - - // Convert string to array based on delimiter '.' - String[] tokens = this.getArrayFromString(key, ".", 4); - - // Token array must contain 4 elements (AddressbookContactManager.columnName.foo.text) - assert(tokens.length == 4) : MessageFormat.format("Array tokens contains not 4 elements: {0}", Arrays.toString(tokens)); - - // Get pre-last element - String columnName = tokens[tokens.length - 2]; - - // Debug message - this.getLogger().debug(MessageFormat.format("columnName={0} - adding ...", columnName)); - - // So add it - this.columnNames.add(columnName); - this.translatedColumnNames.add(this.getBundle().getString(key)); - } - } - - // Debug message - this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N - } - - /** - * A AddressbookContactFrontend instance - * - * @return the database - */ - private AddressbookContactFrontend getContactDatabase () { - return this.contactDatabase; - } - - /** - * "Getter" for own contact instance or null if not found - * - * @return Contact instance or null - */ - private Contact getOwnContact () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Deligate this call to database frontend - Contact contact = this.getContactDatabase().getOwnContact(); - - // Trace message - this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N - - // Return instance or null - return contact; - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java b/Addressbook/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java deleted file mode 100644 index 77d39d3..0000000 --- a/Addressbook/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.manager.contact; - -import java.io.IOException; -import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException; -import org.mxchange.jcore.contact.Contact; -import org.mxchange.jcore.contact.Gender; -import org.mxchange.jcore.exceptions.BadTokenException; -import org.mxchange.jcore.manager.database.ManageableDatabase; - -/** - * - * @author Roland Haeder - */ -public interface ManageableAddressbookContact extends ManageableDatabase { - /** - * Allows the user to enter own cellphone number. - * - * @return Cellphone number - */ - public String enterOwnCellNumber (); - - /** - * Allows the user to enter own city name. - * - * @return City name - */ - public String enterOwnCity (); - - /** - * Allows the user to enter comment for own entry. - * - * @return Comment - */ - public String enterOwnComment (); - - /** - * Allows the user to enter own company name. - * - * @return Company name - */ - public String enterOwnCompanyName (); - - /** - * Allows the user to enter own country code. - * - * @return Country code - */ - public String enterOwnCountryCode (); - - /** - * Allows the user to enter own email address. - * - * @return Email address - */ - public String enterOwnEmailAddress (); - - /** - * Allows the user to enter own family name. - * - * @return Family name - */ - public String enterOwnFamilyName (); - - /** - * Allows the user to enter own fax number. - * - * @return Fax number - */ - public String enterOwnFaxNumber (); - - /** - * Allows the user to enter own gender. - * - * @return Gender - */ - public Gender enterOwnGender (); - - /** - * Allows the user to enter own phone number. - * - * @return Phone number - */ - public String enterOwnPhoneNumber (); - - /** - * Allows the user to enter own street and house number. - * - * @return Street and house number - */ - public String enterOwnStreet (); - - /** - * Allows the user to enter own surname. - * - * @return Surname - */ - public String enterOwnSurname (); - - /** - * Allows the user to enter own ZIP code. - * - * @return ZIP code - */ - public int enterOwnZipCode (); - - /** - * List all contacts - */ - public void doListContacts (); - - /** - * Adds given contact to address book - * - * @param contact Contact being added - * @todo Add check for book size - */ - public void registerContact (final Contact contact); - - /** - * Adds given Contact instance to list - * - * @param contact Contact instance to add - * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added - */ - public void addContact (final Contact contact) throws ContactAlreadyAddedException; - - /** - * Let the user add a new other address - */ - public void doAddOtherAddress (); - - /** - * The user can change address data, like street, ZIP code, city and country - * of given Contact instance. - * - * @param contact Instance to change data - */ - public void doChangeAddressData (final Contact contact); - - /** - * The user can change name data, like gender, surname, family name and - * company name (if business contact). - * - * @param contact Instance to change data - */ - public void doChangeNameData (final Contact contact); - - /** - * Let the user change other address - */ - public void doChangeOtherAddress (); - - /** - * The user can change other data, like phone numbers or comments. - * - * @param contact Instance to change data - */ - public void doChangeOtherData (final Contact contact); - - /** - * Let the user change own data - * @throws java.io.IOException If an IO error was found - * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found - */ - public void doChangeOwnData () throws IOException , BadTokenException; - - /** - * Let the user delete other address - */ - public void doDeleteOtherAddress (); - - /** - * Asks user for own data - * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If own contact is already added - * @throws java.io.IOException If an IO error was found - * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found - */ - public void doEnterOwnData () throws ContactAlreadyAddedException, IOException , BadTokenException; - - /** - * Searches address book for a contact - */ - public void doSearchContacts (); - - /** - * Checks whether own contact is already added by checking all entries for - * isOwnContact flag - * - * @return Whether own contact is already added - * @throws java.io.IOException If an IO error occurs - * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found - */ - public boolean isOwnContactAdded () throws IOException, BadTokenException; -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/AddressbookMenu.java b/Addressbook/src/org/mxchange/addressbook/menu/AddressbookMenu.java deleted file mode 100644 index 12257eb..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/AddressbookMenu.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 menuList, final String menuType, final Client client) { - // Get logger - Logger log = new AddressbookMenu().getLogger(); - - // Trace call - log.trace(MessageFormat.format("menuList={0},menuType={1},client={2} - CALLED!", menuList, menuType, client)); //NOI18N - - // Some instances must be set - if (menuList == null) { - // Abort here - throw new NullPointerException("menuList is null"); //NOI18N - } else if (client == null) { - // Abort here - throw new NullPointerException("contact is null"); //NOI18N - } else if (!(client instanceof AddressbookClient)) { - // Not correct instance - throw new IllegalArgumentException(MessageFormat.format("client{0} must implement AddressbookClient", client)); - } - - // Cast client to proper interface - AddressbookClient c = (AddressbookClient) client; - - // Get list size - int size = menuList.size(); - - // Debug message - log.debug(MessageFormat.format("Adding menu for '{0}' (old size: '{1}') ...", menuType, size)); //NOI18N - - // Depends on type - switch (menuType) { - case "main": // Main menu //NOI18N - // Enter own data - menuList.add(c.getMenuItem('1', "Eigene Adresse anlegen")); - - // Change own data - menuList.add(c.getMenuItem('2', "Eigene Adresse ändern")); - - // Add new addess - menuList.add(c.getMenuItem('3', "Neue Adresse hinzufügen")); - - // List entries - menuList.add(c.getMenuItem('4', "Adressbuch anzeigen")); - - // Address search - menuList.add(c.getMenuItem('5', "Adresse suchen")); - - // Change other address - menuList.add(c.getMenuItem('6', "Adresse ändern")); - - // Delete other address - menuList.add(c.getMenuItem('7', "Adresse löschen")); - - // Always last line: Exit program - menuList.add(c.getMenuItem('0', "Programm verlassen")); - break; - - default: // Not supported - log.error(MessageFormat.format("Menu type '{0}' ont supported", menuType)); //NOI18N - System.exit(1); - } - - // Size must have changed to more entries than before - assert (menuList.size() > size); - } - -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/BaseMenu.java b/Addressbook/src/org/mxchange/addressbook/menu/BaseMenu.java deleted file mode 100644 index f554820..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/BaseMenu.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 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 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 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 getMenuList () { - return this.menuList; - } - - /** - * Initializes menu - * - * @param menuType Menu type to initialize - * @param client CLient to call back - */ - protected void initMenu (final String menuType, final Client client) { - // Trace message - this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N - - // Init menu list - this.menuList = new ArrayList<>(5); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/Menu.java b/Addressbook/src/org/mxchange/addressbook/menu/Menu.java deleted file mode 100644 index 78a5fb1..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/Menu.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 getMenuItemsIterator (); - - /** - * Shows this menu - * - * @param client Client instance - */ - public void show (final Client client); - - /** - * Size of all menu items - * - * @return - */ - public int getMenuItemsCount (); -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/MenuTools.java b/Addressbook/src/org/mxchange/addressbook/menu/MenuTools.java deleted file mode 100644 index 30d8164..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/MenuTools.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -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 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 iterator = menu.getMenuItemsIterator(); - - // Init return array and counter 'i' - char[] accessKeys = new char[menu.getMenuItemsCount()]; - int i = 0; - - // Now "walk" through all menu entries - while (iterator.hasNext()) { - // Get item - SelectableMenuItem item = iterator.next(); - //* NOISY-DEBUG: */ logger.debug("item=" + item); - - // Get access key from item and add it to the array - accessKeys[i] = item.getAccessKey(); - //* NOISY-DEBUG: */ logger.debug("accessKeys[" + i + "]=" + accessKeys[i]); - - // Increment counter - i++; - } - - // Return finished array - return accessKeys; - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java b/Addressbook/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java deleted file mode 100644 index 965f68a..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.menu.console; - -import java.text.MessageFormat; -import org.mxchange.addressbook.menu.AddressbookMenu; -import org.mxchange.addressbook.menu.BaseMenu; -import org.mxchange.addressbook.menu.Menu; -import org.mxchange.jcore.client.Client; - -/** - * - * @author Roland Haeder - */ -public class ConsoleMenu extends BaseMenu implements Menu { - - /** - * Constructor for this menu - * - * @param menuType Menu type to initialize - * @param client CLient to call back - */ - public ConsoleMenu (final String menuType, final Client client) { - // Trace message - this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N - - // Client must not be null - if (client == null) { - // Abort here - throw new NullPointerException("client is null"); - } - - // Init menu - this.initMenu(menuType, client); - - // Add all items - AddressbookMenu.addItemsToList(this.getMenuList(), menuType, client); - } -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java b/Addressbook/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java deleted file mode 100644 index 4bb1cf9..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.menu.item; - -import org.mxchange.addressbook.BaseAddressbookSystem; - -/** - * - * @author Roland Haeder - */ -public class BaseMenuItem extends BaseAddressbookSystem { - -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java b/Addressbook/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java deleted file mode 100644 index a6de00a..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.menu.item; - -import org.mxchange.jcore.client.Client; - -/** - * - * @author Roland Haeder - */ -public interface SelectableMenuItem { - - /** - * Shows this menu item - * - * @param client Client instance - */ - public void show (final Client client); - - /** - * Access key - * - * @return the accessKey - */ - public char getAccessKey (); - - /** - * Text to user - * - * @return the text - */ - public String getText (); -} diff --git a/Addressbook/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java b/Addressbook/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java deleted file mode 100644 index 1090a63..0000000 --- a/Addressbook/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2015 Roland Haeder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.mxchange.addressbook.menu.item.console; - -import java.text.MessageFormat; -import org.mxchange.addressbook.client.AddressbookClient; -import org.mxchange.addressbook.menu.item.BaseMenuItem; -import org.mxchange.addressbook.menu.item.SelectableMenuItem; -import org.mxchange.jcore.client.Client; - -/** - * - * @author Roland Haeder - */ -public class ConsoleMenuItem extends BaseMenuItem implements SelectableMenuItem { - - /** - * Access key - */ - private char accessKey; - - /** - * Text to user - */ - private String text; - - /** - * Constructor for building a console menu with access key and text - * - * @param accessKey Access key for this menu entry - * @param text Text to show to user - */ - public ConsoleMenuItem (final char accessKey, final String text) { - this.setAccessKey(accessKey); - this.setText(text); - } - - /** - * Access key - * - * @return the accessKey - */ - @Override - public final char getAccessKey () { - return this.accessKey; - } - - /** - * Access key - * - * @param accessKey the accessKey to set - */ - private void setAccessKey (char accessKey) { - this.accessKey = accessKey; - } - - /** - * Text to user - * - * @return the text - */ - @Override - public String getText () { - return this.text; - } - - /** - * Text to user - * - * @param text the text to set - */ - private void setText (String text) { - this.text = text; - } - - @Override - public void show (final Client client) { - // Trace message - this.getLogger().trace(MessageFormat.format("client={0} - CALLED!", client)); //NOI18N - - // Client must not be null - if (client == null) { - // Abort here - throw new NullPointerException("client is null"); - } else if (!(client instanceof AddressbookClient)) { - // Wrong interface - throw new IllegalArgumentException("client " + client + " must implement AddressbookClient"); - } - - // Cast it - AddressbookClient c = (AddressbookClient) client; - - // Call-back client over menu - c.showEntry(this); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - -} diff --git a/Addressbook/src/org/mxchange/localization/bundle_de_DE.properties b/Addressbook/src/org/mxchange/localization/bundle_de_DE.properties deleted file mode 100644 index 19ee753..0000000 --- a/Addressbook/src/org/mxchange/localization/bundle_de_DE.properties +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (C) 2015 Roland Haeder -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -AddressbookFrame.border.name.title.text=Anrede, Vorname, Nachname: -AddressbookFrame.border.address.title.text=Anschrift: -AddressbookFrame.border.other.title.text=Andere Angaben: -AddressbookFrame.button.addAddress.text=Adresse hinzuf\u00fcgen -AddressbookFrame.button.cancel.text=Abbrechen -AddressbookFrame.menu.file.text=Datei -AddressbookFrame.menu.addressbook.text=Adressbuch -AddressbookFrame.statusLabel.initializing.text=Initialisiere ... -AddressbookFrame.statusLabel.done.text=Fertig. -AddressbookFrame.statusLabel.shutdown.text=Shuttting down ... -AddressbookFrame.menuItem.exitProgram.text=Programm beenden -AddressbookFrame.menuItem.exitProgram.toolTipText=Beendet das Programm und speichert alle Einstellungen ab. -AddressbookFrame.menuItem.addOwnData.text=Eigene Adresse hinzuf\u00fcgen -AddressbookFrame.menuItem.addOwnData.toolTipText=Erlaubt das Hinzuf\u00fcgen eigener Daten. -AddressbookFrame.menuItem.editOwnData.text=Eigene Adresse \u00e4ndern -AddressbookFrame.menuItem.editOwnData.toolTipText=Erlaubt das \u00c4ndern eigener Daten. -AddressbookFrame.menuItem.addNewContact.text=Neue Adresse hinzuf\u00fcgen -AddressbookFrame.menuItem.addNewContact.toolTipText=Eine neue Adresse hinzuf\u00fcgen. -AddressbookFrame.dialog.addContact.title.text=Neue Adresse hinzuf\u00fcgen -AddressbookFrame.main.title.text=Adressen auflisten -AddressbookFrame.gender.text=Anrede: -AddressbookFrame.gender.toolTipText=W\u00e4hlen Sie die Anrede aus. -AddressbookFrame.surname.text=Vorname: -AddressbookFrame.surname.toolTipText=Geben Sie den Vornamen ein. -AddressbookFrame.familyName.text=Nachname: -AddressbookFrame.familyName.toolTipText=Geben Sie den Nachnamen ein. -AddressbookFrame.street.text=Stra\u00dfe: -AddressbookFrame.street.toolTipText=Geben Sie die Stra\u00dfe ein. -AddressbookFrame.number.text=Hausnummer: -AddressbookFrame.number.toolTipText=Geben Sie die Hausnummer ein. -AddressbookFrame.zip.text=PLZ: -AddressbookFrame.zip.toolTipText=Geben Sie die Postleitzahl ein. -AddressbookFrame.city.text=Stadt: -AddressbookFrame.city.toolTipText=Geben Sie die Stadt ein. -AddressbookFrame.emailAddress.text=Email-Adresse: -AddressbookFrame.emailAddress.toolTipText=Geben Sie die Email-Adresse ein. -AddressbookFrame.phoneNumber.text=Telefon: -AddressbookFrame.phoneNumber.toolTipText=Geben Sie die Telefonnummer ein. -AddressbookFrame.cellphoneNumber.text=Mobil: -AddressbookFrame.cellphoneNumber.toolTipText=Geben Sie die Handynummer ein. -AddressbookFrame.faxNumber.text=Fax: -AddressbookFrame.faxNumber.toolTipText=Geben Sie die Faxnummer ein. -AddressbookFrame.comment.text=Anmerkungen: -AddressbookFrame.comment.toolTipText=Geben Sie eine Anmerkung (Freifeld) ein. -BaseContact.gender.unknown.text=Unbekannt -BaseContact.gender.male.text=Herr -BaseContact.gender.female.text=Frau -BaseContact.gender.company.text=Firma -ContactManager.columnName.gender.text=Anrede -ContactManager.columnName.surname.text=Vorname -ContactManager.columnName.familyName.text=Nachname -ContactManager.columnName.street.text=Strasse -ContactManager.columnName.houseNumber.text=Hausnummer -ContactManager.columnName.zipCode.text=Postleitzahl -ContactManager.columnName.city.text=Stadt diff --git a/Addressbook/src/org/mxchange/localization/bundle_en_US.properties b/Addressbook/src/org/mxchange/localization/bundle_en_US.properties deleted file mode 100644 index 5b2c4d2..0000000 --- a/Addressbook/src/org/mxchange/localization/bundle_en_US.properties +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (C) 2015 Roland Haeder -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -AddressbookFrame.border.name.title.text=Gender, surname, family name: -AddressbookFrame.border.address.title.text=Address: -AddressbookFrame.border.other.title.text=Other data: -AddressbookFrame.button.addAddress.text=Add address -AddressbookFrame.button.cancel.text=Cancel -AddressbookFrame.menu.file.text=File -AddressbookFrame.menu.addressbook.text=Addressbook -AddressbookFrame.statusLabel.initializing.text=Initializing ... -AddressbookFrame.statusLabel.done.text=Done. -AddressbookFrame.statusLabel.shutdown.text=Shuttting down ... -AddressbookFrame.menuItem.exitProgram.toolTipText=Exits the program and saves all data. -AddressbookFrame.menuItem.exitProgram.text=Exit program -AddressbookFrame.menuItem.addOwnData.text=Add own address -AddressbookFrame.menuItem.addOwnData.toolTipText=Allows the user to add own address data -AddressbookFrame.menuItem.editOwnData.text=Edit own data -AddressbookFrame.menuItem.editOwnData.toolTipText=Allows the user to edit own address data -AddressbookFrame.menuItem.addNewContact.text=Add new address -AddressbookFrame.menuItem.addNewContact.toolTipText=Add a new address. -AddressbookFrame.dialog.addContact.title.text=Add new address -AddressbookFrame.main.title.text=List addresses -AddressbookFrame.gender.text=Gender: -AddressbookFrame.gender.toolTipText=Choose gender. -AddressbookFrame.surname.text=Surname: -AddressbookFrame.surname.toolTipText=Enter surname. -AddressbookFrame.familyName.text=Family name: -AddressbookFrame.familyName.toolTipText=Enter family name. -AddressbookFrame.street.text=Street: -AddressbookFrame.street.toolTipText=Enter street. -AddressbookFrame.number.text=Number: -AddressbookFrame.number.toolTipText=Enter number. -AddressbookFrame.zip.text=ZIP: -AddressbookFrame.zip.toolTipText=Enter zip code. -AddressbookFrame.city.text=City: -AddressbookFrame.city.toolTipText=Enter city. -AddressbookFrame.emailAddress.text=Email address: -AddressbookFrame.emailAddress.toolTipText=Enter email address. -AddressbookFrame.phoneNumber.text=Phone: -AddressbookFrame.phoneNumber.toolTipText=Enter phone number. -AddressbookFrame.cellphoneNumber.text=Mobile: -AddressbookFrame.cellphoneNumber.toolTipText=Enter mobile number. -AddressbookFrame.faxNumber.text=Fax: -AddressbookFrame.faxNumber.toolTipText=Enter fax number. -AddressbookFrame.comment.text=Note: -AddressbookFrame.comment.toolTipText=Enter a note (free field). -BaseContact.gender.unknown.text=Unknown -BaseContact.gender.male.text=Mr. -BaseContact.gender.female.text=Mrs. -BaseContact.gender.company.text=Company -ContactManager.columnName.gender.text=Gender -ContactManager.columnName.surname.text=Surname -ContactManager.columnName.familyName.text=Family name -ContactManager.columnName.street.text=Street -ContactManager.columnName.houseNumber.text=House number -ContactManager.columnName.zipCode.text=ZIP code -ContactManager.columnName.city.text=City diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..20590e3 --- /dev/null +++ b/README.txt @@ -0,0 +1,30 @@ +How to launch: +============== + +1) Build it: (you need ant tools) +ant jar + +2) Go to dist folder and create "data": +cd dist +mkdir data + +3) Launch it +$ java -jar Addressbook.jar + +4) The GUI can also be launched: +$ java -jar Addressbook.jar -gui + +If you got an exception, maybe you bumbed into a stub method (unfinished). To reduce possibilities of +crashes try the usual approach: + +$ java -ea -jar Addressbook.jar -gui + +Please report any errors back to me. And yes, not all is finished. :) + +The file config.properties will be created on first run for you. After that you +can customize it. Supported database backends are: + +base64csv - The default backend, BASE64-encoded CSV strings +mysql - The unfinished MySQL backend + +Good luck! diff --git a/VERSIONS.txt b/VERSIONS.txt new file mode 100644 index 0000000..9d25667 --- /dev/null +++ b/VERSIONS.txt @@ -0,0 +1,85 @@ +============================================ +AddressbookApplication management: +============================================ + +Inernet("public" service) and Intranet + +Version 1.0+: +- Single-user local application +- Fields: + + Gender + + Surname + + Family name + + Company name + + Street + number + + ZIP code + + City + + Landline number + + Fax number + + Cell phone number + + Email address + + Birth day + + Comment (?) +- Edit own data +- Add new contact +- Edit contacts +- Delete contacts +- Categorization of contacts + +Version 1.1+: +- Permanent storage in database + +Version 2.0+: +- Multi-user web application +- Local user registration / login / resend confirmation link / password + recovery +- User groups (aka. teams) +- Administration area (user role) + + Create/edit/delete groups + + Edit/delete/lock/unlock user + + Assign user roles/rights +- Allow other users / groups to view addressbook + + Full addressbook + + Only some categories +- VCard export + + Allow users/guests (not recommended) +- XML export of addressbook and compressable (ZIP) +- Form to contact other user/group without need of mail program + + User can disabled this +- Directory for ussers/groups (who allowed to be listed) + + Simple click to add user to own addressbook + + Search form? + +Version 2.1+: +- Multi-language support + +Version 2.2+:("socialized") +- "Social login" (OpenID consumer) + + Connect user account to social account + + Sync own data? +- "Social profile" + + OpenID provider + + RSS/activity feed + +============================================ +Time esitmation: +============================================ +1.0 (console): + + 2 days + +1.1 (database): + + 2 day + + Initial tables: contacts, categories, contact_category + +2.0 (web): + + 3 days + + Additional tables: admins (?), admin_rights, groups, + users, user_contacts, user_user_rights, user_category_rights, + +2.1 (language) + + 1 day + + Additional tables: languages (disable, enable language "pack" ?) + +2.2 (social): + + 3 days + + Additional tables: ??? diff --git a/install/tables.sql b/install/tables.sql new file mode 100644 index 0000000..a08e1de --- /dev/null +++ b/install/tables.sql @@ -0,0 +1,42 @@ +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + + +DROP TABLE IF EXISTS `contacts`; +CREATE TABLE IF NOT EXISTS `contacts` ( +`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key', + `own_contact` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether own contact', + `gender` varchar(10) NOT NULL DEFAULT 'UNKNOWN' COMMENT 'Gender', + `surname` varchar(100) NOT NULL COMMENT 'Surname', + `family_name` varchar(100) NOT NULL COMMENT 'Family name', + `company_name` varchar(255) DEFAULT NULL COMMENT 'Company name', + `street` varchar(255) DEFAULT NULL COMMENT 'Street name', + `house_number` smallint(5) unsigned DEFAULT NULL COMMENT 'House number', + `city` varchar(100) DEFAULT NULL COMMENT 'City name', + `zip_code` smallint(5) unsigned DEFAULT NULL COMMENT 'ZIP code', + `country_code` char(2) DEFAULT NULL COMMENT 'Country code', + `phone_number` varchar(100) DEFAULT NULL COMMENT 'Phone number', + `cellphone_number` varchar(100) DEFAULT NULL COMMENT 'Cellphone number', + `fax_number` varchar(100) DEFAULT NULL COMMENT 'Fax number', + `email_address` varchar(100) DEFAULT NULL COMMENT 'Email addres', + `birthday` date DEFAULT NULL COMMENT 'Birth day', + `comment` tinytext NOT NULL COMMENT 'Comment', + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Entry created', + `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Contacts data' AUTO_INCREMENT=1 ; + + +ALTER TABLE `contacts` + ADD PRIMARY KEY (`id`); + + +ALTER TABLE `contacts` +MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key'; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/lib/jcore.jar b/lib/jcore.jar new file mode 100644 index 0000000..3593f27 Binary files /dev/null and b/lib/jcore.jar differ diff --git a/lib/log4j-api-2.3.jar b/lib/log4j-api-2.3.jar new file mode 100644 index 0000000..2a61bbe Binary files /dev/null and b/lib/log4j-api-2.3.jar differ diff --git a/lib/log4j-core-2.3.jar b/lib/log4j-core-2.3.jar new file mode 100644 index 0000000..5438b0b Binary files /dev/null and b/lib/log4j-core-2.3.jar differ diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..7a1b05a --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..5cab81f --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=39498655 +build.xml.script.CRC32=e7acbc61 +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=b3f3ee43 +nbproject/build-impl.xml.script.CRC32=96150614 +nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..d1a9fce --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,84 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Addressbook +application.vendor=Roland Haeder +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Addressbook.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.log4j-api-2.3.jar=lib/log4j-api-2.3.jar +file.reference.log4j-core-2.3.jar=lib/log4j-core-2.3.jar +file.reference.jcore.jar=./lib/jcore.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.log4j-api-2.3.jar}:\ + ${file.reference.log4j-core-2.3.jar}:\ + ${file.reference.jcore.jar} +# Space-separated list of extra javac options +javac.compilerargs=-Xlint:deprecation -Xlint:unchecked +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=org.mxchange.addressbook.application.AddressbookApplication +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.license=gpl30 +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs=-ea +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +source.reference.log4j-api-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-api-2.3-sources.jar +source.reference.log4j-core-2.3.jar=/home/quix0r/MyProjects/JARs/log4j-core-2.3-sources.jar +src.dir=src +test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..d95b345 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,24 @@ + + + org.netbeans.modules.java.j2seproject + + + Addressbook + + + + + + + + + + jar + + jar + clean + jar + + + + diff --git a/src/log4j2.xml b/src/log4j2.xml new file mode 100644 index 0000000..1ebbd9f --- /dev/null +++ b/src/log4j2.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/src/org/mxchange/addressbook/BaseAddressbookSystem.java b/src/org/mxchange/addressbook/BaseAddressbookSystem.java new file mode 100644 index 0000000..aa8c235 --- /dev/null +++ b/src/org/mxchange/addressbook/BaseAddressbookSystem.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook; + +import org.mxchange.jcore.BaseFrameworkSystem; + +/** + * General class for addressbook application + * + * @author Roland Haeder + */ +public class BaseAddressbookSystem extends BaseFrameworkSystem { + /** + * No instances can be created of this class + */ + protected BaseAddressbookSystem () { + } +} diff --git a/src/org/mxchange/addressbook/application/AddressbookApplication.java b/src/org/mxchange/addressbook/application/AddressbookApplication.java new file mode 100644 index 0000000..4be3359 --- /dev/null +++ b/src/org/mxchange/addressbook/application/AddressbookApplication.java @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.application; + +import java.io.IOException; +import java.sql.SQLException; +import java.text.MessageFormat; +import org.mxchange.addressbook.BaseAddressbookSystem; +import org.mxchange.addressbook.client.AddressbookClient; +import org.mxchange.addressbook.client.console.ConsoleClient; +import org.mxchange.addressbook.client.gui.SwingClient; +import org.mxchange.jcore.BaseFrameworkSystem; +import org.mxchange.jcore.application.Application; +import org.mxchange.jcore.client.Client; +import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; +import org.mxchange.jcore.manager.application.ApplicationManager; + +/** + * ============================================ + * AddressbookApplication management: + * ============================================ + * + * Inernet("public" service) and Intranet + * + * Version 1.0+: + * - Single-user local application + * - Fields: + * + Gender + * + Surname + * + Family name + * + Company name + * + Street + number + * + ZIP code + * + City + * + Landline number + * + Fax number + * + Cell phone number + * + Email address + * + Birth day + * + Comment (?) + * - Edit own data + * - Add new contact + * - Edit contacts + * - Delete contacts + * - Categorization of contacts + * + * Version 1.1+: + * - Permanent storage in database + * + * Version 2.0+: + * - Multi-user web application + * - Local user registration / login / resend confirmation link / password + * recovery + * - User groups (aka. teams) + * - Administration area (user role) + * + Create/edit/delete groups + * + Edit/delete/lock/unlock user + * + Assign user roles/rights + * - Allow other users / groups to view addressbook + * + Full addressbook + * + Only some categories + * - VCard export + * + Allow users/guests (not recommended) + * - XML export of addressbook and compressable (ZIP) + * - Form to contact other user/group without need of mail program + * + User can disabled this + * - Directory for ussers/groups (who allowed to be listed) + * + Simple click to add user to own addressbook + * + Search form? + * + * Version 2.1+: + * - Multi-language support + * + * Version 2.2+:("socialized") + * - "Social login" (OpenID consumer) + * + Connect user account to social account + * + Sync own data? + * - "Social profile" + * + OpenID provider + * + RSS/activity feed + * + * ============================================ + * Time esitmation: + * ============================================ + * 1.0 (console): + * + 2 days + * + * 1.1 (database): + * + 2 day + * + Initial tables: contacts, categories, contact_category + * + * 2.0 (web): + * + 3 days + * + Additional tables: admins (?), admin_rights, groups, + * users, user_contacts, user_user_rights, user_category_rights, + * + * 2.1 (language) + * + 1 day + * + Additional tables: languages (disable, enable language "pack" ?) + * + * 2.2 (social): + * + 3 days + * + Additional tables: ??? +* + * @author Roland Haeder + * @version 0.0 + */ +public class AddressbookApplication extends BaseAddressbookSystem implements Application { + + /** + * Application title + */ + public static final String APP_TITLE = "Adressbuch"; //NOI18N + + /** + * Application version + */ + public static final String APP_VERSION = "0.0"; //NOI18N + + /** + * Console client is enabled by default + */ + private boolean consoleClient = true; + + /** + * GUI client is disabled by default + */ + private boolean guiClient = false; + + /** + * Protected constructor + * @throws java.io.IOException If any IO error occurs + */ + protected AddressbookApplication () throws IOException { + // Init properties file + this.initProperties(); + + // Init bundle + this.initBundle(); + } + + /** + * Bootstraps application + */ + @Override + public void doBootstrap () { + this.getLogger().debug("Initializing application ..."); //NOI18N + + // Init client variable + Client client = null; + + // Is console or Swing choosen? + if (this.isConsole()) { + // Debug message + this.getLogger().debug("Initializing console client ..."); //NOI18N + + // Init console client instance + client = new ConsoleClient(this); + } else if (this.isGui()) { + // Debug message + this.getLogger().debug("Initializing GUI (Swing) client ..."); //NOI18N + + // Init console instance + client = new SwingClient(this); + } else { + // Not client choosen + this.getLogger().error("No client choosen. Cannot launch."); //NOI18N + System.exit(1); + } + + // Init client + client.init(); + + // Set client instance + this.setClient(client); + + // The application is running at this point + this.getClient().enableIsRunning(); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Main loop of the application + */ + @Override + public void doMainLoop () { + // Get client and cast it + AddressbookClient client = (AddressbookClient) this.getClient(); + + // Debug message + this.getLogger().trace("CALLED!"); //NOI18N + + // @TODO The application should be running now + // Output introduction + this.showIntro(); + + // Set current menu to main + client.setCurrentMenu("main"); //NOI18N + + // --- Main loop starts here --- + while (this.getClient().isRunning()) { + // The application is still active, show menu selection + client.showCurrentMenu(); + + try { + // Ask for user input and run proper method + client.doUserMenuChoice(); + } catch (final UnhandledUserChoiceException ex) { + this.getLogger().catching(ex); + } + + try { + // Sleep a little to reduce system load + Thread.sleep(100); + } catch (final InterruptedException ex) { + // Ignore it + } + } + // --- Main loop ends here --- + + // Debug message + this.getLogger().debug("Main loop exit - shutting down ..."); //NOI18N + } + + /** + * Shuts down the application. + */ + @Override + public void doShutdown () throws SQLException, IOException { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Shutdown client + this.getClient().doShutdown(); + + this.getLogger().info("End of program (last line)"); //NOI18N + System.exit(0); + } + + /** + * Enables console client by setting propper flag + */ + private void enableConsoleClient () { + this.getLogger().debug("Enabling console client (may become optional client) ..."); //NOI18N + this.consoleClient = true; + this.guiClient = false; + } + + /** + * Enables GUI client by setting propper flag + */ + private void enableGuiClient () { + this.getLogger().debug("Enabling GUI client (may become new default client) ..."); //NOI18N + this.consoleClient = false; + this.guiClient = true; + } + + /** + * Checks whether the client shoule be console client should be launched by + * checking if -console is set. + * + * @return Whether console client should be taken + */ + private boolean isConsole () { + return this.consoleClient; + } + + /** + * Checks whether the client shoule be GUI client should be launched by + * checking if -gui is set. + * + * @return Whether GUI client should be taken + */ + private boolean isGui () { + return this.guiClient; + } + + /** + * Parses all given arguments + * + * @param args Arguments from program launch + */ + private void parseArguments (final String[] args) { + // Trace message + this.getLogger().trace(MessageFormat.format("args()={0} - CALLED!", args.length)); //NOI18N + + // Debug message + this.getLogger().debug(MessageFormat.format("Parsing {0} arguments ...", args.length)); //NOI18N + + for (final String arg : args) { + // Switch on it + switch (arg) { + case "-console": //NOI18N + enableConsoleClient(); + break; + + case "-gui": //NOI18N + enableGuiClient(); + break; + } + } + } + + /** + * Show introduction which depends on client + */ + private void showIntro () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Let the client show it + this.getClient().showWelcome(); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Launches the application + * + * @param args Arguments handled to program + */ + private void start (final String args[]) { + this.getLogger().info("Program is started."); //NOI18N + try { + // Init properties file + this.initProperties(); + } catch (final IOException ex) { + // Something bad happened + this.abortProgramWithException(ex); + } + + // Parse arguments + this.parseArguments(args); + + // Launch application + ApplicationManager.getManager(this).start(); + + // Good bye, but this should not be reached ... + this.getLogger().warn("Unusual exit reached."); //NOI18N + try { + this.doShutdown(); + } catch (final SQLException | IOException ex) { + this.abortProgramWithException(ex); + } + } + + /** + * Main method (entry point) + * + * @param args the command line arguments + */ + public static void main (String[] args) { + try { + // Start application + new AddressbookApplication().start(args); + } catch (final IOException ex) { + // Get instance + BaseFrameworkSystem.getInstance().getLogger().catching(ex); + System.exit(1); + } + } + + /** + * Getter for printable application name + * + * @return A printable name + */ + public static String printableTitle () { + return MessageFormat.format("{0} v{1}", APP_TITLE, APP_VERSION); //NOI18N + } +} diff --git a/src/org/mxchange/addressbook/client/AddressbookClient.java b/src/org/mxchange/addressbook/client/AddressbookClient.java new file mode 100644 index 0000000..dde3c17 --- /dev/null +++ b/src/org/mxchange/addressbook/client/AddressbookClient.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.client; + +import org.mxchange.addressbook.menu.item.SelectableMenuItem; +import org.mxchange.jcore.client.Client; +import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.contact.Gender; +import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; + +/** + * A special client interface for addressbook applications. + * + * @author Roland Haeder + */ +public interface AddressbookClient extends Client { + + /** + * The user changes own name data + * + * @param contact + */ + public void doChangeOwnNameData (final Contact contact); + + /** + * The user changes own address data + * + * @param contact Contact instance to change + */ + public void doChangeOwnAddressData (final Contact contact); + + /** + * The user changes own other data + * + * @param contact Constact instance to change + */ + public void doChangeOwnOtherData (final Contact contact); + + /** + * Allows the user to enter own data + * + * @return Finished Contact instance + */ + public Contact doEnterOwnData (); + + /** + * Asks the user to enter his/her gender (M=Male, F=Female, C=Company) + * + * @param message Message to output + * @return Gender enum + */ + public Gender enterGender (final String message); + + /** + * Let the user choose what to change on the address: [n]ame, [a]ddress, + * [o]ther + * + * @param contact Contact instance to let the user change data + * @throws UnhandledUserChoiceException If choice is not supported + */ + public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException; + + /** + * Asks the user for a choice and proceeds accordingly + * + * @throws UnhandledUserChoiceException If choice is not supported + */ + public void doUserMenuChoice () throws UnhandledUserChoiceException; + + /** + * Asks the the user to enter a single character which must match validChars + * + * @param validChars Valid chars that are accepted + * @param message Message to user + * @return Allowed character + */ + public char enterChar (final char[] validChars, final String message); + + /** + * Reads a string of minimum and maximum length from the user. An empty + * string should be generally not allowed, but might be okay for e.g. + * company name. + * + * @param minLength Minimum length of the string to read + * @param maxLength Maximum length of the string to read + * @param message Message to user + * @param allowEmpty Whether empty strings are allowed + * @return Entered string by user or null if empty string is allowed + */ + public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty); + + /** + * Reads an integer (int) from the user + * + * @param minimum Minimum allowed number + * @param maximum Maximum allowed number + * @param message Message to user + * @return Entered string by user or null if empty string is allowed + */ + public int enterInt (final int minimum, final int maximum, final String message); + + /** + * Setter for current menu choice + * + * @param currentMenu Current menu choice + */ + public void setCurrentMenu (final String currentMenu); + + /** + * Some "Getter" for menu item + * + * @param accessKey Key to press to access this menu + * @param text Text to show to user + * @return + */ + public SelectableMenuItem getMenuItem (final char accessKey, final String text); + + /** + * Shows given menu entry in client + * + * @param item Menu item to show + */ + public void showEntry (final SelectableMenuItem item); + + /** + * Shows current menu selection to the user + */ + public void showCurrentMenu (); +} diff --git a/src/org/mxchange/addressbook/client/BaseAddressbookClient.java b/src/org/mxchange/addressbook/client/BaseAddressbookClient.java new file mode 100644 index 0000000..2f2e2aa --- /dev/null +++ b/src/org/mxchange/addressbook/client/BaseAddressbookClient.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 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 getMenus () { + return this.menus; + } + + /** + * Initializes contact manager + * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the database backend is not supported + * @throws java.sql.SQLException If any SQL error occurs + */ + protected void initContactManager () throws UnsupportedDatabaseBackendException, SQLException { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Debug message + this.getLogger().debug("Initializing contact manager ..."); //NOI18N + + // Init contact manager with console client + // @TODO Static initial amount of contacts + ManageableDatabase manager = new AddressbookContactManager((Client) this); + + // Set it here + this.setContactManager(manager); + + // Debug message + this.getLogger().debug("Contact manager has been initialized."); //NOI18N + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Shows given menu + * + * @param menuType Given menu to show + */ + protected void showMenu (final String menuType) { + // Trace message + this.getLogger().trace(MessageFormat.format("menuType={0} - CALLED!", menuType)); //NOI18N + + Menu menu = this.getMenu(menuType); + + // Is the menu set? + if (!(menu instanceof Menu)) { + // Not found + // @todo Own exception? + throw new NullPointerException(MessageFormat.format("Menu '{0}' not found.", menuType)); //NOI18N + } + + // Show menu + menu.show(this); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } +} diff --git a/src/org/mxchange/addressbook/client/console/ConsoleClient.java b/src/org/mxchange/addressbook/client/console/ConsoleClient.java new file mode 100644 index 0000000..6ed15fb --- /dev/null +++ b/src/org/mxchange/addressbook/client/console/ConsoleClient.java @@ -0,0 +1,753 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.client.console; + +import java.io.IOException; +import java.sql.SQLException; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Scanner; +import org.mxchange.addressbook.application.AddressbookApplication; +import org.mxchange.addressbook.client.AddressbookClient; +import org.mxchange.addressbook.client.BaseAddressbookClient; +import org.mxchange.addressbook.contact.user.UserContact; +import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException; +import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact; +import org.mxchange.addressbook.menu.Menu; +import org.mxchange.addressbook.menu.MenuTools; +import org.mxchange.addressbook.menu.console.ConsoleMenu; +import org.mxchange.addressbook.menu.item.SelectableMenuItem; +import org.mxchange.addressbook.menu.item.console.ConsoleMenuItem; +import org.mxchange.jcore.application.Application; +import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.contact.Gender; +import org.mxchange.jcore.exceptions.BadTokenException; +import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; +import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; + +/** + * A client for the console + * + * @author Roland Haeder + */ +public class ConsoleClient extends BaseAddressbookClient implements AddressbookClient { + + /** + * Scanner instance for reading data from console input + */ + private final Scanner scanner; + + /** + * Parameterless constructor + * + * @param application An instance of an Application class + */ + public ConsoleClient (final Application application) { + // Trace message + this.getLogger().trace(MessageFormat.format("application={0} - CALLED!", application)); //NOI18N + + // Set application instance + this.setApplication(application); + + // Init scanner instance + this.scanner = new Scanner(System.in, "UTF-8"); //NOI18N + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Displays a textual address "box" of given contact + * + * @param contact Contact to show address for + */ + @Override + public void displayAddressBox (final Contact contact) { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Simple display ... + this.outputMessage(MessageFormat.format("Strasse, PLZ Ort, Land: {0}\n{1} {2}\n{3}", contact.getStreet(), contact.getZipCode(), contact.getCity(), contact.getCountryCode())); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Displays a textual name "box" of given contact + * + * @param contact Contact to show name for + */ + @Override + public void displayNameBox (final Contact contact) { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Get translated gender as the user may want to see "Mr.", "Mrs." + String gender = contact.getTranslatedGender(); + + // Get company name + String companyName = contact.getCompanyName(); + + // If it is empty/null, then assume private contact + if ((companyName == null) || (companyName.isEmpty())) { + // Now put all together: gender, surname, family name + // @todo Use mask + this.outputMessage(MessageFormat.format("Anrede, Vorname, Name: {0} {1} {2}", gender, contact.getSurname(), contact.getFamilyName())); + } else { + // Company contact + this.outputMessage(MessageFormat.format("Firma: {0}\nAnsprechpartner: {1} {2} {3}", companyName, gender, contact.getSurname(), contact.getFamilyName())); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Displays a textual other data "box" of given contact + * + * @param contact Contact to show other data for + */ + @Override + public void displayOtherDataBox (final Contact contact) { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Cellphone and such ... + this.outputMessage(MessageFormat.format("Telefonnumer: {0}\nFaxnummer: {1}\nHandy: {2}\nKommentar:\n{3}", contact.getPhoneNumber(), contact.getFaxNumber(), contact.getCellphoneNumber(), contact.getComment())); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void doChangeOwnAddressData (final Contact contact) { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Make sure it is own contact + if (!contact.isOwnContact()) { + // Not own contact + throw new IllegalArgumentException("Contact is not own data."); //NOI18N + } + + // Get manager and cast it + ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); + + // Own street and number + String streetNumber = manager.enterOwnStreet(); + + // Get zip code + Long zipCode = (long) manager.enterOwnZipCode(); + + // Get city name + String city = manager.enterOwnCity(); + + // Get country code + String countryCode = manager.enterOwnCountryCode(); + + // Update address data + contact.setStreet(streetNumber); + contact.setZipCode(zipCode); + contact.setCity(city); + contact.setCountryCode(countryCode); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void doChangeOwnNameData (final Contact contact) { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Make sure it is own contact + if (!contact.isOwnContact()) { + // Not own contact + throw new IllegalArgumentException("Contact is not own data."); //NOI18N + } + + // Get manager and cast it + ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); + + // Gender: + Gender gender = manager.enterOwnGender(); + + // Surname + String surname = manager.enterOwnSurname(); + + // Family name + String familyName = manager.enterOwnFamilyName(); + + // And company + String companyName = manager.enterOwnCompanyName(); + + // Update contact instance + contact.setGender(gender); + contact.setSurname(surname); + contact.setFamilyName(familyName); + contact.setCompanyName(companyName); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void doChangeOwnOtherData (final Contact contact) { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Make sure it is own contact + if (!contact.isOwnContact()) { + // Not own contact + throw new IllegalArgumentException("Contact is not own data."); //NOI18N + } + + // Get manager and cast it + ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); + + // Phone number + String phoneNumber = manager.enterOwnPhoneNumber(); + + // Phone number + String cellphonePhoneNumber = manager.enterOwnCellNumber(); + + // Fax number + String faxNumber = manager.enterOwnFaxNumber(); + + // Email address + String email = manager.enterOwnEmailAddress(); + + // Comment + String comment = manager.enterOwnComment(); + + // Update contact instance + contact.setPhoneNumber(phoneNumber); + contact.setCellphoneNumber(cellphonePhoneNumber); + contact.setFaxNumber(faxNumber); + contact.setEmailAddress(email); + contact.setComment(comment); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public Contact doEnterOwnData () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Get manager and cast it + ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); + + // First ask for gender + Gender gender = manager.enterOwnGender(); + + // 2nd for surname + String surname = manager.enterOwnSurname(); + + // And 3rd for family name + String familyName = manager.enterOwnFamilyName(); + + // Company name ... + String companyName = manager.enterOwnCompanyName(); + + // Construct UserContact instance + Contact contact = new UserContact(gender, surname, familyName, companyName); + + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N + + // And return object + return contact; + } + + /** + * Shutdown this client + */ + @Override + public void doShutdown () throws SQLException, IOException { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Parent call + super.doShutdown(); + + // @TODO Add other shutdown stuff + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void doUserMenuChoice () throws UnhandledUserChoiceException { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Get all access keys from menu + char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.getMenus(), this.getCurrentMenu()); + + // Output textural message and ask for a char as input + char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Programm beenden): "); + + // Get manager and cast it + ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); + + // Try it! + try { + // @TODO Rewrite this ugly switch() block + switch (choice) { + case '1': + try { + // Enter/add own data + manager.doEnterOwnData(); + } catch (final ContactAlreadyAddedException ex) { + // Already added + this.outputMessage("Sie haben bereits Ihre eigenen Daten eingegeben."); + } + break; + + case '2': // Change own data + manager.doChangeOwnData(); + break; + + case '3': // Add new addess + manager.doAddOtherAddress(); + break; + + case '4': // List contacts + manager.doListContacts(); + break; + + case '5': // Search addresses + manager.doSearchContacts(); + break; + + case '6': // Change other addess + manager.doChangeOtherAddress(); + break; + + case '7': // Delete other address + manager.doDeleteOtherAddress(); + break; + + case '0': { + try { + // Program exit + this.getApplication().doShutdown(); + } catch (final SQLException | IOException ex) { + this.abortProgramWithException(ex); + } + } + break; + + default: + // @TODO throw own exception + throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N + } + } catch (final IOException | BadTokenException ex) { + // Something bad happened + this.abortProgramWithException(ex); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Asks the the user to enter a single character which must match validChars + * + * @param validChars Valid chars that are accepted + * @param message Message to user + * @return Allowed character + */ + @Override + public char enterChar (final char[] validChars, final String message) { + // Trace message + this.getLogger().trace(MessageFormat.format("validChars={0},message={1} - CALLED!", Arrays.toString(validChars), message)); //NOI18N + + // The validChars must not null be null and filled with at least one char + if (validChars == null) { + // Is null + throw new NullPointerException("validChars is null"); //NOI18N + } else if (validChars.length == 0) { + // Is not filled + throw new IllegalArgumentException("validChars is not filled."); //NOI18N + } + + char input = 0; + + // Sort array, else binarySearch() won't work + Arrays.sort(validChars); + + // Keep asking until valid char has been entered + while (Arrays.binarySearch(validChars, input) < 0) { + // Output message + System.out.print(message); + + // Read char + input = this.readChar(); + } + + // Trace message + this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N + + // Return read char + return input; + } + + /** + * Asks the user to enter his/her gender + * + * @param message Message to the user + * @return Gender enum + */ + @Override + public Gender enterGender (final String message) { + // Trace message + this.getLogger().trace(MessageFormat.format("message={0} - CALLED!", message)); //NOI18N + + // Get valid chars + char[] validChars = Gender.validChars(); + + // Debug message + //* NOISY-DEBUG: */ System.out.println(validChars); + // Call inner method + char gender = this.enterChar(validChars, message); + + // Now get a Gender instance back + Gender g = Gender.fromChar(gender); + + // g must not be null + assert(g instanceof Gender) : "g is not set."; //NOI18N + + // Trace message + this.getLogger().trace(MessageFormat.format("g={0} - EXIT!", g)); //NOI18N + + // Return it + return g; + } + + /** + * Reads an integer (int) with a textural message from the user + * + * @param minimum Minimum allowed number + * @param maximum Maximum allowed number + * @param message Messager to display in console + * @return + */ + @Override + public int enterInt (final int minimum, final int maximum, final String message) { + // Trace message + this.getLogger().trace(MessageFormat.format("minimum={0},maximum={1},message={2} - CALLED!", minimum, maximum, message)); //NOI18N + + // Minimum should not be below zero + assert (minimum >= 0); + assert (maximum > minimum); + + // Init input + int input = -1; + + while ((input < minimum) || (input > maximum)) { + // Output message + System.out.print(message); + + // Read integer from user + input = this.readInt(); + } + + // Trace message + this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N + + // Return it + return input; + } + + /** + * Reads a string of minimum and maximum length from the user + * + * @param minLength Minimum length of the string to read + * @param maxLength Maximum length of the string to read + * @param message Message to user + * @param allowEmpty Whether to allow empty string + * @return Entered string by user or null for empty strings + */ + @Override + public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) { + // Trace message + this.getLogger().trace(MessageFormat.format("minLength={0},maxLength={1},message={2}allowEmpty={3} - CALLED!", minLength, maxLength, message, allowEmpty)); //NOI18N + + // Check on length, e.g. country codes are excactly 2 chars long + assert (maxLength >= minLength); + + // Init input + String input = null; + + // Check if it is to short or to long + while (((input == null) || ((input.length() < minLength) && (!allowEmpty))) || ((input.length() > 0) && (input.length() < minLength) && (allowEmpty)) || ((input instanceof String) && (input.length() > maxLength))) { + // Output message + System.out.print(message); + + // Read line + input = this.readString(); + } + + // Trace message + this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N + + // Return it + return input; + } + + /** + * Returns a console menu item + * + * @param accessKey Key to access the menu + * @param text Text to show to user + * @return A SelectableMenuItem + * @todo Make sure the access key is unique + */ + @Override + public SelectableMenuItem getMenuItem (final char accessKey, final String text) { + // Return a new console menu item + return new ConsoleMenuItem(accessKey, text); + } + + /** + * Initializes this client + */ + @Override + public void init () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Init contact manager here + try { + this.initContactManager(); + } catch (final UnsupportedDatabaseBackendException | SQLException ex) { + // End here + this.abortProgramWithException(ex); + } + + // Fill menu map + this.fillMenuMap(); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Displays textural message to the user + * + * @param message + */ + @Override + public void outputMessage (final String message) { + System.out.println(message); + } + + /** + * Shows textural menu on console + */ + @Override + public void showCurrentMenu () { + this.showMenu(this.getCurrentMenu()); + } + + /** + * Shows given menu entry to user + * + * @param item Menu entry + */ + @Override + public void showEntry (final SelectableMenuItem item) { + // Access key then text + this.outputMessage(MessageFormat.format("[{0}] {1}", item.getAccessKey(), item.getText())); + } + + /** + * Shows a textural message to the user + */ + @Override + public void showWelcome () { + this.outputMessage(MessageFormat.format("Welcome to {0}", AddressbookApplication.printableTitle())); + this.outputMessage(""); + this.outputMessage("Copyright(c) 2015 by Roland Haeder, this is free software"); + + // Debug message + this.getLogger().debug("Intro shown to user"); //NOI18N + } + + @Override + public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException { + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N + + // Contact must not be null + if (contact == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Ask the user for editing [name], [a]ddress or [other] data + char choice = this.enterChar(new char[] {'n', 'a', 'o', 'x'}, "Welchen Daten möchten Sie ändern? (n=Namensdaten, a=Anschriftsdaten, o=Andere, x=Zurück zur Hauptauswahl) "); + + // Get manager and cast it + ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getManager(); + + // @TODO Get rid of this ugly switch block, too + switch (choice) { + case 'n': // Name data + manager.doChangeNameData(contact); + break; + + case 'a': // Address data + manager.doChangeAddressData(contact); + break; + + case 'o': // Other data + manager.doChangeOtherData(contact); + break; + + case 'x': // Exit this menu + // Ignored as it should go back + break; + + default: + // @TODO throw own exception + throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Reads one character + * + * @return A single character + */ + private char readChar () { + // Read line + String input = this.readString(); + + // Debug message + this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N + + // This must be only one character + if (input.length() != 1) { + // Return zero + return 0; + } + + // Get char from first (and only) position + return input.charAt(0); + } + + /** + * Reads an integer (int) from user + * + * @return An integer number + */ + private int readInt () { + // First read a string + String input = this.readString(); + + // Debug message + this.getLogger().debug(MessageFormat.format("input={0}", input)); //NOI18N + + // Init number with invalid value + int num = -1; + + // Parse number, this can be risky + try { + num = Integer.parseInt(input); + } catch (final NumberFormatException e) { + this.outputMessage("Bitte geben Sie nur Zahlen ein!"); + this.getLogger().warn(MessageFormat.format("No numbers-only entered. input={0},message={1}", input, e.getMessage())); //NOI18N + } + + // Trace message + this.getLogger().trace(MessageFormat.format("num={0} - EXIT!", num)); //NOI18N + + // Return read number + return num; + } + + /** + * Reads a string from a scanner until RETURN is pressed + * + * @return Read string from scanner + */ + private String readString () { + return this.scanner.nextLine(); + } + + /** + * Fills menu map with menu entries + */ + @Override + protected final void fillMenuMap () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Initialize first (main) menu + Menu menu = new ConsoleMenu("main", this); //NOI18N + + // Add it + this.getMenus().put("main", menu); //NOI18N + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } +} diff --git a/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java b/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java new file mode 100644 index 0000000..4bdb6e9 --- /dev/null +++ b/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java @@ -0,0 +1,1002 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 = new JComboBox<>(new DefaultComboBoxModel<>(genders)); + gender.setToolTipText(this.getBundle().getString("AddressbookFrame.gender.toolTipText")); + + // Add both to gender panel + namePanel.add(gLabel); + namePanel.add(gender); + + // Add text field for surname + this.addTextFieldWithLabelToPanel(namePanel, "surname", 20); //NOI18N + + // Add text field for family name + this.addTextFieldWithLabelToPanel(namePanel, "familyName", 20); //NOI18N + + // Finally add panel to dialog + dialog.add(namePanel); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Initializes "other" data panel + * + * @param dialog A JDialog instance to this components to + * @todo Fill this with life + */ + private void initOtherDataPanel (final JDialog dialog) { + // Trace message + this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N + + // Panel "other" input boxes + JPanel otherPanel = new JPanel(); + otherPanel.setLayout(new GridLayout(0, 2, 3, 3)); + otherPanel.setBorder(new TitledBorder(this.generateBorderTitle("other"))); //NOI18N + + // Add text field for email address + this.addTextFieldWithLabelToPanel(otherPanel, "emailAddress", 20); //NOI18N + + // Add text field for phone number + this.addTextFieldWithLabelToPanel(otherPanel, "phoneNumber", 20); //NOI18N + + // Add text field for cellphone number + this.addTextFieldWithLabelToPanel(otherPanel, "cellphoneNumber", 20); //NOI18N + + // Add text field for fax number + this.addTextFieldWithLabelToPanel(otherPanel, "faxNumber", 20); //NOI18N + + // Init label + JLabel commentLabel = new JLabel(this.getBundle().getString("AddressbookFrame.comment.text")); + + // Init text area with tool tip + JTextArea comment = new JTextArea(5, 20); + comment.setToolTipText(this.getBundle().getString("AddressbookFrame.comment.toolTipText")); + + // Add both to panel + otherPanel.add(commentLabel); + otherPanel.add(comment); + + // Finally add panel to dialog + dialog.add(otherPanel); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Initialize other dialogs (e.g. "Add contact") + */ + private void initOtherDialogs () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Init other windows: + // 1) Add contact + initAddContactDialog(); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Initializes status panel + */ + private void initStatusPanel () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Init status label (which needs to be updated + this.statusLabel = new JLabel(); + this.updateStatus("initializing"); //NOI18N + + // Init status bar in south + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); + panel.add(this.statusLabel); + panel.setBorder(BorderFactory.createEtchedBorder()); + + // Add panel to frame + this.frame.add(panel, BorderLayout.SOUTH); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Initializes the table which will show all contacts + */ + private void initTable () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Instance table model + this.dataModel = new ContactTableModel(this.getClient()); + + // Instance table + this.dataTable = new JTable(this.dataModel); + + // Add mouse listener + this.dataTable.addMouseListener(new MouseAdapter() { + /** + * If the user peformed a click on a cell + * + * @param e Mouse event instance + */ + @Override + public void mouseClicked (final MouseEvent e) { + throw new UnsupportedOperationException("Unfinished."); //NOI18N + } + }); + + // Instance scroll pane + JScrollPane scroller = new JScrollPane(); + + // Add table to scroll pane + scroller.setViewportView(this.dataTable); + scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + // Add pane to frame + this.frame.add(scroller, BorderLayout.CENTER); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Updates status to given type + * + * @param type Status type + */ + private void updateStatus (final String type) { + // Trace message + this.getLogger().trace(MessageFormat.format("type={0} - CALLED!", type)); //NOI18N + + // Set status message + this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type))); //NOI18N + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Class for "add address" button + */ + private static class AddActionListener extends BaseAddressbookSystem implements ActionListener { + /** + * Dialog instance + */ + private final JDialog dialog; + + /** + * Frame (not JFrame) instance + */ + private final ClientFrame frame; + + /** + * Constructor for action listener + * + * @param dialog Dialog instance to call back + * @param frame Frame instance (not JFrame) + */ + protected AddActionListener (final JDialog dialog, final ClientFrame frame) { + // Set dialog and frame here + this.dialog = dialog; + this.frame = frame; + } + + /** + * If the action has been performed + * + * @param e The performed action event + */ + @Override + public void actionPerformed (final ActionEvent e) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + } + + /** + * Class for "cancel address" button + */ + private static class CancelActionListener extends BaseAddressbookSystem implements ActionListener { + /** + * Dialog instance + */ + private final JDialog dialog; + + /** + * Frame (not JFrame) instance + */ + private final ClientFrame frame; + + /** + * Constructor for action listener + * + * @param dialog Dialog instance to call back + * @param frame Frame instance (not JFrame) + */ + protected CancelActionListener (final JDialog dialog, final ClientFrame frame) { + // Set dialog and frame here + this.dialog = dialog; + this.frame = frame; + } + + /** + * If the action has been performed + * + * @param e The performed action event + */ + @Override + public void actionPerformed (final ActionEvent e) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + } +} diff --git a/src/org/mxchange/addressbook/client/gui/SwingClient.java b/src/org/mxchange/addressbook/client/gui/SwingClient.java new file mode 100644 index 0000000..4c7cb13 --- /dev/null +++ b/src/org/mxchange/addressbook/client/gui/SwingClient.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.client.gui; + +import java.io.IOException; +import java.sql.SQLException; +import org.mxchange.addressbook.client.AddressbookClient; +import org.mxchange.addressbook.client.BaseAddressbookClient; +import org.mxchange.addressbook.menu.Menu; +import org.mxchange.addressbook.menu.item.SelectableMenuItem; +import org.mxchange.jcore.application.Application; +import org.mxchange.jcore.client.gui.ClientFrame; +import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.contact.Gender; +import org.mxchange.jcore.exceptions.BadTokenException; +import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException; +import org.mxchange.jcore.exceptions.UnhandledUserChoiceException; +import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; + +/** + * + * @author Roland Haeder + */ +public class SwingClient extends BaseAddressbookClient implements AddressbookClient { + + /** + * Swing frame instance + */ + private final ClientFrame frame; + + /** + * Constructor with an Application instance. + * + * @param application Application instance + */ + public SwingClient (final Application application) { + // Debug message + this.getLogger().trace("CALLED!"); //NOI18N + + // Set application instance + this.setApplication(application); + + // Init frame instance + this.frame = AddressbookFrame.getSelfInstance(this); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void displayAddressBox (final Contact contact) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void displayNameBox (final Contact contact) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void displayOtherDataBox (final Contact contact) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void doChangeOwnAddressData (Contact contact) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void doChangeOwnNameData (Contact contact) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void doChangeOwnOtherData (Contact contact) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + /** + * Shows dialog to enter new contact + * + * @return Returns finished Contact instance + */ + @Override + public Contact doEnterOwnData () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Deligate this call to the frame + return this.frame.doEnterOwnData(); + } + + /** + * Shuts down this client + */ + @Override + public void doShutdown () throws SQLException, IOException { + // Debug message + this.getLogger().trace("CALLED!"); //NOI18N + + // Parent call + super.doShutdown(); + + // Shutdown frame + this.frame.doShutdown(); + + // @TODO Add other shutdown stuff + // Debug message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void doUserMenuChoice () throws UnhandledUserChoiceException { + // Debug message + //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!"); + + // Not implemented here + } + + @Override + public char enterChar (final char[] validChars, String message) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public Gender enterGender (final String message) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public int enterInt (final int minimum, final int maximum, final String message) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public Menu getMenu (final String menuType) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + /** + * Returns a Swing menu item + * + * @param accessKey Key to access the menu + * @param text Text to show to user + * @return A SelectableMenuItem + */ + @Override + public SelectableMenuItem getMenuItem (final char accessKey, final String text) { + // Debug message + this.getLogger().trace("CALLED!"); //NOI18N + + // Returns null as the menu is now no longer controlled here. + return null; + } + + /** + * Inizializes this client + */ + @Override + public void init () { + // Debug message + this.getLogger().trace("CALLED!"); //NOI18N + + try { + // Init contact manager here + this.initContactManager(); + + // Init frame + this.frame.init(); + + // Now start the frame + this.frame.setupFrame(this); + } catch (final FrameAlreadyInitializedException | UnsupportedDatabaseBackendException | IOException | BadTokenException | SQLException ex) { + // Abort program + this.abortProgramWithException(ex); + } + + // Debug message + this.getLogger().trace("EXIT!"); //NOI18N + } + + @Override + public void outputMessage (final String message) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void showCurrentMenu () { + // Debug message + //* NOISY-DEBUG: */ this.getLogger().trace("CALLED!"); + + // Not implemented here + } + + @Override + public void showEntry (final SelectableMenuItem item) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + @Override + public void showWelcome () { + // Debug message + this.getLogger().trace("CALLED!"); //NOI18N + + // Not implemented here + } + + @Override + public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. //NOI18N + } + + /** + * Fills menu map with swing menus + */ + @Override + protected final void fillMenuMap () { + // Nothing to fill here as the Swing frame is handling this all + throw new UnsupportedOperationException("Not implemented."); //NOI18N + } +} diff --git a/src/org/mxchange/addressbook/contact/book/BookContact.java b/src/org/mxchange/addressbook/contact/book/BookContact.java new file mode 100644 index 0000000..d4f4bf1 --- /dev/null +++ b/src/org/mxchange/addressbook/contact/book/BookContact.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.contact.book; + +import org.mxchange.jcore.contact.BaseContact; +import org.mxchange.jcore.contact.Contact; + +/** + * A contact that can be placed into "contact books" + * + * @author Roland Haeder + * @version 0.0 + */ +public class BookContact extends BaseContact implements Contact { + + /** + * Default constructor, may only be used from database backend + */ + public BookContact () { + } + +} diff --git a/src/org/mxchange/addressbook/contact/user/UserContact.java b/src/org/mxchange/addressbook/contact/user/UserContact.java new file mode 100644 index 0000000..1ca7f89 --- /dev/null +++ b/src/org/mxchange/addressbook/contact/user/UserContact.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.contact.user; + +import java.text.MessageFormat; +import org.mxchange.addressbook.contact.book.BookContact; +import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.contact.Gender; + +/** + * + * @author Roland Haeder + * @todo After a Collection has been used in ContactManager, change to + * BaseContact + */ +public class UserContact extends BookContact implements Contact { + + /** + * Creates own contact entry + * + * @param gender Gender to be set + * @param surname Surname to be set + * @param familyName Family name to be set + * @param companyName Company name + * @todo Add validation of data + */ + public UserContact (final Gender gender, final String surname, final String familyName, final String companyName) { + // Make sure all constructors are called + this(); + + // Trace message + this.getLogger().trace(MessageFormat.format("gender={0},surname={1},familyName={2},companyName={3} - CALLED!", gender, surname, familyName, companyName)); //NOI18N + + // Update all data + this.setGender(gender); + this.setSurname(surname); + this.setFamilyName(familyName); + this.setCompanyName(companyName); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * Default constructor, may only be used from database backend + */ + public UserContact () { + this.enableFlagOwnContact(); + } +} diff --git a/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java b/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java new file mode 100644 index 0000000..4596c57 --- /dev/null +++ b/src/org/mxchange/addressbook/database/contact/AddressbookContactDatabaseConstants.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.database.contact; + +/** + * A class holding constants for contact table + * + * @author Roland Haeder + */ +public final class AddressbookContactDatabaseConstants { + /** + * Column own_contact + */ + public static final String COLUMN_OWN_CONTACT = "own_contact"; //NOI18N + + /** + * Column id + */ + public static final String COLUMN_ID = "id"; + + /** + * No instances are allowed as this class only holds static attributes + */ + private AddressbookContactDatabaseConstants () { + } +} diff --git a/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java b/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java new file mode 100644 index 0000000..89802a8 --- /dev/null +++ b/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactDatabaseFrontend.java @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 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 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 map) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + throw new UnsupportedOperationException("Not supported yet: map=" + map); + } + + @Override + public String getIdName () { + // Return id column + return AddressbookContactDatabaseConstants.COLUMN_ID; + } +} diff --git a/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java b/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java new file mode 100644 index 0000000..213575e --- /dev/null +++ b/src/org/mxchange/addressbook/database/frontend/contact/AddressbookContactFrontend.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2015 Roland Häder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.database.frontend.contact; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.sql.SQLException; +import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException; +import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.database.frontend.DatabaseFrontend; +import org.mxchange.jcore.exceptions.BadTokenException; +import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException; + +/** + * An interface for addressbook contact database frontends + * + * @author Roland Häder + */ +public interface AddressbookContactFrontend extends DatabaseFrontend { + + /** + * Adds given contact instance to database + * + * @param contact Contact instance to add + * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added + */ + public void addContact (final Contact contact) throws ContactAlreadyAddedException; + + /** + * Some "getter" for total contacts count + * + * @return Total contacts count + * @throws java.sql.SQLException If any SQL error occurs + */ + public int getContactsCount () throws SQLException; + + /** + * Checks if given Contact is found + * + * @param contact Contact instance to check + * @return Whether the given Contact instance is found + * @throws java.sql.SQLException If an SQL error occurs + * @throws java.io.IOException If an IO error occurs + * @throws org.mxchange.jcore.exceptions.BadTokenException Continued throw + * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged + * @throws java.lang.NoSuchMethodException If a method cannot be found + * @throws java.lang.IllegalAccessException If a method is not accessible + * @throws java.lang.reflect.InvocationTargetException Any other problems? + */ + public boolean isContactFound (final Contact contact) throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException; + + /** + * Some "getter" for own contact instance + * + * @return Own contact instance + */ + public Contact getOwnContact (); + + /** + * Checks whether own contact is found + * + * @return Whether own contact is found + * @throws java.sql.SQLException If any SQL error occurs + * @throws java.io.IOException If an IO error occurs + * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found + * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the database file is damaged + * @throws java.lang.NoSuchMethodException If a method cannot be found + * @throws java.lang.IllegalAccessException If a method is not accessible + * @throws java.lang.reflect.InvocationTargetException Any other problems? + */ + public boolean isOwnContactFound () throws SQLException, IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException; + + /** + * Reads a single row and parses it to a contact instance + * + * @param rowIndex Row index (also how much to skip) + * @return Contact instance + */ + public Contact readSingleContact (final int rowIndex); +} diff --git a/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java b/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java new file mode 100644 index 0000000..634f4b4 --- /dev/null +++ b/src/org/mxchange/addressbook/exceptions/ContactAlreadyAddedException.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.exceptions; + +import java.text.MessageFormat; +import org.mxchange.jcore.contact.Contact; + +/** + * Thrown if the given Contact instance is already added + * + * @author Roland Haeder + */ +public class ContactAlreadyAddedException extends Exception { + + /** + * Constructor with a Contact instance + * + * @param contact Contact that is already added + */ + public ContactAlreadyAddedException (final Contact contact) { + super(MessageFormat.format("Contact with gender={0}, surname={1} and familyName={2} already added.", contact.getGender(), contact.getSurname(), contact.getFamilyName())); + } + + /** + * Default constructor, may be used if no contact instance is available + */ + public ContactAlreadyAddedException () { + super("Contact already added"); + } + +} diff --git a/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java b/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java new file mode 100644 index 0000000..ef41687 --- /dev/null +++ b/src/org/mxchange/addressbook/manager/contact/AddressbookContactManager.java @@ -0,0 +1,803 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 columnNames; + + /** + * A AddressbookContactFrontend instance + */ + private final AddressbookContactFrontend contactDatabase; + + /** + * Translated column name list + */ + private final List 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 iterator = this.getBundle().keySet().iterator(); + + // Then iterate over all + while (iterator.hasNext()) { + // Get next element + String key = iterator.next(); + + // Does the key start with AddressbookContactManager.columnName ? + if (key.startsWith("ContactManager.columnName")) { //NOI18N + // This is the wanted entry. + this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N + + // Convert string to array based on delimiter '.' + String[] tokens = this.getArrayFromString(key, ".", 4); + + // Token array must contain 4 elements (AddressbookContactManager.columnName.foo.text) + assert(tokens.length == 4) : MessageFormat.format("Array tokens contains not 4 elements: {0}", Arrays.toString(tokens)); + + // Get pre-last element + String columnName = tokens[tokens.length - 2]; + + // Debug message + this.getLogger().debug(MessageFormat.format("columnName={0} - adding ...", columnName)); + + // So add it + this.columnNames.add(columnName); + this.translatedColumnNames.add(this.getBundle().getString(key)); + } + } + + // Debug message + this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N + } + + /** + * A AddressbookContactFrontend instance + * + * @return the database + */ + private AddressbookContactFrontend getContactDatabase () { + return this.contactDatabase; + } + + /** + * "Getter" for own contact instance or null if not found + * + * @return Contact instance or null + */ + private Contact getOwnContact () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Deligate this call to database frontend + Contact contact = this.getContactDatabase().getOwnContact(); + + // Trace message + this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N + + // Return instance or null + return contact; + } +} diff --git a/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java b/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java new file mode 100644 index 0000000..77d39d3 --- /dev/null +++ b/src/org/mxchange/addressbook/manager/contact/ManageableAddressbookContact.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.manager.contact; + +import java.io.IOException; +import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException; +import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.contact.Gender; +import org.mxchange.jcore.exceptions.BadTokenException; +import org.mxchange.jcore.manager.database.ManageableDatabase; + +/** + * + * @author Roland Haeder + */ +public interface ManageableAddressbookContact extends ManageableDatabase { + /** + * Allows the user to enter own cellphone number. + * + * @return Cellphone number + */ + public String enterOwnCellNumber (); + + /** + * Allows the user to enter own city name. + * + * @return City name + */ + public String enterOwnCity (); + + /** + * Allows the user to enter comment for own entry. + * + * @return Comment + */ + public String enterOwnComment (); + + /** + * Allows the user to enter own company name. + * + * @return Company name + */ + public String enterOwnCompanyName (); + + /** + * Allows the user to enter own country code. + * + * @return Country code + */ + public String enterOwnCountryCode (); + + /** + * Allows the user to enter own email address. + * + * @return Email address + */ + public String enterOwnEmailAddress (); + + /** + * Allows the user to enter own family name. + * + * @return Family name + */ + public String enterOwnFamilyName (); + + /** + * Allows the user to enter own fax number. + * + * @return Fax number + */ + public String enterOwnFaxNumber (); + + /** + * Allows the user to enter own gender. + * + * @return Gender + */ + public Gender enterOwnGender (); + + /** + * Allows the user to enter own phone number. + * + * @return Phone number + */ + public String enterOwnPhoneNumber (); + + /** + * Allows the user to enter own street and house number. + * + * @return Street and house number + */ + public String enterOwnStreet (); + + /** + * Allows the user to enter own surname. + * + * @return Surname + */ + public String enterOwnSurname (); + + /** + * Allows the user to enter own ZIP code. + * + * @return ZIP code + */ + public int enterOwnZipCode (); + + /** + * List all contacts + */ + public void doListContacts (); + + /** + * Adds given contact to address book + * + * @param contact Contact being added + * @todo Add check for book size + */ + public void registerContact (final Contact contact); + + /** + * Adds given Contact instance to list + * + * @param contact Contact instance to add + * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If the contact is already added + */ + public void addContact (final Contact contact) throws ContactAlreadyAddedException; + + /** + * Let the user add a new other address + */ + public void doAddOtherAddress (); + + /** + * The user can change address data, like street, ZIP code, city and country + * of given Contact instance. + * + * @param contact Instance to change data + */ + public void doChangeAddressData (final Contact contact); + + /** + * The user can change name data, like gender, surname, family name and + * company name (if business contact). + * + * @param contact Instance to change data + */ + public void doChangeNameData (final Contact contact); + + /** + * Let the user change other address + */ + public void doChangeOtherAddress (); + + /** + * The user can change other data, like phone numbers or comments. + * + * @param contact Instance to change data + */ + public void doChangeOtherData (final Contact contact); + + /** + * Let the user change own data + * @throws java.io.IOException If an IO error was found + * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found + */ + public void doChangeOwnData () throws IOException , BadTokenException; + + /** + * Let the user delete other address + */ + public void doDeleteOtherAddress (); + + /** + * Asks user for own data + * @throws org.mxchange.addressbook.exceptions.ContactAlreadyAddedException If own contact is already added + * @throws java.io.IOException If an IO error was found + * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found + */ + public void doEnterOwnData () throws ContactAlreadyAddedException, IOException , BadTokenException; + + /** + * Searches address book for a contact + */ + public void doSearchContacts (); + + /** + * Checks whether own contact is already added by checking all entries for + * isOwnContact flag + * + * @return Whether own contact is already added + * @throws java.io.IOException If an IO error occurs + * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found + */ + public boolean isOwnContactAdded () throws IOException, BadTokenException; +} diff --git a/src/org/mxchange/addressbook/menu/AddressbookMenu.java b/src/org/mxchange/addressbook/menu/AddressbookMenu.java new file mode 100644 index 0000000..12257eb --- /dev/null +++ b/src/org/mxchange/addressbook/menu/AddressbookMenu.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 menuList, final String menuType, final Client client) { + // Get logger + Logger log = new AddressbookMenu().getLogger(); + + // Trace call + log.trace(MessageFormat.format("menuList={0},menuType={1},client={2} - CALLED!", menuList, menuType, client)); //NOI18N + + // Some instances must be set + if (menuList == null) { + // Abort here + throw new NullPointerException("menuList is null"); //NOI18N + } else if (client == null) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } else if (!(client instanceof AddressbookClient)) { + // Not correct instance + throw new IllegalArgumentException(MessageFormat.format("client{0} must implement AddressbookClient", client)); + } + + // Cast client to proper interface + AddressbookClient c = (AddressbookClient) client; + + // Get list size + int size = menuList.size(); + + // Debug message + log.debug(MessageFormat.format("Adding menu for '{0}' (old size: '{1}') ...", menuType, size)); //NOI18N + + // Depends on type + switch (menuType) { + case "main": // Main menu //NOI18N + // Enter own data + menuList.add(c.getMenuItem('1', "Eigene Adresse anlegen")); + + // Change own data + menuList.add(c.getMenuItem('2', "Eigene Adresse ändern")); + + // Add new addess + menuList.add(c.getMenuItem('3', "Neue Adresse hinzufügen")); + + // List entries + menuList.add(c.getMenuItem('4', "Adressbuch anzeigen")); + + // Address search + menuList.add(c.getMenuItem('5', "Adresse suchen")); + + // Change other address + menuList.add(c.getMenuItem('6', "Adresse ändern")); + + // Delete other address + menuList.add(c.getMenuItem('7', "Adresse löschen")); + + // Always last line: Exit program + menuList.add(c.getMenuItem('0', "Programm verlassen")); + break; + + default: // Not supported + log.error(MessageFormat.format("Menu type '{0}' ont supported", menuType)); //NOI18N + System.exit(1); + } + + // Size must have changed to more entries than before + assert (menuList.size() > size); + } + +} diff --git a/src/org/mxchange/addressbook/menu/BaseMenu.java b/src/org/mxchange/addressbook/menu/BaseMenu.java new file mode 100644 index 0000000..f554820 --- /dev/null +++ b/src/org/mxchange/addressbook/menu/BaseMenu.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 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 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 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 getMenuList () { + return this.menuList; + } + + /** + * Initializes menu + * + * @param menuType Menu type to initialize + * @param client CLient to call back + */ + protected void initMenu (final String menuType, final Client client) { + // Trace message + this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N + + // Init menu list + this.menuList = new ArrayList<>(5); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } +} diff --git a/src/org/mxchange/addressbook/menu/Menu.java b/src/org/mxchange/addressbook/menu/Menu.java new file mode 100644 index 0000000..78a5fb1 --- /dev/null +++ b/src/org/mxchange/addressbook/menu/Menu.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 getMenuItemsIterator (); + + /** + * Shows this menu + * + * @param client Client instance + */ + public void show (final Client client); + + /** + * Size of all menu items + * + * @return + */ + public int getMenuItemsCount (); +} diff --git a/src/org/mxchange/addressbook/menu/MenuTools.java b/src/org/mxchange/addressbook/menu/MenuTools.java new file mode 100644 index 0000000..30d8164 --- /dev/null +++ b/src/org/mxchange/addressbook/menu/MenuTools.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 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 iterator = menu.getMenuItemsIterator(); + + // Init return array and counter 'i' + char[] accessKeys = new char[menu.getMenuItemsCount()]; + int i = 0; + + // Now "walk" through all menu entries + while (iterator.hasNext()) { + // Get item + SelectableMenuItem item = iterator.next(); + //* NOISY-DEBUG: */ logger.debug("item=" + item); + + // Get access key from item and add it to the array + accessKeys[i] = item.getAccessKey(); + //* NOISY-DEBUG: */ logger.debug("accessKeys[" + i + "]=" + accessKeys[i]); + + // Increment counter + i++; + } + + // Return finished array + return accessKeys; + } +} diff --git a/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java b/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java new file mode 100644 index 0000000..965f68a --- /dev/null +++ b/src/org/mxchange/addressbook/menu/console/ConsoleMenu.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.menu.console; + +import java.text.MessageFormat; +import org.mxchange.addressbook.menu.AddressbookMenu; +import org.mxchange.addressbook.menu.BaseMenu; +import org.mxchange.addressbook.menu.Menu; +import org.mxchange.jcore.client.Client; + +/** + * + * @author Roland Haeder + */ +public class ConsoleMenu extends BaseMenu implements Menu { + + /** + * Constructor for this menu + * + * @param menuType Menu type to initialize + * @param client CLient to call back + */ + public ConsoleMenu (final String menuType, final Client client) { + // Trace message + this.getLogger().trace(MessageFormat.format("menuType={0},client={1} - CALLED!", menuType, client)); //NOI18N + + // Client must not be null + if (client == null) { + // Abort here + throw new NullPointerException("client is null"); + } + + // Init menu + this.initMenu(menuType, client); + + // Add all items + AddressbookMenu.addItemsToList(this.getMenuList(), menuType, client); + } +} diff --git a/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java b/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java new file mode 100644 index 0000000..4bb1cf9 --- /dev/null +++ b/src/org/mxchange/addressbook/menu/item/BaseMenuItem.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.menu.item; + +import org.mxchange.addressbook.BaseAddressbookSystem; + +/** + * + * @author Roland Haeder + */ +public class BaseMenuItem extends BaseAddressbookSystem { + +} diff --git a/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java b/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java new file mode 100644 index 0000000..a6de00a --- /dev/null +++ b/src/org/mxchange/addressbook/menu/item/SelectableMenuItem.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.menu.item; + +import org.mxchange.jcore.client.Client; + +/** + * + * @author Roland Haeder + */ +public interface SelectableMenuItem { + + /** + * Shows this menu item + * + * @param client Client instance + */ + public void show (final Client client); + + /** + * Access key + * + * @return the accessKey + */ + public char getAccessKey (); + + /** + * Text to user + * + * @return the text + */ + public String getText (); +} diff --git a/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java b/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java new file mode 100644 index 0000000..1090a63 --- /dev/null +++ b/src/org/mxchange/addressbook/menu/item/console/ConsoleMenuItem.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.addressbook.menu.item.console; + +import java.text.MessageFormat; +import org.mxchange.addressbook.client.AddressbookClient; +import org.mxchange.addressbook.menu.item.BaseMenuItem; +import org.mxchange.addressbook.menu.item.SelectableMenuItem; +import org.mxchange.jcore.client.Client; + +/** + * + * @author Roland Haeder + */ +public class ConsoleMenuItem extends BaseMenuItem implements SelectableMenuItem { + + /** + * Access key + */ + private char accessKey; + + /** + * Text to user + */ + private String text; + + /** + * Constructor for building a console menu with access key and text + * + * @param accessKey Access key for this menu entry + * @param text Text to show to user + */ + public ConsoleMenuItem (final char accessKey, final String text) { + this.setAccessKey(accessKey); + this.setText(text); + } + + /** + * Access key + * + * @return the accessKey + */ + @Override + public final char getAccessKey () { + return this.accessKey; + } + + /** + * Access key + * + * @param accessKey the accessKey to set + */ + private void setAccessKey (char accessKey) { + this.accessKey = accessKey; + } + + /** + * Text to user + * + * @return the text + */ + @Override + public String getText () { + return this.text; + } + + /** + * Text to user + * + * @param text the text to set + */ + private void setText (String text) { + this.text = text; + } + + @Override + public void show (final Client client) { + // Trace message + this.getLogger().trace(MessageFormat.format("client={0} - CALLED!", client)); //NOI18N + + // Client must not be null + if (client == null) { + // Abort here + throw new NullPointerException("client is null"); + } else if (!(client instanceof AddressbookClient)) { + // Wrong interface + throw new IllegalArgumentException("client " + client + " must implement AddressbookClient"); + } + + // Cast it + AddressbookClient c = (AddressbookClient) client; + + // Call-back client over menu + c.showEntry(this); + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + +} diff --git a/src/org/mxchange/localization/bundle_de_DE.properties b/src/org/mxchange/localization/bundle_de_DE.properties new file mode 100644 index 0000000..19ee753 --- /dev/null +++ b/src/org/mxchange/localization/bundle_de_DE.properties @@ -0,0 +1,69 @@ +# Copyright (C) 2015 Roland Haeder +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +AddressbookFrame.border.name.title.text=Anrede, Vorname, Nachname: +AddressbookFrame.border.address.title.text=Anschrift: +AddressbookFrame.border.other.title.text=Andere Angaben: +AddressbookFrame.button.addAddress.text=Adresse hinzuf\u00fcgen +AddressbookFrame.button.cancel.text=Abbrechen +AddressbookFrame.menu.file.text=Datei +AddressbookFrame.menu.addressbook.text=Adressbuch +AddressbookFrame.statusLabel.initializing.text=Initialisiere ... +AddressbookFrame.statusLabel.done.text=Fertig. +AddressbookFrame.statusLabel.shutdown.text=Shuttting down ... +AddressbookFrame.menuItem.exitProgram.text=Programm beenden +AddressbookFrame.menuItem.exitProgram.toolTipText=Beendet das Programm und speichert alle Einstellungen ab. +AddressbookFrame.menuItem.addOwnData.text=Eigene Adresse hinzuf\u00fcgen +AddressbookFrame.menuItem.addOwnData.toolTipText=Erlaubt das Hinzuf\u00fcgen eigener Daten. +AddressbookFrame.menuItem.editOwnData.text=Eigene Adresse \u00e4ndern +AddressbookFrame.menuItem.editOwnData.toolTipText=Erlaubt das \u00c4ndern eigener Daten. +AddressbookFrame.menuItem.addNewContact.text=Neue Adresse hinzuf\u00fcgen +AddressbookFrame.menuItem.addNewContact.toolTipText=Eine neue Adresse hinzuf\u00fcgen. +AddressbookFrame.dialog.addContact.title.text=Neue Adresse hinzuf\u00fcgen +AddressbookFrame.main.title.text=Adressen auflisten +AddressbookFrame.gender.text=Anrede: +AddressbookFrame.gender.toolTipText=W\u00e4hlen Sie die Anrede aus. +AddressbookFrame.surname.text=Vorname: +AddressbookFrame.surname.toolTipText=Geben Sie den Vornamen ein. +AddressbookFrame.familyName.text=Nachname: +AddressbookFrame.familyName.toolTipText=Geben Sie den Nachnamen ein. +AddressbookFrame.street.text=Stra\u00dfe: +AddressbookFrame.street.toolTipText=Geben Sie die Stra\u00dfe ein. +AddressbookFrame.number.text=Hausnummer: +AddressbookFrame.number.toolTipText=Geben Sie die Hausnummer ein. +AddressbookFrame.zip.text=PLZ: +AddressbookFrame.zip.toolTipText=Geben Sie die Postleitzahl ein. +AddressbookFrame.city.text=Stadt: +AddressbookFrame.city.toolTipText=Geben Sie die Stadt ein. +AddressbookFrame.emailAddress.text=Email-Adresse: +AddressbookFrame.emailAddress.toolTipText=Geben Sie die Email-Adresse ein. +AddressbookFrame.phoneNumber.text=Telefon: +AddressbookFrame.phoneNumber.toolTipText=Geben Sie die Telefonnummer ein. +AddressbookFrame.cellphoneNumber.text=Mobil: +AddressbookFrame.cellphoneNumber.toolTipText=Geben Sie die Handynummer ein. +AddressbookFrame.faxNumber.text=Fax: +AddressbookFrame.faxNumber.toolTipText=Geben Sie die Faxnummer ein. +AddressbookFrame.comment.text=Anmerkungen: +AddressbookFrame.comment.toolTipText=Geben Sie eine Anmerkung (Freifeld) ein. +BaseContact.gender.unknown.text=Unbekannt +BaseContact.gender.male.text=Herr +BaseContact.gender.female.text=Frau +BaseContact.gender.company.text=Firma +ContactManager.columnName.gender.text=Anrede +ContactManager.columnName.surname.text=Vorname +ContactManager.columnName.familyName.text=Nachname +ContactManager.columnName.street.text=Strasse +ContactManager.columnName.houseNumber.text=Hausnummer +ContactManager.columnName.zipCode.text=Postleitzahl +ContactManager.columnName.city.text=Stadt diff --git a/src/org/mxchange/localization/bundle_en_US.properties b/src/org/mxchange/localization/bundle_en_US.properties new file mode 100644 index 0000000..5b2c4d2 --- /dev/null +++ b/src/org/mxchange/localization/bundle_en_US.properties @@ -0,0 +1,69 @@ +# Copyright (C) 2015 Roland Haeder +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +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