From 41c9c9cd0d9516892f9b123a3028afeebe0289ad Mon Sep 17 00:00:00 2001 From: Emmanuel Bigeon Date: Mon, 8 Oct 2018 12:21:43 -0400 Subject: [PATCH] Licensing, upgrade configuration, use official license-plugin. Signed-off-by: Emmanuel Bigeon --- gclc-socket/LICENSE.txt | 517 ++++++++++++++++ gclc-socket/pom.xml | 292 +++++---- .../bigeon/gclc/socket/ConnexionManager.java | 198 +++--- .../bigeon/gclc/socket/DConnexionManager.java | 348 +++++------ .../gclc/socket/PluggableConsoleInput.java | 570 +++++++++--------- .../gclc/socket/PluggableConsoleOutput.java | 254 ++++---- .../gclc/socket/RemoteDisconnectCommand.java | 266 ++++---- .../socket/SocketConsoleApplicationShell.java | 398 ++++++------ .../gclc/socket/SocketConsoleInterface.java | 166 ++--- .../fr/bigeon/gclc/socket/package-info.java | 79 ++- .../gclc/socket/ConsoleTestApplication.java | 318 +++++----- .../socket/PluggableConsoleInputTest.java | 402 ++++++------ .../socket/RemoteDisconnectCommandTest.java | 212 +++---- .../socket/SocketConsoleApplicationTest.java | 340 +++++------ .../bigeon/gclc/socket/TestConsoleClient.java | 186 +++--- .../fr/bigeon/gclc/socket/TestServer.java | 212 +++---- gclc/pom.xml | 6 +- 17 files changed, 2671 insertions(+), 2093 deletions(-) create mode 100644 gclc-socket/LICENSE.txt diff --git a/gclc-socket/LICENSE.txt b/gclc-socket/LICENSE.txt new file mode 100644 index 0000000..1753629 --- /dev/null +++ b/gclc-socket/LICENSE.txt @@ -0,0 +1,517 @@ + CeCILL FREE SOFTWARE LICENSE AGREEMENT + +Version 2.1 dated 2013-06-21 + + + Notice + +This Agreement is a Free Software license agreement that is the result +of discussions between its authors in order to ensure compliance with +the two main principles guiding its drafting: + + * firstly, compliance with the principles governing the distribution + of Free Software: access to source code, broad rights granted to users, + * secondly, the election of a governing law, French law, with which it + is conformant, both as regards the law of torts and intellectual + property law, and the protection that it offers to both authors and + holders of the economic rights over software. + +The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) +license are: + +Commissariat à l'énergie atomique et aux énergies alternatives - CEA, a +public scientific, technical and industrial research establishment, +having its principal place of business at 25 rue Leblanc, immeuble Le +Ponant D, 75015 Paris, France. + +Centre National de la Recherche Scientifique - CNRS, a public scientific +and technological establishment, having its principal place of business +at 3 rue Michel-Ange, 75794 Paris cedex 16, France. + +Institut National de Recherche en Informatique et en Automatique - +Inria, a public scientific and technological establishment, having its +principal place of business at Domaine de Voluceau, Rocquencourt, BP +105, 78153 Le Chesnay cedex, France. + + + Preamble + +The purpose of this Free Software license agreement is to grant users +the right to modify and redistribute the software governed by this +license within the framework of an open source distribution model. + +The exercising of this right is conditional upon certain obligations for +users so as to preserve this status for all subsequent redistributions. + +In consideration of access to the source code and the rights to copy, +modify and redistribute granted by the license, users are provided only +with a limited warranty and the software's author, the holder of the +economic rights, and the successive licensors only have limited liability. + +In this respect, the risks associated with loading, using, modifying +and/or developing or reproducing the software by the user are brought to +the user's attention, given its Free Software status, which may make it +complicated to use, with the result that its use is reserved for +developers and experienced professionals having in-depth computer +knowledge. Users are therefore encouraged to load and test the +suitability of the software as regards their requirements in conditions +enabling the security of their systems and/or data to be ensured and, +more generally, to use and operate it in the same conditions of +security. This Agreement may be freely reproduced and published, +provided it is not altered, and that no provisions are either added or +removed herefrom. + +This Agreement may apply to any or all software for which the holder of +the economic rights decides to submit the use thereof to its provisions. + +Frequently asked questions can be found on the official website of the +CeCILL licenses family (http://www.cecill.info/index.en.html) for any +necessary clarification. + + + Article 1 - DEFINITIONS + +For the purpose of this Agreement, when the following expressions +commence with a capital letter, they shall have the following meaning: + +Agreement: means this license agreement, and its possible subsequent +versions and annexes. + +Software: means the software in its Object Code and/or Source Code form +and, where applicable, its documentation, "as is" when the Licensee +accepts the Agreement. + +Initial Software: means the Software in its Source Code and possibly its +Object Code form and, where applicable, its documentation, "as is" when +it is first distributed under the terms and conditions of the Agreement. + +Modified Software: means the Software modified by at least one +Contribution. + +Source Code: means all the Software's instructions and program lines to +which access is required so as to modify the Software. + +Object Code: means the binary files originating from the compilation of +the Source Code. + +Holder: means the holder(s) of the economic rights over the Initial +Software. + +Licensee: means the Software user(s) having accepted the Agreement. + +Contributor: means a Licensee having made at least one Contribution. + +Licensor: means the Holder, or any other individual or legal entity, who +distributes the Software under the Agreement. + +Contribution: means any or all modifications, corrections, translations, +adaptations and/or new functions integrated into the Software by any or +all Contributors, as well as any or all Internal Modules. + +Module: means a set of sources files including their documentation that +enables supplementary functions or services in addition to those offered +by the Software. + +External Module: means any or all Modules, not derived from the +Software, so that this Module and the Software run in separate address +spaces, with one calling the other when they are run. + +Internal Module: means any or all Module, connected to the Software so +that they both execute in the same address space. + +GNU GPL: means the GNU General Public License version 2 or any +subsequent version, as published by the Free Software Foundation Inc. + +GNU Affero GPL: means the GNU Affero General Public License version 3 or +any subsequent version, as published by the Free Software Foundation Inc. + +EUPL: means the European Union Public License version 1.1 or any +subsequent version, as published by the European Commission. + +Parties: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + + + Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the +Licensee of a non-exclusive, transferable and worldwide license for the +Software as set forth in Article 5 <#scope> hereinafter for the whole +term of the protection granted by the rights over said Software. + + + Article 3 - ACCEPTANCE + +3.1 The Licensee shall be deemed as having accepted the terms and +conditions of this Agreement upon the occurrence of the first of the +following events: + + * (i) loading the Software by any or all means, notably, by + downloading from a remote server, or by loading from a physical medium; + * (ii) the first time the Licensee exercises any of the rights granted + hereunder. + +3.2 One copy of the Agreement, containing a notice relating to the +characteristics of the Software, to the limited warranty, and to the +fact that its use is restricted to experienced users has been provided +to the Licensee prior to its acceptance as set forth in Article 3.1 +<#accepting> hereinabove, and the Licensee hereby acknowledges that it +has read and understood it. + + + Article 4 - EFFECTIVE DATE AND TERM + + + 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by +the Licensee as set forth in Article 3.1 <#accepting>. + + + 4.2 TERM + +The Agreement shall remain in force for the entire legal term of +protection of the economic rights over the Software. + + + Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following +rights over the Software for any or all use, and for the term of the +Agreement, on the basis of the terms and conditions set forth hereinafter. + +Besides, if the Licensor owns or comes to own one or more patents +protecting all or part of the functions of the Software or of its +components, the Licensor undertakes not to enforce the rights granted by +these patents against successive Licensees using, exploiting or +modifying the Software. If these patents are transferred, the Licensor +undertakes to have the transferees subscribe to the obligations set +forth in this paragraph. + + + 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation +as to its fields of application, with it being hereinafter specified +that this comprises: + + 1. permanent or temporary reproduction of all or part of the Software + by any or all means and in any or all form. + + 2. loading, displaying, running, or storing the Software on any or all + medium. + + 3. entitlement to observe, study or test its operation so as to + determine the ideas and principles behind any or all constituent + elements of said Software. This shall apply when the Licensee + carries out any or all loading, displaying, running, transmission or + storage operation as regards the Software, that it is entitled to + carry out hereunder. + + + 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS + +The right to make Contributions includes the right to translate, adapt, +arrange, or make any or all modifications to the Software, and the right +to reproduce the resulting software. + +The Licensee is authorized to make any or all Contributions to the +Software provided that it includes an explicit notice that it is the +author of said Contribution and indicates the date of the creation thereof. + + + 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, +transmit and communicate the Software to the general public on any or +all medium, and by any or all means, and the right to market, either in +consideration of a fee, or free of charge, one or more copies of the +Software by any means. + +The Licensee is further authorized to distribute copies of the modified +or unmodified Software to third parties according to the terms and +conditions set forth hereinafter. + + + 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is authorized to distribute true copies of the Software in +Source Code or Object Code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's warranty + and liability as set forth in Articles 8 and 9, + +and that, in the event that only the Object Code of the Software is +redistributed, the Licensee allows effective access to the full Source +Code of the Software for a period of at least three years from the +distribution of the Software, it being understood that the additional +acquisition cost of the Source Code shall not exceed the cost of the +data transfer. + + + 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee makes a Contribution to the Software, the terms and +conditions for the distribution of the resulting Modified Software +become subject to all the provisions of this Agreement. + +The Licensee is authorized to distribute the Modified Software, in +source code or object code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's warranty + and liability as set forth in Articles 8 and 9, + +and, in the event that only the object code of the Modified Software is +redistributed, + + 3. a note stating the conditions of effective access to the full source + code of the Modified Software for a period of at least three years + from the distribution of the Modified Software, it being understood + that the additional acquisition cost of the source code shall not + exceed the cost of the data transfer. + + + 5.3.3 DISTRIBUTION OF EXTERNAL MODULES + +When the Licensee has developed an External Module, the terms and +conditions of this Agreement do not apply to said External Module, that +may be distributed under a separate license agreement. + + + 5.3.4 COMPATIBILITY WITH OTHER LICENSES + +The Licensee can include a code that is subject to the provisions of one +of the versions of the GNU GPL, GNU Affero GPL and/or EUPL in the +Modified or unmodified Software, and distribute that entire code under +the terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL. + +The Licensee can include the Modified or unmodified Software in a code +that is subject to the provisions of one of the versions of the GNU GPL, +GNU Affero GPL and/or EUPL and distribute that entire code under the +terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL. + + + Article 6 - INTELLECTUAL PROPERTY + + + 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the economic rights over the Initial Software. Any or +all use of the Initial Software is subject to compliance with the terms +and conditions under which the Holder has elected to distribute its work +and no one shall be entitled to modify the terms and conditions for the +distribution of said Initial Software. + +The Holder undertakes that the Initial Software will remain ruled at +least by this Agreement, for the duration set forth in Article 4.2 <#term>. + + + 6.2 OVER THE CONTRIBUTIONS + +The Licensee who develops a Contribution is the owner of the +intellectual property rights over this Contribution as defined by +applicable law. + + + 6.3 OVER THE EXTERNAL MODULES + +The Licensee who develops an External Module is the owner of the +intellectual property rights over this External Module as defined by +applicable law and is free to choose the type of agreement that shall +govern its distribution. + + + 6.4 JOINT PROVISIONS + +The Licensee expressly undertakes: + + 1. not to remove, or modify, in any manner, the intellectual property + notices attached to the Software; + + 2. to reproduce said notices, in an identical manner, in the copies of + the Software modified or not. + +The Licensee undertakes not to directly or indirectly infringe the +intellectual property rights on the Software of the Holder and/or +Contributors, and to take, where applicable, vis-à-vis its staff, any +and all measures required to ensure respect of said intellectual +property rights of the Holder and/or Contributors. + + + Article 7 - RELATED SERVICES + +7.1 Under no circumstances shall the Agreement oblige the Licensor to +provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The +terms and conditions of such technical assistance, and/or such +maintenance, shall be set forth in a separate instrument. Only the +Licensor offering said maintenance and/or technical assistance services +shall incur liability therefor. + +7.2 Similarly, any Licensor is entitled to offer to its licensees, under +its sole responsibility, a warranty, that shall only be binding upon +itself, for the redistribution of the Software and/or the Modified +Software, under terms and conditions that it is free to decide. Said +warranty, and the financial terms and conditions of its application, +shall be subject of a separate instrument executed between the Licensor +and the Licensee. + + + Article 8 - LIABILITY + +8.1 Subject to the provisions of Article 8.2, the Licensee shall be +entitled to claim compensation for any direct loss it may have suffered +from the Software as a result of a fault on the part of the relevant +Licensor, subject to providing evidence thereof. + +8.2 The Licensor's liability is limited to the commitments made under +this Agreement and shall not be incurred as a result of in particular: +(i) loss due the Licensee's total or partial failure to fulfill its +obligations, (ii) direct or consequential loss that is suffered by the +Licensee due to the use or performance of the Software, and (iii) more +generally, any consequential loss. In particular the Parties expressly +agree that any or all pecuniary or business loss (i.e. loss of data, +loss of profits, operating loss, loss of customers or orders, +opportunity cost, any disturbance to business activities) or any or all +legal proceedings instituted against the Licensee by a third party, +shall constitute consequential loss and shall not provide entitlement to +any or all compensation from the Licensor. + + + Article 9 - WARRANTY + +9.1 The Licensee acknowledges that the scientific and technical +state-of-the-art when the Software was distributed did not enable all +possible uses to be tested and verified, nor for the presence of +possible defects to be detected. In this respect, the Licensee's +attention has been drawn to the risks associated with loading, using, +modifying and/or developing and reproducing the Software which are +reserved for experienced users. + +The Licensee shall be responsible for verifying, by any or all means, +the suitability of the product for its requirements, its good working +order, and for ensuring that it shall not cause damage to either persons +or properties. + +9.2 The Licensor hereby represents, in good faith, that it is entitled +to grant all the rights over the Software (including in particular the +rights set forth in Article 5 <#scope>). + +9.3 The Licensee acknowledges that the Software is supplied "as is" by +the Licensor without any other express or tacit warranty, other than +that provided for in Article 9.2 <#good-faith> and, in particular, +without any warranty as to its commercial value, its secured, safe, +innovative or relevant nature. + +Specifically, the Licensor does not warrant that the Software is free +from any error, that it will operate without interruption, that it will +be compatible with the Licensee's own equipment and software +configuration, nor that it will meet the Licensee's requirements. + +9.4 The Licensor does not either expressly or tacitly warrant that the +Software does not infringe any third party intellectual property right +relating to a patent, software or any other property right. Therefore, +the Licensor disclaims any and all liability towards the Licensee +arising out of any or all proceedings for infringement that may be +instituted in respect of the use, modification and redistribution of the +Software. Nevertheless, should such proceedings be instituted against +the Licensee, the Licensor shall provide it with technical and legal +expertise for its defense. Such technical and legal expertise shall be +decided on a case-by-case basis between the relevant Licensor and the +Licensee pursuant to a memorandum of understanding. The Licensor +disclaims any and all liability as regards the Licensee's use of the +name of the Software. No warranty is given as regards the existence of +prior rights over the name of the Software or as regards the existence +of a trademark. + + + Article 10 - TERMINATION + +10.1 In the event of a breach by the Licensee of its obligations +hereunder, the Licensor may automatically terminate this Agreement +thirty (30) days after notice has been sent to the Licensee and has +remained ineffective. + +10.2 A Licensee whose Agreement is terminated shall no longer be +authorized to use, modify or distribute the Software. However, any +licenses that it may have granted prior to termination of the Agreement +shall remain valid subject to their having been granted in compliance +with the terms and conditions hereof. + + + Article 11 - MISCELLANEOUS + + + 11.1 EXCUSABLE EVENTS + +Neither Party shall be liable for any or all delay, or failure to +perform the Agreement, that may be attributable to an event of force +majeure, an act of God or an outside cause, such as defective +functioning or interruptions of the electricity or telecommunications +networks, network paralysis following a virus attack, intervention by +government authorities, natural disasters, water damage, earthquakes, +fire, explosions, strikes and labor unrest, war, etc. + +11.2 Any failure by either Party, on one or more occasions, to invoke +one or more of the provisions hereof, shall under no circumstances be +interpreted as being a waiver by the interested Party of its right to +invoke said provision(s) subsequently. + +11.3 The Agreement cancels and replaces any or all previous agreements, +whether written or oral, between the Parties and having the same +purpose, and constitutes the entirety of the agreement between said +Parties concerning said purpose. No supplement or modification to the +terms and conditions hereof shall be effective as between the Parties +unless it is made in writing and signed by their duly authorized +representatives. + +11.4 In the event that one or more of the provisions hereof were to +conflict with a current or future applicable act or legislative text, +said act or legislative text shall prevail, and the Parties shall make +the necessary amendments so as to comply with said act or legislative +text. All other provisions shall remain effective. Similarly, invalidity +of a provision of the Agreement, for any reason whatsoever, shall not +cause the Agreement as a whole to be invalid. + + + 11.5 LANGUAGE + +The Agreement is drafted in both French and English and both versions +are deemed authentic. + + + Article 12 - NEW VERSIONS OF THE AGREEMENT + +12.1 Any person is authorized to duplicate and distribute copies of this +Agreement. + +12.2 So as to ensure coherence, the wording of this Agreement is +protected and may only be modified by the authors of the License, who +reserve the right to periodically publish updates or new versions of the +Agreement, each with a separate number. These subsequent versions may +address new issues encountered by Free Software. + +12.3 Any Software distributed under a given version of the Agreement may +only be subsequently distributed under the same version of the Agreement +or a subsequent version, subject to the provisions of Article 5.3.4 +<#compatibility>. + + + Article 13 - GOVERNING LAW AND JURISDICTION + +13.1 The Agreement is governed by French law. The Parties agree to +endeavor to seek an amicable solution to any disagreements or disputes +that may arise during the performance of the Agreement. + +13.2 Failing an amicable solution within two (2) months as from their +occurrence, and unless emergency proceedings are necessary, the +disagreements or disputes shall be referred to the Paris Courts having +jurisdiction, by the more diligent Party. diff --git a/gclc-socket/pom.xml b/gclc-socket/pom.xml index 768f088..2a5e062 100644 --- a/gclc-socket/pom.xml +++ b/gclc-socket/pom.xml @@ -1,135 +1,171 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 4.0.0 - gclc-socket - 1.1.10-SNAPSHOT - jar - http://www.bigeon.fr/emmanuel - - UTF-8 - git.bigeon.net - - - - fr.bigeon - gclc - 2.0.5 - - - fr.bigeon - smu - 0.0.9 - - - - fr.bigeon.config - ebigeon-config - 1.8.2 - - GCLC Socket - Socket implementation of GCLC - - scm:git:gogs@git.code.bigeon.net:emmanuel/gclc.git - HEAD - - fr.bigeon.gclc + + 4.0.0 + gclc-socket + 1.1.10-SNAPSHOT + jar + http://www.bigeon.net + + UTF-8 + git.code.bigeon.net + cecill_2.1 + emmanuel@bigeon.fr + + + + fr.bigeon + gclc + 2.0.5 + + + fr.bigeon + smu + 0.0.9 + + + + net.bigeon.config + ebigeon-config + 1.8.3 + + + + manual + CeCILL 2.1 + https://cecill.info/licences/Licence_CeCILL_V2.1-en.html + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + com.github.sevntu-checkstyle + dsm-maven-plugin + 2.2.0 + + + + + + emmanuel@bigeon.fr + Emmanuel Bigeon + bigeon.net + + PM + + + + GCLC Socket + Socket implementation of GCLC + + scm:git:gogs@git.code.bigeon.net:emmanuel/gclc.git + HEAD + + net.bigeon.gclc + 2016 diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/ConnexionManager.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/ConnexionManager.java index fecf085..9f61781 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/ConnexionManager.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/ConnexionManager.java @@ -1,98 +1,100 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.ConnexionManager.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import java.util.Collection; - -/** A manager for connected elements. - *

- * Connected elements are given an identifier (unique) at connexion. - * - * @author Emmanuel Bigeon - * @param the type of object connected */ -public interface ConnexionManager { - /** Add a connection in the name. - * - * @param handle the connected object - * @return the name */ - String addConnexion(T handle); - - /** Disconnect an element. - * - * @param id the element connection id - * @return the object being disconnected */ - T disconnect(String id); - - /** Get the connected object. - * - * @param id the connexion id - * @return the object */ - T get(String id); - - /** Get the connected elements' ids. - * - * @return the connected elements' ids */ - Collection getConnected(); - - /** Test if a connection is active. - * - * @param id the connexion id - * @return if the connection is active. */ - boolean isConnected(String id); - - /** Add a lock on the disconnection. - *

- * This lock will not prevent calls to - * {@link #disconnect(String)}. It will however stop them from completing - * after the effective disconnection of the specified connection. - *

- * Calls to {@link #releaseDisconnexionLock(String)} remove a lock (at a - * pace of one for one). - * - * @param id the connexion id */ - void lockDisconnexion(String id); - - /** Release one lock on a disconnection - * - * @param id the connexion being released. */ - void releaseDisconnexionLock(String id); - - /** Wait for calls to {@link #disconnect(String)} - * - * @param id the connexion id - * @throws InterruptedException if the wait was interrupted. */ - void waitDisconnexion(String id) throws InterruptedException; -} +/** + * gclc-socket:fr.bigeon.gclc.socket.ConnexionManager.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.util.Collection; + +/** A manager for connected elements. + *

+ * Connected elements are given an identifier (unique) at connexion. + * + * @author Emmanuel Bigeon + * @param the type of object connected */ +public interface ConnexionManager { + /** Add a connection in the name. + * + * @param handle the connected object + * @return the name */ + String addConnexion(T handle); + + /** Disconnect an element. + * + * @param id the element connection id + * @return the object being disconnected */ + T disconnect(String id); + + /** Get the connected object. + * + * @param id the connexion id + * @return the object */ + T get(String id); + + /** Get the connected elements' ids. + * + * @return the connected elements' ids */ + Collection getConnected(); + + /** Test if a connection is active. + * + * @param id the connexion id + * @return if the connection is active. */ + boolean isConnected(String id); + + /** Add a lock on the disconnection. + *

+ * This lock will not prevent calls to + * {@link #disconnect(String)}. It will however stop them from completing after + * the effective disconnection of the specified connection. + *

+ * Calls to {@link #releaseDisconnexionLock(String)} remove a lock (at a pace of + * one for one). + * + * @param id the connexion id */ + void lockDisconnexion(String id); + + /** Release one lock on a disconnection + * + * @param id the connexion being released. */ + void releaseDisconnexionLock(String id); + + /** Wait for calls to {@link #disconnect(String)} + * + * @param id the connexion id + * @throws InterruptedException if the wait was interrupted. */ + void waitDisconnexion(String id) throws InterruptedException; +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/DConnexionManager.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/DConnexionManager.java index 28a1d2f..aef855a 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/DConnexionManager.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/DConnexionManager.java @@ -1,173 +1,175 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.DConnexionManager.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** Default implementation of the {@link ConnexionManager}. - * - * @author Emmanuel Bigeon - * @param the connected objects */ -public final class DConnexionManager implements ConnexionManager { - - /** Class logger. */ - private static final Logger LOGGER = Logger - .getLogger(DConnexionManager.class.getName()); - /** The connected objects. */ - private final Map connecteds = new HashMap<>(); - /** The locks for the connexions. */ - private final Map locks = new HashMap<>(); - /** The counter for the disconnexion locks. */ - private final Map counters = new HashMap<>(); - /** The lock for modification of {@link #counters}. */ - private final Object counterLock = new Object(); - /** The count of connexions. */ - private int count = 0; - - /** Default.constructor. */ - public DConnexionManager() { - // - } - /* (non-Javadoc) - * @see - * fr.bigeon.gclc.socket.ConnexionManager#addConnexion(java.lang.Object) */ - @Override - public String addConnexion(final T handle) { - final String newID = newID(); - connecteds.put(newID, handle); - locks.put(newID, new Object()); - counters.put(newID, Integer.valueOf(0)); - return newID; - } - - /* (non-Javadoc) - * @see - * fr.bigeon.gclc.socket.ConnexionManager#disconnect(java.lang.String) */ - @Override - public T disconnect(final String id) { - if (connecteds.containsKey(id)) { - final T disc = connecteds.remove(id); - final Object lock = locks.get(id); - synchronized (lock) { - lock.notifyAll(); - } - synchronized (counterLock) { - while (counters.get(id).intValue() > 0) { - try { - counterLock.wait(); - } catch (final InterruptedException e) { - LOGGER.log(Level.FINE, "Interruption of thread", e); //$NON-NLS-1$ - Thread.currentThread().interrupt(); - } - } - } - return disc; - } - return null; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.socket.ConnexionManager#get(java.lang.String) */ - @Override - public T get(final String id) { - return connecteds.get(id); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.socket.ConnexionManager#getConnected() */ - @Override - public Collection getConnected() { - return connecteds.keySet(); - } - - /* (non-Javadoc) - * @see - * fr.bigeon.gclc.socket.ConnexionManager#isConnected(java.lang.String) */ - @Override - public boolean isConnected(final String id) { - return connecteds.containsKey(id); - } - - /* (non-Javadoc) - * @see - * fr.bigeon.gclc.socket.ConnexionManager#lockDisconnexion(java.lang.String) */ - @Override - public void lockDisconnexion(final String id) { - if (!connecteds.containsKey(id)) { - return; - } - synchronized (counterLock) { - counters.put(id, Integer.valueOf(counters.get(id).intValue() + 1)); - } - } - - /** Get a new identifier for connexion. - * - * @return a new ID */ - private String newID() { - return "Client " + count++; //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see - * fr.bigeon.gclc.socket.ConnexionManager#releaseDisconnexionLock(java.lang. - * String) */ - @Override - public void releaseDisconnexionLock(final String id) { - synchronized (counterLock) { - counters.put(id, Integer - .valueOf(Math.max(counters.get(id).intValue() - 1, 0))); - counterLock.notifyAll(); - } - } - - /* (non-Javadoc) - * @see - * fr.bigeon.gclc.socket.ConnexionManager#waitDisconnexion(java.lang.String) */ - @Override - public void waitDisconnexion(final String id) throws InterruptedException { - final Object lock = locks.get(id); - while (connecteds.containsKey(id)) { - synchronized (lock) { - lock.wait(); - } - } - } -} +/** + * gclc-socket:fr.bigeon.gclc.socket.DConnexionManager.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Default implementation of the {@link ConnexionManager}. + * + * @author Emmanuel Bigeon + * @param the connected objects */ +public final class DConnexionManager implements ConnexionManager { + + /** Class logger. */ + private static final Logger LOGGER = Logger + .getLogger(DConnexionManager.class.getName()); + /** The connected objects. */ + private final Map connecteds = new HashMap<>(); + /** The locks for the connexions. */ + private final Map locks = new HashMap<>(); + /** The counter for the disconnexion locks. */ + private final Map counters = new HashMap<>(); + /** The lock for modification of {@link #counters}. */ + private final Object counterLock = new Object(); + /** The count of connexions. */ + private int count = 0; + + /** Default.constructor. */ + public DConnexionManager() { + // + } + /* (non-Javadoc) + * @see + * fr.bigeon.gclc.socket.ConnexionManager#addConnexion(java.lang.Object) */ + @Override + public String addConnexion(final T handle) { + final String newID = newID(); + connecteds.put(newID, handle); + locks.put(newID, new Object()); + counters.put(newID, Integer.valueOf(0)); + return newID; + } + + /* (non-Javadoc) + * @see + * fr.bigeon.gclc.socket.ConnexionManager#disconnect(java.lang.String) */ + @Override + public T disconnect(final String id) { + if (connecteds.containsKey(id)) { + final T disc = connecteds.remove(id); + final Object lock = locks.get(id); + synchronized (lock) { + lock.notifyAll(); + } + synchronized (counterLock) { + while (counters.get(id).intValue() > 0) { + try { + counterLock.wait(); + } catch (final InterruptedException e) { + LOGGER.log(Level.FINE, "Interruption of thread", e); //$NON-NLS-1$ + Thread.currentThread().interrupt(); + } + } + } + return disc; + } + return null; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.socket.ConnexionManager#get(java.lang.String) */ + @Override + public T get(final String id) { + return connecteds.get(id); + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.socket.ConnexionManager#getConnected() */ + @Override + public Collection getConnected() { + return connecteds.keySet(); + } + + /* (non-Javadoc) + * @see + * fr.bigeon.gclc.socket.ConnexionManager#isConnected(java.lang.String) */ + @Override + public boolean isConnected(final String id) { + return connecteds.containsKey(id); + } + + /* (non-Javadoc) + * @see + * fr.bigeon.gclc.socket.ConnexionManager#lockDisconnexion(java.lang.String) */ + @Override + public void lockDisconnexion(final String id) { + if (!connecteds.containsKey(id)) { + return; + } + synchronized (counterLock) { + counters.put(id, Integer.valueOf(counters.get(id).intValue() + 1)); + } + } + + /** Get a new identifier for connexion. + * + * @return a new ID */ + private String newID() { + return "Client " + count++; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see + * fr.bigeon.gclc.socket.ConnexionManager#releaseDisconnexionLock(java.lang. + * String) */ + @Override + public void releaseDisconnexionLock(final String id) { + synchronized (counterLock) { + counters.put(id, Integer + .valueOf(Math.max(counters.get(id).intValue() - 1, 0))); + counterLock.notifyAll(); + } + } + + /* (non-Javadoc) + * @see + * fr.bigeon.gclc.socket.ConnexionManager#waitDisconnexion(java.lang.String) */ + @Override + public void waitDisconnexion(final String id) throws InterruptedException { + final Object lock = locks.get(id); + while (connecteds.containsKey(id)) { + synchronized (lock) { + lock.wait(); + } + } + } +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleInput.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleInput.java index 739cd27..9086c72 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleInput.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleInput.java @@ -1,284 +1,286 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.PlugableConsoleInput.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.nio.charset.StandardCharsets; -import java.util.logging.Level; -import java.util.logging.Logger; - -import fr.bigeon.gclc.manager.ConsoleInput; -import fr.bigeon.gclc.manager.ReadingRunnable; -import fr.bigeon.gclc.tools.ConstantString; -import fr.bigeon.gclc.tools.StringProvider; - -/** A console input where the stream can be plugged. - *

- * This pluggable console input accepts an input and output to be connected to - * it. The connexion cannot be concurrent, which mean that any connected stream - * must be disconnected before a new call to - * {@link #connect(InputStream, PrintStream)} is done. - * - * @author Emmanuel Bigeon */ -public final class PluggableConsoleInput implements ConsoleInput { - /** The ten constant. */ - private static final int TENTH = 10; - /** Class logger. */ - private static final Logger LOGGER = Logger - .getLogger(PluggableConsoleInput.class.getName()); - /** The default time out. */ - private static final long TIMEOUT = 100; - /** The prompting. */ - private boolean prompting = false; - /** If the element is closed. */ - private boolean closed = false; - /** The default prompt. */ - private StringProvider prompt = new ConstantString("> "); //$NON-NLS-1$ - /** If the input is plugged or buffering. */ - private boolean connected = false; - /** The current connexion (if any). */ - private ReadingRunnable connexion; - /** The interrupted status for prompts. */ - private boolean interrupted = false; - /** The last hint hint. */ - private String hint; - /** The output for hints. */ - private PrintStream output; - - // Locks - /** The lock for connexion and disconnexion of actual streams. */ - private final Object connexionLock = new Object(); - - /** Create the pluggable console input. */ - public PluggableConsoleInput() { - // do nothing - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#close() */ - @Override - public void close() { - closed = true; - } - - /** Connect the given input stream to the input and output to the hints - * writing. - * - * @param stream the input stream - * @param out the output for hints. - * @throws IOException if the input is already connected. */ - public void connect(final InputStream stream, - final PrintStream out) throws IOException { - synchronized (connexionLock) { - if (connected) { - throw new IOException( - "Input already connected to an input stream"); //$NON-NLS-1$ - } - - output = out; - if (prompting) { - out.print(hint); - out.flush(); - } - - final InputStreamReader streamReader = new InputStreamReader( - stream, StandardCharsets.UTF_8); - final BufferedReader reader = new BufferedReader(streamReader); - connexion = new ReadingRunnable(reader); - final Thread th = new Thread(connexion, "GCLC Socket - Read input"); //$NON-NLS-1$ - th.start(); - connexionLock.notifyAll(); - connected = true; - } - } - - /** Disconnect the current input and hint output. */ - public synchronized void disconnect() { - synchronized (connexionLock) { - if (!connected) { - return; - } - connected = false; - connexion.setRunning(false); - } - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#getPrompt() */ - @Override - public StringProvider getPrompt() { - return prompt; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#interruptPrompt() */ - @Override - public void interruptPrompt() { - interrupted = true; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#isClosed() */ - @Override - public boolean isClosed() { - return closed; - } - - /** Test if a prompt is occuring. - * - * @return the prompting */ - public boolean isPrompting() { - return prompting; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt() */ - @Override - public String prompt() throws IOException { - return prompt(prompt.apply()); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long) */ - @Override - public String prompt(final long timeout) throws IOException { - return prompt(prompt.apply(), timeout); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String) */ - @Override - public String prompt(final String message) throws IOException { - if (closed) { - throw new IOException(); - } - prompting = true; - hint = message; - synchronized (connexionLock) { - hint = message; - if (connected) { - output.print(message); - output.flush(); - } - } - - String res = null; - while (res == null && !interrupted) { - try { - res = waitMessageOrConnexion(TIMEOUT, TIMEOUT / TENTH); - } catch (final InterruptedException e) { - LOGGER.log(Level.FINE, "Interruption of thread", e); //$NON-NLS-1$ - Thread.currentThread().interrupt(); - } - if (closed) { - throw new IOException(); - } - } - prompting = false; - return res; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, - * long) */ - @Override - public String prompt(final String message, - final long timeout) throws IOException { - if (closed) { - throw new IOException(); - } - prompting = true; - synchronized (connexionLock) { - hint = message; - if (connected) { - output.print(message); - output.flush(); - } - } - - String res = null; - final long tic = System.currentTimeMillis(); - long time = System.currentTimeMillis() - tic; - while (res == null && !interrupted && time < timeout) { - try { - res = waitMessageOrConnexion(timeout - time, - (timeout - time) / TENTH); - } catch (final InterruptedException e) { - LOGGER.log(Level.FINE, "Interruption of thread", e); //$NON-NLS-1$ - Thread.currentThread().interrupt(); - } - time = System.currentTimeMillis() - tic; - if (closed) { - throw new IOException(); - } - } - prompting = false; - return res; - } - - @Override - public void setPrompt(final StringProvider prompt) { - this.prompt = prompt; - } - - @Override - public void setPrompt(String prompt) { - setPrompt(new ConstantString(prompt)); - } - - /** Wait for a hint or connexion. - * - * @param messageTimeout the timeout on the current connexion hint waiting - * @param connexionTimeout the timeout on the new connexion wait - * @return the hint, or null if not connected or timed out. - * @throws IOException if the reading failed. - * @throws InterruptedException if the wait was interrupted */ - private String waitMessageOrConnexion(final long messageTimeout, - final long connexionTimeout) throws IOException, - InterruptedException { - synchronized (connexionLock) { - if (connected) { - return connexion.getNextMessage(messageTimeout); - } - connexionLock.wait(connexionTimeout); - } - return null; - } -} +/** + * gclc-socket:fr.bigeon.gclc.socket.PlugableConsoleInput.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.logging.Level; +import java.util.logging.Logger; + +import fr.bigeon.gclc.manager.ConsoleInput; +import fr.bigeon.gclc.manager.ReadingRunnable; +import fr.bigeon.gclc.tools.ConstantString; +import fr.bigeon.gclc.tools.StringProvider; + +/** A console input where the stream can be plugged. + *

+ * This pluggable console input accepts an input and output to be connected to + * it. The connexion cannot be concurrent, which mean that any connected stream + * must be disconnected before a new call to + * {@link #connect(InputStream, PrintStream)} is done. + * + * @author Emmanuel Bigeon */ +public final class PluggableConsoleInput implements ConsoleInput { + /** The ten constant. */ + private static final int TENTH = 10; + /** Class logger. */ + private static final Logger LOGGER = Logger + .getLogger(PluggableConsoleInput.class.getName()); + /** The default time out. */ + private static final long TIMEOUT = 100; + /** The prompting. */ + private boolean prompting = false; + /** If the element is closed. */ + private boolean closed = false; + /** The default prompt. */ + private StringProvider prompt = new ConstantString("> "); //$NON-NLS-1$ + /** If the input is plugged or buffering. */ + private boolean connected = false; + /** The current connexion (if any). */ + private ReadingRunnable connexion; + /** The interrupted status for prompts. */ + private boolean interrupted = false; + /** The last hint hint. */ + private String hint; + /** The output for hints. */ + private PrintStream output; + + // Locks + /** The lock for connexion and disconnexion of actual streams. */ + private final Object connexionLock = new Object(); + + /** Create the pluggable console input. */ + public PluggableConsoleInput() { + // do nothing + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#close() */ + @Override + public void close() { + closed = true; + } + + /** Connect the given input stream to the input and output to the hints + * writing. + * + * @param stream the input stream + * @param out the output for hints. + * @throws IOException if the input is already connected. */ + public void connect(final InputStream stream, + final PrintStream out) throws IOException { + synchronized (connexionLock) { + if (connected) { + throw new IOException( + "Input already connected to an input stream"); //$NON-NLS-1$ + } + + output = out; + if (prompting) { + out.print(hint); + out.flush(); + } + + final InputStreamReader streamReader = new InputStreamReader( + stream, StandardCharsets.UTF_8); + final BufferedReader reader = new BufferedReader(streamReader); + connexion = new ReadingRunnable(reader); + final Thread th = new Thread(connexion, "GCLC Socket - Read input"); //$NON-NLS-1$ + th.start(); + connexionLock.notifyAll(); + connected = true; + } + } + + /** Disconnect the current input and hint output. */ + public synchronized void disconnect() { + synchronized (connexionLock) { + if (!connected) { + return; + } + connected = false; + connexion.setRunning(false); + } + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#getPrompt() */ + @Override + public StringProvider getPrompt() { + return prompt; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#interruptPrompt() */ + @Override + public void interruptPrompt() { + interrupted = true; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#isClosed() */ + @Override + public boolean isClosed() { + return closed; + } + + /** Test if a prompt is occuring. + * + * @return the prompting */ + public boolean isPrompting() { + return prompting; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#prompt() */ + @Override + public String prompt() throws IOException { + return prompt(prompt.apply()); + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long) */ + @Override + public String prompt(final long timeout) throws IOException { + return prompt(prompt.apply(), timeout); + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String) */ + @Override + public String prompt(final String message) throws IOException { + if (closed) { + throw new IOException(); + } + prompting = true; + hint = message; + synchronized (connexionLock) { + hint = message; + if (connected) { + output.print(message); + output.flush(); + } + } + + String res = null; + while (res == null && !interrupted) { + try { + res = waitMessageOrConnexion(TIMEOUT, TIMEOUT / TENTH); + } catch (final InterruptedException e) { + LOGGER.log(Level.FINE, "Interruption of thread", e); //$NON-NLS-1$ + Thread.currentThread().interrupt(); + } + if (closed) { + throw new IOException(); + } + } + prompting = false; + return res; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, + * long) */ + @Override + public String prompt(final String message, + final long timeout) throws IOException { + if (closed) { + throw new IOException(); + } + prompting = true; + synchronized (connexionLock) { + hint = message; + if (connected) { + output.print(message); + output.flush(); + } + } + + String res = null; + final long tic = System.currentTimeMillis(); + long time = System.currentTimeMillis() - tic; + while (res == null && !interrupted && time < timeout) { + try { + res = waitMessageOrConnexion(timeout - time, + (timeout - time) / TENTH); + } catch (final InterruptedException e) { + LOGGER.log(Level.FINE, "Interruption of thread", e); //$NON-NLS-1$ + Thread.currentThread().interrupt(); + } + time = System.currentTimeMillis() - tic; + if (closed) { + throw new IOException(); + } + } + prompting = false; + return res; + } + + @Override + public void setPrompt(final StringProvider prompt) { + this.prompt = prompt; + } + + @Override + public void setPrompt(String prompt) { + setPrompt(new ConstantString(prompt)); + } + + /** Wait for a hint or connexion. + * + * @param messageTimeout the timeout on the current connexion hint waiting + * @param connexionTimeout the timeout on the new connexion wait + * @return the hint, or null if not connected or timed out. + * @throws IOException if the reading failed. + * @throws InterruptedException if the wait was interrupted */ + private String waitMessageOrConnexion(final long messageTimeout, + final long connexionTimeout) throws IOException, + InterruptedException { + synchronized (connexionLock) { + if (connected) { + return connexion.getNextMessage(messageTimeout); + } + connexionLock.wait(connexionTimeout); + } + return null; + } +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleOutput.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleOutput.java index 9b57af0..86d7226 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleOutput.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/PluggableConsoleOutput.java @@ -1,126 +1,128 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.PluggableConsoleOutput.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayDeque; -import java.util.Deque; - -import fr.bigeon.gclc.manager.ConsoleOutput; - -/** An output that can be hotplugged to an actual output. - * - * @author Emmanuel Bigeon */ -public final class PluggableConsoleOutput implements ConsoleOutput { - - /** The actual output. */ - private PrintStream out; - /** The buffered messages. */ - private final Deque messages = new ArrayDeque<>(); - /** If this output is closed. */ - private boolean closed = false; - - /** Default constructor. */ - public PluggableConsoleOutput() { - // - } - /* (non-Javadoc) - * @see java.lang.AutoCloseable#close() */ - @Override - public void close() { - closed = true; - } - - /** Set the output to write to. - * - * @param output the output to set */ - public synchronized void connect(final PrintStream output) { - out = output; - while (!messages.isEmpty()) { - output.print(messages.pop()); - } - } - - /** Disconnects the output. */ - public synchronized void disconnect() { - out = null; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleOutput#isClosed() */ - @Override - public boolean isClosed() { - return closed; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleOutput#print(java.lang.String) */ - @Override - public synchronized void print(final String text) throws IOException { - if (closed) { - throw new IOException("Closed output"); //$NON-NLS-1$ - } - if (out == null) { - messages.add(text); - } else { - out.print(text); - } - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleOutput#println() */ - @Override - public synchronized void println() throws IOException { - if (closed) { - throw new IOException("Closed output"); //$NON-NLS-1$ - } - if (out == null) { - messages.add("\n"); //$NON-NLS-1$ - } else { - out.println(); - } - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleOutput#println(java.lang.String) */ - @Override - public synchronized void println(final String message) throws IOException { - print(message); - println(); - } - -} +/** + * gclc-socket:fr.bigeon.gclc.socket.PluggableConsoleOutput.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayDeque; +import java.util.Deque; + +import fr.bigeon.gclc.manager.ConsoleOutput; + +/** An output that can be hotplugged to an actual output. + * + * @author Emmanuel Bigeon */ +public final class PluggableConsoleOutput implements ConsoleOutput { + + /** The actual output. */ + private PrintStream out; + /** The buffered messages. */ + private final Deque messages = new ArrayDeque<>(); + /** If this output is closed. */ + private boolean closed = false; + + /** Default constructor. */ + public PluggableConsoleOutput() { + // + } + /* (non-Javadoc) + * @see java.lang.AutoCloseable#close() */ + @Override + public void close() { + closed = true; + } + + /** Set the output to write to. + * + * @param output the output to set */ + public synchronized void connect(final PrintStream output) { + out = output; + while (!messages.isEmpty()) { + output.print(messages.pop()); + } + } + + /** Disconnects the output. */ + public synchronized void disconnect() { + out = null; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleOutput#isClosed() */ + @Override + public boolean isClosed() { + return closed; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleOutput#print(java.lang.String) */ + @Override + public synchronized void print(final String text) throws IOException { + if (closed) { + throw new IOException("Closed output"); //$NON-NLS-1$ + } + if (out == null) { + messages.add(text); + } else { + out.print(text); + } + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleOutput#println() */ + @Override + public synchronized void println() throws IOException { + if (closed) { + throw new IOException("Closed output"); //$NON-NLS-1$ + } + if (out == null) { + messages.add("\n"); //$NON-NLS-1$ + } else { + out.println(); + } + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.manager.ConsoleOutput#println(java.lang.String) */ + @Override + public synchronized void println(final String message) throws IOException { + print(message); + println(); + } + +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/RemoteDisconnectCommand.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/RemoteDisconnectCommand.java index 312dd53..28b2b27 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/RemoteDisconnectCommand.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/RemoteDisconnectCommand.java @@ -1,132 +1,134 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.RemoteDisconnectCommand.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import java.io.IOException; -import java.text.MessageFormat; -import java.util.Collection; - -import fr.bigeon.gclc.command.Command; -import fr.bigeon.gclc.exception.CommandRunException; -import fr.bigeon.gclc.exception.CommandRunExceptionType; -import fr.bigeon.gclc.manager.ConsoleInput; -import fr.bigeon.gclc.manager.ConsoleOutput; - -/** A {@link Command} to disconnect elements from a {@link ConnexionManager}. - * - * @author Emmanuel Bigeon - * @param the type of connected object */ -public final class RemoteDisconnectCommand extends Command { - - /** The connexion manager. */ - private final ConnexionManager manager; - /** If all connexion should be disconnected when no argument have been - * specified. */ - private final boolean all; - - /** Create the disconnection command. - * - * @param name the command name - * @param manager the manager - * @param all if all elements should be disconnected when no argument is - * provided */ - public RemoteDisconnectCommand(final String name, - final ConnexionManager manager, final boolean all) { - super(name); - this.manager = manager; - this.all = all; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc.manager. - * ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, final ConsoleInput in, - final String... args) throws CommandRunException { - if (args.length == 0 && all) { - final Collection coll = manager.getConnected(); - for (final String string : coll) { - manager.disconnect(string); - } - } - for (final String string : args) { - if (manager.isConnected(string)) { - manager.disconnect(string); - } else { - print(out, MessageFormat - .format("[WARNING] {0} is not connected", string)); //$NON-NLS-1$ - } - } - } - - /** Print a message if the output is defined. - * - * @param out the output - * @param string the message - * @throws CommandRunException if the output exists but cannot be printed - * to */ - private void print(final ConsoleOutput out, - final String string) throws CommandRunException { - if (out != null) { - try { - out.println(string); - } catch (final IOException e) { - throw new CommandRunException( - CommandRunExceptionType.INTERACTION, - "Unable to print to existing output", e, this); //$NON-NLS-1$ - } - } - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#tip() */ - @Override - public String tip() { - return "Close a connexion."; //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() */ - @SuppressWarnings("nls") - @Override - protected String usageDetail() { - return MessageFormat.format( - " If arguments are provided the corresponding connexions are closed, " + - "otherwise{0}{1} are.", - System.lineSeparator(), all ? "all connexions" : "none"); - } -} +/** + * gclc-socket:fr.bigeon.gclc.socket.RemoteDisconnectCommand.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collection; + +import fr.bigeon.gclc.command.Command; +import fr.bigeon.gclc.exception.CommandRunException; +import fr.bigeon.gclc.exception.CommandRunExceptionType; +import fr.bigeon.gclc.manager.ConsoleInput; +import fr.bigeon.gclc.manager.ConsoleOutput; + +/** A {@link Command} to disconnect elements from a {@link ConnexionManager}. + * + * @author Emmanuel Bigeon + * @param the type of connected object */ +public final class RemoteDisconnectCommand extends Command { + + /** The connexion manager. */ + private final ConnexionManager manager; + /** If all connexion should be disconnected when no argument have been + * specified. */ + private final boolean all; + + /** Create the disconnection command. + * + * @param name the command name + * @param manager the manager + * @param all if all elements should be disconnected when no argument is + * provided */ + public RemoteDisconnectCommand(final String name, + final ConnexionManager manager, final boolean all) { + super(name); + this.manager = manager; + this.all = all; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc.manager. + * ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, + * java.lang.String[]) */ + @Override + public void execute(final ConsoleOutput out, final ConsoleInput in, + final String... args) throws CommandRunException { + if (args.length == 0 && all) { + final Collection coll = manager.getConnected(); + for (final String string : coll) { + manager.disconnect(string); + } + } + for (final String string : args) { + if (manager.isConnected(string)) { + manager.disconnect(string); + } else { + print(out, MessageFormat + .format("[WARNING] {0} is not connected", string)); //$NON-NLS-1$ + } + } + } + + /** Print a message if the output is defined. + * + * @param out the output + * @param string the message + * @throws CommandRunException if the output exists but cannot be printed + * to */ + private void print(final ConsoleOutput out, + final String string) throws CommandRunException { + if (out != null) { + try { + out.println(string); + } catch (final IOException e) { + throw new CommandRunException( + CommandRunExceptionType.INTERACTION, + "Unable to print to existing output", e, this); //$NON-NLS-1$ + } + } + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ICommand#tip() */ + @Override + public String tip() { + return "Close a connexion."; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#usageDetail() */ + @SuppressWarnings("nls") + @Override + protected String usageDetail() { + return MessageFormat.format( + " If arguments are provided the corresponding connexions are closed, " + + "otherwise{0}{1} are.", + System.lineSeparator(), all ? "all connexions" : "none"); + } +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleApplicationShell.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleApplicationShell.java index 20ce92c..b981459 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleApplicationShell.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleApplicationShell.java @@ -1,198 +1,200 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -package fr.bigeon.gclc.socket; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import fr.bigeon.gclc.ConsoleApplication; - -/** This is a socket communicating console consoleManager. - *

- * To use this application, the following flow should be used: - * - *

- * SocketConsoleApplicationShell shell = new SocketConsoleApplicationShell();
- * ConsoleApplication myApplication = new MyConsoleApplication(shell.getConsoleManager(), ...);
- * shell.setApplication(myApplication);
- * Thread th = new Thread(shell);
- * th.start();
- * 
- *

- * This will start the application in a separate thread. The application will be - * listening on the given socket and writing back on it. If this is all your - * application, you should then {@link Thread#join()} the thread to wait for the - * end of the execution. - * - * @author Emmanuel Bigeon */ -public final class SocketConsoleApplicationShell implements Runnable { - - /** The class logger. */ - private static final Logger LOGGER = Logger - .getLogger(SocketConsoleApplicationShell.class.getName()); - /** The listening port. */ - private final int port; - /** The running status. */ - private boolean running; - /** The socket console interface. */ - private SocketConsoleInterface sci; - /** The remote disconnection command. */ - private ConnexionManager rdc; - /** The application. */ - private ConsoleApplication app; - - /** The server socket. */ - private ServerSocket serverSocket; - /** THe server address. */ - private final InetAddress addr; - - /** Create a socket application shell which will listen on the given port - * and network interface. - * - * @param port the part - * @param addr the inet address */ - public SocketConsoleApplicationShell(final int port, - final InetAddress addr) { - super(); - this.port = port; - this.addr = addr; - } - - /** Wait for the identified connection to disconnect. - * - * @param id the connexion id. */ - private void awaitDisconnexion(final String id) { - while (rdc.isConnected(id)) { - try { - rdc.waitDisconnexion(id); - } catch (final InterruptedException e) { - LOGGER.log(Level.SEVERE, "Unexpected interruption", e); //$NON-NLS-1$ - Thread.currentThread().interrupt(); - } - } - sci.disconnect(); - } - - /** If the port provided was 0, this allows to get the actual port. - * @return the local port - * @see java.net.ServerSocket#getLocalPort() - */ - public int getLocalPort() { - return serverSocket.getLocalPort(); - } - - /* (non-Javadoc) - * @see java.lang.Runnable#run() */ - @Override - public void run() { - // Create the server - try (ServerSocket actualServerSocket = new ServerSocket(port, 1, - addr)) { - serverSocket = actualServerSocket; - running = true; - // Create the streams - runSokectServer(); - } catch (final IOException e) { - LOGGER.severe("Communication error between client and server"); //$NON-NLS-1$ - LOGGER.log(Level.FINE, - "Communication error between client and server", e); //$NON-NLS-1$ - } - } - - /** Acctually run the server loop on connexion. - * - * @throws IOException if the communication with the client failed */ - private void runSokectServer() throws IOException { - while (running && app.isRunning()) { - LOGGER.info("Waiting client"); //$NON-NLS-1$ - try (Socket clientSocket = serverSocket.accept();) { - - sci.connect(clientSocket); - - final String id = rdc.addConnexion(clientSocket); - rdc.lockDisconnexion(id); - awaitDisconnexion(id); - rdc.releaseDisconnexionLock(id); - } catch (final SocketException e) { - LOGGER.log(Level.INFO, "Socket closed"); //$NON-NLS-1$ - LOGGER.log(Level.FINE, - "Socket closed with exception (probably due to server interruption)", //$NON-NLS-1$ - e); - } catch (final IOException e) { - throw e; - } - LOGGER.info("Closing client"); //$NON-NLS-1$ - } - LOGGER.info("Closing Server"); //$NON-NLS-1$ - } - - /** Set the application. - *

- * If the application is closed, the server will also close. - * - * @param app the app to set */ - public void setApplication(final ConsoleApplication app) { - this.app = app; - } - - /** Set the connexion manager. - * - * @param rdc the rdc to set */ - public void setConnexionManager(final ConnexionManager rdc) { - this.rdc = rdc; - } - - /** Set the socket console interface. - * - * @param sci the console interface to set */ - public void setInterface(final SocketConsoleInterface sci) { - this.sci = sci; - } - - /** This method will request the server to stop. - *

- * In most cases, this will terminate communication on every client. On some - * cases, the */ - public void stop() { - running = false; - try { - serverSocket.close(); - } catch (final IOException e) { - LOGGER.log(Level.SEVERE, "Exception in closing socket server", e); //$NON-NLS-1$ - } - } -} +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import fr.bigeon.gclc.ConsoleApplication; + +/** This is a socket communicating console consoleManager. + *

+ * To use this application, the following flow should be used: + * + *

+ * SocketConsoleApplicationShell shell = new SocketConsoleApplicationShell();
+ * ConsoleApplication myApplication = new MyConsoleApplication(shell.getConsoleManager(), ...);
+ * shell.setApplication(myApplication);
+ * Thread th = new Thread(shell);
+ * th.start();
+ * 
+ *

+ * This will start the application in a separate thread. The application will be + * listening on the given socket and writing back on it. If this is all your + * application, you should then {@link Thread#join()} the thread to wait for the + * end of the execution. + * + * @author Emmanuel Bigeon */ +public final class SocketConsoleApplicationShell implements Runnable { + + /** The class logger. */ + private static final Logger LOGGER = Logger + .getLogger(SocketConsoleApplicationShell.class.getName()); + /** The listening port. */ + private final int port; + /** The running status. */ + private boolean running; + /** The socket console interface. */ + private SocketConsoleInterface sci; + /** The remote disconnection command. */ + private ConnexionManager rdc; + /** The application. */ + private ConsoleApplication app; + + /** The server socket. */ + private ServerSocket serverSocket; + /** THe server address. */ + private final InetAddress addr; + + /** Create a socket application shell which will listen on the given port + * and network interface. + * + * @param port the part + * @param addr the inet address */ + public SocketConsoleApplicationShell(final int port, + final InetAddress addr) { + super(); + this.port = port; + this.addr = addr; + } + + /** Wait for the identified connection to disconnect. + * + * @param id the connexion id. */ + private void awaitDisconnexion(final String id) { + while (rdc.isConnected(id)) { + try { + rdc.waitDisconnexion(id); + } catch (final InterruptedException e) { + LOGGER.log(Level.SEVERE, "Unexpected interruption", e); //$NON-NLS-1$ + Thread.currentThread().interrupt(); + } + } + sci.disconnect(); + } + + /** If the port provided was 0, this allows to get the actual port. + * @return the local port + * @see java.net.ServerSocket#getLocalPort() + */ + public int getLocalPort() { + return serverSocket.getLocalPort(); + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() */ + @Override + public void run() { + // Create the server + try (ServerSocket actualServerSocket = new ServerSocket(port, 1, + addr)) { + serverSocket = actualServerSocket; + running = true; + // Create the streams + runSokectServer(); + } catch (final IOException e) { + LOGGER.severe("Communication error between client and server"); //$NON-NLS-1$ + LOGGER.log(Level.FINE, + "Communication error between client and server", e); //$NON-NLS-1$ + } + } + + /** Acctually run the server loop on connexion. + * + * @throws IOException if the communication with the client failed */ + private void runSokectServer() throws IOException { + while (running && app.isRunning()) { + LOGGER.info("Waiting client"); //$NON-NLS-1$ + try (Socket clientSocket = serverSocket.accept();) { + + sci.connect(clientSocket); + + final String id = rdc.addConnexion(clientSocket); + rdc.lockDisconnexion(id); + awaitDisconnexion(id); + rdc.releaseDisconnexionLock(id); + } catch (final SocketException e) { + LOGGER.log(Level.INFO, "Socket closed"); //$NON-NLS-1$ + LOGGER.log(Level.FINE, + "Socket closed with exception (probably due to server interruption)", //$NON-NLS-1$ + e); + } catch (final IOException e) { + throw e; + } + LOGGER.info("Closing client"); //$NON-NLS-1$ + } + LOGGER.info("Closing Server"); //$NON-NLS-1$ + } + + /** Set the application. + *

+ * If the application is closed, the server will also close. + * + * @param app the app to set */ + public void setApplication(final ConsoleApplication app) { + this.app = app; + } + + /** Set the connexion manager. + * + * @param rdc the rdc to set */ + public void setConnexionManager(final ConnexionManager rdc) { + this.rdc = rdc; + } + + /** Set the socket console interface. + * + * @param sci the console interface to set */ + public void setInterface(final SocketConsoleInterface sci) { + this.sci = sci; + } + + /** This method will request the server to stop. + *

+ * In most cases, this will terminate communication on every client. On some + * cases, the */ + public void stop() { + running = false; + try { + serverSocket.close(); + } catch (final IOException e) { + LOGGER.log(Level.SEVERE, "Exception in closing socket server", e); //$NON-NLS-1$ + } + } +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleInterface.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleInterface.java index 2aff21d..5fcc054 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleInterface.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/SocketConsoleInterface.java @@ -1,82 +1,84 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.SocketConsoleInterface.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import java.io.IOException; -import java.io.PrintStream; -import java.net.Socket; -import java.nio.charset.StandardCharsets; - -/** The interface for socket based access to console application. - * - * @author Emmanuel Bigeon */ -public final class SocketConsoleInterface { - - /** The application's input. */ - private final PluggableConsoleInput input; - /** The application's output. */ - private final PluggableConsoleOutput output; - - /** Create the interfacing object. - * - * @param input the input - * @param output the output */ - public SocketConsoleInterface(final PluggableConsoleInput input, - final PluggableConsoleOutput output) { - super(); - this.input = input; - this.output = output; - } - - /** Connect the application's input and outputs to the socket's. - * - * @param socket the socket - * @throws IOException if the connection failed */ - public void connect(final Socket socket) throws IOException { - final PrintStream printStream = new PrintStream( - socket.getOutputStream(), true, - StandardCharsets.UTF_8.name()); - output.connect(printStream); - input.connect(socket.getInputStream(), - printStream); - } - - /** Disconnect the input and output of the application from the socket's. */ - public void disconnect() { - input.disconnect(); - output.disconnect(); - } -} +/** + * gclc-socket:fr.bigeon.gclc.socket.SocketConsoleInterface.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.IOException; +import java.io.PrintStream; +import java.net.Socket; +import java.nio.charset.StandardCharsets; + +/** The interface for socket based access to console application. + * + * @author Emmanuel Bigeon */ +public final class SocketConsoleInterface { + + /** The application's input. */ + private final PluggableConsoleInput input; + /** The application's output. */ + private final PluggableConsoleOutput output; + + /** Create the interfacing object. + * + * @param input the input + * @param output the output */ + public SocketConsoleInterface(final PluggableConsoleInput input, + final PluggableConsoleOutput output) { + super(); + this.input = input; + this.output = output; + } + + /** Connect the application's input and outputs to the socket's. + * + * @param socket the socket + * @throws IOException if the connection failed */ + public void connect(final Socket socket) throws IOException { + final PrintStream printStream = new PrintStream( + socket.getOutputStream(), true, + StandardCharsets.UTF_8.name()); + output.connect(printStream); + input.connect(socket.getInputStream(), + printStream); + } + + /** Disconnect the input and output of the application from the socket's. */ + public void disconnect() { + input.disconnect(); + output.disconnect(); + } +} diff --git a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/package-info.java b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/package-info.java index a0f3219..263d1e4 100644 --- a/gclc-socket/src/main/java/fr/bigeon/gclc/socket/package-info.java +++ b/gclc-socket/src/main/java/fr/bigeon/gclc/socket/package-info.java @@ -1,40 +1,39 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.package-info.java - * Created on: Nov 18, 2017 - */ -/** This package define a framework to access - * {@link fr.bigeon.gclc.ConsoleApplication} through a socket. - * - * @author Emmanuel Bigeon */ -package fr.bigeon.gclc.socket; +/** This package define a framework to access + * {@link fr.bigeon.gclc.ConsoleApplication} through a socket. + * + * @author Emmanuel Bigeon */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ diff --git a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/ConsoleTestApplication.java b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/ConsoleTestApplication.java index 8a16289..1894f34 100644 --- a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/ConsoleTestApplication.java +++ b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/ConsoleTestApplication.java @@ -1,158 +1,160 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -package fr.bigeon.gclc.socket; - -import java.io.IOException; -import java.net.Socket; -import java.util.Collection; - -import fr.bigeon.gclc.ConsoleApplication; -import fr.bigeon.gclc.command.Command; -import fr.bigeon.gclc.command.ExitCommand; -import fr.bigeon.gclc.command.HelpExecutor; -import fr.bigeon.gclc.exception.CommandRunException; -import fr.bigeon.gclc.exception.InvalidCommandName; -import fr.bigeon.gclc.manager.ConsoleInput; -import fr.bigeon.gclc.manager.ConsoleOutput; - -/** A test-purpose application - * - * @author Emmanuel Bigeon */ -public class ConsoleTestApplication { - - /** Exit command */ - public static final String EXIT = "exit"; //$NON-NLS-1$ - - /** Create the test application. - * - * @param output the output - * @param input the input - * @param manager the manager - * @return create the application */ - @SuppressWarnings("nls") - public static ConsoleApplication create(final ConsoleOutput output, - final ConsoleInput input, - final ConnexionManager manager) { - try { - final ConsoleApplication application = new ConsoleApplication( - output, input, - "Welcome to the test application. Type help or test.", - "See you"); - application.add(new ExitCommand(EXIT, application) { - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ExitCommand#beforeExit() */ - @Override - protected void beforeExit() { - final Collection coll = manager.getConnected(); - for (final String string : coll) { - manager.disconnect(string); - } - } - }); - application - .add(new HelpExecutor("help", application.root)); - application.add(new Command("test") { - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. - * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, - final ConsoleInput in, - final String... args) throws CommandRunException { - try { - output.println("Test command ran fine"); - } catch (final IOException e) { - throw new CommandRunException("manager closed", e, - this); - } - } - - @Override - public String tip() { - return "A test command"; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() - */ - @Override - protected String usageDetail() { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); - } - }); - application.add(new Command("long") { - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. - * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, - final ConsoleInput in, - final String... args) throws CommandRunException { - try { - Thread.sleep(2000); - output.println("Test command ran fine"); - } catch (IOException | InterruptedException e) { - throw new CommandRunException("manager closed", e, - this); - } - } - - @Override - public String tip() { - return "A long run test command"; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() - */ - @Override - protected String usageDetail() { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); - } - }); - application.add( - new RemoteDisconnectCommand<>("out", manager, true)); - return application; - } catch (final InvalidCommandName e) { - e.printStackTrace(); - } - return null; - } -} +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.IOException; +import java.net.Socket; +import java.util.Collection; + +import fr.bigeon.gclc.ConsoleApplication; +import fr.bigeon.gclc.command.Command; +import fr.bigeon.gclc.command.ExitCommand; +import fr.bigeon.gclc.command.HelpExecutor; +import fr.bigeon.gclc.exception.CommandRunException; +import fr.bigeon.gclc.exception.InvalidCommandName; +import fr.bigeon.gclc.manager.ConsoleInput; +import fr.bigeon.gclc.manager.ConsoleOutput; + +/** A test-purpose application + * + * @author Emmanuel Bigeon */ +public class ConsoleTestApplication { + + /** Exit command */ + public static final String EXIT = "exit"; //$NON-NLS-1$ + + /** Create the test application. + * + * @param output the output + * @param input the input + * @param manager the manager + * @return create the application */ + @SuppressWarnings("nls") + public static ConsoleApplication create(final ConsoleOutput output, + final ConsoleInput input, + final ConnexionManager manager) { + try { + final ConsoleApplication application = new ConsoleApplication( + output, input, + "Welcome to the test application. Type help or test.", + "See you"); + application.add(new ExitCommand(EXIT, application) { + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ExitCommand#beforeExit() */ + @Override + protected void beforeExit() { + final Collection coll = manager.getConnected(); + for (final String string : coll) { + manager.disconnect(string); + } + } + }); + application + .add(new HelpExecutor("help", application.root)); + application.add(new Command("test") { + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. + * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, + * java.lang.String[]) */ + @Override + public void execute(final ConsoleOutput out, + final ConsoleInput in, + final String... args) throws CommandRunException { + try { + output.println("Test command ran fine"); + } catch (final IOException e) { + throw new CommandRunException("manager closed", e, + this); + } + } + + @Override + public String tip() { + return "A test command"; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#usageDetail() + */ + @Override + protected String usageDetail() { + // TODO Auto-generated method stub + // return null; + throw new RuntimeException("Not implemented yet"); + } + }); + application.add(new Command("long") { + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. + * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, + * java.lang.String[]) */ + @Override + public void execute(final ConsoleOutput out, + final ConsoleInput in, + final String... args) throws CommandRunException { + try { + Thread.sleep(2000); + output.println("Test command ran fine"); + } catch (IOException | InterruptedException e) { + throw new CommandRunException("manager closed", e, + this); + } + } + + @Override + public String tip() { + return "A long run test command"; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#usageDetail() + */ + @Override + protected String usageDetail() { + // TODO Auto-generated method stub + // return null; + throw new RuntimeException("Not implemented yet"); + } + }); + application.add( + new RemoteDisconnectCommand<>("out", manager, true)); + return application; + } catch (final InvalidCommandName e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/PluggableConsoleInputTest.java b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/PluggableConsoleInputTest.java index cc214e1..c81bcc9 100644 --- a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/PluggableConsoleInputTest.java +++ b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/PluggableConsoleInputTest.java @@ -1,200 +1,202 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.PluggableConsoleInputTest.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.PrintStream; - -import org.junit.Test; - -/** - *

- * TODO - * - * @author Emmanuel Bigeon */ -public class PluggableConsoleInputTest { - - /** Test method for - * {@link fr.bigeon.gclc.socket.PluggableConsoleInput#close()}. */ - @Test - public final void testClose() { - final PluggableConsoleInput input = new PluggableConsoleInput(); - assertFalse("Input should not be initially closed", input.isClosed()); - input.close(); - assertTrue("Close should close the input", input.isClosed()); - - try { - input.prompt(); - fail("Closed prompt should cause an IO"); - } catch (final IOException e) { - // ok - } - try { - input.prompt(10); - fail("Closed prompt should cause an IO"); - } catch (final IOException e) { - // ok - } - - final PluggableConsoleInput input2 = new PluggableConsoleInput(); - - final Thread th = new Thread(new Runnable() { - - @Override - public void run() { - while (!input2.isPrompting()) { - - } - try { - Thread.sleep(100); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - input2.close(); - } - }); - th.start(); - try { - input.prompt(); - fail("Closed prompt should cause an IO"); - } catch (final IOException e) { - // ok - } - final PluggableConsoleInput input3 = new PluggableConsoleInput(); - - final Thread th2 = new Thread(new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(200); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - input3.close(); - } - }); - th2.start(); - try { - input.prompt(2000); - fail("Closed prompt should cause an IO"); - } catch (final IOException e) { - // ok - } - } - - @Test - public final void testConnect() throws IOException, InterruptedException { - final PluggableConsoleInput input = new PluggableConsoleInput(); - - input.disconnect(); - try (final PipedInputStream pis = new PipedInputStream(); - final PipedOutputStream pos = new PipedOutputStream(); - final PipedInputStream inner = new PipedInputStream(pos); - final PipedOutputStream innerPos = new PipedOutputStream(pis); - final PrintStream testIn = new PrintStream(innerPos, true, "UTF8"); - final PrintStream out = new PrintStream(pos)) { - input.connect(pis, out); - try { - input.connect(pis, out); - fail("Should not be able to connect already connected"); - } catch (final IOException e) { - // ok - } - input.disconnect(); - - final Thread th = new Thread(new Runnable() { - - @Override - public void run() { - try { - input.prompt("Test", 5000); - } catch (final IOException e) { - e.printStackTrace(); - } - } - }); - th.start(); - - while (!input.isPrompting()) { - Thread.sleep(10); - } - - input.connect(pis, out); - testIn.println("tac"); - - final Thread th2 = new Thread(new Runnable() { - - @Override - public void run() { - try { - input.prompt("Test", 5000); - fail("Prompt should io"); - } catch (final IOException e) { - // ok - } - } - }); - th2.start(); - while (!input.isPrompting()) { - Thread.sleep(10); - } - - input.close(); - - - } - } - - /** Test method for - * {@link fr.bigeon.gclc.socket.PluggableConsoleInput#getPrompt()}. */ - @Test - public final void testGetPrompt() { - final PluggableConsoleInput input = new PluggableConsoleInput(); - assertEquals("Default prompt invalid", "> ", input.getPrompt()); - input.setPrompt("test"); - assertEquals("Prompt setting failed", "test", input.getPrompt()); - } -} +/** + * gclc-socket:fr.bigeon.gclc.socket.PluggableConsoleInputTest.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; + +import org.junit.Test; + +/** + *

+ * TODO + * + * @author Emmanuel Bigeon */ +public class PluggableConsoleInputTest { + + /** Test method for + * {@link fr.bigeon.gclc.socket.PluggableConsoleInput#close()}. */ + @Test + public final void testClose() { + final PluggableConsoleInput input = new PluggableConsoleInput(); + assertFalse("Input should not be initially closed", input.isClosed()); + input.close(); + assertTrue("Close should close the input", input.isClosed()); + + try { + input.prompt(); + fail("Closed prompt should cause an IO"); + } catch (final IOException e) { + // ok + } + try { + input.prompt(10); + fail("Closed prompt should cause an IO"); + } catch (final IOException e) { + // ok + } + + final PluggableConsoleInput input2 = new PluggableConsoleInput(); + + final Thread th = new Thread(new Runnable() { + + @Override + public void run() { + while (!input2.isPrompting()) { + + } + try { + Thread.sleep(100); + } catch (final InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + input2.close(); + } + }); + th.start(); + try { + input.prompt(); + fail("Closed prompt should cause an IO"); + } catch (final IOException e) { + // ok + } + final PluggableConsoleInput input3 = new PluggableConsoleInput(); + + final Thread th2 = new Thread(new Runnable() { + + @Override + public void run() { + try { + Thread.sleep(200); + } catch (final InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + input3.close(); + } + }); + th2.start(); + try { + input.prompt(2000); + fail("Closed prompt should cause an IO"); + } catch (final IOException e) { + // ok + } + } + + @Test + public final void testConnect() throws IOException, InterruptedException { + final PluggableConsoleInput input = new PluggableConsoleInput(); + + input.disconnect(); + try (final PipedInputStream pis = new PipedInputStream(); + final PipedOutputStream pos = new PipedOutputStream(); + final PipedInputStream inner = new PipedInputStream(pos); + final PipedOutputStream innerPos = new PipedOutputStream(pis); + final PrintStream testIn = new PrintStream(innerPos, true, "UTF8"); + final PrintStream out = new PrintStream(pos)) { + input.connect(pis, out); + try { + input.connect(pis, out); + fail("Should not be able to connect already connected"); + } catch (final IOException e) { + // ok + } + input.disconnect(); + + final Thread th = new Thread(new Runnable() { + + @Override + public void run() { + try { + input.prompt("Test", 5000); + } catch (final IOException e) { + e.printStackTrace(); + } + } + }); + th.start(); + + while (!input.isPrompting()) { + Thread.sleep(10); + } + + input.connect(pis, out); + testIn.println("tac"); + + final Thread th2 = new Thread(new Runnable() { + + @Override + public void run() { + try { + input.prompt("Test", 5000); + fail("Prompt should io"); + } catch (final IOException e) { + // ok + } + } + }); + th2.start(); + while (!input.isPrompting()) { + Thread.sleep(10); + } + + input.close(); + + + } + } + + /** Test method for + * {@link fr.bigeon.gclc.socket.PluggableConsoleInput#getPrompt()}. */ + @Test + public final void testGetPrompt() { + final PluggableConsoleInput input = new PluggableConsoleInput(); + assertEquals("Default prompt invalid", "> ", input.getPrompt().apply()); + input.setPrompt("test"); + assertEquals("Prompt setting failed", "test", input.getPrompt().apply()); + } +} diff --git a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/RemoteDisconnectCommandTest.java b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/RemoteDisconnectCommandTest.java index dc7528d..4551513 100644 --- a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/RemoteDisconnectCommandTest.java +++ b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/RemoteDisconnectCommandTest.java @@ -1,105 +1,107 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.RemoteDisconnectCommandTest.java - * Created on: Nov 18, 2017 - */ -package fr.bigeon.gclc.socket; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.junit.Test; - -import fr.bigeon.gclc.exception.CommandRunException; -import fr.bigeon.gclc.manager.PipedConsoleOutput; - -/** - *

- * TODO - * - * @author Emmanuel Bigeon */ -public class RemoteDisconnectCommandTest { - - /** Test method for - * {@link fr.bigeon.gclc.socket.RemoteDisconnectCommand#execute(fr.bigeon.gclc.manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, java.lang.String[])}. - * - * @throws CommandRunException if the command unexpectedly failed. - * @throws IOException if the output could not be written to */ - @Test - public final void testExecute() throws CommandRunException, IOException { - final DConnexionManager manager = new DConnexionManager<>(); - final RemoteDisconnectCommand cmd = new RemoteDisconnectCommand<>( - "quit", manager, true); - final RemoteDisconnectCommand cmd2 = new RemoteDisconnectCommand<>( - "quit", manager, false); - manager.addConnexion("test"); - - cmd2.execute(null, null); - assertFalse("No arguemnt should remova no connections", - manager.getConnected().isEmpty()); - cmd.execute(null, null); - assertTrue("No arguemnt should remova all connections", - manager.getConnected().isEmpty()); - - final String name1 = manager.addConnexion("test"); - final String name2 = manager.addConnexion("test"); - - cmd.execute(null, null, name1); - assertFalse("With argument shuld remove specified name", - manager.getConnected().contains(name1)); - assertTrue("With argument shuld remove only specified name", - manager.getConnected().contains(name2)); - - cmd.execute(null, null, name1); - assertTrue("With argument shuld remove only specified name", - manager.getConnected().contains(name2)); - - try (PipedConsoleOutput out = new PipedConsoleOutput()) { - cmd.execute(out, null, name1); - assertTrue("With argument shuld remove only specified name", - manager.getConnected().contains(name2)); - - out.close(); - try { - cmd.execute(out, null, name1); - fail("Closed stream should cause error in printing"); - } catch (final CommandRunException e) { - // ok - } - } - } - -} +/** + * gclc-socket:fr.bigeon.gclc.socket.RemoteDisconnectCommandTest.java + * Created on: Nov 18, 2017 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.junit.Test; + +import fr.bigeon.gclc.exception.CommandRunException; +import fr.bigeon.gclc.manager.PipedConsoleOutput; + +/** + *

+ * TODO + * + * @author Emmanuel Bigeon */ +public class RemoteDisconnectCommandTest { + + /** Test method for + * {@link fr.bigeon.gclc.socket.RemoteDisconnectCommand#execute(fr.bigeon.gclc.manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, java.lang.String[])}. + * + * @throws CommandRunException if the command unexpectedly failed. + * @throws IOException if the output could not be written to */ + @Test + public final void testExecute() throws CommandRunException, IOException { + final DConnexionManager manager = new DConnexionManager<>(); + final RemoteDisconnectCommand cmd = new RemoteDisconnectCommand<>( + "quit", manager, true); + final RemoteDisconnectCommand cmd2 = new RemoteDisconnectCommand<>( + "quit", manager, false); + manager.addConnexion("test"); + + cmd2.execute(null, null); + assertFalse("No arguemnt should remova no connections", + manager.getConnected().isEmpty()); + cmd.execute(null, null); + assertTrue("No arguemnt should remova all connections", + manager.getConnected().isEmpty()); + + final String name1 = manager.addConnexion("test"); + final String name2 = manager.addConnexion("test"); + + cmd.execute(null, null, name1); + assertFalse("With argument shuld remove specified name", + manager.getConnected().contains(name1)); + assertTrue("With argument shuld remove only specified name", + manager.getConnected().contains(name2)); + + cmd.execute(null, null, name1); + assertTrue("With argument shuld remove only specified name", + manager.getConnected().contains(name2)); + + try (PipedConsoleOutput out = new PipedConsoleOutput()) { + cmd.execute(out, null, name1); + assertTrue("With argument shuld remove only specified name", + manager.getConnected().contains(name2)); + + out.close(); + try { + cmd.execute(out, null, name1); + fail("Closed stream should cause error in printing"); + } catch (final CommandRunException e) { + // ok + } + } + } + +} diff --git a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/SocketConsoleApplicationTest.java b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/SocketConsoleApplicationTest.java index 9f24fd1..37cb7c5 100644 --- a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/SocketConsoleApplicationTest.java +++ b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/SocketConsoleApplicationTest.java @@ -1,169 +1,171 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-socket:fr.bigeon.gclc.socket.SocketConsoleApplicationTest.java - * Created on: Jun 1, 2016 - */ -package fr.bigeon.gclc.socket; - -import static org.junit.Assert.assertEquals; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.logging.Logger; - -import org.junit.Test; - -/** Test class for {@link SocketConsoleApplicationShell} - * - * @author Emmanuel Bigeon */ -@SuppressWarnings({"static-method", "javadoc", "nls"}) -public class SocketConsoleApplicationTest { - - private static final Logger LOGGER = Logger - .getLogger(SocketConsoleApplicationTest.class.getName()); - - /** @param in the input - * @return the string - * @throws IOException if the input reading failed */ - private String consumeToPrompt(final String server, - final BufferedReader in) throws IOException { - String fromServer = server; - LOGGER.fine("Server: \n" + fromServer); - while (fromServer != null && !fromServer.equals("Bye.") && - !fromServer.equals("> ")) { - fromServer = in.readLine(); - LOGGER.fine("Server: \n" + fromServer); - } - return fromServer; - } - - @Test - public void testIntegration() throws IOException, InterruptedException { - Thread server; - server = TestServer.getServer(); - Thread.sleep(1000); - final String hostName = "127.0.0.1"; - final int portNumber = 3300; - - try (Socket kkSocket = new Socket(hostName, portNumber); - PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), - true); - BufferedReader in = new BufferedReader( - new InputStreamReader(kkSocket.getInputStream()));) { - - String fromServer; - int i = -1; - final String[] cmds = {"help", "toto", "test", "out"}; - while ((fromServer = in.readLine()) != null) { - i++; - fromServer = consumeToPrompt(fromServer, in); - if (fromServer == null || fromServer.equals("Bye.")) { - break; - } - - final String fromUser = cmds[i]; - if (fromUser != null) { - LOGGER.fine("Client: " + fromUser); - out.println(fromUser); - } - } - assertEquals("Disconnection command should close connection", 3, i); - } - - try (Socket kkSocket = new Socket(hostName, portNumber); - PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), - true); - BufferedReader in = new BufferedReader( - new InputStreamReader(kkSocket.getInputStream()));) { - - String fromServer; - int i = 0; - final String[] cmds = {"help", "toto", "test", - ConsoleTestApplication.EXIT}; - while ((fromServer = in.readLine()) != null) { - fromServer = consumeToPrompt(fromServer, in); - if (fromServer == null || fromServer.equals("Bye.")) { - break; - } - LOGGER.info("Server: \n" + fromServer); - - final String fromUser = cmds[i]; - if (fromUser != null) { - LOGGER.info("Client: " + fromUser); - out.println(fromUser); - } - i++; - } - assertEquals("Application exit command should close connection", 4, - i); - } - Thread.sleep(100); - TestServer.closeServer(); - server.join(); - server = TestServer.getServer(); - Thread.sleep(1000); - - - try (Socket kkSocket = new Socket(hostName, portNumber); - PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), - true); - BufferedReader in = new BufferedReader( - new InputStreamReader(kkSocket.getInputStream()));) { - - String fromServer; - int i = 0; - final String[] cmds = {"help", "toto", "test", - ConsoleTestApplication.EXIT}; - while ((fromServer = in.readLine()) != null) { - fromServer = consumeToPrompt(fromServer, in); - if (fromServer == null || fromServer.equals("Bye.")) { - break; - } - - final String fromUser = cmds[i]; - if (fromUser != null) { - LOGGER.fine("Client: " + fromUser); - out.println(fromUser); - } - i++; - } - assertEquals("Application exit command should close connection", 4, - i); - } - TestServer.closeServer(); - server.join(); - } -} +/** + * gclc-socket:fr.bigeon.gclc.socket.SocketConsoleApplicationTest.java + * Created on: Jun 1, 2016 + */ +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.logging.Logger; + +import org.junit.Test; + +/** Test class for {@link SocketConsoleApplicationShell} + * + * @author Emmanuel Bigeon */ +@SuppressWarnings({"static-method", "javadoc", "nls"}) +public class SocketConsoleApplicationTest { + + private static final Logger LOGGER = Logger + .getLogger(SocketConsoleApplicationTest.class.getName()); + + /** @param in the input + * @return the string + * @throws IOException if the input reading failed */ + private String consumeToPrompt(final String server, + final BufferedReader in) throws IOException { + String fromServer = server; + LOGGER.fine("Server: \n" + fromServer); + while (fromServer != null && !fromServer.equals("Bye.") && + !fromServer.equals("> ")) { + fromServer = in.readLine(); + LOGGER.fine("Server: \n" + fromServer); + } + return fromServer; + } + + @Test + public void testIntegration() throws IOException, InterruptedException { + Thread server; + server = TestServer.getServer(); + Thread.sleep(1000); + final String hostName = "127.0.0.1"; + final int portNumber = 3300; + + try (Socket kkSocket = new Socket(hostName, portNumber); + PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), + true); + BufferedReader in = new BufferedReader( + new InputStreamReader(kkSocket.getInputStream()));) { + + String fromServer; + int i = -1; + final String[] cmds = {"help", "toto", "test", "out"}; + while ((fromServer = in.readLine()) != null) { + i++; + fromServer = consumeToPrompt(fromServer, in); + if (fromServer == null || fromServer.equals("Bye.")) { + break; + } + + final String fromUser = cmds[i]; + if (fromUser != null) { + LOGGER.fine("Client: " + fromUser); + out.println(fromUser); + } + } + assertEquals("Disconnection command should close connection", 3, i); + } + + try (Socket kkSocket = new Socket(hostName, portNumber); + PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), + true); + BufferedReader in = new BufferedReader( + new InputStreamReader(kkSocket.getInputStream()));) { + + String fromServer; + int i = 0; + final String[] cmds = {"help", "toto", "test", + ConsoleTestApplication.EXIT}; + while ((fromServer = in.readLine()) != null) { + fromServer = consumeToPrompt(fromServer, in); + if (fromServer == null || fromServer.equals("Bye.")) { + break; + } + LOGGER.info("Server: \n" + fromServer); + + final String fromUser = cmds[i]; + if (fromUser != null) { + LOGGER.info("Client: " + fromUser); + out.println(fromUser); + } + i++; + } + assertEquals("Application exit command should close connection", 4, + i); + } + Thread.sleep(100); + TestServer.closeServer(); + server.join(); + server = TestServer.getServer(); + Thread.sleep(1000); + + + try (Socket kkSocket = new Socket(hostName, portNumber); + PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), + true); + BufferedReader in = new BufferedReader( + new InputStreamReader(kkSocket.getInputStream()));) { + + String fromServer; + int i = 0; + final String[] cmds = {"help", "toto", "test", + ConsoleTestApplication.EXIT}; + while ((fromServer = in.readLine()) != null) { + fromServer = consumeToPrompt(fromServer, in); + if (fromServer == null || fromServer.equals("Bye.")) { + break; + } + + final String fromUser = cmds[i]; + if (fromUser != null) { + LOGGER.fine("Client: " + fromUser); + out.println(fromUser); + } + i++; + } + assertEquals("Application exit command should close connection", 4, + i); + } + TestServer.closeServer(); + server.join(); + } +} diff --git a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestConsoleClient.java b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestConsoleClient.java index 97dce4e..0afcd3e 100644 --- a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestConsoleClient.java +++ b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestConsoleClient.java @@ -1,92 +1,94 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -package fr.bigeon.gclc.socket; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collection; - -import fr.bigeon.smu.StringEncoder; - -/** TODO Describe TestConsoleClient.java - * @author Emmanuel Bigeon - * - */ -@SuppressWarnings("nls") -public class TestConsoleClient { - @SuppressWarnings("javadoc") - private static final Collection TO_ENCODE = new ArrayList<>(); - static { - TO_ENCODE.add("\n"); - } - - @SuppressWarnings("javadoc") - private static final StringEncoder ENCODER = new StringEncoder("%", - TO_ENCODE); - - @SuppressWarnings("javadoc") - public static void main(String[] args) { - final String hostName = "127.0.0.1"; - final int portNumber = 3300; - - try (Socket kkSocket = new Socket(hostName, portNumber); - PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), - true); - BufferedReader in = new BufferedReader(new InputStreamReader( - kkSocket.getInputStream()));) { - - String fromServer; - while ((fromServer = in.readLine()) != null) { - System.out.println("Server: \n" + ENCODER.decode(fromServer)); - if (fromServer.equals("Bye.")) { - break; - } - - final BufferedReader stdIn = new BufferedReader( - new InputStreamReader(System.in)); - final String fromUser = stdIn.readLine(); - if (fromUser != null) { - System.out.println("Client: " + fromUser); - out.println(fromUser); - } - } - } catch (final IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } -} +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Collection; + +import fr.bigeon.smu.StringEncoder; + +/** TODO Describe TestConsoleClient.java + * @author Emmanuel Bigeon + * + */ +@SuppressWarnings("nls") +public class TestConsoleClient { + @SuppressWarnings("javadoc") + private static final Collection TO_ENCODE = new ArrayList<>(); + static { + TO_ENCODE.add("\n"); + } + + @SuppressWarnings("javadoc") + private static final StringEncoder ENCODER = new StringEncoder("%", + TO_ENCODE); + + @SuppressWarnings("javadoc") + public static void main(String[] args) { + final String hostName = "127.0.0.1"; + final int portNumber = 3300; + + try (Socket kkSocket = new Socket(hostName, portNumber); + PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), + true); + BufferedReader in = new BufferedReader(new InputStreamReader( + kkSocket.getInputStream()));) { + + String fromServer; + while ((fromServer = in.readLine()) != null) { + System.out.println("Server: \n" + ENCODER.decode(fromServer)); + if (fromServer.equals("Bye.")) { + break; + } + + final BufferedReader stdIn = new BufferedReader( + new InputStreamReader(System.in)); + final String fromUser = stdIn.readLine(); + if (fromUser != null) { + System.out.println("Client: " + fromUser); + out.println(fromUser); + } + } + } catch (final IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestServer.java b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestServer.java index 58fbce2..86c1f1a 100644 --- a/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestServer.java +++ b/gclc-socket/src/test/java/fr/bigeon/gclc/socket/TestServer.java @@ -1,105 +1,107 @@ -/* - * GCLC Socket, Socket implementation of GCLC - * Copyright (C) 2014-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -package fr.bigeon.gclc.socket; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import fr.bigeon.gclc.ConsoleApplication; - -/** A test server - * - * @author Emmanuel Bigeon */ -@SuppressWarnings({"javadoc", "nls"}) -public class TestServer { - - private static SocketConsoleApplicationShell SHELL; - private static ConnexionManager manager; - - private static Thread server; - private static PluggableConsoleInput input; - private static PluggableConsoleOutput output; - - public static synchronized void closeServer() { - SHELL.stop(); - input.close(); - output.close(); - SHELL = null; - server = null; - } - - public static synchronized Thread getServer() throws IOException { - if (server == null) { - server = new Thread(getShell(), "gclcServer"); - server.start(); - } - return server; - } - - private static SocketConsoleApplicationShell getShell() throws UnknownHostException { - if (SHELL == null) { - input = new PluggableConsoleInput(); - input.setPrompt("> \n"); - output = new PluggableConsoleOutput(); - manager = new DConnexionManager<>(); - SHELL = new SocketConsoleApplicationShell(3300, - InetAddress.getByName("127.0.0.1")); - final ConsoleApplication app = ConsoleTestApplication - .create(output, input, manager); - SHELL.setInterface(new SocketConsoleInterface(input, output)); - SHELL.setConnexionManager(manager); - SHELL.setApplication(app); - final Thread th = new Thread(new Runnable() { - - @Override - public void run() { - app.start(); - } - }); - th.start(); - } - return SHELL; - } - - /** @param args no argument - * @throws IOException if the server starting failed */ - public static void main(final String... args) throws IOException { - try { - getServer().join(); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } - -} +package fr.bigeon.gclc.socket; + +/*- + * #%L + * GCLC Socket + * %% + * Copyright (C) 2016 - 2018 Bigeon + * %% + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * #L% + */ +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import fr.bigeon.gclc.ConsoleApplication; + +/** A test server + * + * @author Emmanuel Bigeon */ +@SuppressWarnings({"javadoc", "nls"}) +public class TestServer { + + private static SocketConsoleApplicationShell SHELL; + private static ConnexionManager manager; + + private static Thread server; + private static PluggableConsoleInput input; + private static PluggableConsoleOutput output; + + public static synchronized void closeServer() { + SHELL.stop(); + input.close(); + output.close(); + SHELL = null; + server = null; + } + + public static synchronized Thread getServer() throws IOException { + if (server == null) { + server = new Thread(getShell(), "gclcServer"); + server.start(); + } + return server; + } + + private static SocketConsoleApplicationShell getShell() throws UnknownHostException { + if (SHELL == null) { + input = new PluggableConsoleInput(); + input.setPrompt("> \n"); + output = new PluggableConsoleOutput(); + manager = new DConnexionManager<>(); + SHELL = new SocketConsoleApplicationShell(3300, + InetAddress.getByName("127.0.0.1")); + final ConsoleApplication app = ConsoleTestApplication + .create(output, input, manager); + SHELL.setInterface(new SocketConsoleInterface(input, output)); + SHELL.setConnexionManager(manager); + SHELL.setApplication(app); + final Thread th = new Thread(new Runnable() { + + @Override + public void run() { + app.start(); + } + }); + th.start(); + } + return SHELL; + } + + /** @param args no argument + * @throws IOException if the server starting failed */ + public static void main(final String... args) throws IOException { + try { + getServer().join(); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/gclc/pom.xml b/gclc/pom.xml index fb16a65..fc98d44 100644 --- a/gclc/pom.xml +++ b/gclc/pom.xml @@ -6,10 +6,10 @@ gclc 2.0.6-SNAPSHOT jar - http://www.bigeon.fr/emmanuel + http://www.bigeon.net UTF-8 - git.bigeon.net + git.code.bigeon.net emmanuel@bigeon.fr cecill_2.1 @@ -75,8 +75,8 @@ Generic Command Ligne console A generic framework for console applications, with customized command input and output streams. - scm:git:gogs@git.code.bigeon.net:emmanuel/gclc.git + HEAD net.bigeon