Author: tchemit Date: 2010-12-30 10:44:04 +0100 (Thu, 30 Dec 2010) New Revision: 1998 Url: http://nuiton.org/repositories/revision/nuiton-utils/1998 Log: Evolution #1187: Introduce nuiton-validator module Added: trunk/LICENSE.txt trunk/README.txt trunk/changelog.txt trunk/nuiton-validator/ trunk/nuiton-validator/LICENSE.txt trunk/nuiton-validator/README.txt trunk/nuiton-validator/changelog.txt trunk/nuiton-validator/pom.xml trunk/nuiton-validator/src/ trunk/nuiton-validator/src/license/ trunk/nuiton-validator/src/license/THIRD-PARTY.properties trunk/nuiton-validator/src/main/ trunk/nuiton-validator/src/main/java/ trunk/nuiton-validator/src/main/java/org/ trunk/nuiton-validator/src/main/java/org/nuiton/ trunk/nuiton-validator/src/main/java/org/nuiton/validator/ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionFieldExpressionValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionUniqueKeyValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingDirectoryFieldValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingFileFieldValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/FieldExpressionWithParamsValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingFileFieldValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/RequiredFileFieldValidator.java trunk/nuiton-validator/src/main/resources/ trunk/nuiton-validator/src/main/resources/i18n/ trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_en_GB.properties trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_fr_FR.properties trunk/nuiton-validator/src/main/resources/validators.xml trunk/nuiton-validator/src/site/ trunk/nuiton-validator/src/site/apt/ trunk/nuiton-validator/src/site/apt/index.apt trunk/nuiton-validator/src/site/site_fr.xml trunk/nuiton-validator/src/test/ trunk/nuiton-validator/src/test/java/ trunk/nuiton-validator/src/test/java/org/ trunk/nuiton-validator/src/test/java/org/nuiton/ trunk/nuiton-validator/src/test/java/org/nuiton/validator/ trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractValidatorBeanFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionFieldExpressionValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionUniqueKeyValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingDirectoryFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingFileFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionBean.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionWithParamsValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingFileFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/RequiredFileFieldValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ValidatorBean.java trunk/nuiton-validator/src/test/resources/ trunk/nuiton-validator/src/test/resources/log4j.properties trunk/nuiton-validator/src/test/resources/org/ trunk/nuiton-validator/src/test/resources/org/nuiton/ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/FieldExpressionBean-error-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ValidatorBean-error-validation.xml trunk/nuiton-validator/src/test/resources/validators.xml trunk/pom.xml trunk/src/ trunk/src/site/ trunk/src/site/apt/ trunk/src/site/apt/index.apt trunk/src/site/site_fr.xml Modified: trunk/nuiton-utils/ trunk/nuiton-utils/pom.xml trunk/nuiton-utils/src/site/site_fr.xml Added: trunk/LICENSE.txt =================================================================== --- trunk/LICENSE.txt (rev 0) +++ trunk/LICENSE.txt 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Property changes on: trunk/LICENSE.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Property changes on: trunk/README.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Property changes on: trunk/changelog.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Property changes on: trunk/nuiton-utils ___________________________________________________________________ Added: svn:ignore + target velocity.log maven.log .eclipse .classpath *.iml *.ipr *.iws .settings .project Modified: trunk/nuiton-utils/pom.xml =================================================================== --- trunk/nuiton-utils/pom.xml 2010-12-29 23:16:21 UTC (rev 1997) +++ trunk/nuiton-utils/pom.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -22,7 +22,9 @@ <http://www.gnu.org/licenses/lgpl-3.0.html>. #L% --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -32,23 +34,15 @@ <parent> <groupId>org.nuiton</groupId> - <artifactId>mavenpom4redmineAndCentral</artifactId> - <version>2.4.1</version> + <artifactId>nuiton-utils-parent</artifactId> + <version>2.0-SNAPSHOT</version> </parent> <artifactId>nuiton-utils</artifactId> - <version>2.0-SNAPSHOT</version> <dependencies> <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - <!--version>1.2.16</version--> - <scope>provided</scope> - </dependency> - - <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </dependency> @@ -71,8 +65,6 @@ <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> - <version>${nuitonI18nVersion}</version> - <scope>compile</scope> </dependency> <dependency> @@ -84,17 +76,21 @@ <dependency> <groupId>org.jvnet.hudson.winstone</groupId> <artifactId>winstone</artifactId> - <version>0.9.10-hudson-24</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty.aggregate</groupId> <artifactId>jetty-webapp</artifactId> - <version>7.1.0.v20100505</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> @@ -102,84 +98,19 @@ <!-- *** Project Information ************************************* --> <!-- ************************************************************* --> - <name>Nuiton Utils</name> + <name>Nuiton Utils :: Nuiton Utils</name> <description>Library of usefull class to be used in any project.</description> <inceptionYear>2004</inceptionYear> - <url>http://maven-site.nuiton.org/nuiton-utils</url> - <developers> - - <developer> - <name>Brendan Le Ny</name> - <id>bleny</id> - <email>bleny@codelutin.com</email> - <organization>CodeLutin</organization> - <timezone>+2</timezone> - <roles> - <role>developer</role> - </roles> - </developer> - - <developer> - <name>Benjamin Poussin</name> - <id>bpoussin</id> - <email>poussin@codelutin.com</email> - <organization>CodeLutin</organization> - <timezone>+2</timezone> - <roles> - <role>Développeur</role> - <role>Debian packager</role> - </roles> - </developer> - - <developer> - <name>Éric Chatellier</name> - <id>echatellier</id> - <email>chatellier@codelutin.com</email> - <organization>CodeLutin</organization> - <timezone>+2</timezone> - <roles> - <role>Développeur</role> - </roles> - </developer> - - <developer> - <name>Sylvain Letellier</name> - <id>sletellier</id> - <email>letellier@codelutin.com</email> - <organization>CodeLutin</organization> - <timezone>+2</timezone> - <roles> - <role>Développeur</role> - </roles> - </developer> - - <developer> - <name>Tony Chemit</name> - <id>tchemit</id> - <email>chemit@codelutin.com</email> - <organization>CodeLutin</organization> - <timezone>+2</timezone> - <roles> - <role>developer</role> - </roles> - </developer> - - </developers> - <!-- ************************************************************* --> <!-- *** Build Settings ****************************************** --> <!-- ************************************************************* --> - <packaging>jar</packaging> - <properties> - - <nuitonI18nVersion>2.0.1</nuitonI18nVersion> - + <!-- extra files to include in release --> <redmine.releaseFiles>${redmine.libReleaseFiles}</redmine.releaseFiles> - + </properties> <build> @@ -190,7 +121,6 @@ <plugin> <groupId>org.nuiton.i18n</groupId> <artifactId>maven-i18n-plugin</artifactId> - <version>${nuitonI18nVersion}</version> <configuration> <silent>true</silent> </configuration> @@ -212,13 +142,6 @@ <!-- *** Build Environment ************************************** --> <!-- ************************************************************* --> - <!-- Source control management. --> - <scm> - <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-utils/trunk</connection> - <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-utils/trunk</developerConnection> - <url>http://www.nuiton.org/repositories/browse/nuiton-utils/trunk</url> - </scm> - <profiles> <profile> <id>reporting</id> Modified: trunk/nuiton-utils/src/site/site_fr.xml =================================================================== --- trunk/nuiton-utils/src/site/site_fr.xml 2010-12-29 23:16:21 UTC (rev 1997) +++ trunk/nuiton-utils/src/site/site_fr.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -31,16 +31,14 @@ <href>index.html</href> </bannerLeft> - <poweredBy> - <logo href="http://maven.apache.org" name="Maven" img="images/logos/maven-feather.png"/> - </poweredBy> - <body> <breadcrumbs> <item name="${project.name}" href="index.html"/> </breadcrumbs> + <menu ref="parent"/> + <menu name="Utilisateur"> <item name="Accueil" href="index.html"/> <item name="Documentation" href="/nuitonUtil.html"/> Property changes on: trunk/nuiton-validator ___________________________________________________________________ Added: svn:ignore + target velocity.log maven.log .eclipse .classpath *.iml *.ipr *.iws .settings .project Added: trunk/nuiton-validator/LICENSE.txt =================================================================== --- trunk/nuiton-validator/LICENSE.txt (rev 0) +++ trunk/nuiton-validator/LICENSE.txt 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Property changes on: trunk/nuiton-validator/LICENSE.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Property changes on: trunk/nuiton-validator/README.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Property changes on: trunk/nuiton-validator/changelog.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/pom.xml =================================================================== --- trunk/nuiton-validator/pom.xml (rev 0) +++ trunk/nuiton-validator/pom.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,242 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils-parent</artifactId> + <version>2.0-SNAPSHOT</version> + </parent> + + <artifactId>nuiton-validator</artifactId> + + <dependencies> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>nuiton-utils</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> + </dependency> + + <dependency> + <groupId>org.nuiton.i18n</groupId> + <artifactId>nuiton-i18n</artifactId> + </dependency> + + <!-- xworks dependencies --> + + <dependency> + <groupId>com.opensymphony</groupId> + <artifactId>xwork</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>provided</scope> + </dependency> + + </dependencies> + + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>Nuiton Utils :: Validator</name> + <description>Validator Api.</description> + <inceptionYear>2011</inceptionYear> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <properties> + + <!-- extra files to include in release --> + <redmine.releaseFiles>${redmine.libReleaseFiles}</redmine.releaseFiles> + + </properties> + + <build> + + <plugins> + + <!-- plugin i18n --> + <plugin> + <groupId>org.nuiton.i18n</groupId> + <artifactId>maven-i18n-plugin</artifactId> + <configuration> + <silent>true</silent> + </configuration> + <executions> + <execution> + <goals> + <goal>parserJava</goal> + <goal>gen</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + + <pluginManagement> + <plugins> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <id>attach-test</id> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </pluginManagement> + + </build> + + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + + <profiles> + + <!-- perform only on a release stage when using the maven-release-plugin --> + <profile> + <id>release-profile</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + + <build> + <plugins> + + <!-- always compute tests source jar --> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <id>attach-test-sources</id> + </execution> + </executions> + </plugin> + + <!-- always compute tests javadoc jar --> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <executions> + <execution> + <id>attach-test-javadoc</id> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + </build> + </profile> + + <profile> + <id>reporting</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <quiet>true</quiet> + <links> + <link>http://java.sun.com/javase/6/docs/api/</link> + </links> + </configuration> + </plugin> + </plugins> + </reporting> + + </profile> + + <!-- create assemblies at release time --> + <profile> + <id>assembly-profile</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + <build> + <plugins> + + <!-- launch in a release the assembly automaticly --> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>create-assemblies</id> + <phase>verify</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + <configuration> + <attach>false</attach> + <descriptorRefs> + <descriptorRef>deps</descriptorRef> + <descriptorRef>full</descriptorRef> + </descriptorRefs> + </configuration> + </plugin> + + </plugins> + + </build> + </profile> + + </profiles> + +</project> Property changes on: trunk/nuiton-validator/pom.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/license/THIRD-PARTY.properties =================================================================== --- trunk/nuiton-validator/src/license/THIRD-PARTY.properties (rev 0) +++ trunk/nuiton-validator/src/license/THIRD-PARTY.properties 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,16 @@ +# Generated by org.nuiton.license.plugin.AddThirdPartyMojo +#------------------------------------------------------------------------------- +# Already used licenses in project : +# - BSD License +# - Common Public License Version 1.0 +# - Lesser General Public License (LGPL) v 3.0 +# - The Apache Software License, Version 2.0 +# - The OpenSymphony Software License 1.1 +#------------------------------------------------------------------------------- +# Please fill the missing licenses for dependencies : +# +# +#Thu Dec 30 09:14:11 CET 2010 +commons-primitives--commons-primitives--1.0--jar=The Apache Software License, Version 2.0 +opensymphony--ognl--2.6.11--jar=The OpenSymphony Software License 1.1 + Property changes on: trunk/nuiton-validator/src/license/THIRD-PARTY.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,635 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.converter.ConverterUtil; + +import javax.swing.event.EventListenerList; +import java.beans.EventSetDescriptor; +import java.beans.Introspector; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +/** + * A customized validator for a given bean. + * <p/> + * <b>Note:</b> The bean must be listenable on properyChange events (means must + * have public addPropertychangeListener and removePropertyChangeListener + * methods). + * + * @author tchemit <chemit@codelutin.com> + * @param <B> type of the bean to validate. + */ +public class BeanValidator<B> { + + /** la nom de la propriété bean */ + static public final String BEAN_PROERTY = "bean"; + + /** la nom de la propriété contextName */ + static public final String CONTEXT_NAME_PROPERTY = "contextName"; + + /** la nom de l'état valid */ + static public final String VALID_PROERTY = "valid"; + + /** la nom de l'état changed */ + static public final String CHANGED_PROERTY = "changed"; + + /** Logger */ + static protected final Log log = LogFactory.getLog(BeanValidator.class); + + protected static final BeanValidatorScope[] FILTER_SCOPES_EMPTY = + new BeanValidatorScope[0]; + + /** the type of bean to watch */ + protected final Class<B> beanClass; + + /** the validation named context (can be null) */ + protected String contextName; + + /** to chain to a prent validator */ + protected BeanValidator<?> parentValidator; + + /** + * state to indicate that validator has changed since the last time bean was + * setted + */ + protected boolean changed; + + /** state of the validator (is true if no errors of error scope is found) */ + protected boolean valid = true; + + /** bean to be watched */ + protected B bean; + + /** to add and remove PropertyChangeListener on watched beans */ + protected EventSetDescriptor beanEventDescriptor; + + /** list of fields watched by this validator */ + protected Set<BeanValidatorField<B>> fields; + + /** map of conversion errors detected by this validator */ + protected Map<String, String> conversionErrors; + + /** xworks scope validator * */ + protected EnumMap<BeanValidatorScope, XWorkBeanValidator<B>> validators; + + /** filter scopes (if {@code null}, no filter on scopes) */ + protected BeanValidatorScope[] filterScopes; + + /** listener that listens on bean modification */ + protected PropertyChangeListener l; + + /** delegate property change support */ + protected PropertyChangeSupport pcs; + + /** A list of event listeners for this validators */ + protected EventListenerList listenerList = new EventListenerList(); + + public BeanValidator(Class<B> beanClass, + String contextName) { + this(beanClass, + contextName, + BeanValidatorScope.values() + ); + } + + public BeanValidator(Class<B> beanClass, + String contextName, + BeanValidatorScope... filterScopes) { + this.beanClass = beanClass; + if (filterScopes != null && filterScopes.length > 0) { + this.filterScopes = filterScopes; + } + pcs = new PropertyChangeSupport(this); + conversionErrors = new TreeMap<String, String>(); + validators = new EnumMap<BeanValidatorScope, XWorkBeanValidator<B>>( + BeanValidatorScope.class); + + setContextName(contextName); + + l = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + // chaque modification lance la validation + doValidate(); + } + }; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public BeanValidator<?> getParentValidator() { + return parentValidator; + } + + public String getContextName() { + return contextName; + } + + public Set<BeanValidatorField<B>> getFields() { + return fields; + } + + public Set<BeanValidatorScope> getScopes() { + return new HashSet<BeanValidatorScope>(validators.keySet()); + } + + /** + * Retourne vrai si l'objet bean a ete modifie depuis le dernier {@link + * #setBean} + * + * @return <code>true</code> if bean was modify since last {@link + * #setBean(Object)} invocation + */ + public boolean isChanged() { + return changed; + } + + public boolean isValid() { + return valid; + } + + public B getBean() { + return bean; + } + + public BeanValidatorField<B> getField(String fieldName) { + for (BeanValidatorField<B> field : fields) { + if (fieldName.equals(field.getName())) { + return field; + } + } + return null; + } + + public boolean hasFatalErrors() { + for (BeanValidatorField<B> field : fields) { + if (field.hasFatalErrors()) { + return true; + } + } + return false; + } + + public boolean hasErrors() { + for (BeanValidatorField<B> field : fields) { + if (field.hasErrors()) { + return true; + } + } + return false; + } + + public boolean hasWarnings() { + for (BeanValidatorField<B> field : fields) { + if (field.hasWarnings()) { + return true; + } + } + return false; + } + + public boolean hasInfos() { + for (BeanValidatorField<B> field : fields) { + if (field.hasInfos()) { + return true; + } + } + return false; + } + + /** + * Test a the validator contains the field given his name + * + * @param fieldName the name of the searched field + * @return <code>true</code> if validator contaisn this field, + * <code>false</code> otherwise + */ + public boolean containsField(String fieldName) { + BeanValidatorField<B> field = getField(fieldName); + return field != null; + } + + public boolean isValid(String fieldName) { + BeanValidatorField<B> field = getField(fieldName); + if (field == null) { + throw new IllegalArgumentException( + "could not find a validator field " + fieldName); + } + return field.isValid(); + } + + /** + * Permet de force la remise a false de l'etat de changement du bean + * + * @param changed flag to force reset of property {@link #changed} + */ + public void setChanged(boolean changed) { + this.changed = changed; + // force the property to be fired (never pass the older value) + pcs.firePropertyChange(CHANGED_PROERTY, null, changed); + } + + public void setValid(boolean valid) { + this.valid = valid; + // force the property to be fired (never pass the older value) + pcs.firePropertyChange(VALID_PROERTY, null, valid); + } + + public void setBean(B bean) { + B oldBean = this.bean; + if (log.isDebugEnabled()) { + log.debug(this + " : " + bean); + } + + // clean conversions of previous bean + conversionErrors.clear(); + + if (oldBean != null) { + try { + EventSetDescriptor descriptor = getBeanEventDescriptor(oldBean); + descriptor.getRemoveListenerMethod().invoke(oldBean, l); + } catch (Exception eee) { + if (log.isInfoEnabled()) { + log.info("Can't register as listener for bean " + beanClass + + " for reason " + eee.getMessage(), eee); + } + } + } + this.bean = bean; + + if (bean == null) { + + // remove all messages for all fields of the validator + + for (BeanValidatorField<B> f : fields) { + + f.updateMessages(this, null, null); + } + + } else { + try { + EventSetDescriptor descriptor = getBeanEventDescriptor(bean); + descriptor.getAddListenerMethod().invoke(bean, l); + } catch (Exception eee) { + if (log.isInfoEnabled()) { + log.info("Can't register as listener for bean " + beanClass + + " for reason " + eee.getMessage(), eee); + } + } + validate(); + } + setChanged(false); + setValid(!hasFatalErrors() && !hasErrors()); + pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); + } + + public void setContextName(String contextName) { + String oldContextName = this.contextName; + this.contextName = contextName; + // changing contextName could change fields definition + // so dettach bean, must rebuild the fields + if (bean != null) { + setBean(null); + } + // rebuild the fields + initFields(); + pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, + oldContextName, + contextName + ); + } + + /** + * Sets the filter scopes. + * + * @param filterScopes the scopes to used + */ + public void setFilterScopes(BeanValidatorScope... filterScopes) { + this.filterScopes = filterScopes; + // changing contextName could change fields definition + // so dettach bean, must rebuild the fields + if (bean != null) { + setBean(null); + } + // rebuild the fields + initFields(); + } + + public void setParentValidator(BeanValidator<?> parentValidator) { + this.parentValidator = parentValidator; + } + + /** + * Convert a value. + * <p/> + * If an error occurs, then add an error in validator. + * + * @param <T> the type of conversion + * @param fieldName the name of the bean property + * @param value the value to convert + * @param valueClass the type of converted value + * @return the converted value, or null if conversion was not ok + */ + @SuppressWarnings({"unchecked"}) + public <T> T convert(String fieldName, String value, Class<T> valueClass) { + if (fieldName == null) { + throw new IllegalArgumentException("fieldName can not be null"); + } + if (valueClass == null) { + throw new IllegalArgumentException("valueClass can not be null"); + } + + // on ne convertit pas si il y a un bean et que le resultat de la + // validation pourra etre affiche quelque part + if (!canValidate() || value == null) { + return null; + } + + // remove the previous conversion error for the field + conversionErrors.remove(fieldName); + + T result; + try { + Converter converter = ConverterUtil.getConverter(valueClass); + if (converter == null) { + throw new RuntimeException( + "could not find converter for the type " + valueClass); + } + result = (T) converter.convert(valueClass, value); + /* Why this test ? if (result != null && !value.equals(result.toString())) { + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + }*/ + } catch (ConversionException e) { + // get + String s = Introspector.decapitalize(valueClass.getSimpleName()); + conversionErrors.put(fieldName, "error.convertor." + s); + result = null; + validate(); + } + return result; + } + + /** + * Methode pour forcer la revalidation d'un bean en mettant a jour les etats + * internes. + * <p/> + * La méthode appelle {@link #validate()} puis met à jour les etats internes + * {@link #valid} et {@link #changed}. + * + * @since 1.5 + */ + public void doValidate() { + validate(); + setValid(!hasFatalErrors() && !hasErrors()); + setChanged(true); + } + + /** + * il faut eviter le code re-intrant (durant une validation, une autre est + * demandee). Pour cela on fait la validation dans un thread, et tant que la + * premiere validation n'est pas fini, on ne repond pas aux solicitations. + * Cette method est public pour permettre de force une validation par + * programmation, ce qui est utile par exemple si le bean ne supporte pas + * les {@link PropertyChangeListener} + * <p/> + * <b>Note:</b> la methode est protected et on utilise la methode + * {@link #doValidate()} car la méthode ne modifie pas les etats + * internes et cela en rend son utilisation delicate (le validateur entre + * dans un etat incoherent par rapport aux messages envoyés). + */ + protected void validate() { + + // on ne valide que si il y a un bean et que le resultat de la validation + // pourra etre affiche quelque part + if (!canValidate()) { + return; + } + + for (BeanValidatorScope scope : validators.keySet()) { + + XWorkBeanValidator<B> validator = validators.get(scope); + + Map<String, List<String>> newMessages = validator.validate(bean); + + if (scope == BeanValidatorScope.ERROR) { + // treate conversion errors + // reinject them + for (Entry<String, String> entry : conversionErrors.entrySet()) { + // remove from validation, errors occurs on this field + List<String> errors = newMessages.get(entry.getKey()); + String conversionError = entry.getValue(); + if (errors != null) { + errors.clear(); + errors.add(conversionError); + } else { + errors = Collections.singletonList(conversionError); + if (XWorkBeanValidator.EMPTY_RESULT.equals(newMessages)) { + newMessages = new HashMap<String, List<String>>(); + } + // add the concrete conversion error + newMessages.put(entry.getKey(), errors); + } + } + } + + // for each field, update his list of messages + for (BeanValidatorField<B> field : fields) { + List<String> messagesForField = newMessages.get(field.getName()); + if (field.getScopes().contains(scope)) { + field.updateMessages(this, scope, messagesForField); + } + } + } + + if (parentValidator != null) { + // chained validation + // the parent validator should not be changed from this validation + boolean wasModified = parentValidator.isChanged(); + parentValidator.doValidate(); + if (!wasModified) { + // push back old state + parentValidator.setChanged(false); + } + } + + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + beanClass + + ", contextName:" + contextName + ">"; + } + + public void addBeanValidatorListener(BeanValidatorListener listener) { + listenerList.add(BeanValidatorListener.class, listener); + } + + public void removeBeanValidatorListener(BeanValidatorListener listener) { + listenerList.remove(BeanValidatorListener.class, listener); + } + + public BeanValidatorListener[] getBeanValidatorListeners() { + return listenerList.getListeners(BeanValidatorListener.class); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + + /** + * @return <code>true</code> if validation is enabled, <code>false</code> + * otherwise. + */ + protected boolean canValidate() { + return !(bean == null || fields.isEmpty()); + } + + protected void fireFieldChanged(BeanValidatorField<B> field, + BeanValidatorScope scope, + String[] toAdd, + String[] toDelete) { + + BeanValidatorEvent evt = new BeanValidatorEvent( + this, + field, + scope, + toAdd, + toDelete + ); + + for (BeanValidatorListener listener : + listenerList.getListeners(BeanValidatorListener.class)) { + listener.onFieldChanged(evt); + } + } + + protected void initFields() { + + Set<String> detectedFieldNames = new HashSet<String>(); + EnumMap<BeanValidatorScope, Set<String>> tmp; + tmp = new EnumMap<BeanValidatorScope, Set<String>>( + BeanValidatorScope.class + ); + Set<BeanValidatorField<B>> detectedFields = + new HashSet<BeanValidatorField<B>>(); + + validators.clear(); + + BeanValidatorScope[] scopeUniverse; + if (filterScopes == null) { + // use all scopes + scopeUniverse = BeanValidatorScope.values(); + } else { + // use customized scopes + scopeUniverse = filterScopes; + } + + for (BeanValidatorScope scope : scopeUniverse) { + String scopeContext = + (contextName == null ? "" : contextName + "-") + + scope.name().toLowerCase(); + + XWorkBeanValidator<B> newValidator = + new XWorkBeanValidator<B>(beanClass, scopeContext, false); + Set<String> fieldNames = newValidator.getFieldNames(); + if (log.isDebugEnabled()) { + log.debug("detected validators for scope " + scopeContext + + " : " + fieldNames); + } + if (!fieldNames.isEmpty()) { + // fields detected in this validator, keep it + validators.put(scope, newValidator); + detectedFieldNames.addAll(fieldNames); + tmp.put(scope, fieldNames); + } + } + + List<BeanValidatorScope> scopes = new ArrayList<BeanValidatorScope>(); + for (String fieldName : detectedFieldNames) { + scopes.clear(); + // detect scopes for the field + for (BeanValidatorScope scope : scopeUniverse) { + if (tmp.containsKey(scope) && + tmp.get(scope).contains(fieldName)) { + scopes.add(scope); + } + } + BeanValidatorField<B> f = + new BeanValidatorField<B>(beanClass, fieldName, scopes); + detectedFields.add(f); + } + tmp.clear(); + detectedFieldNames.clear(); + + fields = Collections.unmodifiableSet(detectedFields); + } + + protected EventSetDescriptor getBeanEventDescriptor(B bean) { + if (beanEventDescriptor == null) { + // check that the bean is listenable, otherwise, can't use the + // validator on it + beanEventDescriptor = + BeanValidatorUtil.getPropertyChangeListenerDescriptor( + bean.getClass() + ); + } + return beanEventDescriptor; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,342 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.apache.commons.beanutils.ConstructorUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.io.FilenameFilter; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Un detecteur de validateurs pour un liste de classes données et un répertoire + * où chercher les fichiers de validation. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6.0 + */ +public class BeanValidatorDetector { + + /** Logger */ + private static final Log log = + LogFactory.getLog(BeanValidatorDetector.class); + + public SortedSet<BeanValidator<?>> detect(File sourceRoot, + Class<?>... types) { + SortedSet<BeanValidator<?>> result = + detect(BeanValidator.class, sourceRoot, null, types); + return result; + } + + public SortedSet<BeanValidator<?>> detect(Class<?> validatorClass, + File sourceRoot, + Pattern contextFilter, + Class<?>... types) { + SortedSet<BeanValidator<?>> result = detect(validatorClass, + sourceRoot, + contextFilter, + null, + types); + return result; + } + + public SortedSet<BeanValidator<?>> detect(Class<?> validatorClass, + File sourceRoot, + Pattern contextFilter, + BeanValidatorScope[] scopes, + Class<?>... types) { + + SortedSet<BeanValidator<?>> result = + new TreeSet<BeanValidator<?>>(new BeanValidatorComparator()); + + for (Class<?> c : types) { + File dir = getClassDir(sourceRoot, c); + if (!dir.exists()) { + + // pas de repertoire adequate + if (log.isDebugEnabled()) { + log.debug("skip non existing directory " + dir); + } + continue; + } + String[] contexts = getContexts(c, dir); + if (log.isDebugEnabled()) { + log.debug("contexts : " + Arrays.toString(contexts)); + } + + if (contexts.length > 0) { + String[] realContexts = getContextsWithoutScopes(contexts); + + if (log.isDebugEnabled()) { + log.debug("realContexts : " + + Arrays.toString(realContexts)); + } + + if (contextFilter != null) { + + // filter contexts + realContexts = getFilterContexts(contextFilter, + realContexts + ); + if (log.isDebugEnabled()) { + log.debug("filterContexts : " + + Arrays.toString(realContexts)); + } + } + + for (String context : realContexts) { + + // on cherche le validateur + BeanValidator<?> validator = getValidator( + validatorClass, + c, + context.isEmpty() ? null : context, + scopes + ); + if (validator != null) { + // on enregistre le validateur + result.add(validator); + } + } + } + } + return result; + } + + /** + * Pour un context et un type d'entité donné, instancie un validateur et + * test si ce validateur est utilisable (i.e qu'il admet des champs à + * valider). + * <p/> + * Si aucun champ n'est trouvé dans le validateur, alors on retourne null. + * + * @param <B> le type du bean + * @param validatorClass le type de validateur a instancie + * @param klass le type du bean + * @param context le context du validateur + * @param scopes les scopes a utiliser (si {@code null} alors pas de + * filtre sur les scopes) + * @return le validateur initialisé, ou <code>null</code> si aucun scope + * détecté dans le validateur. + */ + protected <B> BeanValidator<B> getValidator(Class<?> validatorClass, + Class<B> klass, + String context, + BeanValidatorScope... scopes) { + + BeanValidator<B> valitator; + valitator = createValidator(validatorClass, klass, context, scopes); + + Set<BeanValidatorScope> resultScopes = valitator.getScopes(); + if (resultScopes.isEmpty()) { + valitator = null; + if (log.isDebugEnabled()) { + log.debug(klass + " : validator skip (no scopes detected)"); + } + } else { + if (log.isDebugEnabled()) { + log.debug(klass + " : keep validator " + valitator); + } + } + return valitator; + } + + protected <B> BeanValidator<B> createValidator( + Class<?> validatorClass, + Class<B> klass, + String context, + BeanValidatorScope[] scopes) { + BeanValidator<B> valitator; + Constructor<?> con; + try { + con = ConstructorUtils.getAccessibleConstructor( + validatorClass, + new Class<?>[]{ + Class.class, + String.class, + BeanValidatorScope[].class + } + ); + if (con != null) { + + valitator = (BeanValidator<B>) con.newInstance( + klass, + context, scopes + ); + + } else { + con = ConstructorUtils.getAccessibleConstructor( + validatorClass, + new Class<?>[]{ + Class.class, + String.class, + BeanValidatorScope[].class + } + ); + + if (con == null) { + throw new IllegalStateException( + "could not find a constructor with " + + "(Class.class, String) or " + + "(Class,String BeanValidatorScope[])"); + } + + valitator = (BeanValidator<B>) con.newInstance( + klass, + context + ); + if (scopes != null && scopes.length > 0) { + valitator.setFilterScopes(scopes); + } + } + + } catch (Exception ex) { + throw new RuntimeException( + "could not instanciate validator " + validatorClass + + " for reason " + ex.getMessage(), ex); + } + return valitator; + } + + protected File getClassDir(File sourceRoot, Class<?> clazz) { + String path = clazz.getPackage().getName(); + path = path.replaceAll("\\.", File.separator); + File dir = new File(sourceRoot, path); + return dir; + } + + protected String[] getContexts(Class<?> clazz, File dir) { + Set<String> result = new TreeSet<String>(); + ValidatorFilenameFilter filter = new ValidatorFilenameFilter(clazz); + if (log.isDebugEnabled()) { + log.debug("dir : " + dir); + } + String[] files = dir.list(filter); + for (String file : files) { + if (log.isDebugEnabled()) { + log.debug("file " + file); + } + String context = file.substring( + filter.prefix.length(), + file.length() - ValidatorFilenameFilter.SUFFIX.length() + ); + if (log.isDebugEnabled()) { + log.debug("detect " + clazz.getSimpleName() + + " context [" + context + "]"); + } + result.add(context); + } + return result.toArray(new String[result.size()]); + } + + protected String[] getContextsWithoutScopes(String[] contexts) { + Set<String> result = new TreeSet<String>(); + BeanValidatorScope[] scopes = BeanValidatorScope.values(); + for (String context : contexts) { + for (BeanValidatorScope scope : scopes) { + String scopeName = scope.name().toLowerCase(); + if (!context.endsWith(scopeName)) { + // pas concerne par ce scope + continue; + } + if (log.isDebugEnabled()) { + log.debug("detect context : " + context); + } + String realContext = context.substring( + 0, + context.length() - scopeName.length() + ); + if (realContext.endsWith("-")) { + realContext = realContext.substring( + 0, + realContext.length() - 1 + ); + } + result.add(realContext); + } + } + return result.toArray(new String[result.size()]); + } + + protected String[] getFilterContexts(Pattern contextFilter, + String[] realContexts) { + List<String> result = new ArrayList<String>(); + for (String c : realContexts) { + Matcher m = contextFilter.matcher(c); + if (m.matches()) { + result.add(c); + } + } + return result.toArray(new String[result.size()]); + } + + protected static class ValidatorFilenameFilter implements FilenameFilter { + + protected static final String SUFFIX = "-validation.xml"; + + protected Class<?> clazz; + + protected String prefix; + + public ValidatorFilenameFilter(Class<?> clazz) { + this.clazz = clazz; + prefix = clazz.getSimpleName() + "-"; + } + + @Override + public boolean accept(File dir, String name) { + boolean result = name.endsWith(SUFFIX); + if (result) { + result = name.startsWith(prefix); + } + return result; + } + } + + protected static class BeanValidatorComparator implements Comparator<BeanValidator<?>> { + + @Override + public int compare(BeanValidator<?> o1, BeanValidator<?> o2) { + String contextName1 = + o1.getBeanClass().getSimpleName() + "-" + + (o1.getContextName() == null ? "" : o1.getContextName()); + String contextName2 = + o2.getBeanClass().getSimpleName() + "-" + + (o2.getContextName() == null ? "" : o2.getContextName()); + return contextName1.compareTo(contextName2); + } + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,86 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.util.EventObject; + +/** + * The definition of an event on {@link BeanValidatorListener} + * to be fired by a {@link BeanValidator}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public class BeanValidatorEvent extends EventObject { + + private static final long serialVersionUID = 1L; + + /** the field impacted by the validator */ + protected BeanValidatorField<?> field; + + /** the scope impacted by the event */ + protected BeanValidatorScope scope; + + protected String[] messagestoAdd; + + protected String[] messagestoDelete; + + public BeanValidatorEvent(BeanValidator<?> source, + BeanValidatorField<?> field, + BeanValidatorScope scope, + String[] messagestoAdd, + String[] messagestoDelete) { + super(source); + this.field = field; + this.scope = scope; + this.messagestoAdd = messagestoAdd; + this.messagestoDelete = messagestoDelete; + } + + @Override + public BeanValidator<?> getSource() { + return (BeanValidator<?>) super.getSource(); + } + + public String getFieldName() { + return field.getName(); + } + + public String[] getMessagesToAdd() { + return messagestoAdd; + } + + public String[] getMessagesToDelete() { + return messagestoDelete; + } + + public BeanValidatorScope getScope() { + return scope; + } + + public BeanValidatorField<?> getField() { + return field; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,286 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import com.opensymphony.xwork2.validator.FieldValidator; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +import static org.nuiton.i18n.I18n._; + +/** + * Definition of a field to be handled in a {@link BeanValidator}. + * <p/> + * A such class is only registred in {@link BeanValidator } when the field of + * the bean was found in validator xml configuration file for a {@link + * FieldValidator} only. + * <p/> + * This class use properties {@link #beanClass}, {@link #name} to define his + * naturel order. + * + * @author tchemit <chemit@codelutin.com> + * @param <B> the type of the bean handled by the validator and this field of + * validation. + * @since 1.3 + */ +public class BeanValidatorField<B> implements Serializable { + + private static final long serialVersionUID = 1L; + + /** the class of bean */ + protected final Class<B> beanClass; + + /** name of field in bean */ + protected final String name; + + protected EnumMap<BeanValidatorScope, Set<String>> messages; + + public BeanValidatorField(Class<B> beanClass, + String name, + List<BeanValidatorScope> scopes) { + this.beanClass = beanClass; + this.name = name; + messages = new EnumMap<BeanValidatorScope, Set<String>>( + BeanValidatorScope.class + ); + for (BeanValidatorScope scope : scopes) { + messages.put(scope, new HashSet<String>()); + } + } + + public String getName() { + return name; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + /** + * @return {@code true} if this field is valid : no fatal errors and no + * errors), {@code false} otherwise. + */ + public boolean isValid() { + return !hasFatalErrors() && !hasErrors(); + } + + public BeanValidatorScope getScope() { + if (hasErrors()) { + return BeanValidatorScope.ERROR; + } + if (hasWarnings()) { + return BeanValidatorScope.WARNING; + } + if (hasInfos()) { + return BeanValidatorScope.INFO; + } + return null; + } + + public Set<BeanValidatorScope> getScopes() { + return messages.keySet(); + } + + public boolean hasFatalErrors() { + return hasMessages(BeanValidatorScope.FATAL); + } + + public boolean hasErrors() { + return hasMessages(BeanValidatorScope.ERROR); + } + + public boolean hasWarnings() { + return hasMessages(BeanValidatorScope.WARNING); + } + + public boolean hasInfos() { + return hasMessages(BeanValidatorScope.INFO); + } + + public Set<String> getFatalErrors() { + return getMessages(BeanValidatorScope.FATAL); + } + + public Set<String> getErrors() { + return getMessages(BeanValidatorScope.ERROR); + } + + public Set<String> getWarnings() { + return getMessages(BeanValidatorScope.WARNING); + } + + public Set<String> getInfos() { + return getMessages(BeanValidatorScope.INFO); + } + + public boolean hasMessages(BeanValidatorScope scope) { + return messages.containsKey(scope) && !getMessages(scope).isEmpty(); + } + + public Set<String> getMessages(BeanValidatorScope scope) { + return messages.get(scope); + } + + public void updateMessages(BeanValidator<B> validator, + BeanValidatorScope scope, + List<String> messages) { + + if (scope == null) { + + // special case to reset all messages from all scopes + + for (BeanValidatorScope s : getScopes()) { + + clearMessages(s, validator); + } + return; + } + + if (!this.messages.containsKey(scope)) { + throw new IllegalArgumentException( + "the scope " + scope + " was not registred for " + this); + } + + if (messages == null || messages.isEmpty()) { + + // no incoming message for this scope + + clearMessages(scope, validator); + return; + } + + // build the diff of messages (the one to delete, the one to add) + + boolean hasChanged = false; + + Set<String> currentMessages = getMessages(scope); + + // detect messages to delete + Set<String> toDelete = new HashSet<String>(currentMessages); + toDelete.removeAll(messages); + + if (!toDelete.isEmpty()) { + // apply delete + currentMessages.removeAll(toDelete); + hasChanged = true; + } + + // detect messages to add + Set<String> toAdd = new HashSet<String>(messages); + toAdd.removeAll(currentMessages); + + if (!toAdd.isEmpty()) { + // apply add + currentMessages.addAll(toAdd); + hasChanged = true; + } + + if (hasChanged) { + + // something has changed, fire notifications + String[] del = toDelete.toArray(new String[toDelete.size()]); + String[] add = toAdd.toArray(new String[toAdd.size()]); + + validator.fireFieldChanged(this, scope, add, del); + } + toAdd.clear(); + toDelete.clear(); + + } + + public String getI18nError(String error) { + String text; + if (!error.contains("##")) { + text = _(error); + } else { + StringTokenizer stk = new StringTokenizer(error, "##"); + String errorName = stk.nextToken(); + List<String> args = new ArrayList<String>(); + while (stk.hasMoreTokens()) { + args.add(stk.nextToken()); + } + text = _(errorName, args.toArray()); + } + return text; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BeanValidatorField<?>)) { + return false; + } + + BeanValidatorField<?> that = (BeanValidatorField<?>) o; + return beanClass.equals(that.beanClass) && name.equals(that.name); + } + + @Override + public int hashCode() { + int result = beanClass.hashCode(); + result = 31 * result + name.hashCode(); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("<").append(super.toString()); + sb.append(" beanClass:").append(beanClass); + sb.append(", name:").append(name); + sb.append(", scopes:"); + sb.append(messages == null ? "[]" : messages.keySet()); + sb.append(", scope:").append(getScope()); + //sb.append(", errors:").append(errors); + sb.append('>'); + return sb.toString(); + } + + protected void clearMessages(BeanValidatorScope scope, + BeanValidator<B> validator) { + // remove all messages + Set<String> toDelete = getMessages(scope); + + if (!toDelete.isEmpty()) { + + // there is some messages to delete + String[] toDel = toDelete.toArray(new String[toDelete.size()]); + + // apply deletion + toDelete.clear(); + + // fire + validator.fireFieldChanged(this, scope, null, toDel); + } + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,43 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.util.EventListener; + +/** + * The listener contract to be used on {@link BeanValidator} + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public interface BeanValidatorListener extends EventListener { + + /** + * Invoked when a validator detects some changes on a field. + * + * @param event the event + */ + void onFieldChanged(BeanValidatorEvent event); +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,118 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +/** + * The object to box a validation message. + * + * @author tchemit <chemit@codelutin.com> + * @param <E> type of message (use for override {@link #compareTo(Object)} + * method. + * @since 1.3 + */ +public class BeanValidatorMessage<E extends BeanValidatorMessage<?>> implements Comparable<E> { + + /** the validator that produce the message */ + protected BeanValidator<?> validator; + + /** the field that produce the message */ + protected BeanValidatorField<?> field; + + /** the label of the message (to be displayed somewhere) */ + protected String message; + + /** the scope of the message */ + protected BeanValidatorScope scope; + + public BeanValidatorMessage(BeanValidator<?> validator, + BeanValidatorField<?> field, + String message, + BeanValidatorScope scope) { + this.field = field; + this.validator = validator; + this.message = message == null ? null : message.trim(); + this.scope = scope; + } + + public BeanValidator<?> getValidator() { + return validator; + } + + public BeanValidatorField<?> getField() { + return field; + } + + public BeanValidatorScope getScope() { + return scope; + } + + public String getMessage() { + return message; + } + + @Override + public int compareTo(E o) { + // sort on scope + int result = getScope().compareTo(o.getScope()); + if (result == 0) { + // sort on field name + result = field.getName().compareTo(o.field.getName()); + if (result == 0) { + // sort on message + result = message.compareTo(o.message); + } + } + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + BeanValidatorMessage<?> that = (BeanValidatorMessage<?>) o; + + return field.equals(that.field) && + message.equals(that.message) && + scope == that.scope; + } + + @Override + public int hashCode() { + int result = field.hashCode(); + result = 31 * result + message.hashCode(); + result = 31 * result + scope.hashCode(); + return result; + } + + @Override + public String toString() { + return scope + " - " + field.getI18nError(message); + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,79 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import static org.nuiton.i18n.I18n.n_; + +/** + * The differents levels of messages in validation process. + * <p/> + * The order of the enum defines the severity of validation. + * <p/> + * Always begin with fatal, then error, then if no error found, try warning, then info... + * + * @author tchemit <chemit@codelutin.com> + */ +public enum BeanValidatorScope { + + /** + * the fatal error scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is invalid and modified. + * @since 2.2.4 + */ + FATAL(n_("validator.scope.fatal.label")), + /** + * the error scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is invalid and modified. + */ + ERROR(n_("validator.scope.error.label")), + /** + * the warning scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is still valid but modified. + */ + WARNING(n_("validator.scope.warning.label")), + /** + * the information scope level. + * <p/> + * When a message of a sucg scope is found on a validator, then the + * validator is still valid and not modified. + */ + INFO(n_("validator.scope.info.label")); + + private final String label; + + BeanValidatorScope(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,196 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +/** + * The helper class for validation module. + * + * @author tchemit <chemit@codelutin.com> + */ +public class BeanValidatorUtil { + + /** Logger */ + static private final Log log = LogFactory.getLog(BeanValidatorUtil.class); + + /** + * a shared value stack to allow external operations on it (for example add + * some datas in stack to be usedby validators + */ + static private ValueStack sharedValueStack; + + public static ValueStack getSharedValueStack() { + if (sharedValueStack == null) { + + // init context + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + + Container container = conf.getContainer(); + ValueStackFactory stackFactory = container.getInstance( + ValueStackFactory.class); + sharedValueStack = stackFactory.createValueStack(); + if (log.isDebugEnabled()) { + log.debug("init shared value stack " + sharedValueStack); + } + } + return sharedValueStack; + } + + protected BeanValidatorUtil() { + // no instance + } + + /** + * Convert a value to a given type and then if was succesffull try to set it + * in the bean manage by the validator. + * + * @param validator validator to be involved + * @param fieldName the name of the bean property + * @param value the actual value to convert + * @param valueClass the type of the conversion + */ + public static void convert(BeanValidator<?> validator, + String fieldName, + String value, + Class<?> valueClass) { + + Object result = validator.convert(fieldName, value, valueClass); + if (result != null) { + try { + BeanInfo info = + Introspector.getBeanInfo(validator.getBean().getClass()); + + for (PropertyDescriptor descriptor : + info.getPropertyDescriptors()) { + if (fieldName.equals(descriptor.getName()) && + descriptor.getWriteMethod() != null) { + + descriptor.getWriteMethod().invoke( + validator.getBean(), + result + ); + break; + } + } + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("could not obtain beanInfo for " + + valueClass.getClass() + ", reason : " + + e.getMessage(), e); + } + } + } else { + //fixme : conversion failed, we should be able to notify ui + // that values has changed ? + // otherwise, bean value has not changed,... + } + } + + public static EventSetDescriptor getPropertyChangeListenerDescriptor(Class<?> beanClass) { + try { + // check that the bean is listenable, otherwise, can't use + // the validator on it + BeanInfo infos = Introspector.getBeanInfo(beanClass); + EventSetDescriptor[] events = infos.getEventSetDescriptors(); + for (EventSetDescriptor event : events) { + if ("propertyChange".equals(event.getName())) { + + if (event.getAddListenerMethod() == null) { + // no property event listener, so can not use the validator + throw new IllegalStateException( + "no addPropertyChangeListener method found " + + "for " + beanClass); + } + if (event.getRemoveListenerMethod() == null) { + // no property event listener, so can not use the validator + throw new IllegalStateException( + "no removePropertyChangeListener method found" + + " for " + beanClass); + } + return event; + } + } + + // no property event listener, so can not use the validator + throw new IllegalStateException( + "no PropertyChangeListener access method found for " + + beanClass); + } catch (IntrospectionException ex) { + throw new IllegalStateException( + "could not acquire PropertyChangeListener bean info for " + + beanClass + " for reason " + ex.getMessage(), ex); + } + } + + public static EnumSet<BeanValidatorScope> getScopes( + List<BeanValidatorMessage<?>> messages) { + EnumSet<BeanValidatorScope> result = + EnumSet.noneOf(BeanValidatorScope.class); + for (BeanValidatorMessage<?> m : messages) { + result.add(m.getScope()); + } + return result; + } + + public static EnumMap<BeanValidatorScope, Integer> getScopesCount( + List<BeanValidatorMessage<?>> messages) { + EnumMap<BeanValidatorScope, Integer> result = + new EnumMap<BeanValidatorScope, Integer>(BeanValidatorScope.class); + for (BeanValidatorScope s : BeanValidatorScope.values()) { + result.put(s, 0); + } + for (BeanValidatorMessage<?> m : messages) { + + BeanValidatorScope scope = m.getScope(); + + result.put(scope, result.get(scope) + 1); + } + + for (BeanValidatorScope s : BeanValidatorScope.values()) { + if (result.get(s) == 0) { + result.remove(s); + } + } + return result; + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,126 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Un dictionnaire de validateurs ordonnees par le type de leur bean. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.1 + */ +public class ValidatorsMap implements Map<Class<?>, BeanValidator<?>> { + + protected final Map<Class<?>, BeanValidator<?>> delegate; + + public ValidatorsMap() { + delegate = new HashMap<Class<?>, BeanValidator<?>>(); + } + + public BeanValidatorScope[] getScopes() { + EnumSet<BeanValidatorScope> result = + EnumSet.noneOf(BeanValidatorScope.class); + for (BeanValidator<?> b : values()) { + result.addAll(b.getScopes()); + } + return result.toArray(new BeanValidatorScope[result.size()]); + } + +// public <X> BeanValidator<X> getValidator(X klass) { +// BeanValidator<X> beanValidator = (BeanValidator<X>) get(klass.getClass()); +// return beanValidator; +// } + + public <X> BeanValidator<X> getValidator(Class<X> klass) { + BeanValidator<X> beanValidator = (BeanValidator<X>) get(klass); + return beanValidator; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return delegate.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + @Override + public BeanValidator<?> get(Object key) { + return delegate.get(key); + } + + @Override + public BeanValidator<?> put(Class<?> key, BeanValidator<?> value) { + return delegate.put(key, value); + } + + @Override + public BeanValidator<?> remove(Object key) { + return delegate.remove(key); + } + + @Override + public void putAll(Map<? extends Class<?>, ? extends BeanValidator<?>> m) { + delegate.putAll(m); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public Set<Class<?>> keySet() { + return delegate.keySet(); + } + + @Override + public Collection<BeanValidator<?>> values() { + return delegate.values(); + } + + @Override + public Set<Entry<Class<?>, BeanValidator<?>>> entrySet() { + return delegate.entrySet(); + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,324 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ValidationAwareSupport; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import com.opensymphony.xwork2.validator.ActionValidatorManager; +import com.opensymphony.xwork2.validator.DelegatingValidatorContext; +import com.opensymphony.xwork2.validator.FieldValidator; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.Validator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A customized validator for a given bean. + * <p/> + * Use the method {@link #validate(Object)} to obtain the messages detected by + * the validator for the given bean. + * + * @author tchemit <chemit@codelutin.com> + * @param <B> type of the bean to validate. + * @since 1.3 + */ +public class XWorkBeanValidator<B> { + + /** Logger */ + private static final Log log = LogFactory.getLog(XWorkBeanValidator.class); + + protected final static Map<String, List<String>> EMPTY_RESULT = + Collections.unmodifiableMap(new HashMap<String, List<String>>()); + + /** the type of bean to validate */ + protected final Class<B> beanClass; + + /** the validation named context (can be null) */ + protected String contextName; + + /** the list of field names detected for this validator */ + protected Set<String> fieldNames; + + /** a flag to include or not the default context validators */ + protected boolean includeDefaultContext; + + // -- + // XWorks fields + // -- + + protected ValidationAwareSupport validationSupport; + + protected DelegatingValidatorContext validationContext; + + protected ActionValidatorManager validator; + + protected ActionContext context; + + public XWorkBeanValidator(Class<B> beanClass, String contextName) { + this(beanClass, + contextName, + true, + BeanValidatorUtil.getSharedValueStack() + ); + } + + public XWorkBeanValidator(Class<B> beanClass, + String contextName, + ValueStack vs) { + this(beanClass, contextName, true, vs); + } + + public XWorkBeanValidator(Class<B> beanClass, + String contextName, + boolean includeDefaultContext) { + this(beanClass, + contextName, + includeDefaultContext, + BeanValidatorUtil.getSharedValueStack() + ); + } + + public XWorkBeanValidator(Class<B> beanClass, + String contextName, + boolean includeDefaultContext, + ValueStack vs) { + + this.beanClass = beanClass; + this.includeDefaultContext = includeDefaultContext; + validationSupport = new ValidationAwareSupport(); + validationContext = new DelegatingValidatorContext(validationSupport); + + if (vs == null) { + // create a standalone value stack + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + Container container = conf.getContainer(); + ValueStackFactory stackFactory = + container.getInstance(ValueStackFactory.class); + vs = stackFactory.createValueStack(); + if (log.isDebugEnabled()) { + log.debug("create a standalone value stack " + vs); + } + } else { + if (log.isDebugEnabled()) { + log.debug("use given value stack " + vs); + } + } + + context = new ActionContext(vs.getContext()); + ActionContext.setContext(context); + + // init validator + Container container = context.getContainer(); + validator = container.getInstance(ActionValidatorManager.class, + "no-annotations" + ); + + // init context + setContextName(contextName); + } + + public boolean isIncludeDefaultContext() { + return includeDefaultContext; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public String getContextName() { + return contextName; + } + + public Set<String> getFieldNames() { + return fieldNames; + } + + public ActionValidatorManager getValidator() { + return validator; + } + + /** + * Test a the validator contains the field given his name + * + * @param fieldName the name of the searched field + * @return <code>true</code> if validator contaisn this field, + * <code>false</code> otherwise + */ + public boolean containsField(String fieldName) { + return fieldNames.contains(fieldName); + } + + public void setIncludeDefaultContext(boolean includeDefaultContext) { + this.includeDefaultContext = includeDefaultContext; + if (contextName != null) { + // reload context + setContextName(contextName); + } + } + + public void setContextName(String contextName) { + this.contextName = contextName; + // changing contextName may change fields definition + // so reload fields + initFields(); + } + + /** + * Valide le bean donné et retourne les messages produits. + * + * @param bean le bean a valider (il doit etre non null) + * @return le dictionnaire des messages produits par la validation indexées + * par le nom du champs du bean impacté. + */ + public Map<String, List<String>> validate(B bean) { + + if (bean == null) { + throw new NullPointerException( + "bean can not be null in method validate"); + } + + Map<String, List<String>> result = EMPTY_RESULT; + + // on lance la validation uniquement si des champs sont a valider + if (!fieldNames.isEmpty()) { + + try { + + //TC - 20081024 : since context is in a ThreadLocal variable, + // we must do the check + if (ActionContext.getContext() == null) { + ActionContext.setContext(context); + } + + validator.validate(bean, contextName, validationContext); + + if (log.isTraceEnabled()) { + log.trace("Action errors: " + + validationContext.getActionErrors()); + log.trace("Action messages: " + + validationContext.getActionMessages()); + log.trace("Field errors: " + + validationContext.getFieldErrors()); + } + + if (log.isDebugEnabled()) { + log.debug(this + " : " + + validationContext.getFieldErrors()); + } + + // retreave errors by field + if (validationContext.hasFieldErrors()) { + Map<?, ?> messages = validationContext.getFieldErrors(); + result = new HashMap<String, List<String>>(messages.size()); + for (Object fieldName : messages.keySet()) { + Collection<?> c = + (Collection<?>) messages.get(fieldName); + List<String> mm = new ArrayList<String>(c.size()); + for (Object message : c) { + // tchemit 2010-08-28 : trim the incoming message + // (I18n will not translate it otherwise) + String messageStr = message == null ? "" : message + ""; + mm.add(messageStr.trim()); + } + result.put(fieldName + "", mm); + } + } + + } catch (ValidationException eee) { + if (log.isWarnEnabled()) { + log.warn("Error during validation on " + beanClass + + " for reason : " + eee.getMessage(), eee); + } + + } finally { + // on nettoye toujours le validateur apres operation + validationSupport.clearErrorsAndMessages(); + } + } + + return result; + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + beanClass + + ", contextName:" + contextName + ">"; + } + + /** update the property {@link #fieldNames}, says search in XWorks */ + protected void initFields() { + + if (fieldNames != null) { + fieldNames = null; + } + + Set<String> detectedFieldNames = new HashSet<String>(); + + int skip = 0; + if (contextName != null && !includeDefaultContext) { + // count the number of validator to skip + for (Validator<?> v : validator.getValidators(beanClass, null)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + skip++; + } + } + } + + for (Validator<?> v : validator.getValidators(beanClass, contextName)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + if (skip > 0) { + skip--; + continue; + } + FieldValidator fieldValidator = (FieldValidator) v; + if (log.isDebugEnabled()) { + log.debug("context " + contextName + " - field " + + fieldValidator.getFieldName()); + } + String fName = fieldValidator.getFieldName(); + detectedFieldNames.add(fName); + } + } + + fieldNames = Collections.unmodifiableSet(detectedFieldNames); + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionFieldExpressionValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionFieldExpressionValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionFieldExpressionValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,490 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldExpressionValidator; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * Un validateur basé sur {@link FieldExpressionValidator} qui valide sur une + * collection de propriéte. + * + * @author tchemit <chemit@codelutin.com> + */ +public class CollectionFieldExpressionValidator extends FieldExpressionValidator { + + public enum Mode { + + /** au moins une entrée de la collection doit etre valide */ + AT_LEAST_ONE, + /** exactement une entrée dela collection doit être valide */ + EXACTLY_ONE, + /** toutes les valeurs de la collection doivent etre valides */ + ALL, + /** aucune valeur de la collection doivent etre valides */ + NONE, + /** detection de clef unique */ + UNIQUE_KEY + } + + /** le mode de validation sur la liste */ + protected Mode mode; + + /** + * pour indiquer la propriété qui contient la liste à valider. + * <p/> + * Si cette prorpiété n'est pas renseignée alors on utilise la + * {@link #getFieldName()} pour obtenir la collection. + * <p/> + * Cela permet d'effectuer une validation si une collection mais portant + * en fait sur un autre champs + * + * @since 1.5 + */ + protected String collectionFieldName; + + /** + * drapeau pour utiliser le contexte de parcours pour valider + * l'expression, on dispose donc alors des variables previous, current, + * index, size et empty dans l'expression. + * <p/> + * Sinon l'expression s'applique directement sur l'entrée courant dans le + * parcours sans préfixe. + */ + protected boolean useSensitiveContext; + + /** + * expression a valider sur la premiètre entrée de la collection. + * <p/> + * Note : Pour le moment, on autorise uniquement cela en mode ALL. + */ + protected String expressionForFirst; + + /** + * expression a valider sur la dernière entrée de la collection. + * <p/> + * Note : Pour le moment, on autorise uniquement cela en mode ALL. + */ + protected String expressionForLast; + + /** + * la liste des propriétés d'une entrée de la collection qui définit la + * clef unique (en mode UNIQUE_KEY). + */ + protected String[] keys; + + /** le context de parcours */ + protected WalkerContext c; + + private boolean useFirst, useLast; + + public Mode getMode() { + return mode; + } + + public void setMode(Mode mode) { + this.mode = mode; + } + + public String getCollectionFieldName() { + return collectionFieldName; + } + + public void setCollectionFieldName(String collectionFieldName) { + this.collectionFieldName = collectionFieldName; + } + + public boolean isUseSensitiveContext() { + return useSensitiveContext; + } + + public void setUseSensitiveContext(boolean useSensitiveContext) { + this.useSensitiveContext = useSensitiveContext; + } + + public String getExpressionForFirst() { + return expressionForFirst; + } + + public void setExpressionForFirst(String expressionForFirst) { + this.expressionForFirst = expressionForFirst; + } + + public String getExpressionForLast() { + return expressionForLast; + } + + public void setExpressionForLast(String expressionForLast) { + this.expressionForLast = expressionForLast; + } + + public String[] getKeys() { + return keys; + } + + public void setKeys(String[] keys) { + if (keys != null && keys.length == 1 && keys[0].contains(",")) { + this.keys = keys[0].split(","); + } else { + this.keys = keys; + } + } + + @Override + public void validate(Object object) throws ValidationException { + if (mode == null) { + throw new ValidationException("no mode defined!"); + } + useFirst = expressionForFirst != null && !expressionForFirst.trim().isEmpty(); + useLast = expressionForLast != null && !expressionForLast.trim().isEmpty(); + + if (useFirst && mode != Mode.ALL) { + throw new ValidationException("can only use expressionForFirst in " + + "mode ALL but was " + mode); + } + if (useLast && mode != Mode.ALL) { + throw new ValidationException("can only use expressionForLast in " + + "mode ALL but was " + mode); + } + + String fieldName = getFieldName(); + + Collection<?> col = getCollection(object); + + if (useSensitiveContext) { + c = new WalkerContext(col.size()); + } + + boolean answer; + + boolean pop = false; + + if (!stack.getRoot().contains(object)) { + stack.push(object); + pop = true; + } + + switch (mode) { + case ALL: + answer = validateAllEntries(col); + break; + case AT_LEAST_ONE: + answer = validateAtLeastOneEntry(col); + break; + case EXACTLY_ONE: + answer = validateExtacltyOneEntry(col); + break; + case NONE: + answer = validateNoneEntry(col); + break; + case UNIQUE_KEY: + if (keys == null || keys.length == 0) { + throw new ValidationException("no unique keys defined"); + } + answer = validateUniqueKey(col); + break; + + default: + // should never come here... + answer = false; + } + + if (!answer) { + addFieldError(fieldName, object); + } + if (pop) { + stack.pop(); + } + } + + protected ValueStack stack; + + @Override + public void setValueStack(ValueStack stack) { + super.setValueStack(stack); + this.stack = stack; + } + + @Override + public String getMessage(Object object) { + boolean pop = false; + + if (useSensitiveContext && !stack.getRoot().contains(c)) { + stack.push(c); + pop = true; + } + String message = super.getMessage(object); + + if (pop) { + stack.pop(); + } + return message; + } + + protected Boolean validateAllEntries(Collection<?> col) throws ValidationException { + boolean answer = true; + for (Object entry : col) { + answer = validateOneEntry(entry); + if (!answer) { + // validation on one entry has failed + // no need to continue + break; + } + } + return answer; + } + + protected Boolean validateNoneEntry(Collection<?> col) throws ValidationException { + boolean answer = true; + for (Object entry : col) { + boolean b = validateOneEntry(entry); + if (b) { + // one entry has sucessed, validation has failed + // no need to continue + answer = false; + break; + } + } + return answer; + } + + protected Boolean validateAtLeastOneEntry(Collection<?> col) throws ValidationException { + boolean answer = false; + for (Object entry : col) { + answer = validateOneEntry(entry); + if (answer) { + // one entry was succes, validation is ok, + // no need to continue + break; + } + } + return answer; + } + + protected Boolean validateExtacltyOneEntry(Collection<?> col) throws ValidationException { + int count = 0; + for (Object entry : col) { + boolean answer = validateOneEntry(entry); + if (answer) { + // one entry has succed + count++; + if (count > 1) { + // more than one entriy was successfull + // so validation has failed + break; + } + + } + } + return count == 1; + } + + protected Boolean validateUniqueKey(Collection<?> col) throws ValidationException { + boolean answer = true; + + Set<Integer> hashCodes = new HashSet<Integer>(); + int index = -1; + for (Object entry : col) { + index++; + // construction du hash de la clef d'unicite + Integer hash = getUniqueKeyHashCode(entry); + if (!hashCodes.contains(hash)) { + hashCodes.add(hash); + continue; + } + // une entree avec ce hash a deja ete trouvee + // on est donc en violation sur la clef unique + answer = false; + if (log.isDebugEnabled()) { + log.debug("duplicated uniquekey " + hash + " for entry " + index); + } + } + hashCodes.clear(); + return answer; + } + + protected boolean validateOneEntry(Object object) throws ValidationException { + + Boolean answer = Boolean.FALSE; + + boolean extraExpression = false; + + if (useSensitiveContext) { + c.addCurrent(object); + object = c; + + if (c.isFirst() && useFirst) { + // on valide l'expression sur la premiètre entrée + answer = evaluateExpression(expressionForFirst, object); + extraExpression = true; + } + if (c.isLast() && useLast) { + // on valide l'expression sur la dernière entrée + answer = (!extraExpression || answer) && evaluateExpression(expressionForLast, object); + extraExpression = true; + } + } + + answer = (!extraExpression || answer) && evaluateExpression(getExpression(), object); + + return answer; + } + + protected boolean evaluateExpression(String expression, Object object) throws ValidationException { + Object obj = null; + try { + obj = getFieldValue(expression, object); + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + log.error(e.getMessage(), e); + // let this pass, but it will be logged right below + } + + Boolean answer = Boolean.FALSE; + + if (obj != null && obj instanceof Boolean) { + answer = (Boolean) obj; + } else { + log.warn("Got result of " + obj + " when trying to get Boolean for expression " + expression); + } + return answer; + } + + /** + * @param object the incoming object containing the collection to test + * @return the collection of the incoming object given by the fieldName property + * @throws ValidationException if any pb to retreave the collection + */ + protected Collection<?> getCollection(Object object) throws ValidationException { + String fieldName = getCollectionFieldName(); + if (fieldName == null || fieldName.trim().isEmpty()) { + // on travaille directement sur le fieldName + fieldName = getFieldName(); + } + + Object obj = null; + + // obtain the collection to test + try { + obj = getFieldValue(fieldName, object); + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + // let this pass, but it will be logged right below + } + + if (obj == null) { + // la collection est nulle, donc on renvoie une collection vide + return Collections.emptyList(); + } + + if (!Collection.class.isInstance(obj)) { + throw new ValidationException("field " + fieldName + " is not a collection type! (" + obj.getClass() + ")"); + } + return (Collection<?>) obj; + } + + /** + * Calcule pour une entrée donné, le hash de la clef unique + * + * @param o l'entree de la collection dont on va calculer le hash de la clef unique + * @return le hashCode calclé de la clef unique sur l'entrée donné + * @throws ValidationException if any pb to retreave properties values + */ + protected Integer getUniqueKeyHashCode(Object o) throws ValidationException { + // calcul du hash à la volée + HashCodeBuilder builder = new HashCodeBuilder(); + for (String key : keys) { + Object property = getFieldValue(key, o); + if (log.isDebugEnabled()) { + log.debug("key " + key + " : " + property); + } + builder.append(property); + } + return builder.toHashCode(); + } + + @Override + public String getValidatorType() { + return "collectionFieldExpression"; + } + + public class WalkerContext { + + protected final int size; + + public WalkerContext(int size) { + this.size = size; + } + + protected int index = -1; + + protected Object current; + + protected Object previous; + + public void addCurrent(Object current) { + index++; + previous = this.current; + this.current = current; + } + + public Object getCurrent() { + return current; + } + + public int getIndex() { + return index; + } + + public Object getPrevious() { + return previous; + } + + public int getSize() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public boolean isFirst() { + return index == 0; + } + + public boolean isLast() { + return index == size - 1; + } + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionFieldExpressionValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionUniqueKeyValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionUniqueKeyValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionUniqueKeyValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,287 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldExpressionValidator; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Un validateur basé sur {@link FieldExpressionValidator} qui valide une clef + * unique sur une collection. + * <p/> + * Le {@link #fieldName} sert à récupérer la propriété de type de collection du + * bean. + * + * @author tchemit <chemit@codelutin.com> + */ +public class CollectionUniqueKeyValidator extends FieldExpressionValidator { + + /** + * pour indiquer la propriété qui contient la liste à valider. + * <p/> + * Si cette prorpiété n'est pas renseignée alors on utilise la + * {@link #getFieldName()} pour obtenir la collection. + * <p/> + * Cela permet d'effectuer une validation si une collection mais portant + * en fait sur un autre champs + * + * @since 1.5 + */ + protected String collectionFieldName; + + /** + * la liste des propriétés d'une entrée de la collection qui définit la + * clef unique. + */ + protected String[] keys; + + /** + * Une propriété optionnelle pour valider que l'objet reflétée par cette + * propriété ne viole pas l'intégrité de la clef unique. + * Cela permet de valider l'unicité sans que l'objet soit dans la collection + */ + protected String againstProperty; + + /** + * Une propriété optionnelle pour utiliser l'objet en cours de validation pour + * valider que l'objet reflétée par cette propriété ne viole pas l'intégrité de la clef unique. + * Cela permet de valider l'unicité sans que l'objet soit dans la collection + */ + protected boolean againstMe; + + /** + * Lors de l'utilisation de la againstProperty et qu'un ne peut pas utiliser + * le equals sur l'objet, on peut spécifier une expression pour exclure des + * tests lors de la recherche de la violation de clef unique. + */ + protected String againstIndexExpression; + + public String getCollectionFieldName() { + return collectionFieldName; + } + + public void setCollectionFieldName(String collectionFieldName) { + this.collectionFieldName = collectionFieldName; + } + + public String[] getKeys() { + return keys; + } + + public boolean getAgainstMe() { + return againstMe; + } + + public void setKeys(String[] keys) { + if (keys != null && keys.length == 1 && keys[0].indexOf(',') != -1) { + this.keys = keys[0].split(","); + } else { + this.keys = keys; + } + } + + public String getAgainstProperty() { + return againstProperty; + } + + public void setAgainstProperty(String againstProperty) { + this.againstProperty = againstProperty; + } + + public String getAgainstIndexExpression() { + return againstIndexExpression; + } + + public void setAgainstIndexExpression(String againstIndexExpression) { + this.againstIndexExpression = againstIndexExpression; + } + + public void setAgainstMe(boolean againstMe) { + this.againstMe = againstMe; + } + + @Override + public void validate(Object object) throws ValidationException { + + if (keys == null || keys.length == 0) { + throw new ValidationException("no unique keys defined"); + } + + String fieldName = getFieldName(); + + Collection<?> col = getCollection(object); + + if (log.isDebugEnabled()) { + log.debug("collection found : " + col); + } + Object againstBean = againstProperty == null ? null : + getFieldValue(againstProperty, object); + + if (log.isDebugEnabled()) { + log.debug("againtBean = " + againstBean); + } + Integer againstIndex = (Integer) (againstIndexExpression == null ? + -1 : + getFieldValue(againstIndexExpression, object)); + if (againstIndex == null) { + againstIndex = -1; + } + if (againstBean == null && col.size() < 2) { + // la liste ne contient pas deux entrées donc c'est valide + return; + } + + if (againstMe) { + // try on this object + againstBean = object; + if (log.isDebugEnabled()) { + log.debug("againtBean from me = " + againstBean); + } + } + + + boolean answer = true; + + Integer againstHashCode = againstBean == null ? + null : getUniqueKeyHashCode(againstBean); + if (log.isDebugEnabled()) { + log.debug("hash for new key " + againstHashCode); + } + List<Integer> hashCodes = new ArrayList<Integer>(); + + int index = 0; + for (Object o : col) { + Integer hash = getUniqueKeyHashCode(o); + if (log.isDebugEnabled()) { + log.debug("hash for object " + o + " = " + hash); + } + if (againstBean == null) { + if (hashCodes.contains(hash)) { + // on a deja rencontre cette clef unique, + // donc la validation a echouee + answer = false; + if (log.isDebugEnabled()) { + log.debug("Found same hashcode, not unique!"); + } + break; + } + } else { + // utilisation de againstBean + if (againstIndex != -1) { + if (index != againstIndex && + hash.equals(againstHashCode)) { + // on a deja rencontre cette clef unique, + // donc la validation a echouee + answer = false; + break; + } + } else { + if (!againstBean.equals(o) && + hash.equals(againstHashCode)) { + // on a deja rencontre cette clef unique, + // donc la validation a echouee + answer = false; + break; + } + } + } + // nouveau hashcode enregistre + hashCodes.add(hash); + // index suivant + index++; + } + + if (!answer) { + addFieldError(fieldName, object); + } + } + + /** + * Calcule pour une entrée donné, le hash de la clef unique + * + * @param o l'entree de la collection dont on va calculer le hash de + * la clef unique + * @return le hashCode calclé de la clef unique sur l'entrée donné + * @throws ValidationException if any pb to retreave properties values + */ + protected Integer getUniqueKeyHashCode(Object o) + throws ValidationException { + // calcul du hash à la volée + HashCodeBuilder builder = new HashCodeBuilder(); + for (String key : keys) { + Object property = getFieldValue(key, o); + builder.append(property); + } + return builder.toHashCode(); + } + + /** + * @param object the incoming object containing the collection to test + * @return the collection of the incoming object given by the fieldName + * property + * @throws ValidationException if any pb to retreave the collection + */ + protected Collection<?> getCollection(Object object) + throws ValidationException { + String fieldName = getCollectionFieldName(); + if (fieldName == null || fieldName.trim().isEmpty()) { + // on travaille directement sur le fieldName + fieldName = getFieldName(); + } + + Object obj = null; + + // obtain the collection to test + try { + obj = getFieldValue(fieldName, object); + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + // let this pass, but it will be logged right below + } + + if (obj == null) { + // la collection est nulle, donc on renvoie une collection vide + return Collections.emptyList(); + } + + if (!Collection.class.isInstance(obj)) { + throw new ValidationException("field " + fieldName + + " is not a collection type! (" + obj.getClass() + ')'); + } + return (Collection<?>) obj; + } + + @Override + public String getValidatorType() { + return "collectionUniqueKey"; + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/CollectionUniqueKeyValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingDirectoryFieldValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingDirectoryFieldValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingDirectoryFieldValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,97 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * ExistingDirectoryFieldValidator checks that a File field exists and is a directory. + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="existingDirectory"> + * <param name="fieldName">tmp</param> + * <message>tmp is not an existing directory</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="existingDirectory"> + * <message>tmp is not an existing directory</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author tchemit <chemit@codelutin.com> + */ +public class ExistingDirectoryFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (!(f.isDirectory() && f.exists())) { + // f is not a directory, nor exists + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "existingDirectory"; + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingDirectoryFieldValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingFileFieldValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingFileFieldValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingFileFieldValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,97 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * ExistingFileFieldValidator checks that a File field exists. * + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="fileExisting"> + * <param name="fieldName">tmp</param> + * <message>tmp is not an existing file</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="fileExisting"> + * <message>tmp is not an existing file</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author tchemit <chemit@codelutin.com> + */ +public class ExistingFileFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (!(f.isFile() && f.exists())) { + // f is not a file nor exists + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "existingFile"; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/ExistingFileFieldValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/FieldExpressionWithParamsValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/FieldExpressionWithParamsValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/FieldExpressionWithParamsValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,219 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldExpressionValidator; +import org.nuiton.util.converter.ConverterUtil; + +import java.util.Map; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Extends {@link FieldExpressionValidator} to add some extra parameters available + * in the {@link #getExpression()} + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public class FieldExpressionWithParamsValidator extends FieldExpressionValidator { + + protected static final Pattern EXTRA_BOOLEAN_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(false|true)"); + + protected static final Pattern EXTRA_SHORT_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+)"); + + protected static final Pattern EXTRA_INT_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+)"); + + protected static final Pattern EXTRA_LONG_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+)"); + + protected static final Pattern EXTRA_DOUBLE_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+\\.\\d+)"); + + protected static final Pattern EXTRA_STRING_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(.+)"); + + protected ValueStack stack; + + protected String booleanParams; + + protected String shortParams; + + protected String intParams; + + protected String longParams; + + protected String doubleParams; + + protected String stringParams; + + protected Map<String, Boolean> booleans; + + protected Map<String, Short> shorts; + + protected Map<String, Integer> ints; + + protected Map<String, Long> longs; + + protected Map<String, Double> doubles; + + protected Map<String, String> strings; + + public String getBooleanParams() { + return booleanParams; + } + + public void setBooleanParams(String booleanParams) { + this.booleanParams = booleanParams; + } + + public String getDoubleParams() { + return doubleParams; + } + + public void setDoubleParams(String doubleParams) { + this.doubleParams = doubleParams; + } + + public String getIntParams() { + return intParams; + } + + public void setIntParams(String intParams) { + this.intParams = intParams; + } + + public String getLongParams() { + return longParams; + } + + public void setLongParams(String longParams) { + this.longParams = longParams; + } + + public String getShortParams() { + return shortParams; + } + + public void setShortParams(String shortParams) { + this.shortParams = shortParams; + } + + public String getStringParams() { + return stringParams; + } + + public void setStringParams(String stringParams) { + this.stringParams = stringParams; + } + + public Map<String, Boolean> getBooleans() { + return booleans; + } + + public Map<String, Double> getDoubles() { + return doubles; + } + + public Map<String, Integer> getInts() { + return ints; + } + + public Map<String, Long> getLongs() { + return longs; + } + + public Map<String, Short> getShorts() { + return shorts; + } + + public Map<String, String> getStrings() { + return strings; + } + + @Override + public String getValidatorType() { + return "fieldexpressionwithparams"; + } + + @Override + public void setValueStack(ValueStack stack) { + super.setValueStack(stack); + this.stack = stack; + } + + @Override + public void validate(Object object) throws ValidationException { + + booleans = initParams(Boolean.class, booleanParams, EXTRA_BOOLEAN_PARAM_ENTRY_PATTERN); + shorts = initParams(Short.class, shortParams, EXTRA_SHORT_PARAM_ENTRY_PATTERN); + ints = initParams(Integer.class, intParams, EXTRA_INT_PARAM_ENTRY_PATTERN); + longs = initParams(Long.class, longParams, EXTRA_LONG_PARAM_ENTRY_PATTERN); + doubles = initParams(Double.class, doubleParams, EXTRA_DOUBLE_PARAM_ENTRY_PATTERN); + strings = initParams(String.class, stringParams, EXTRA_STRING_PARAM_ENTRY_PATTERN); + + boolean pop = false; + if (!stack.getRoot().contains(this)) { + stack.push(this); + pop = true; + } + + try { + super.validate(object); + } finally { + if (pop) { + stack.pop(); + } + } + + } + + protected <T> Map<String, T> initParams(Class<T> klass, String extraParams, Pattern pattern) throws ValidationException { + + if (extraParams == null || extraParams.isEmpty()) { + // not using + return null; + } + + StringTokenizer stk = new StringTokenizer(extraParams, "|"); + Map<String, T> result = new TreeMap<String, T>(); + while (stk.hasMoreTokens()) { + String entry = stk.nextToken(); + Matcher matcher = pattern.matcher(entry); + if (!matcher.matches()) { + throw new ValidationException("could not parse for extra params " + extraParams + " for type " + klass.getName()); + } + String paramName = matcher.group(1); + String paramValueStr = matcher.group(2); + T paramValue = ConverterUtil.convert(klass, paramValueStr); + if (log.isDebugEnabled()) { + log.debug("detected extra param : <type:" + klass + ", name:" + paramName + ", value:" + paramValue + ">"); + } + result.put(paramName, paramValue); + } + return result; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/FieldExpressionWithParamsValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,96 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * NotExistingDirectoryFieldValidator checks that a File field as a directory does not exist. * + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="notExistingDirectory"> + * <param name="fieldName">tmp</param> + * <message>tmp is an existing directory</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="notExistingDirectory"> + * <message>tmp is an existing directory</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author tchemit <chemit@codelutin.com> + */ +public class NotExistingDirectoryFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (f.exists() || f.isFile()) { + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "notExistingDirectory"; + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingFileFieldValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingFileFieldValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingFileFieldValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,97 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * NotExistingFileFieldValidator checks that a File field as a file does not exist. * + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="notExistingFile"> + * <param name="fieldName">tmp</param> + * <message>tmp is an existing file</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="notExistingFile"> + * <message>tmp is an existing file</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author tchemit <chemit@codelutin.com> + */ +public class NotExistingFileFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (f.exists() || f.isDirectory()) { + // f is not a file and exist + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "notExistingFile"; + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/NotExistingFileFieldValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/RequiredFileFieldValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/RequiredFileFieldValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/RequiredFileFieldValidator.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,97 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * RequiredFileFieldValidator checks that a File field is not null nor have an empty filename. + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="requiredFile"> + * <param name="fieldName">tmp</param> + * <message>tmp is required</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="requiredFile"> + * <message>tmp is required</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author tchemit <chemit@codelutin.com> + */ +public class RequiredFileFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (f.getPath().trim().isEmpty()) { + // f is not a directory nor exists + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "requiredFile"; + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/field/RequiredFileFieldValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_en_GB.properties =================================================================== --- trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_en_GB.properties (rev 0) +++ trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_en_GB.properties 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,4 @@ +validator.scope.error.label=Error +validator.scope.fatal.label=Fatal error +validator.scope.info.label=Information +validator.scope.warning.label=Warning Property changes on: trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_en_GB.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_fr_FR.properties =================================================================== --- trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_fr_FR.properties (rev 0) +++ trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_fr_FR.properties 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,4 @@ +validator.scope.error.label=Erreur +validator.scope.fatal.label=Erreur fatale +validator.scope.info.label=Information +validator.scope.warning.label=Avertissement Property changes on: trunk/nuiton-validator/src/main/resources/i18n/nuiton-validator_fr_FR.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/resources/validators.xml =================================================================== --- trunk/nuiton-validator/src/main/resources/validators.xml (rev 0) +++ trunk/nuiton-validator/src/main/resources/validators.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> + +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator Config 1.0//EN" + "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd"> + +<!-- START SNIPPET: validators --> +<validators> + <validator name="requiredFile" + class="org.nuiton.validator.field.RequiredFileFieldValidator"/> + <validator name="existingFile" + class="org.nuiton.validator.field.ExistingFileFieldValidator"/> + <validator name="notExistingFile" + class="org.nuiton.validator.field.NotExistingFileFieldValidator"/> + <validator name="existingDirectory" + class="org.nuiton.validator.field.ExistingDirectoryFieldValidator"/> + <validator name="notExistingDirectory" + class="org.nuiton.validator.field.NotExistingDirectoryFieldValidator"/> + <validator name="collectionFieldExpression" + class="org.nuiton.validator.field.CollectionFieldExpressionValidator"/> + <validator name="collectionUniqueKey" + class="org.nuiton.validator.field.CollectionUniqueKeyValidator"/> +</validators> +<!-- END SNIPPET: validators --> Property changes on: trunk/nuiton-validator/src/main/resources/validators.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/site/apt/index.apt =================================================================== --- trunk/nuiton-validator/src/site/apt/index.apt (rev 0) +++ trunk/nuiton-validator/src/site/apt/index.apt 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,67 @@ + ---- + Nuiton utils + ---- + ---- + 2009-08-23 + ---- + +~~~ +~~ #%L +~~ Nuiton Utils +~~ +~~ $Id$ +~~ $HeadURL$ +~~ %% +~~ Copyright (C) 2004 - 2010 CodeLutin +~~ %% +~~ This program is free software: you can redistribute it and/or modify +~~ it under the terms of the GNU Lesser General Public License as +~~ published by the Free Software Foundation, either version 3 of the +~~ License, or (at your option) any later version. +~~ +~~ This program is distributed in the hope that it will be useful, +~~ but WITHOUT ANY WARRANTY; without even the implied warranty of +~~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +~~ GNU General Lesser Public License for more details. +~~ +~~ You should have received a copy of the GNU General Lesser Public +~~ License along with this program. If not, see +~~ <http://www.gnu.org/licenses/lgpl-3.0.html>. +~~ #L% +~~~ + + +Présentation + + Ensemble de classe Java permettant de simplifier le développement en + factorisant des besoins que l'on retrouve dans tous les développements. + On y trouve des fonctions de travail sur les chaînes de caractères, des + fonctions de parsage des arguements de la ligne de commande, des fonctions + permettant très simplement de rechercher une resource (images, fichier de + propriétés, ...), ... + +Librairie Util + + Librairie regroupant les utilitaires classiques sur les fichiers, les tableaux, + les collections, les maps, les chaînes de caractères, ... De plus elle intègre + un parser des arguments et des options pour les lignes de commande. + +Librairie LutinLog + + N'existe plus depuis la version <<1.1>>. + +Librairie i18n + + Depuis la version <<1.1>>, cette librairie est déplacé dans le projet + {{{http://maven-site.nuiton.org/i18n/nuiton-i18n}nuiton-i18n}}. + + Librairie permettant de rendre les programmes Java multilangue de façon + simple. Il utilise la même philosophie que gettext. C'est à dire que chaque + chaîne de caractères devant être traduite sont tagge avec I18n._("..."). + Ensuite il suffit d'extraire ces cha?nes pour les mettres dans un fichier de + propriété, et d'indiquer quel fichier de propré?té charger au démarrage de + l'application selon la langue souhaitée. + + + <Veuillez consulter la JavaDoc pour de plus ample détails sur les différentes + librairies.> Property changes on: trunk/nuiton-validator/src/site/apt/index.apt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/site/site_fr.xml =================================================================== --- trunk/nuiton-validator/src/site/site_fr.xml (rev 0) +++ trunk/nuiton-validator/src/site/site_fr.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Nuiton Utils + + $Id$ + $HeadURL$ + %% + Copyright (C) 2004 - 2010 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> + +<project name="${project.name}"> + + <bannerLeft> + <name>${project.name}</name> + <href>index.html</href> + </bannerLeft> + + <body> + + <breadcrumbs> + <item name="${project.name}" href="index.html"/> + </breadcrumbs> + + <menu ref="parent"/> + + <menu name="Utilisateur"> + <item name="Accueil" href="index.html"/> + <item name="Documentation" href="/nuitonUtil.html"/> + <item name="Application config" href="/ApplicationConfig.html"/> + <item name="War launcher" href="/Warlauncher.html"/> + </menu> + + <menu name="Téléchargement"> + <item + href="${repository.home.url}/org/nuiton/${project.artifactId}/${project.version}/${project.build.finalName}.jar" + name="Librairie (jar)"/> + <item + href="${repository.home.url}/org/nuiton/${project.artifactId}/${project.version}/${project.build.finalName}-javadoc.jar" + name="Javadoc (jar)"/> + <item + href="${repository.home.url}/org/nuiton/${project.artifactId}/${project.version}/${project.build.finalName}-sources.jar" + name="Sources (jar)"/> + </menu> + + <menu ref="reports"/> + + </body> +</project> Property changes on: trunk/nuiton-validator/src/site/site_fr.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,196 @@ +/* + * #%L + * Nuiton Utils :: Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.regex.Pattern; + +import static org.junit.Assert.assertEquals; + +/** + * An abstract test to detects validators for a given list of objets types and + * <p/> + * a given sourceroot directory where to find validations definitions. + * <p/> + * You just have to implements to {@link #assertDetect(SortedSet)} which contains + * the set of validators detected. + * <p/> + * See {@link BeanValidatorDetectorTest} for an example. + * <p/> + * Note : An implementation of this test should be produced in evry projects which + * defines some validation definitions just to test they are syntax valid. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6.0 + */ +public abstract class AbstractBeanValidatorDetectorTest { + + /** Logger */ + private static final Log log = + LogFactory.getLog(AbstractBeanValidatorDetectorTest.class); + + protected static File basedir; + + protected BeanValidatorDetector instance; + + protected Class<?>[] classes; + + protected Class<?> validatorClass; + + protected File sourceRoot; + + protected AbstractBeanValidatorDetectorTest( + File sourceRoot, + Class<?>... classes) { + this(BeanValidator.class, sourceRoot, classes); + } + + protected AbstractBeanValidatorDetectorTest( + Class<?> validatorClass, + File sourceRoot, + Class<?>... classes) { + this.sourceRoot = sourceRoot; + this.classes = classes; + this.validatorClass = validatorClass; + + if (log.isInfoEnabled()) { + log.info("sourceRoot " + sourceRoot); + log.info("validatorClass " + validatorClass); + log.info("classes " + Arrays.toString(classes)); + } + } + + protected AbstractBeanValidatorDetectorTest( + File sourceRoot, + Collection<Class<?>> classes) { + this(sourceRoot, classes.toArray(new Class<?>[classes.size()])); + } + + public static void setUpClass() throws Exception { + String b = System.getenv("basedir"); + if (b == null) { + b = new File("").getAbsolutePath(); + } + basedir = new File(b); + if (log.isInfoEnabled()) { + log.info("basedir " + basedir); + } + } + + @Before + public void setUp() { + instance = new BeanValidatorDetector(); + } + + @After + public void tearDown() { + instance = null; + } + + /** Test of detect method, of class BeanValidatorDetector. */ + @Test + public void testDetect() { + SortedSet<BeanValidator<?>> result = detect(sourceRoot, classes, null); + if (log.isInfoEnabled()) { + log.info(printValidators("testDetect : ", result)); + } + assertDetect(result); + } + + protected abstract void assertDetect( + SortedSet<BeanValidator<?>> validators); + + protected SortedSet<BeanValidator<?>> detect( + File sourceRoot, + Class<?>[] classes, + Pattern contextPattern) { + + SortedSet<BeanValidator<?>> result = instance.detect( + validatorClass, + sourceRoot, + contextPattern, + classes); + return result; + } + + protected static void assertValidator( + Class<?> expectedBeanClass, + String expectedContextName, + BeanValidator<?> validator) { + assertEquals(expectedBeanClass, validator.getBeanClass()); + assertEquals(expectedContextName, validator.getContextName()); + } + + protected static void assertValidatorSetWithSameContextName( + SortedSet<BeanValidator<?>> validators, + String contextName, + Class<?>... expectedClasses) { + + assertEquals(expectedClasses.length, validators.size()); + Iterator<BeanValidator<?>> itrV = validators.iterator(); + + for (Class<?> expectedClass : expectedClasses) { + assertValidator(expectedClass, contextName, itrV.next()); + } + } + + protected static void assertValidatorSetWithMultiContextName( + SortedSet<BeanValidator<?>> validators, + Object... expecteds) { + + assertEquals(expecteds.length % 2, 0); + assertEquals(expecteds.length / 2, validators.size()); + Iterator<BeanValidator<?>> itrV = validators.iterator(); + + for (int i = 0; i < expecteds.length / 2; i++) { + String contextName = (String) expecteds[2 * i]; + Class<?> expectedClass = (Class<?>) expecteds[2 * i + 1]; + assertValidator(expectedClass, contextName, itrV.next()); + } + + } + + protected static String printValidators( + String prefix, + SortedSet<BeanValidator<?>> result) { + StringBuilder buffer; + buffer = new StringBuilder(result.size() * (prefix.length() + 50)); + buffer.append(prefix).append(result.size()).append('\n'); + for (BeanValidator<?> v : result) { + buffer.append(prefix).append(v).append('\n'); + } + return buffer.toString(); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,116 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.util.SortedSet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/** @author tchemit <chemit@codelutin.com> */ +public class BeanValidatorDetectorTest extends AbstractBeanValidatorDetectorTest { + + private static final Class<?>[] TYPES = new Class<?>[]{Object.class}; + + @BeforeClass + public static void setUpClass() throws Exception { + AbstractBeanValidatorDetectorTest.setUpClass(); + + } + + public BeanValidatorDetectorTest() { + super(new File(basedir, "src" + File.separator + "test" + File.separator + "resources"), SimpleBean.class); + } + + /** Test of detect method, of class BeanValidatorDetector. */ + @Test + public void testDetectNothing() { + + SortedSet<BeanValidator<?>> validators = instance.detect(sourceRoot, TYPES); + assertEquals(0, validators.size()); + } + + @Override + protected void assertDetect(SortedSet<BeanValidator<?>> validators) { + assertEquals(1, validators.size()); + BeanValidator<?> validator = validators.iterator().next(); + assertEquals(classes[0], validator.getBeanClass()); + assertNull(validator.getContextName()); + } + + /** Test of getValidator method, of class BeanValidatorDetector. */ + @Test + public void testGetValidator() { + Class<?>[] types = {SimpleBean.class}; + SortedSet<BeanValidator<?>> result = instance.detect(sourceRoot, types); + assertEquals(1, result.size()); + BeanValidator<?> validator = result.iterator().next(); + assertEquals(types[0], validator.getBeanClass()); + assertNull(validator.getContextName()); + + types = TYPES; + result = instance.detect(sourceRoot, types); + assertEquals(0, result.size()); + + } + + /** Test of getClassDir method, of class BeanValidatorDetector. */ + @Test + public void testGetClassDir() { + Class<?> clazz = classes[0]; + + File expected = new File(sourceRoot, "org" + File.separator + "nuiton" + File.separator + "validator"); + File result = instance.getClassDir(sourceRoot, clazz); + assertEquals(expected, result); + } + + /** Test of getContexts method, of class BeanValidatorDetector. */ + @Test + public void testGetContexts() { + + String[] expResult = {"fatal", "error", "info", "simple", "warning"}; + Class<?> clazz = classes[0]; + File dir = instance.getClassDir(sourceRoot, clazz); + String[] result = instance.getContexts(clazz, dir); + assertEquals(expResult.length, result.length); + } + + /** Test of getContextsWithoutScopes method, of class BeanValidatorDetector. */ + @Test + public void testGetContextsWithoutScopes() { + + Class<?> clazz = SimpleBean.class; + String[] expResult = {""}; + File dir = instance.getClassDir(sourceRoot, clazz); + String[] contexts = instance.getContexts(clazz, dir); + String[] result = instance.getContextsWithoutScopes(contexts); + assertEquals(expResult.length, result.length); + + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,290 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** @author tchemit <chemit@codelutin.com> */ +public class BeanValidatorTest { + + /** Logger */ + static protected final Log log = LogFactory.getLog(BeanValidator.class); + + protected BeanValidator<SimpleBean> validator; + + protected SimpleBean bean; + + BeanValidatorListenerImpl fatalListener; + + BeanValidatorListenerImpl errorListener; + + BeanValidatorListenerImpl warningListener; + + BeanValidatorListenerImpl infoListener; + + @Before + public void setUp() { + bean = new SimpleBean(); + validator = new BeanValidator<SimpleBean>(SimpleBean.class, null); + validator.addBeanValidatorListener(fatalListener = new BeanValidatorListenerImpl(BeanValidatorScope.FATAL)); + validator.addBeanValidatorListener(errorListener = new BeanValidatorListenerImpl(BeanValidatorScope.ERROR)); + validator.addBeanValidatorListener(warningListener = new BeanValidatorListenerImpl(BeanValidatorScope.WARNING)); + validator.addBeanValidatorListener(infoListener = new BeanValidatorListenerImpl(BeanValidatorScope.INFO)); + } + + @After + public void tearDown() { + bean = null; + if (validator != null) { + validator.setBean(null); + validator = null; + } + } + + private static final String STRING_VALUE_FATAL= "stringValue.fatal"; + + private static final String STRING_VALUE_ERROR = "stringValue.error"; + + private static final String STRING_VALUE_WARNING = "stringValue.warning"; + + private static final String INT_VALUE_FATAL = "intValue.fatal"; + + private static final String INT_VALUE_ERROR = "intValue.error"; + + private static final String INT_VALUE_INFO = "intValue.info"; + + @Test + public void testValidate() { + + assertMessages(fatalListener); + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + validator.setBean(bean); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setStringValue("one"); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setStringValue("oneone"); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, INT_VALUE_ERROR); + assertMessages(warningListener); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setIntValue(1); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setIntValue(10); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + bean.setStringValue(null); + bean.setIntValue(0); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + bean.setStringValue("5"); + bean.setIntValue(5); + assertMessages(fatalListener); + assertMessages(errorListener); + assertMessages(warningListener,STRING_VALUE_WARNING); + assertMessages(infoListener,INT_VALUE_INFO); + } + + @Test + public void testConvert() { + + + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + validator.setBean(bean); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + Object value = validator.convert("intValue", "abc", Class.class); + + Assert.assertNull(value); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, "error.convertor.class"); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setStringValue("one"); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, "error.convertor.class"); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + value = validator.convert("intValue", "3", Integer.class); + + bean.setIntValue((Integer) value); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + bean.setIntValue(-1); + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + } + + void assertMessages(BeanValidatorListenerImpl listener, + String... expected) { + List<String> actual = listener.getMessages(); + Assert.assertEquals(" shoudl have " + + Arrays.toString(expected) + " but had " + actual, + expected.length, actual.size()); + for (String m : expected) { + Assert.assertEquals("could not find " + m + " in " + actual, + true, actual.contains(m)); + } + } + + class BeanValidatorListenerImpl implements BeanValidatorListener { + + final BeanValidatorScope scope; + + public BeanValidatorListenerImpl(BeanValidatorScope scope) { + this.scope = scope; + } + + List<String> messages = new ArrayList<String>(); + + public List<String> getMessages() { + return messages; + } + + @Override + public void onFieldChanged(BeanValidatorEvent event) { + if (scope != event.getScope()) { + return; + } + String[] messagesToDelete = event.getMessagesToDelete(); + if (messagesToDelete != null && messagesToDelete.length > 0) { + if (log.isInfoEnabled()) { + log.info(event.getScope() + " messages to delete : " + Arrays.toString(messagesToDelete)); + } + for (String m : messagesToDelete) { + messages.remove(m); + } + } + String[] messagesToAdd = event.getMessagesToAdd(); + if (messagesToAdd != null && messagesToAdd.length > 0) { + if (log.isInfoEnabled()) { + log.info(event.getScope() + " messages to add : " + Arrays.toString(messagesToAdd)); + } + messages.addAll(Arrays.asList(messagesToAdd)); + } + } + } +} Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,79 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +public class SimpleBean { + + protected int intValue; + + protected String stringValue; + + final PropertyChangeSupport p; + + public SimpleBean() { + p = new PropertyChangeSupport(this); + } + + public int getIntValue() { + return intValue; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + String old = this.stringValue; + this.stringValue = stringValue; + p.firePropertyChange("stringValue", old, stringValue); + } + + public void setIntValue(int intValue) { + int old = this.intValue; + this.intValue = intValue; + p.firePropertyChange("intValue", old, intValue); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + p.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + p.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + p.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + p.removePropertyChangeListener(propertyName, listener); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,182 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.List; +import java.util.Map; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public class XWorkBeanValidatorTest { + + protected XWorkBeanValidator<SimpleBean> validator; + + protected SimpleBean bean; + + protected Map<String, List<String>> messages; + + @Before + public void setUp() { + bean = new SimpleBean(); + validator = new XWorkBeanValidator<SimpleBean>(SimpleBean.class, "simple"); + } + + @After + public void tearDown() { + bean = null; + messages = null; + } + + @Test + public void testUnknownField() { + Assert.assertEquals(false, validator.containsField("fake_" + System.nanoTime())); + } + + @Test(expected = NullPointerException.class) + public void testValidateNPE() { + validator.validate(null); + } + + @Test + public void testValidate() { + + + messages = validator.validate(bean); + + assertFieldInError("stringValue", "stringValue.null", true, messages); + assertFieldInError("intValue", "intValue.null", true, messages); + + bean.setStringValue("notnull"); + messages = validator.validate(bean); + + assertFieldInError("stringValue", "stringValue.null", false, messages); + assertFieldInError("intValue", "intValue.null", true, messages); + + bean.setIntValue(1); + messages = validator.validate(bean); + + assertFieldInError("stringValue", "stringValue.null", false, messages); + assertFieldInError("intValue", "intValue.null", false, messages); + + } + + @Test + public void testSetContextName() { + + + String expected = "simple"; + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "error"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "warning"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + validator.setContextName(expected = "info"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "fake_" + System.nanoTime()); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + } + + @Test + public void testSetIncludeDefaultContext() { + + validator.setIncludeDefaultContext(false); + + String expected = "simple"; + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "error"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "warning"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + validator.setContextName(expected = "info"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "fake_" + System.nanoTime()); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + } + + protected void assertFieldInError(String fieldName, String error, boolean required, Map<String, List<String>> messages) { + + Assert.assertEquals(true, validator.containsField(fieldName)); + List<String> fieldMessages = messages.get(fieldName); + //Assert.assertEquals(true,validator.containsField(fieldName)); + if (fieldMessages != null) { + for (String o : fieldMessages) { + if (o.equals(error)) { + Assert.assertTrue(required); + return; + } + } + } + + // error was not found + Assert.assertFalse(required); + } +} Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,127 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.nuiton.validator.BeanValidator; +import org.nuiton.validator.BeanValidatorField; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; + +import java.io.File; + +/** + * Abstract class to test a specific validator. + * <p/> + * To implements a test on a new validator, just extends this class + * and implements the method {@link #testValidator()}. + * + * @author tchemit <chemit@codelutin.com> + * @param <B> the type of bean to validate. + */ +public abstract class AbstractFieldValidatorTest<B> extends Assert { + + /** Logger */ + static private final Log log = + LogFactory.getLog(AbstractFieldValidatorTest.class); + + protected static BeanValidator<?> cacheValidator; + + protected static File basedir; + + protected final Class<B> type; + + protected BeanValidator<B> validator; + + protected B bean; + + public AbstractFieldValidatorTest(Class<B> type) { + this.type = type; + } + + /** + * the method to test the given validator on the given bean. + * <p/> + * When coming here a validator and bean were instanciated and the bean was + * setted into validator via setBean method. + * + * @throws Exception if any error ? + */ + public abstract void testValidator() throws Exception; + + @Before + @SuppressWarnings("unchecked") + public void setUp() throws Exception { + log.debug("start test " + getClass().getSimpleName()); + bean = type.newInstance(); + if (cacheValidator == null) { + validator = new BeanValidator<B>(type, null); + cacheValidator = validator; + } else { + validator = (BeanValidator<B>) cacheValidator; + } + validator.setBean(bean); + } + + @After + @SuppressWarnings("unchecked") + public void tearDown() { + validator.setBean(null); + } + + @AfterClass + public static void afterclass() throws Exception { + cacheValidator = null; + } + + @BeforeClass + public static void initValidator() throws Exception { + + String b = System.getenv("basedir"); + if (b == null) { + b = new File("").getAbsolutePath(); + } + basedir = new File(b); + } + + @SuppressWarnings("unchecked") + protected void assertFieldInError(String fieldName, String error, boolean required) { + BeanValidatorField<B> field = validator.getField(fieldName); + if (field != null && field.getErrors() != null) { + for (String o : field.getErrors()) { + if (o.equals(error)) { + assertTrue("error " + error + " should not exist but was found.", required); + return; + } + } + } + // error was not found + assertFalse("error " + error + " should exist but was not found.", required); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractValidatorBeanFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractValidatorBeanFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractValidatorBeanFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,38 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +/** + * Abstract class to test a specific validator for the {@link ValidatorBean}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public abstract class AbstractValidatorBeanFieldValidatorTest extends AbstractFieldValidatorTest<ValidatorBean> { + + public AbstractValidatorBeanFieldValidatorTest() { + super(ValidatorBean.class); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/AbstractValidatorBeanFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionFieldExpressionValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionFieldExpressionValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionFieldExpressionValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,264 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.nuiton.validator.field.ValidatorBean.ValidatorBeanEntry; +import org.junit.Test; + +import java.util.Arrays; + +/** @author tchemit <chemit@codelutin.com> */ +public class CollectionFieldExpressionValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + protected static final String PROPERTY = "entries"; + + static protected ValidatorBeanEntry beanEntry0 = new ValidatorBeanEntry(0, "stringValue"); + + static protected ValidatorBeanEntry beanEntry0Bis = new ValidatorBeanEntry(0, "fake"); + + static protected ValidatorBeanEntry beanEntry1 = new ValidatorBeanEntry(1, "fake"); + + static protected ValidatorBeanEntry beanEntry3 = new ValidatorBeanEntry(3, "fake"); + + static protected ValidatorBeanEntry beanEntry5 = new ValidatorBeanEntry(5, "fake"); + + @Test + @Override + public void testValidator() throws Exception { + assertNull(bean.getEntries()); + + // no entry + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.none", false); + + + // add a matching etry + bean.setEntries(Arrays.asList(beanEntry0)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.all", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.none", true); + + // two matching etries + bean.setEntries(Arrays.asList(beanEntry0, beanEntry0)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.none", true); + + // add a none matching etry + bean.setEntries(Arrays.asList(beanEntry0Bis)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none", false); + + // add a none matching etry and a matching entry + bean.setEntries(Arrays.asList(beanEntry0Bis, beanEntry0)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.all", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none", true); + } + + @Test + public void testValidatorWithContext() throws Exception { + assertNull(bean.getEntries()); + + // no entry + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + + // add a matching etry + bean.setEntries(Arrays.asList(beanEntry0)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + + // add a none matching etry + bean.setEntries(Arrays.asList(beanEntry0Bis)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + + // add a none matching etry and a matching entry + bean.setEntries(Arrays.asList(beanEntry0Bis, beanEntry0)); + + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1)); + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + + bean.setEntries(Arrays.asList(beanEntry1, beanEntry0)); + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3)); + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5)); + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1)); + assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true); + assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", false); + assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false); + } + + @Test + public void testValidatorWithContextAndFirst() throws Exception { + assertNull(bean.getEntries()); + String message = "collectionFieldExpression.all.useFirst"; + + // no entry + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0)); + assertFieldInError(PROPERTY, message, false); + + + bean.setEntries(Arrays.asList(beanEntry0Bis)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry1)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry1, beanEntry0)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1)); + assertFieldInError(PROPERTY, message, true); + } + + @Test + public void testValidatorWithContextAndLast() throws Exception { + assertNull(bean.getEntries()); + String message = "collectionFieldExpression.all.useLast"; + + // no entry + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0)); + assertFieldInError(PROPERTY, message, true); + + + bean.setEntries(Arrays.asList(beanEntry0Bis)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry1)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry1, beanEntry0)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry1, beanEntry3)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1)); + assertFieldInError(PROPERTY, message, true); + } + + @Test + public void testValidatorWithContextAndFirstAndLast() throws Exception { + assertNull(bean.getEntries()); + + String message = "collectionFieldExpression.all.useFirstAndLast"; + // no entry + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0)); + assertFieldInError(PROPERTY, message, true); + + + bean.setEntries(Arrays.asList(beanEntry0Bis)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry1)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry1, beanEntry0)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry1, beanEntry3)); + assertFieldInError(PROPERTY, message, true); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5)); + assertFieldInError(PROPERTY, message, false); + + bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1)); + assertFieldInError(PROPERTY, message, true); + } +} Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionFieldExpressionValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionUniqueKeyValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionUniqueKeyValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionUniqueKeyValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,113 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.nuiton.validator.field.ValidatorBean.ValidatorBeanEntry; +import org.junit.Test; + +import java.util.Arrays; + +/** @author tchemit <chemit@codelutin.com> */ +public class CollectionUniqueKeyValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + static protected ValidatorBeanEntry beanEntry = new ValidatorBeanEntry(0, "stringValue"); + + static protected ValidatorBeanEntry beanEntry2 = new ValidatorBeanEntry(0, "fake"); + + static protected ValidatorBeanEntry beanEntry3 = new ValidatorBeanEntry(0, "stringValue", "stringValue2"); + + @Test + @Override + public void testValidator() throws Exception { + assertNull(bean.getEntries()); + + // no entry + assertFieldInError("entries", "collectionUniqueKey.one.failed", false); + assertFieldInError("entries", "collectionUniqueKey.two.failed", false); + assertFieldInError("entries", "collectionUniqueKey.three.failed", false); + assertFieldInError("entries", "collectionUniqueKey.four.failed", false); + assertFieldInError("entries", "collectionUniqueKey.five.failed", false); + + // add a entry + bean.setEntries(Arrays.asList(beanEntry)); + + assertFieldInError("entries", "collectionUniqueKey.one.failed", false); + assertFieldInError("entries", "collectionUniqueKey.two.failed", false); + assertFieldInError("entries", "collectionUniqueKey.three.failed", false); + assertFieldInError("entries", "collectionUniqueKey.four.failed", false); + assertFieldInError("entries", "collectionUniqueKey.five.failed", false); + + // add violating property + bean.setEntry(beanEntry3); + assertFieldInError("entries", "collectionUniqueKey.one.failed", false); + assertFieldInError("entries", "collectionUniqueKey.two.failed", false); + assertFieldInError("entries", "collectionUniqueKey.three.failed", false); + assertFieldInError("entries", "collectionUniqueKey.four.failed", false); + assertFieldInError("entries", "collectionUniqueKey.five.failed", true); + + + // two entries with same key + bean.setEntries(Arrays.asList(beanEntry, beanEntry)); + + assertFieldInError("entries", "collectionUniqueKey.one.failed", true); + assertFieldInError("entries", "collectionUniqueKey.two.failed", true); + assertFieldInError("entries", "collectionUniqueKey.three.failed", true); + assertFieldInError("entries", "collectionUniqueKey.four.failed", true); + + // add a entry + bean.setEntries(Arrays.asList(beanEntry2)); + + assertFieldInError("entries", "collectionUniqueKey.one.failed", false); + assertFieldInError("entries", "collectionUniqueKey.two.failed", false); + assertFieldInError("entries", "collectionUniqueKey.three.failed", false); + assertFieldInError("entries", "collectionUniqueKey.four.failed", false); + + // add two entries (will violated unique key on intValue) + bean.setEntries(Arrays.asList(beanEntry2, beanEntry)); + + assertFieldInError("entries", "collectionUniqueKey.one.failed", true); + assertFieldInError("entries", "collectionUniqueKey.two.failed", false); + assertFieldInError("entries", "collectionUniqueKey.three.failed", false); + assertFieldInError("entries", "collectionUniqueKey.four.failed", false); + + + // two entries with same key (except validator four) + bean.setEntries(Arrays.asList(beanEntry, beanEntry3)); + assertFieldInError("entries", "collectionUniqueKey.one.failed", true); + assertFieldInError("entries", "collectionUniqueKey.two.failed", true); + assertFieldInError("entries", "collectionUniqueKey.three.failed", true); + assertFieldInError("entries", "collectionUniqueKey.four.failed", false); + + beanEntry.setStringValue2("stringValue2"); + // two entries with same key + bean.setEntries(Arrays.asList(beanEntry, beanEntry3)); + assertFieldInError("entries", "collectionUniqueKey.one.failed", true); + assertFieldInError("entries", "collectionUniqueKey.two.failed", true); + assertFieldInError("entries", "collectionUniqueKey.three.failed", true); + assertFieldInError("entries", "collectionUniqueKey.four.failed", true); + + + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/CollectionUniqueKeyValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingDirectoryFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingDirectoryFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingDirectoryFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,56 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.junit.Test; + +import java.io.File; + +/** @author tchemit <chemit@codelutin.com> */ +public class ExistingDirectoryFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + @Test + @Override + public void testValidator() throws Exception { + + assertNull(bean.getExistingDirectory()); + assertFieldInError("existingDirectory", "existingDirectory.required", true); + + bean.setExistingDirectory(new File("")); + assertFieldInError("existingDirectory", "existingDirectory.required", true); + + // existing file + bean.setExistingDirectory(new File(basedir, "pom.xml")); + assertFieldInError("existingDirectory", "existingDirectory.required", false); + assertFieldInError("existingDirectory", "existingDirectory.not.exist", true); + + // existing directory + bean.setExistingDirectory(basedir); + assertFieldInError("existingDirectory", "existingDirectory.required", false); + assertFieldInError("existingDirectory", "existingDirectory.not.exist", false); + + } + +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingDirectoryFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingFileFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingFileFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingFileFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,56 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.junit.Test; + +import java.io.File; + +/** @author tchemit <chemit@codelutin.com> */ +public class ExistingFileFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + @Test + @Override + public void testValidator() throws Exception { + + assertNull(bean.getExistingFile()); + assertFieldInError("existingFile", "existingFile.required", true); + + bean.setExistingFile(new File("")); + assertFieldInError("existingFile", "existingFile.required", true); + + // existing directory + bean.setExistingFile(basedir); + assertFieldInError("existingFile", "existingFile.required", false); + assertFieldInError("existingFile", "existingFile.not.exist", true); + + // existing file + bean.setExistingFile(new File(basedir, "pom.xml")); + assertFieldInError("existingFile", "existingFile.required", false); + assertFieldInError("existingFile", "existingFile.not.exist", false); + + } + +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ExistingFileFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionBean.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionBean.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionBean.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,130 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** @author tchemit <chemit@codelutin.com> */ +public class FieldExpressionBean { + + protected final PropertyChangeSupport p; + + protected boolean booleanValue; + + protected short shortValue; + + protected int intValue; + + protected long longValue; + + protected double doubleValue; + + protected String stringValue; + + public FieldExpressionBean() { + p = new PropertyChangeSupport(this); + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public double getDoubleValue() { + return doubleValue; + } + + public int getIntValue() { + return intValue; + } + + public long getLongValue() { + return longValue; + } + + public short getShortValue() { + return shortValue; + } + + public String getStringValue() { + return stringValue; + } + + public void setBooleanValue(boolean newValue) { + Object oldValue = booleanValue; + booleanValue = newValue; + firePropertyChange("booleanValue", oldValue, newValue); + } + + public void setDoubleValue(double newValue) { + Object oldValue = doubleValue; + doubleValue = newValue; + firePropertyChange("doubleValue", oldValue, newValue); + } + + public void setIntValue(int newValue) { + Object oldValue = stringValue; + intValue = newValue; + firePropertyChange("intValue", oldValue, newValue); + } + + public void setLongValue(long newValue) { + Object oldValue = longValue; + longValue = newValue; + firePropertyChange("longValue", oldValue, newValue); + } + + public void setShortValue(short newValue) { + Object oldValue = shortValue; + shortValue = newValue; + firePropertyChange("shortValue", oldValue, newValue); + } + + public void setStringValue(String newValue) { + Object oldValue = stringValue; + stringValue = newValue; + firePropertyChange("stringValue", oldValue, newValue); + } + + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + p.firePropertyChange(propertyName, oldValue, newValue); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + p.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + p.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + p.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + p.removePropertyChangeListener(propertyName, listener); + } +} Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionBean.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionWithParamsValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionWithParamsValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionWithParamsValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,143 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.junit.Test; + +/** @author tchemit <chemit@codelutin.com> */ +public class FieldExpressionWithParamsValidatorTest extends AbstractFieldValidatorTest<FieldExpressionBean> { + + public static final String MESSAGE = "expression.too.big##100"; + + public static final String MESSAGE2 = "expression.too.big##100##2000"; + + public FieldExpressionWithParamsValidatorTest() { + super(FieldExpressionBean.class); + } + + @Test + @Override + public void testValidator() throws Exception { + + testBooleanType(); + testShortType(); + testIntType(); + testLongType(); + testDoubleType(); + testStringType(); + + + } + + protected void testBooleanType() { + + assertEquals(false, bean.isBooleanValue()); + assertFieldInError("booleanValue", "expression.boolean.not.equals##true", true); + assertFieldInError("booleanValue", "expression.boolean.not.equals##false", false); + + bean.setBooleanValue(true); + assertFieldInError("booleanValue", "expression.boolean.not.equals##true", false); + assertFieldInError("booleanValue", "expression.boolean.not.equals##false", true); + } + + protected void testShortType() { + assertEquals(0, bean.getShortValue()); + assertFieldInError("shortValue", MESSAGE, false); + assertFieldInError("shortValue", MESSAGE2, false); + bean.setShortValue((short) 10); + assertFieldInError("shortValue", MESSAGE, false); + assertFieldInError("shortValue", MESSAGE2, false); + bean.setShortValue((short) 1000); + assertFieldInError("shortValue", MESSAGE, true); + assertFieldInError("shortValue", MESSAGE2, false); + bean.setShortValue((short) 3000); + assertFieldInError("shortValue", MESSAGE, true); + assertFieldInError("shortValue", MESSAGE2, true); + } + + protected void testIntType() { + assertEquals(0, bean.getIntValue()); + assertFieldInError("intValue", MESSAGE, false); + assertFieldInError("intValue", MESSAGE2, false); + bean.setIntValue(10); + assertFieldInError("intValue", MESSAGE, false); + assertFieldInError("intValue", MESSAGE2, false); + bean.setIntValue(1000); + assertFieldInError("intValue", MESSAGE, true); + assertFieldInError("intValue", MESSAGE2, false); + bean.setIntValue(3000); + assertFieldInError("intValue", MESSAGE, true); + assertFieldInError("intValue", MESSAGE2, true); + } + + protected void testLongType() { + assertEquals(0, bean.getLongValue()); + assertFieldInError("longValue", MESSAGE, false); + assertFieldInError("longValue", MESSAGE2, false); + bean.setLongValue(10); + assertFieldInError("longValue", MESSAGE, false); + assertFieldInError("longValue", MESSAGE2, false); + bean.setLongValue(1000); + assertFieldInError("longValue", MESSAGE, true); + assertFieldInError("longValue", MESSAGE2, false); + bean.setLongValue(3000); + assertFieldInError("longValue", MESSAGE, true); + assertFieldInError("longValue", MESSAGE2, true); + } + + protected void testDoubleType() { + assertEquals(0.0, bean.getDoubleValue(), 0); + assertFieldInError("doubleValue", MESSAGE + ".0", false); + assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", false); + bean.setDoubleValue(10); + assertFieldInError("doubleValue", MESSAGE + ".0", false); + assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", false); + bean.setDoubleValue(1000); + assertFieldInError("doubleValue", MESSAGE + ".0", true); + assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", false); + bean.setDoubleValue(3000); + assertFieldInError("doubleValue", MESSAGE + ".0", true); + assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", true); + } + + protected void testStringType() { + assertEquals(null, bean.getStringValue()); + + assertFieldInError("stringValue", "expression.stringNotValue##1000", true); + assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", true); + bean.setStringValue("100"); + + assertFieldInError("stringValue", "expression.stringNotValue##1000", true); + assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", true); + + bean.setStringValue("1000"); + assertFieldInError("stringValue", "expression.stringNotValue##1000", false); + assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", false); + + bean.setStringValue("3000"); + assertFieldInError("stringValue", "expression.stringNotValue##1000", true); + assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", false); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/FieldExpressionWithParamsValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,59 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.junit.Test; + +import java.io.File; + +/** @author tchemit <chemit@codelutin.com> */ +public class NotExistingDirectoryFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + @Test + @Override + public void testValidator() throws Exception { + assertNull(bean.getNotExistingDirectory()); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", true); + + bean.setNotExistingDirectory(new File("")); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", true); + + // existing directory + bean.setNotExistingDirectory(basedir); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", false); + assertFieldInError("notExistingDirectory", "notExistingDirectory.exist", true); + + // existing file + bean.setNotExistingDirectory(new File(basedir, "pom.xml")); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", false); + assertFieldInError("notExistingDirectory", "notExistingDirectory.exist", true); + + // none existing directory + bean.setNotExistingDirectory(new File(basedir, "pom.xml-" + System.currentTimeMillis())); + assertFieldInError("notExistingDirectory", "notEexistingFile.required", false); + assertFieldInError("notExistingDirectory", "notExistingDirectory.exist", false); + } + +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingDirectoryFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingFileFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingFileFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingFileFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,63 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.junit.Test; + +import java.io.File; + +/** @author tchemit <chemit@codelutin.com> */ +public class NotExistingFileFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + + @Test + @Override + public void testValidator() throws Exception { + + assertNull(bean.getNotExistingFile()); + assertFieldInError("notExistingFile", "notExistingFile.required", true); + + bean.setNotExistingFile(new File("")); + assertFieldInError("notExistingFile", "notExistingFile.required", true); + + // existing directory + bean.setNotExistingFile(basedir); + assertFieldInError("notExistingFile", "notExistingFile.required", false); + assertFieldInError("notExistingFile", "notExistingFile.exist", true); + + // existing file + bean.setNotExistingFile(new File(basedir, "pom.xml")); + assertFieldInError("notExistingFile", "notExistingFile.required", false); + assertFieldInError("notExistingFile", "notExistingFile.exist", true); + + // none existing file + bean.setNotExistingFile(new File(basedir, "pom.xml-" + System.currentTimeMillis())); + assertFieldInError("notExistingFile", "notEexistingFile.required", false); + assertFieldInError("notExistingFile", "notExistingFile.exist", false); + + + } + +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/NotExistingFileFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/RequiredFileFieldValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/RequiredFileFieldValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/RequiredFileFieldValidatorTest.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,55 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import org.junit.Test; + +import java.io.File; + +/** @author tchemit <chemit@codelutin.com> */ +public class RequiredFileFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest { + + @Test + @Override + public void testValidator() throws Exception { + + assertNull(bean.getExistingFile()); + assertFieldInError("existingFile", "existingFile.required", true); + + bean.setExistingFile(new File("")); + assertFieldInError("existingFile", "existingFile.required", true); + + bean.setExistingFile(basedir); + assertFieldInError("existingFile", "existingFile.required", false); + + assertFieldInError("existingFile", "existingFile.not.exist", true); + + bean.setExistingFile(new File(basedir, "pom.xml")); + assertFieldInError("existingFile", "existingFile.required", false); + assertFieldInError("existingFile", "existingFile.not.exist", false); + + } + +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/RequiredFileFieldValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ValidatorBean.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ValidatorBean.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ValidatorBean.java 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,183 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.field; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.File; +import java.util.Collection; + +public class ValidatorBean { + + public static class ValidatorBeanEntry { + + protected int intValue; + + protected String stringValue; + + protected String stringValue2; + + public ValidatorBeanEntry(int intValue, String stringValue) { + this.intValue = intValue; + this.stringValue = stringValue; + } + + public ValidatorBeanEntry(int intValue, String stringValue, String stringValue2) { + this.intValue = intValue; + this.stringValue = stringValue; + this.stringValue2 = stringValue2; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public String getStringValue2() { + return stringValue2; + } + + public void setStringValue2(String stringValue2) { + this.stringValue2 = stringValue2; + } + } + + protected File existingFile; + + protected File notExistingFile; + + protected File existingDirectory; + + protected File notExistingDirectory; + + protected Collection<ValidatorBeanEntry> entries; + + protected String stringValue; + + protected ValidatorBeanEntry entry; + + PropertyChangeSupport p; + + public ValidatorBean() { + p = new PropertyChangeSupport(this); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + p.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + p.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + p.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + p.removePropertyChangeListener(propertyName, listener); + } + + public String getStringValue() { + return stringValue; + } + + public File getExistingFile() { + return existingFile; + } + + public File getNotExistingFile() { + return notExistingFile; + } + + public File getExistingDirectory() { + return existingDirectory; + } + + public File getNotExistingDirectory() { + return notExistingDirectory; + } + + public ValidatorBeanEntry getEntry() { + return entry; + } + + public Collection<ValidatorBeanEntry> getEntries() { + return entries; + } + + public void setStringValue(String stringValue) { + String old = this.stringValue; + this.stringValue = stringValue; + p.firePropertyChange("stringValue", old, existingFile); + } + + public void setExistingFile(File existingFile) { + File old = this.existingFile; + this.existingFile = existingFile; + p.firePropertyChange("existingFile", old, existingFile); + } + + public void setNotExistingFile(File notExistingFile) { + File old = this.notExistingFile; + this.notExistingFile = notExistingFile; + p.firePropertyChange("notExistingFile", old, notExistingFile); + } + + public void setExistingDirectory(File existingDirectory) { + File old = this.existingDirectory; + this.existingDirectory = existingDirectory; + p.firePropertyChange("existingDirectory", old, existingDirectory); + } + + public void setNotExistingDirectory(File notExistingDirectory) { + File old = this.notExistingDirectory; + this.notExistingDirectory = notExistingDirectory; + p.firePropertyChange("notExistingDirectory", old, notExistingDirectory); + } + + public void setEntries(Collection<ValidatorBeanEntry> entries) { + this.entries = entries; + // set null oldValue to always fire event + // otherwise it could been not sent... + p.firePropertyChange("entries", null, entries); + } + + public void setEntry(ValidatorBeanEntry entry) { + this.entry = entry; + p.firePropertyChange("entry", null, entry); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/field/ValidatorBean.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/log4j.properties =================================================================== --- trunk/nuiton-validator/src/test/resources/log4j.properties (rev 0) +++ trunk/nuiton-validator/src/test/resources/log4j.properties 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,32 @@ +### +# #%L +# JAXX :: Runtime +# +# $Id$ +# $HeadURL$ +# %% +# Copyright (C) 2008 - 2010 CodeLutin +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Lesser Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/lgpl-3.0.html>. +# #L% +### +# Global logging configuration +log4j.rootLogger=ERROR, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +log4j.logger.org.nuiton=INFO Property changes on: trunk/nuiton-validator/src/test/resources/log4j.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,43 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="requiredstring"> + <message>stringValue.error</message> + </field-validator> + </field> + + <field name="intValue"> + <field-validator type="int"> + <param name="min">1</param> + <message>intValue.error</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,47 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="fieldexpression"> + <param name="expression"> + <![CDATA[ stringValue != null && stringValue == "5"]]></param> + <message>stringValue.fatal</message> + </field-validator> + </field> + + + <field name="intValue"> + <field-validator type="int"> + <param name="min">5</param> + <param name="max">5</param> + <message>intValue.fatal</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,37 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="intValue"> + <field-validator type="int"> + <param name="min">10</param> + <message>intValue.info</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,43 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="requiredstring"> + <message>stringValue.null</message> + </field-validator> + </field> + + <field name="intValue"> + <field-validator type="int"> + <param name="min">1</param> + <message>intValue.null</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,37 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="fieldexpression"> + <param name="expression"><![CDATA[ stringValue != null && stringValue.length() > 5]]></param> + <message>stringValue.warning</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/FieldExpressionBean-error-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/FieldExpressionBean-error-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/FieldExpressionBean-error-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,123 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + +<field name="booleanValue"> + <field-validator type="fieldexpressionwithparams"> + <param name="booleanParams">boolean:true</param> + <param name="expression"><![CDATA[ booleanValue == booleans.boolean]]> + </param> + <message>expression.boolean.not.equals##${booleans.boolean}</message> + </field-validator> + <field-validator type="fieldexpressionwithparams"> + <param name="booleanParams">boolean:false</param> + <param name="expression"><![CDATA[ booleanValue == booleans.boolean]]> + </param> + <message>expression.boolean.not.equals##${booleans.boolean}</message> + </field-validator> + </field> + + <field name="shortValue"> + <field-validator type="fieldexpressionwithparams"> + <param name="shortParams">short:100</param> + <param name="expression"><![CDATA[ shortValue < shorts.short]]> + </param> + <message>expression.too.big##${shorts.short}</message> + </field-validator> + <field-validator type="fieldexpressionwithparams"> + <param name="shortParams">short:100|short2:2000</param> + <param name="expression"><![CDATA[ shortValue < shorts.short || shortValue < shorts.short2]]> + </param> + <message>expression.too.big##${shorts.short}##${shorts.short2}</message> + </field-validator> + </field> + + <field name="intValue"> + <field-validator type="fieldexpressionwithparams"> + <param name="intParams">int:100</param> + <param name="expression"><![CDATA[ intValue < ints.int]]> + </param> + <message>expression.too.big##${ints.int}</message> + </field-validator> + <field-validator type="fieldexpressionwithparams"> + <param name="intParams">int:100|int2:2000</param> + <param name="expression"><![CDATA[ intValue < ints.int || intValue < ints.int2]]> + </param> + <message>expression.too.big##${ints.int}##${ints.int2}</message> + </field-validator> + </field> + + <field name="longValue"> + <field-validator type="fieldexpressionwithparams"> + <param name="longParams">long:100</param> + <param name="expression"><![CDATA[ longValue < longs.long]]> + </param> + <message>expression.too.big##${longs.long}</message> + </field-validator> + <field-validator type="fieldexpressionwithparams"> + <param name="longParams">long:100|long2:2000</param> + <param name="expression"><![CDATA[ longValue < longs.long || longValue < longs.long2]]> + </param> + <message>expression.too.big##${longs.long}##${longs.long2}</message> + </field-validator> + </field> + + <field name="doubleValue"> + <field-validator type="fieldexpressionwithparams"> + <param name="doubleParams">double:100.0</param> + <param name="expression"><![CDATA[ doubleValue < doubles.double]]> + </param> + <message>expression.too.big##${doubles.double}</message> + </field-validator> + <field-validator type="fieldexpressionwithparams"> + <param name="doubleParams">double:100.0|double2:2000.0</param> + <param name="expression"><![CDATA[ doubleValue < doubles.double || doubleValue < doubles.double2]]> + </param> + <message>expression.too.big##${doubles.double}##${doubles.double2}</message> + </field-validator> + </field> + + <field name="stringValue"> + <field-validator type="fieldexpressionwithparams"> + <param name="stringParams">string:1000</param> + <param name="expression"><![CDATA[ stringValue.equals(strings.string)]]> + </param> + <message>expression.stringNotValue##${strings.string}</message> + </field-validator> + <field-validator type="fieldexpressionwithparams"> + <param name="stringParams">string:1000|string2:3000</param> + <param name="expression"><![CDATA[ stringValue.equals(strings.string) || stringValue.equals(strings.string2)]]> + </param> + <message>expression.stringNotValue##${strings.string}##${strings.string2}</message> + </field-validator> + </field> + + + + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/FieldExpressionBean-error-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ValidatorBean-error-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ValidatorBean-error-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ValidatorBean-error-validation.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,179 @@ +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="requiredstring" short-circuit="true"> + <message>stringValue.required</message> + </field-validator> + </field> + + <field name="existingFile"> + <field-validator type="requiredFile" short-circuit="true"> + <message>existingFile.required</message> + </field-validator> + <field-validator type="existingFile" short-circuit="true"> + <message>existingFile.not.exist</message> + </field-validator> + </field> + + <field name="notExistingFile"> + <field-validator type="requiredFile" short-circuit="true"> + <message>notExistingFile.required</message> + </field-validator> + <field-validator type="notExistingFile" short-circuit="true"> + <message>notExistingFile.exist</message> + </field-validator> + </field> + + <field name="existingDirectory"> + <field-validator type="requiredFile" short-circuit="true"> + <message>existingDirectory.required</message> + </field-validator> + + <field-validator type="existingDirectory" short-circuit="true"> + <message>existingDirectory.not.exist</message> + </field-validator> + </field> + + <field name="notExistingDirectory"> + <field-validator type="requiredFile" short-circuit="true"> + <message>notExistingDirectory.required</message> + </field-validator> + + <field-validator type="notExistingDirectory" short-circuit="true"> + <message>notExistingDirectory.exist</message> + </field-validator> + </field> + + <field name="entries"> + + <field-validator type="collectionUniqueKey"> + <param name="keys">intValue</param> + <message>collectionUniqueKey.one.failed</message> + </field-validator> + <field-validator type="collectionUniqueKey"> + <param name="keys">stringValue</param> + <message>collectionUniqueKey.two.failed</message> + </field-validator> + <field-validator type="collectionUniqueKey"> + <param name="keys">intValue,stringValue</param> + <message>collectionUniqueKey.three.failed</message> + </field-validator> + <field-validator type="collectionUniqueKey"> + <param name="keys">intValue,stringValue,stringValue2</param> + <message>collectionUniqueKey.four.failed</message> + </field-validator> + <field-validator type="collectionUniqueKey"> + <param name="keys">stringValue</param> + <param name="againstProperty">entry</param> + <message>collectionUniqueKey.five.failed</message> + </field-validator> + + <field-validator type="collectionFieldExpression"> + <param name="mode">AT_LEAST_ONE</param> + <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]> + </param> + <message>collectionFieldExpression.atLeastOne</message> + </field-validator> + <field-validator type="collectionFieldExpression"> + <param name="mode">EXACTLY_ONE</param> + <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]> + </param> + <message>collectionFieldExpression.exactlyOne</message> + </field-validator> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]> + </param> + <message>collectionFieldExpression.all</message> + </field-validator> + <field-validator type="collectionFieldExpression"> + <param name="mode">NONE</param> + <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]> + </param> + <message>collectionFieldExpression.none</message> + </field-validator> + + <!-- useContext --> + <field-validator type="collectionFieldExpression"> + <param name="mode">AT_LEAST_ONE</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ size > 1 && previous != null && previous.intValue < current.intValue]]></param> + <message>collectionFieldExpression.atLeastOne.useSensitiveContext</message> + </field-validator> + <field-validator type="collectionFieldExpression"> + <param name="mode">EXACTLY_ONE</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ size > 1 && previous != null && ( previous.intValue == 2 + current.intValue || current.intValue == 2 + previous.intValue) ]]></param> + <message>collectionFieldExpression.exactlyOne.useSensitiveContext</message> + </field-validator> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ size > 1 && (previous == null || previous.intValue < current.intValue)]]></param> + <message>collectionFieldExpression.all.useSensitiveContext</message> + </field-validator> + <field-validator type="collectionFieldExpression"> + <param name="mode">NONE</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ size > 1 && previous != null && ( current.intValue == 2 + previous.intValue)]]></param> + <message>collectionFieldExpression.none.useSensitiveContext</message> + </field-validator> + + <!-- useFirst --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expressionForFirst"><![CDATA[ current.intValue == 0]]></param> + <param name="expression"><![CDATA[ previous == null || previous.intValue < current.intValue]]></param> + <message>collectionFieldExpression.all.useFirst</message> + </field-validator> + + <!-- useLast --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expressionForLast"><![CDATA[ current.intValue > 0]]></param> + <param name="expression"><![CDATA[ previous == null || previous.intValue < current.intValue]]></param> + <message>collectionFieldExpression.all.useLast</message> + </field-validator> + + <!-- useFirstAndLast --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expressionForFirst"><![CDATA[ current.intValue == 0]]></param> + <param name="expressionForLast"><![CDATA[ current.intValue > 0]]></param> + <param name="expression"><![CDATA[ previous == null || previous.intValue < current.intValue]]></param> + <message>collectionFieldExpression.all.useFirstAndLast</message> + </field-validator> + + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ValidatorBean-error-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/test/resources/validators.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/validators.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/validators.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Nuiton Utils :: Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> + + +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator Config 1.0//EN" + "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd"> +<validators> + <!-- default validators from XWork framework --> + <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/> + <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/> + <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/> + <validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/> + <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/> + <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/> + <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/> + <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/> + <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/> + <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/> + <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/> + <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/> + <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/> + <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/> + <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/> + <validator name="conditionalvisitor" + class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/> + + <!-- jaxx validators --> + <validator name="collectionFieldExpression" class="org.nuiton.validator.field.CollectionFieldExpressionValidator"/> + <validator name="collectionUniqueKey" class="org.nuiton.validator.field.CollectionUniqueKeyValidator"/> + <validator name="requiredFile" class="org.nuiton.validator.field.RequiredFileFieldValidator"/> + <validator name="existingFile" class="org.nuiton.validator.field.ExistingFileFieldValidator"/> + <validator name="notExistingFile" class="org.nuiton.validator.field.NotExistingFileFieldValidator"/> + <validator name="existingDirectory" class="org.nuiton.validator.field.ExistingDirectoryFieldValidator"/> + <validator name="notExistingDirectory" class="org.nuiton.validator.field.NotExistingDirectoryFieldValidator"/> + <validator name="fieldexpressionwithparams" class="org.nuiton.validator.field.FieldExpressionWithParamsValidator"/> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/validators.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/pom.xml =================================================================== --- trunk/pom.xml (rev 0) +++ trunk/pom.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Nuiton Utils + $Id$ + $HeadURL$ + %% + Copyright (C) 2004 - 2010 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.nuiton</groupId> + <artifactId>mavenpom4redmineAndCentral</artifactId> + <version>2.4.1</version> + </parent> + + <artifactId>nuiton-utils-parent</artifactId> + <version>2.0-SNAPSHOT</version> + + <modules> + <module>nuiton-utils</module> + <module>nuiton-validator</module> + </modules> + + <dependencyManagement> + + <dependencies> + + <dependency> + <groupId>org.nuiton.i18n</groupId> + <artifactId>nuiton-i18n</artifactId> + <version>${nuitonI18nVersion}</version> + </dependency> + + <dependency> + <groupId>org.jvnet.hudson.winstone</groupId> + <artifactId>winstone</artifactId> + <version>0.9.10-hudson-24</version> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty.aggregate</groupId> + <artifactId>jetty-webapp</artifactId> + <version>7.1.0.v20100505</version> + </dependency> + + <!-- xworks dependencies --> + + <dependency> + <groupId>com.opensymphony</groupId> + <artifactId>xwork</artifactId> + <version>2.1.3</version> + <exclusions> + <exclusion> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + </exclusion> + </exclusions> + </dependency> + + </dependencies> + </dependencyManagement> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>Nuiton Utils :: Parent</name> + <description>Parent of nuiton utils projects.</description> + <inceptionYear>2011</inceptionYear> + <url>http://maven-site.nuiton.org/nuiton-utils</url> + + <developers> + + <developer> + <name>Brendan Le Ny</name> + <id>bleny</id> + <email>bleny@codelutin.com</email> + <organization>CodeLutin</organization> + <timezone>+2</timezone> + <roles> + <role>developer</role> + </roles> + </developer> + + <developer> + <name>Benjamin Poussin</name> + <id>bpoussin</id> + <email>poussin@codelutin.com</email> + <organization>CodeLutin</organization> + <timezone>+2</timezone> + <roles> + <role>Développeur</role> + <role>Debian packager</role> + </roles> + </developer> + + <developer> + <name>Éric Chatellier</name> + <id>echatellier</id> + <email>chatellier@codelutin.com</email> + <organization>CodeLutin</organization> + <timezone>+2</timezone> + <roles> + <role>Développeur</role> + </roles> + </developer> + + <developer> + <name>Sylvain Letellier</name> + <id>sletellier</id> + <email>letellier@codelutin.com</email> + <organization>CodeLutin</organization> + <timezone>+2</timezone> + <roles> + <role>Développeur</role> + </roles> + </developer> + + <developer> + <name>Tony Chemit</name> + <id>tchemit</id> + <email>chemit@codelutin.com</email> + <organization>CodeLutin</organization> + <timezone>+2</timezone> + <roles> + <role>developer</role> + </roles> + </developer> + + </developers> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>pom</packaging> + + <properties> + + <projectId>nuiton-utils</projectId> + + <nuitonI18nVersion>2.0.1</nuitonI18nVersion> + + </properties> + + <build> + <pluginManagement> + <plugins> + <!-- plugin i18n --> + <plugin> + <groupId>org.nuiton.i18n</groupId> + <artifactId>maven-i18n-plugin</artifactId> + <version>${nuitonI18nVersion}</version> + </plugin> + + </plugins> + </pluginManagement> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + + <!-- Source control management. --> + <scm> + <connection> + scm:svn:http://svn.nuiton.org/svn/nuiton-utils/trunk + </connection> + <developerConnection> + scm:svn:http://svn.nuiton.org/svn/nuiton-utils/trunk + </developerConnection> + <url>http://www.nuiton.org/repositories/browse/nuiton-utils/trunk</url> + </scm> + +</project> Property changes on: trunk/pom.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/src/site/apt/index.apt =================================================================== --- trunk/src/site/apt/index.apt (rev 0) +++ trunk/src/site/apt/index.apt 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,61 @@ +~~~ +~~ #%L +~~ Nuiton Utils :: Parent +~~ +~~ $Id$ +~~ $HeadURL$ +~~ %% +~~ Copyright (C) 2004 - 2010 CodeLutin +~~ %% +~~ This program is free software: you can redistribute it and/or modify +~~ it under the terms of the GNU Lesser General Public License as +~~ published by the Free Software Foundation, either version 3 of the +~~ License, or (at your option) any later version. +~~ +~~ This program is distributed in the hope that it will be useful, +~~ but WITHOUT ANY WARRANTY; without even the implied warranty of +~~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +~~ GNU General Lesser Public License for more details. +~~ +~~ You should have received a copy of the GNU General Lesser Public +~~ License along with this program. If not, see +~~ <http://www.gnu.org/licenses/lgpl-3.0.html>. +~~ #L% +~~~ + ---- + Nuiton utils + ---- + ---- + 2009-08-23 + ---- + + +Présentation + + Ensemble de projets utilitaires. + +Librairie Nuiton-utils + + Librairie regroupant les utilitaires classiques sur les fichiers, les tableaux, + les collections, les maps, les chaînes de caractères, ... De plus elle intègre + un parser des arguments et des options pour les lignes de commande. + +Librairie Nuiton-utils-extra + + TODO + +Librairie Nuiton-validator + + TODO + +Librairie Nuiton-web + + TODO + +Librairie Nuiton-rss + + TODO + + + <Veuillez consulter la documentation de chaque sous projet pour de plus + amples détails sur les différentes librairies.> Property changes on: trunk/src/site/apt/index.apt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/src/site/site_fr.xml =================================================================== --- trunk/src/site/site_fr.xml (rev 0) +++ trunk/src/site/site_fr.xml 2010-12-30 09:44:04 UTC (rev 1998) @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Nuiton Utils Parent + + $Id$ + $HeadURL$ + %% + Copyright (C) 2004 - 2010 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> + + +<project name="${project.name}"> + + <bannerLeft> + <name>${project.name}</name> + <href>index.html</href> + </bannerLeft> + + <poweredBy> + <logo href="http://maven.apache.org" name="Maven" + img="images/logos/maven-feather.png"/> + </poweredBy> + + <body> + + <breadcrumbs> + <item name="${project.name}" href="index.html"/> + </breadcrumbs> + + <menu ref="modules"/> + + <menu ref="reports"/> + + </body> +</project> Property changes on: trunk/src/site/site_fr.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native