[joda-convert] 01/05: Imported Upstream version 1.2
Tony Mancill
tmancill at moszumanska.debian.org
Sat Sep 5 21:38:38 UTC 2015
This is an automated email from the git hooks/post-receive script.
tmancill pushed a commit to branch master
in repository joda-convert.
commit 12d0f776fbeb133eac4c69e9be675260951b4bde
Author: tony mancill <tmancill at debian.org>
Date: Sat Sep 5 14:37:05 2015 -0700
Imported Upstream version 1.2
---
LICENSE.txt | 202 +++++++++
NOTICE.txt | 5 +
RELEASE-NOTES.txt | 21 +
checkstyle.xml | 79 ++++
pom.xml | 322 +++++++++++++
src/changes/changes.xml | 50 +++
src/conf/MANIFEST.MF | 17 +
src/main/assembly/dist.xml | 29 ++
src/main/java/org/joda/convert/FromString.java | 39 ++
.../java/org/joda/convert/FromStringConverter.java | 36 ++
.../java/org/joda/convert/JDKStringConverter.java | 413 +++++++++++++++++
.../convert/MethodConstructorStringConverter.java | 80 ++++
.../org/joda/convert/MethodsStringConverter.java | 81 ++++
.../joda/convert/ReflectionStringConverter.java | 80 ++++
src/main/java/org/joda/convert/StringConvert.java | 488 ++++++++++++++++++++
.../java/org/joda/convert/StringConverter.java | 28 ++
src/main/java/org/joda/convert/ToString.java | 37 ++
.../java/org/joda/convert/ToStringConverter.java | 35 ++
src/site/resources/css/site.css | 129 ++++++
src/site/site.xml | 55 +++
src/site/xdoc/index.xml | 99 ++++
src/site/xdoc/privacy.xml | 49 ++
src/site/xdoc/userguide.xml | 108 +++++
...tanceFromStringConstructorInvalidParameter.java | 45 ++
...FromStringConstructorInvalidParameterCount.java | 45 ++
.../joda/convert/DistanceFromStringException.java | 47 ++
.../DistanceFromStringInvalidParameter.java | 45 ++
.../DistanceFromStringInvalidParameterCount.java | 45 ++
.../DistanceFromStringInvalidReturnType.java | 45 ++
.../joda/convert/DistanceFromStringNoToString.java | 45 ++
.../DistanceMethodAndConstructorAnnotations.java | 52 +++
.../joda/convert/DistanceMethodConstructor.java | 46 ++
.../DistanceMethodConstructorCharSequence.java | 46 ++
.../org/joda/convert/DistanceMethodMethod.java | 46 ++
.../convert/DistanceMethodMethodCharSequence.java | 46 ++
.../org/joda/convert/DistanceNoAnnotations.java | 48 ++
.../convert/DistanceNoAnnotationsCharSequence.java | 48 ++
.../joda/convert/DistanceToStringException.java | 48 ++
.../convert/DistanceToStringInvalidParameters.java | 46 ++
.../convert/DistanceToStringInvalidReturnType.java | 46 ++
.../joda/convert/DistanceToStringNoFromString.java | 45 ++
.../DistanceTwoFromStringMethodAnnotations.java | 57 +++
.../convert/DistanceTwoToStringAnnotations.java | 47 ++
.../joda/convert/MockDistanceStringConverter.java | 45 ++
.../joda/convert/MockIntegerStringConverter.java | 45 ++
.../org/joda/convert/SubMethodConstructor.java | 28 ++
.../java/org/joda/convert/SubMethodMethod.java | 33 ++
.../java/org/joda/convert/SubNoAnnotations.java | 27 ++
.../java/org/joda/convert/SuperFactorySub.java | 27 ++
.../java/org/joda/convert/SuperFactorySuper.java | 47 ++
.../org/joda/convert/TestJDKStringConverters.java | 391 ++++++++++++++++
.../java/org/joda/convert/TestStringConvert.java | 497 +++++++++++++++++++++
52 files changed, 4560 insertions(+)
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..ac95834
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,5 @@
+=============================================================================
+= NOTICE file corresponding to section 4d of the Apache License Version 2.0 =
+=============================================================================
+This product includes software developed by
+Joda.org (http://www.joda.org/).
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
new file mode 100644
index 0000000..0d18d7c
--- /dev/null
+++ b/RELEASE-NOTES.txt
@@ -0,0 +1,21 @@
+Joda-Convert version 1.1
+------------------------
+
+Joda-Convert is a small library providing conversion to and from String.
+
+This is the second release of Joda-Convert.
+
+JDK 1.5 or later is required.
+
+Joda-Convert is licensed under the business-friendly Apache License Version 2.
+This is the same license as all of Apache, plus other open source projects such as Spring.
+The intent is to make the code available to the Java community with the minimum
+of restrictions. If the license causes you problems please contact the mailing list.
+
+
+Feedback
+--------
+All feedback is welcomed via the joda-convert-interest mailing list.
+
+The Joda team
+http://joda-convert.sourceforge.net
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..999d5ae
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE module PUBLIC
+ "-//Puppy Crawl//DTD Check Configuration 1.1//EN"
+ "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
+
+<!-- customization of default Checkstyle behavior -->
+<module name="Checker">
+ <!--property name="basedir" value="."/-->
+ <property name="localeLanguage" value="en"/>
+ <!--module name="PackageHtml"/-->
+ <module name="TreeWalker">
+ <module name="MemberName">
+ <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+ </module>
+ <module name="LocalVariableName">
+ <property name="format" value="^ex[0-9]*$"/>
+ <property name="tokens" value="PARAMETER_DEF"/>
+ </module>
+ <module name="AvoidStarImport"/>
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+
+ <module name="TabCharacter"/>
+ <module name="NeedBraces"/>
+ <!--module name="TypecastParenPad"/-->
+ <module name="WhitespaceAfter"/>
+ <module name="WhitespaceAround"/>
+ <module name="ModifierOrder"/>
+ <module name="RedundantModifier"/>
+
+ <module name="EmptyBlock"/>
+ <module name="LeftCurly"/>
+ <module name="NeedBraces"/>
+ <module name="RightCurly"/>
+ <!--module name="AvoidNestedBlocks">
+ <property name="allowInSwitchCase" value="true"/>
+ </module-->
+
+ <!--module name="ArrayTrailingComma"/-->
+ <!--module name="CovariantEquals"/-->
+ <module name="DoubleCheckedLocking"/>
+ <module name="EmptyStatement"/>
+ <module name="EqualsHashCode"/>
+ <!--module name="HiddenField">
+ <property name="ignoreConstructorParameter" value="true"/>
+ <property name="ignoreSetter" value="true"/>
+ </module-->
+ <module name="IllegalInstantiation">
+ <property name="classes" value="java.lang.Boolean"/>
+ </module>
+ <!--module name="SuperClone"/-->
+ <!--module name="ExplicitInitialization"/-->
+
+ <module name="GenericIllegalRegexp">
+ <property name="format" value="System\.out\.println"/>
+ </module>
+ <module name="GenericIllegalRegexp">
+ <property name="format" value="System\.err\.println"/>
+ </module>
+ <module name="TodoComment"/>
+ <module name="UpperEll"/>
+ <module name="ArrayTypeStyle"/>
+ <module name="Indentation"/>
+
+ <module name="RedundantThrows">
+ <property name="allowUnchecked" value="true"/>
+ </module>
+ <module name="LineLength">
+ <property name="max" value="120"/>
+ </module>
+ <module name="JavadocVariable"/>
+ <module name="JavadocMethod">
+ <property name="allowUndeclaredRTE" value="true"/>
+ </module>
+ </module>
+</module>
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..c068041
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,322 @@
+<?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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.joda</groupId>
+ <artifactId>joda-convert</artifactId>
+ <packaging>jar</packaging>
+ <name>Joda convert</name>
+ <version>1.2</version>
+ <description>Library to convert Objects to and from String</description>
+ <url>http://joda-convert.sourceforge.net</url>
+ <issueManagement>
+ <system>Sourceforge</system>
+ <url>https://sourceforge.net/tracker/?group_id=344317&atid=1440693</url>
+ </issueManagement>
+ <inceptionYear>2010</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Joda Convert Interest list</name>
+ <subscribe>https://lists.sourceforge.net/lists/listinfo/joda-convert-interest</subscribe>
+ <unsubscribe>https://lists.sourceforge.net/lists/listinfo/joda-convert-interest</unsubscribe>
+ <archive>http://sourceforge.net/mailarchive/forum.php?forum_name=joda-convert-interest</archive>
+ </mailingList>
+ </mailingLists>
+ <developers>
+ <developer>
+ <id>scolebourne</id>
+ <name>Stephen Colebourne</name>
+ <email></email>
+ <roles>
+ <role>Project Lead</role>
+ </roles>
+ <timezone>0</timezone>
+ </developer>
+ </developers>
+ <licenses>
+ <license>
+ <name>Apache 2</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <scm>
+ <connection>scm:git:git at github.com:JodaOrg/joda-convert.git</connection>
+ <developerConnection>scm:git:git at github.com:JodaOrg/joda-convert.git</developerConnection>
+ <url>https://github.com/JodaOrg/joda-convert</url>
+ </scm>
+ <organization>
+ <name>Joda.org</name>
+ <url>http://www.joda.org</url>
+ </organization>
+ <build>
+ <resources>
+ <resource>
+ <targetPath>META-INF</targetPath>
+ <directory>.</directory>
+ <includes>
+ <include>LICENSE.txt</include>
+ <include>NOTICE.txt</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.4.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <verbose>true</verbose>
+ <fork>true</fork>
+ <compilerVersion>1.5</compilerVersion>
+ <source>1.5</source>
+ <target>1.5</target>
+ <debug>true</debug>
+ <debuglevel>lines,source</debuglevel>
+ <optimize>true</optimize>
+ <showDeprecation>false</showDeprecation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.5</version>
+ <configuration>
+ <includes>
+ <include>**/Test*.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <archive>
+ <manifestFile>src/conf/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <linksource>true</linksource>
+ <links>
+ <link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
+ </links>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.2</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>2.1.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-repository-plugin</artifactId>
+ <version>2.3.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/dist.xml</descriptor>
+ </descriptors>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>index</report>
+ <report>dependencies</report>
+ <report>project-team</report>
+ <report>mailing-list</report>
+ <report>issue-tracking</report>
+ <report>license</report>
+ <report>scm</report>
+ <report>summary</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <configLocation>${basedir}/checkstyle.xml</configLocation>
+ <enableRulesSummary>false</enableRulesSummary>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <linksource>true</linksource>
+ <links>
+ <link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
+ </links>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>2.5</version>
+ <configuration>
+ <showSuccess>true</showSuccess>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+ <distributionManagement>
+ <repository>
+ <id>sonatype-joda-staging</id>
+ <name>Sonatype OSS staging repository</name>
+ <url>http://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ <layout>default</layout>
+ </repository>
+ <snapshotRepository>
+ <uniqueVersion>false</uniqueVersion>
+ <id>sonatype-joda-snapshot</id>
+ <name>Sonatype OSS snapshot repository</name>
+ <url>http://oss.sonatype.org/content/repositories/joda-snapshots</url>
+ <layout>default</layout>
+ </snapshotRepository>
+ <site>
+ <id>sf-web-joda-convert</id>
+ <name>Sourceforge Site</name>
+ <url>scpexe://shell.sourceforge.net/home/project-web/joda-convert/htdocs</url>
+ </site>
+ <downloadUrl>http://oss.sonatype.org/content/repositories/joda-releases</downloadUrl>
+ </distributionManagement>
+ <profiles>
+ <profile>
+ <id>repo-sign-artifacts</id>
+ <activation>
+ <property>
+ <name>oss.repo</name>
+ <value>true</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-toolchains-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>toolchain</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <toolchains>
+ <jdk>
+ <version>1.5</version>
+ <vendor>sun</vendor>
+ </jdk>
+ </toolchains>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+</project>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
new file mode 100644
index 0000000..0ddc2ac
--- /dev/null
+++ b/src/changes/changes.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document>
+ <properties>
+ <title>Java convert - Changes</title>
+ <author>Stephen Colebourne</author>
+ </properties>
+
+ <body>
+ <!-- types are add, fix, remove, update -->
+ <release version="1.2" date="2011-10-27">
+ <action dev="scolebourne" type="add" >
+ Add support for CharSequence based fromString methods.
+ </action>
+ <action dev="scolebourne" type="add" >
+ Add support for JSR-310 by reflection, avoiding a dependency.
+ </action>
+ <action dev="scolebourne" type="add" >
+ Allow registration of conversions by method name.
+ </action>
+ <action dev="scolebourne" type="add" >
+ Allow toString conversion to specify the desired type.
+ </action>
+ </release>
+ <release version="1.1.1" date="2011-10-21">
+ <action dev="scolebourne" type="fix" >
+ Allow conversion of primitive types.
+ </action>
+ </release>
+ <release version="1.1.1" date="2011-10-24">
+ <action dev="scolebourne" type="fix" >
+ Allow conversion of primitive types
+ </action>
+ </release>
+ <release version="1.1" date="2010-12-04">
+ <action dev="scolebourne" type="fix" >
+ Enable superclass factories.
+ </action>
+ </release>
+ <release version="1.0" date="2010-09-05">
+ <action dev="scolebourne" type="fix" >
+ Lots of tests and fixes.
+ </action>
+ </release>
+ <release version="0.5" date="unreleased">
+ <action dev="scolebourne" type="fix" >
+ Initial checkin.
+ </action>
+ </release>
+ </body>
+</document>
diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF
new file mode 100644
index 0000000..7da94d7
--- /dev/null
+++ b/src/conf/MANIFEST.MF
@@ -0,0 +1,17 @@
+Package: org.joda.convert
+Extension-Name: joda-convert
+Specification-Title: Joda-Convert
+Specification-Vendor: Joda.org
+Specification-Version: 1.2
+Implementation-Vendor: Joda.org
+Implementation-Title: org.joda.convert
+Implementation-Version: 1.2
+Implementation-Vendor-Id: org.joda
+Bundle-ManifestVersion: 2
+Bundle-Vendor: Joda.org
+Bundle-Name: Joda-Convert
+Bundle-SymbolicName: joda-convert
+Bundle-Version: 1.2
+Export-Package: org.joda.time.convert;version=1.2
+Bundle-License: Apache 2.0
+Bundle-DocURL: http://joda-convert.sourceforge.net/
diff --git a/src/main/assembly/dist.xml b/src/main/assembly/dist.xml
new file mode 100644
index 0000000..d1a282c
--- /dev/null
+++ b/src/main/assembly/dist.xml
@@ -0,0 +1,29 @@
+<assembly>
+ <id>dist</id>
+ <formats>
+ <format>tar.gz</format>
+ <format>zip</format>
+ </formats>
+ <baseDirectory>${artifactId}-${version}</baseDirectory>
+ <fileSets>
+ <fileSet>
+ <includes>
+ <include>checkstyle.xml</include>
+ <include>LICENSE.txt</include>
+ <include>NOTICE.txt</include>
+ <include>pom.xml</include>
+ <include>RELEASE-NOTES.txt</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>src</directory>
+ </fileSet>
+ <fileSet>
+ <directory>target</directory>
+ <outputDirectory></outputDirectory>
+ <includes>
+ <include>*.jar</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/src/main/java/org/joda/convert/FromString.java b/src/main/java/org/joda/convert/FromString.java
new file mode 100644
index 0000000..4403300
--- /dev/null
+++ b/src/main/java/org/joda/convert/FromString.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to mark a method or constructor as being suitable for converting
+ * an object from a {@code String}.
+ * <p>
+ * When applying to a method, this annotation should be applied once per class.
+ * The method must be static and have one {@code String} parameter with a
+ * return type of the type that the method is implemented on.
+ * For example, {@link Integer#parseInt(String)}.
+ * <p>
+ * When applying to a constructor, this annotation should be applied to the constructor
+ * that takes one {@code String} parameter.
+ */
+ at Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface FromString {
+
+}
diff --git a/src/main/java/org/joda/convert/FromStringConverter.java b/src/main/java/org/joda/convert/FromStringConverter.java
new file mode 100644
index 0000000..e5bace9
--- /dev/null
+++ b/src/main/java/org/joda/convert/FromStringConverter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Interface defining conversion from a {@code String}.
+ * <p>
+ * FromStringConverter is an interface and must be implemented with care.
+ * Implementations must be immutable and thread-safe.
+ *
+ * @param <T> the type of the converter
+ */
+public interface FromStringConverter<T> {
+
+ /**
+ * Converts the specified object from a {@code String}.
+ * @param cls the class to convert to, not null
+ * @param str the string to convert, not null
+ * @return the converted object, may be null but generally not
+ */
+ T convertFromString(Class<? extends T> cls, String str);
+
+}
diff --git a/src/main/java/org/joda/convert/JDKStringConverter.java b/src/main/java/org/joda/convert/JDKStringConverter.java
new file mode 100644
index 0000000..c90448d
--- /dev/null
+++ b/src/main/java/org/joda/convert/JDKStringConverter.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Currency;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Conversion between JDK classes and a {@code String}.
+ */
+enum JDKStringConverter implements StringConverter<Object> {
+
+ /**
+ * String converter.
+ */
+ STRING(String.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return str;
+ }
+ },
+ /**
+ * CharSequence converter.
+ */
+ CHAR_SEQUENCE(CharSequence.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return str;
+ }
+ },
+ /**
+ * StringBuffer converter.
+ */
+ STRING_BUFFER(StringBuffer.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new StringBuffer(str);
+ }
+ },
+ /**
+ * StringBuilder converter.
+ */
+ STRING_BUILDER(StringBuilder.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new StringBuilder(str);
+ }
+ },
+ /**
+ * Long converter.
+ */
+ LONG(Long.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new Long(str);
+ }
+ },
+
+ /**
+ * Integer converter.
+ */
+ INTEGER(Integer.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new Integer(str);
+ }
+ },
+
+ /**
+ * Short converter.
+ */
+ SHORT (Short.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new Short(str);
+ }
+ },
+
+ /**
+ * Byte converter.
+ */
+ BYTE(Byte.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new Byte(str);
+ }
+ },
+ /**
+ * Character converter.
+ */
+ CHARACTER(Character.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ if (str.length() != 1) {
+ throw new IllegalArgumentException("Character value must be a string length 1");
+ }
+ return new Character(str.charAt(0));
+ }
+ },
+ /**
+ * Boolean converter.
+ */
+ BOOLEAN(Boolean.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ if ("true".equalsIgnoreCase(str)) {
+ return Boolean.TRUE;
+ }
+ if ("false".equalsIgnoreCase(str)) {
+ return Boolean.FALSE;
+ }
+ throw new IllegalArgumentException("Boolean value must be 'true' or 'false', case insensitive");
+ }
+ },
+ /**
+ * Double converter.
+ */
+ DOUBLE(Double.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new Double(str);
+ }
+ },
+ /**
+ * Float converter.
+ */
+ FLOAT(Float.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new Float(str);
+ }
+ },
+ /**
+ * BigInteger converter.
+ */
+ BIG_INTEGER(BigInteger.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new BigInteger(str);
+ }
+ },
+ /**
+ * BigDecimal converter.
+ */
+ BIG_DECIMAL(BigDecimal.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new BigDecimal(str);
+ }
+ },
+ /**
+ * AtomicLong converter.
+ */
+ ATOMIC_LONG(AtomicLong.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ long val = Long.parseLong(str);
+ return new AtomicLong(val);
+ }
+ },
+ /**
+ * AtomicLong converter.
+ */
+ ATOMIC_INTEGER(AtomicInteger.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ int val = Integer.parseInt(str);
+ return new AtomicInteger(val);
+ }
+ },
+ /**
+ * AtomicBoolean converter.
+ */
+ ATOMIC_BOOLEAN(AtomicBoolean.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ if ("true".equalsIgnoreCase(str)) {
+ return new AtomicBoolean(true);
+ }
+ if ("false".equalsIgnoreCase(str)) {
+ return new AtomicBoolean(false);
+ }
+ throw new IllegalArgumentException("Boolean value must be 'true' or 'false', case insensitive");
+ }
+ },
+ /**
+ * Locale converter.
+ */
+ LOCALE(Locale.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ String[] split = str.split("_", 3);
+ switch (split.length) {
+ case 1:
+ return new Locale(split[0]);
+ case 2:
+ return new Locale(split[0], split[1]);
+ case 3:
+ return new Locale(split[0], split[1], split[2]);
+ }
+ throw new IllegalArgumentException("Unable to parse Locale: " + str);
+ }
+ },
+ /**
+ * Class converter.
+ */
+ CLASS(Class.class) {
+ @Override
+ public String convertToString(Object object) {
+ return ((Class<?>) object).getName();
+ }
+ public Object convertFromString(Class<?> cls, String str) {
+ try {
+ return getClass().getClassLoader().loadClass(str);
+ } catch (ClassNotFoundException ex) {
+ throw new RuntimeException("Unable to create class: " + str, ex);
+ }
+ }
+ },
+ /**
+ * Package converter.
+ */
+ PACKAGE(Package.class) {
+ @Override
+ public String convertToString(Object object) {
+ return ((Package) object).getName();
+ }
+ public Object convertFromString(Class<?> cls, String str) {
+ return Package.getPackage(str);
+ }
+ },
+ /**
+ * Currency converter.
+ */
+ CURRENCY(Currency.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return Currency.getInstance(str);
+ }
+ },
+ /**
+ * TimeZone converter.
+ */
+ TIME_ZONE(TimeZone.class) {
+ @Override
+ public String convertToString(Object object) {
+ return ((TimeZone) object).getID();
+ }
+ public Object convertFromString(Class<?> cls, String str) {
+ return TimeZone.getTimeZone(str);
+ }
+ },
+ /**
+ * UUID converter.
+ */
+ UUID(UUID.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return java.util.UUID.fromString(str);
+ }
+ },
+ /**
+ * URL converter.
+ */
+ URL(URL.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ try {
+ return new URL(str);
+ } catch (MalformedURLException ex) {
+ throw new RuntimeException(ex.getMessage(), ex);
+ }
+ }
+ },
+ /**
+ * URI converter.
+ */
+ URI(URI.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return java.net.URI.create(str);
+ }
+ },
+ /**
+ * InetAddress converter.
+ */
+ INET_ADDRESS(InetAddress.class) {
+ @Override
+ public String convertToString(Object object) {
+ return ((InetAddress) object).getHostAddress();
+ }
+ public Object convertFromString(Class<?> cls, String str) {
+ try {
+ return InetAddress.getByName(str);
+ } catch (UnknownHostException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ },
+ /**
+ * File converter.
+ */
+ FILE(File.class) {
+ public Object convertFromString(Class<?> cls, String str) {
+ return new File(str);
+ }
+ },
+ /**
+ * Date converter.
+ */
+ DATE(Date.class) {
+ @Override
+ public String convertToString(Object object) {
+ SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ String str = f.format(object);
+ return str.substring(0, 26) + ":" + str.substring(26);
+ }
+ public Object convertFromString(Class<?> cls, String str) {
+ if (str.length() != 29) {
+ throw new IllegalArgumentException("Unable to parse date: " + str);
+ }
+ str = str.substring(0, 26) + str.substring(27);
+ SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ try {
+ return f.parseObject(str);
+ } catch (ParseException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ },
+ /**
+ * Calendar converter.
+ */
+ CALENDAR(Calendar.class) {
+ @Override
+ public String convertToString(Object object) {
+ if (object instanceof GregorianCalendar == false) {
+ throw new RuntimeException("Unable to convert calendar as it is not a GregorianCalendar");
+ }
+ GregorianCalendar cal = (GregorianCalendar) object;
+ SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ f.setCalendar(cal);
+ String str = f.format(cal.getTime());
+ return str.substring(0, 26) + ":" + str.substring(26) + "[" + cal.getTimeZone().getID() + "]";
+ }
+ public Object convertFromString(Class<?> cls, String str) {
+ if (str.length() < 31 || str.charAt(26) != ':'
+ || str.charAt(29) != '[' || str.charAt(str.length() - 1) != ']') {
+ throw new IllegalArgumentException("Unable to parse date: " + str);
+ }
+ TimeZone zone = TimeZone.getTimeZone(str.substring(30, str.length() - 1));
+ str = str.substring(0, 26) + str.substring(27, 29);
+ SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ GregorianCalendar cal = new GregorianCalendar(zone);
+ cal.setTimeInMillis(0);
+ f.setCalendar(cal);
+ try {
+ f.parseObject(str);
+ return f.getCalendar();
+ } catch (ParseException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ },
+ /**
+ * Enum converter.
+ */
+ ENUM(Enum.class) {
+ @SuppressWarnings("rawtypes")
+ public String convertToString(Object object) {
+ return ((Enum) object).name(); // avoid toString() as that can be overridden
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Object convertFromString(Class cls, String str) {
+ return Enum.valueOf(cls, str);
+ }
+ },
+ ;
+
+ /** The type. */
+ private Class<?> type;
+
+ /**
+ * Creates an enum.
+ * @param type the type, not null
+ */
+ private JDKStringConverter(Class<?> type) {
+ this.type = type;
+ }
+
+ /**
+ * Gets the type of the converter.
+ * @return the type, not null
+ */
+ Class<?> getType() {
+ return type;
+ }
+
+ //-----------------------------------------------------------------------
+ public String convertToString(Object object) {
+ return object.toString();
+ }
+
+}
diff --git a/src/main/java/org/joda/convert/MethodConstructorStringConverter.java b/src/main/java/org/joda/convert/MethodConstructorStringConverter.java
new file mode 100644
index 0000000..3b31467
--- /dev/null
+++ b/src/main/java/org/joda/convert/MethodConstructorStringConverter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Conversion to and from a string using a toString method and a fromString constructor.
+ * <p>
+ * The toString method must meet the following signature:<br />
+ * {@code String anyName()} on Class T.
+ * <p>
+ * The fromString constructor must take a single {@code String} parameter.
+ * <p>
+ * MethodConstructorStringConverter is thread-safe and immutable.
+ *
+ * @param <T> the type of the converter
+ */
+final class MethodConstructorStringConverter<T> extends ReflectionStringConverter<T> {
+
+ /** Conversion from a string. */
+ private final Constructor<T> fromString;
+
+ /**
+ * Creates an instance using a method and a constructor.
+ * @param cls the class this converts for, not null
+ * @param toString the toString method, not null
+ * @param fromString the fromString method, not null
+ * @throws RuntimeException (or subclass) if the method signatures are invalid
+ */
+ MethodConstructorStringConverter(Class<T> cls, Method toString, Constructor<T> fromString) {
+ super(cls, toString);
+ if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers()) || cls.isLocalClass() || cls.isMemberClass()) {
+ throw new IllegalArgumentException("FromString constructor must be on an instantiable class");
+ }
+ if (fromString.getDeclaringClass() != cls) {
+ throw new IllegalStateException("FromString constructor must be defined on specified class");
+ }
+ this.fromString = fromString;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts the {@code String} to an object.
+ * @param cls the class to convert to, not null
+ * @param str the string to convert, not null
+ * @return the converted object, may be null but generally not
+ */
+ public T convertFromString(Class<? extends T> cls, String str) {
+ try {
+ return fromString.newInstance(str);
+ } catch (IllegalAccessException ex) {
+ throw new IllegalStateException("Constructor is not accessible");
+ } catch (InstantiationException ex) {
+ throw new IllegalStateException("Constructor is not valid");
+ } catch (InvocationTargetException ex) {
+ if (ex.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) ex.getCause();
+ }
+ throw new RuntimeException(ex.getMessage(), ex.getCause());
+ }
+ }
+
+}
diff --git a/src/main/java/org/joda/convert/MethodsStringConverter.java b/src/main/java/org/joda/convert/MethodsStringConverter.java
new file mode 100644
index 0000000..330b5d9
--- /dev/null
+++ b/src/main/java/org/joda/convert/MethodsStringConverter.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Conversion to and from a string using two methods.
+ * <p>
+ * The toString method must meet the following signature:<br />
+ * {@code String anyName()} on Class T.
+ * <p>
+ * The fromString method must meet the following signature:<br />
+ * {@code static T anyName(String)} on any class.
+ * <p>
+ * MethodsStringConverter is thread-safe and immutable.
+ *
+ * @param <T> the type of the converter
+ */
+final class MethodsStringConverter<T> extends ReflectionStringConverter<T> {
+
+ /** Conversion from a string. */
+ private final Method fromString;
+
+ /**
+ * Creates an instance using two methods.
+ * @param cls the class this converts for, not null
+ * @param toString the toString method, not null
+ * @param fromString the fromString method, not null
+ * @throws RuntimeException (or subclass) if the method signatures are invalid
+ */
+ MethodsStringConverter(Class<T> cls, Method toString, Method fromString) {
+ super(cls, toString);
+ if (fromString.getParameterTypes().length != 1) {
+ throw new IllegalStateException("FromString method must have one parameter");
+ }
+ Class<?> param = fromString.getParameterTypes()[0];
+ if (param != String.class && param != CharSequence.class) {
+ throw new IllegalStateException("FromString method must take a String or CharSequence");
+ }
+ if (fromString.getReturnType().isAssignableFrom(cls) == false) {
+ throw new IllegalStateException("FromString method must return specified class or a superclass");
+ }
+ this.fromString = fromString;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts the {@code String} to an object.
+ * @param cls the class to convert to, not null
+ * @param str the string to convert, not null
+ * @return the converted object, may be null but generally not
+ */
+ public T convertFromString(Class<? extends T> cls, String str) {
+ try {
+ return cls.cast(fromString.invoke(null, str));
+ } catch (IllegalAccessException ex) {
+ throw new IllegalStateException("Method is not accessible");
+ } catch (InvocationTargetException ex) {
+ if (ex.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) ex.getCause();
+ }
+ throw new RuntimeException(ex.getMessage(), ex.getCause());
+ }
+ }
+
+}
diff --git a/src/main/java/org/joda/convert/ReflectionStringConverter.java b/src/main/java/org/joda/convert/ReflectionStringConverter.java
new file mode 100644
index 0000000..8c6b8cd
--- /dev/null
+++ b/src/main/java/org/joda/convert/ReflectionStringConverter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Conversion to and from a string using reflection.
+ * <p>
+ * The toString method must meet the following signature:<br />
+ * {@code String anyName()} on Class T.
+ * <p>
+ * ReflectionStringConverter is abstract, but all known implementations are thread-safe and immutable.
+ *
+ * @param <T> the type of the converter
+ */
+abstract class ReflectionStringConverter<T> implements StringConverter<T> {
+
+ /** The converted class. */
+ final Class<T> cls;
+ /** Conversion to a string. */
+ final Method toString;
+
+ /**
+ * Creates an instance using two methods.
+ * @param cls the class this converts for, not null
+ * @param toString the toString method, not null
+ * @throws RuntimeException (or subclass) if the method signatures are invalid
+ */
+ ReflectionStringConverter(Class<T> cls, Method toString) {
+ if (toString.getParameterTypes().length != 0) {
+ throw new IllegalStateException("ToString method must have no parameters");
+ }
+ if (toString.getReturnType() != String.class) {
+ throw new IllegalStateException("ToString method must return a String");
+ }
+ this.cls = cls;
+ this.toString = toString;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts the object to a {@code String}.
+ * @param object the object to convert, not null
+ * @return the converted string, may be null but generally not
+ */
+ public String convertToString(T object) {
+ try {
+ return (String) toString.invoke(object);
+ } catch (IllegalAccessException ex) {
+ throw new IllegalStateException("Method is not accessible");
+ } catch (InvocationTargetException ex) {
+ if (ex.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) ex.getCause();
+ }
+ throw new RuntimeException(ex.getMessage(), ex.getCause());
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ @Override
+ public String toString() {
+ return "RefectionStringConverter[" + cls.getSimpleName() + "]";
+ }
+
+}
diff --git a/src/main/java/org/joda/convert/StringConvert.java b/src/main/java/org/joda/convert/StringConvert.java
new file mode 100644
index 0000000..50197e8
--- /dev/null
+++ b/src/main/java/org/joda/convert/StringConvert.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Manager for conversion to and from a {@code String}, acting as the main client interface.
+ * <p>
+ * Support is provided for conversions based on the {@link StringConverter} interface
+ * or the {@link ToString} and {@link FromString} annotations.
+ * <p>
+ * StringConvert is thread-safe with concurrent caches.
+ */
+public final class StringConvert {
+
+ /**
+ * An immutable global instance.
+ * <p>
+ * This instance cannot be added to using {@link #register}, however annotated classes
+ * are picked up. To register your own converters, simply create an instance of this class.
+ */
+ public static final StringConvert INSTANCE = new StringConvert();
+
+ /**
+ * The cache of converters.
+ */
+ private final ConcurrentMap<Class<?>, StringConverter<?>> registered = new ConcurrentHashMap<Class<?>, StringConverter<?>>();
+
+ /**
+ * Creates a new conversion manager including the JDK converters.
+ */
+ public StringConvert() {
+ this(true);
+ }
+
+ /**
+ * Creates a new conversion manager.
+ *
+ * @param includeJdkConverters true to include the JDK converters
+ */
+ public StringConvert(boolean includeJdkConverters) {
+ if (includeJdkConverters) {
+ for (JDKStringConverter conv : JDKStringConverter.values()) {
+ registered.put(conv.getType(), conv);
+ }
+ registered.put(Boolean.TYPE, JDKStringConverter.BOOLEAN);
+ registered.put(Byte.TYPE, JDKStringConverter.BYTE);
+ registered.put(Short.TYPE, JDKStringConverter.SHORT);
+ registered.put(Integer.TYPE, JDKStringConverter.INTEGER);
+ registered.put(Long.TYPE, JDKStringConverter.LONG);
+ registered.put(Float.TYPE, JDKStringConverter.FLOAT);
+ registered.put(Double.TYPE, JDKStringConverter.DOUBLE);
+ registered.put(Character.TYPE, JDKStringConverter.CHARACTER);
+ // JSR-310 classes
+ tryRegister("javax.time.Instant", "parse");
+ tryRegister("javax.time.Duration", "parse");
+ tryRegister("javax.time.calendar.LocalDate", "parse");
+ tryRegister("javax.time.calendar.LocalTime", "parse");
+ tryRegister("javax.time.calendar.LocalDateTime", "parse");
+ tryRegister("javax.time.calendar.OffsetDate", "parse");
+ tryRegister("javax.time.calendar.OffsetTime", "parse");
+ tryRegister("javax.time.calendar.OffsetDateTime", "parse");
+ tryRegister("javax.time.calendar.ZonedDateTime", "parse");
+ tryRegister("javax.time.calendar.Year", "parse");
+ tryRegister("javax.time.calendar.YearMonth", "parse");
+ tryRegister("javax.time.calendar.MonthDay", "parse");
+ tryRegister("javax.time.calendar.Period", "parse");
+ tryRegister("javax.time.calendar.ZoneOffset", "of");
+ tryRegister("javax.time.calendar.ZoneId", "of");
+ tryRegister("javax.time.calendar.TimeZone", "of");
+ }
+ }
+
+ /**
+ * Tries to register a class using the standard toString/parse pattern.
+ *
+ * @param className the class name, not null
+ */
+ private void tryRegister(String className, String fromStringMethodName) {
+ try {
+ Class<?> cls = getClass().getClassLoader().loadClass(className);
+ registerMethods(cls, "toString", fromStringMethodName);
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Converts the specified object to a {@code String}.
+ * <p>
+ * This uses {@link #findConverter} to provide the converter.
+ *
+ * @param <T> the type to convert from
+ * @param object the object to convert, null returns null
+ * @return the converted string, may be null
+ * @throws RuntimeException (or subclass) if unable to convert
+ */
+ @SuppressWarnings("unchecked")
+ public <T> String convertToString(T object) {
+ if (object == null) {
+ return null;
+ }
+ Class<T> cls = (Class<T>) object.getClass();
+ StringConverter<T> conv = findConverter(cls);
+ return conv.convertToString(object);
+ }
+
+ /**
+ * Converts the specified object to a {@code String}.
+ * <p>
+ * This uses {@link #findConverter} to provide the converter.
+ * The class can be provided to select a more specific converter.
+ *
+ * @param <T> the type to convert from
+ * @param cls the class to convert from, not null
+ * @param object the object to convert, null returns null
+ * @return the converted string, may be null
+ * @throws RuntimeException (or subclass) if unable to convert
+ */
+ public <T> String convertToString(Class<T> cls, T object) {
+ if (object == null) {
+ return null;
+ }
+ StringConverter<T> conv = findConverter(cls);
+ return conv.convertToString(object);
+ }
+
+ /**
+ * Converts the specified object from a {@code String}.
+ * <p>
+ * This uses {@link #findConverter} to provide the converter.
+ *
+ * @param <T> the type to convert to
+ * @param cls the class to convert to, not null
+ * @param str the string to convert, null returns null
+ * @return the converted object, may be null
+ * @throws RuntimeException (or subclass) if unable to convert
+ */
+ public <T> T convertFromString(Class<T> cls, String str) {
+ if (str == null) {
+ return null;
+ }
+ StringConverter<T> conv = findConverter(cls);
+ return conv.convertFromString(cls, str);
+ }
+
+ /**
+ * Finds a suitable converter for the type.
+ * <p>
+ * This returns an instance of {@code StringConverter} for the specified class.
+ * This could be useful in other frameworks.
+ * <p>
+ * The search algorithm first searches the registered converters.
+ * It then searches for {@code ToString} and {@code FromString} annotations on the specified class.
+ * Both searches consider superclasses, but not interfaces.
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to find a converter for, not null
+ * @return the converter, not null
+ * @throws RuntimeException (or subclass) if no converter found
+ */
+ @SuppressWarnings("unchecked")
+ public <T> StringConverter<T> findConverter(final Class<T> cls) {
+ if (cls == null) {
+ throw new IllegalArgumentException("Class must not be null");
+ }
+ StringConverter<T> conv = (StringConverter<T>) registered.get(cls);
+ if (conv == null) {
+ if (cls == Object.class) {
+ throw new IllegalStateException("No registered converter found: " + cls);
+ }
+ Class<?> loopCls = cls.getSuperclass();
+ while (loopCls != null && conv == null) {
+ conv = (StringConverter<T>) registered.get(loopCls);
+ loopCls = loopCls.getSuperclass();
+ }
+ if (conv == null) {
+ conv = findAnnotationConverter(cls);
+ if (conv == null) {
+ throw new IllegalStateException("No registered converter found: " + cls);
+ }
+ }
+ registered.putIfAbsent(cls, conv);
+ }
+ return conv;
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to find a method for, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private <T> StringConverter<T> findAnnotationConverter(final Class<T> cls) {
+ Method toString = findToStringMethod(cls);
+ if (toString == null) {
+ return null;
+ }
+ Constructor<T> con = findFromStringConstructor(cls);
+ Method fromString = findFromStringMethod(cls, con == null);
+ if (con == null && fromString == null) {
+ throw new IllegalStateException("Class annotated with @ToString but not with @FromString");
+ }
+ if (con != null && fromString != null) {
+ throw new IllegalStateException("Both method and constructor are annotated with @FromString");
+ }
+ if (con != null) {
+ return new MethodConstructorStringConverter<T>(cls, toString, con);
+ } else {
+ return new MethodsStringConverter<T>(cls, toString, fromString);
+ }
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param cls the class to find a method for, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private Method findToStringMethod(Class<?> cls) {
+ Method matched = null;
+ Class<?> loopCls = cls;
+ while (loopCls != null && matched == null) {
+ Method[] methods = loopCls.getDeclaredMethods();
+ for (Method method : methods) {
+ ToString toString = method.getAnnotation(ToString.class);
+ if (toString != null) {
+ if (matched != null) {
+ throw new IllegalStateException("Two methods are annotated with @ToString");
+ }
+ matched = method;
+ }
+ }
+ loopCls = loopCls.getSuperclass();
+ }
+ return matched;
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to find a method for, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private <T> Constructor<T> findFromStringConstructor(Class<T> cls) {
+ Constructor<T> con;
+ try {
+ con = cls.getDeclaredConstructor(String.class);
+ } catch (NoSuchMethodException ex) {
+ try {
+ con = cls.getDeclaredConstructor(CharSequence.class);
+ } catch (NoSuchMethodException ex2) {
+ return null;
+ }
+ }
+ FromString fromString = con.getAnnotation(FromString.class);
+ return fromString != null ? con : null;
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param cls the class to find a method for, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private Method findFromStringMethod(Class<?> cls, boolean searchSuperclasses) {
+ Method matched = null;
+ Class<?> loopCls = cls;
+ while (loopCls != null && matched == null) {
+ Method[] methods = loopCls.getDeclaredMethods();
+ for (Method method : methods) {
+ FromString fromString = method.getAnnotation(FromString.class);
+ if (fromString != null) {
+ if (matched != null) {
+ throw new IllegalStateException("Two methods are annotated with @ToString");
+ }
+ matched = method;
+ }
+ }
+ if (searchSuperclasses == false) {
+ break;
+ }
+ loopCls = loopCls.getSuperclass();
+ }
+ return matched;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Registers a converter for a specific type.
+ * <p>
+ * The converter will be used for subclasses unless overidden.
+ * <p>
+ * No new converters may be registered for the global singleton.
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to register a converter for, not null
+ * @param converter the String converter, not null
+ * @throws IllegalArgumentException if unable to register
+ * @throws IllegalStateException if class already registered
+ */
+ public <T> void register(final Class<T> cls, StringConverter<T> converter) {
+ if (cls == null ) {
+ throw new IllegalArgumentException("Class must not be null");
+ }
+ if (converter == null) {
+ throw new IllegalArgumentException("StringConverter must not be null");
+ }
+ if (this == INSTANCE) {
+ throw new IllegalStateException("Global singleton cannot be extended");
+ }
+ StringConverter<?> old = registered.putIfAbsent(cls, converter);
+ if (old != null) {
+ throw new IllegalStateException("Converter already registered for class: " + cls);
+ }
+ }
+
+ /**
+ * Registers a converter for a specific type by method names.
+ * <p>
+ * This method allows the converter to be used when the target class cannot have annotations added.
+ * The two method names must obey the same rules as defined by the annotations
+ * {@link ToString} and {@link FromString}.
+ * The converter will be used for subclasses unless overidden.
+ * <p>
+ * No new converters may be registered for the global singleton.
+ * <p>
+ * For example, {@code convert.registerMethods(Distance.class, "toString", "parse");}
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to register a converter for, not null
+ * @param toStringMethodName the name of the method converting to a string, not null
+ * @param fromStringMethodName the name of the method converting from a string, not null
+ * @throws IllegalArgumentException if unable to register
+ * @throws IllegalStateException if class already registered
+ */
+ public <T> void registerMethods(final Class<T> cls, String toStringMethodName, String fromStringMethodName) {
+ if (cls == null ) {
+ throw new IllegalArgumentException("Class must not be null");
+ }
+ if (toStringMethodName == null || fromStringMethodName == null) {
+ throw new IllegalArgumentException("Method names must not be null");
+ }
+ if (this == INSTANCE) {
+ throw new IllegalStateException("Global singleton cannot be extended");
+ }
+ Method toString = findToStringMethod(cls, toStringMethodName);
+ Method fromString = findFromStringMethod(cls, fromStringMethodName);
+ MethodsStringConverter<T> converter = new MethodsStringConverter<T>(cls, toString, fromString);
+ StringConverter<?> old = registered.putIfAbsent(cls, converter);
+ if (old != null) {
+ throw new IllegalStateException("Converter already registered for class: " + cls);
+ }
+ }
+
+ /**
+ * Registers a converter for a specific type by method and constructor.
+ * <p>
+ * This method allows the converter to be used when the target class cannot have annotations added.
+ * The two method name and constructor must obey the same rules as defined by the annotations
+ * {@link ToString} and {@link FromString}.
+ * The converter will be used for subclasses unless overidden.
+ * <p>
+ * No new converters may be registered for the global singleton.
+ * <p>
+ * For example, {@code convert.registerMethodConstructor(Distance.class, "toString");}
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to register a converter for, not null
+ * @param toStringMethodName the name of the method converting to a string, not null
+ * @throws IllegalArgumentException if unable to register
+ * @throws IllegalStateException if class already registered
+ */
+ public <T> void registerMethodConstructor(final Class<T> cls, String toStringMethodName) {
+ if (cls == null ) {
+ throw new IllegalArgumentException("Class must not be null");
+ }
+ if (toStringMethodName == null) {
+ throw new IllegalArgumentException("Method name must not be null");
+ }
+ if (this == INSTANCE) {
+ throw new IllegalStateException("Global singleton cannot be extended");
+ }
+ Method toString = findToStringMethod(cls, toStringMethodName);
+ Constructor<T> fromString = findFromStringConstructorByType(cls);
+ MethodConstructorStringConverter<T> converter = new MethodConstructorStringConverter<T>(cls, toString, fromString);
+ StringConverter<?> old = registered.putIfAbsent(cls, converter);
+ if (old != null) {
+ throw new IllegalStateException("Converter already registered for class: " + cls);
+ }
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param cls the class to find a method for, not null
+ * @param methodName the name of the method to find, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private Method findToStringMethod(Class<?> cls, String methodName) {
+ Method m;
+ try {
+ m = cls.getMethod(methodName);
+ } catch (NoSuchMethodException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ if (Modifier.isStatic(m.getModifiers())) {
+ throw new IllegalArgumentException("Method must not be static: " + methodName);
+ }
+ return m;
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param cls the class to find a method for, not null
+ * @param methodName the name of the method to find, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private Method findFromStringMethod(Class<?> cls, String methodName) {
+ Method m;
+ try {
+ m = cls.getMethod(methodName, String.class);
+ } catch (NoSuchMethodException ex) {
+ try {
+ m = cls.getMethod(methodName, CharSequence.class);
+ } catch (NoSuchMethodException ex2) {
+ throw new IllegalArgumentException("Method not found", ex2);
+ }
+ }
+ if (Modifier.isStatic(m.getModifiers()) == false) {
+ throw new IllegalArgumentException("Method must be static: " + methodName);
+ }
+ return m;
+ }
+
+ /**
+ * Finds the conversion method.
+ *
+ * @param <T> the type of the converter
+ * @param cls the class to find a method for, not null
+ * @return the method to call, null means use {@code toString}
+ */
+ private <T> Constructor<T> findFromStringConstructorByType(Class<T> cls) {
+ try {
+ return cls.getDeclaredConstructor(String.class);
+ } catch (NoSuchMethodException ex) {
+ try {
+ return cls.getDeclaredConstructor(CharSequence.class);
+ } catch (NoSuchMethodException ex2) {
+ throw new IllegalArgumentException("Constructor not found", ex2);
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a simple string representation of the object.
+ *
+ * @return the string representation, never null
+ */
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+
+}
diff --git a/src/main/java/org/joda/convert/StringConverter.java b/src/main/java/org/joda/convert/StringConverter.java
new file mode 100644
index 0000000..e90f51b
--- /dev/null
+++ b/src/main/java/org/joda/convert/StringConverter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Interface defining conversion to and from a {@code String}.
+ * <p>
+ * StringConverter is an interface and must be implemented with care.
+ * Implementations must be immutable and thread-safe.
+ *
+ * @param <T> the type of the converter
+ */
+public interface StringConverter<T> extends ToStringConverter<T>, FromStringConverter<T> {
+
+}
diff --git a/src/main/java/org/joda/convert/ToString.java b/src/main/java/org/joda/convert/ToString.java
new file mode 100644
index 0000000..da248e1
--- /dev/null
+++ b/src/main/java/org/joda/convert/ToString.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to mark a method as being suitable for converting an
+ * object to a standard format {@code String}.
+ * <p>
+ * This annotation should be applied to one method on a class.
+ * The method must not be static. It must take no parameters and return a {@code String}.
+ * The string format must be able to be parsed by the matching @FromString on
+ * the same class. The format should be human readable and an industry standard
+ * where possible, for example ISO-8601 for dates and times.
+ */
+ at Target(ElementType.METHOD)
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface ToString {
+
+}
diff --git a/src/main/java/org/joda/convert/ToStringConverter.java b/src/main/java/org/joda/convert/ToStringConverter.java
new file mode 100644
index 0000000..39b32af
--- /dev/null
+++ b/src/main/java/org/joda/convert/ToStringConverter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Interface defining conversion to a {@code String}.
+ * <p>
+ * ToStringConverter is an interface and must be implemented with care.
+ * Implementations must be immutable and thread-safe.
+ *
+ * @param <T> the type of the converter
+ */
+public interface ToStringConverter<T> {
+
+ /**
+ * Converts the specified object to a {@code String}.
+ * @param object the object to convert, not null
+ * @return the converted string, may be null but generally not
+ */
+ String convertToString(T object);
+
+}
diff --git a/src/site/resources/css/site.css b/src/site/resources/css/site.css
new file mode 100644
index 0000000..2ed8bb6
--- /dev/null
+++ b/src/site/resources/css/site.css
@@ -0,0 +1,129 @@
+body, td, select, input, li{
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ background-color: #fff;
+}
+a {
+ text-decoration: none;
+}
+a:link {
+ color:#009;
+}
+a:visited {
+ color:#009;
+}
+a:active, a:hover {
+ text-decoration: underline;
+}
+a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
+ background: url(../images/external.png) right center no-repeat;
+ padding-right: 15px;
+}
+a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
+ background: url(../images/newwindow.png) right center no-repeat;
+ padding-right: 18px;
+}
+h2 {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ padding: 4px 4px 4px 6px;
+ border: 1px solid #999;
+ color: #006;
+ background-color: #eef;
+ font-weight:bold;
+ font-size: 16px;
+ margin-top: 4px;
+ margin-bottom: 6px;
+}
+h3 {
+ padding: 4px 4px 4px 6px;
+ border: 1px solid #aaa;
+ color: #006;
+ background-color: #eee;
+ font-weight: normal;
+ font-size: 14px;
+ margin-top: 4px;
+ margin-bottom: 6px;
+}
+p, ul {
+ font-size: 13px;
+ margin-top: 4px;
+ margin-bottom: 6px;
+}
+#banner {
+ background-color: #eef;
+ border-bottom: 1px solid #aaa;
+ padding: 8px;
+}
+#bannerLeft, #bannerRight {
+ font-size: 30px;
+ color:black;
+ background-color:white;
+ border: 1px solid #999;
+ padding: 0px 5px;
+}
+#banner a:hover {
+ text-decoration:none;
+}
+#breadcrumbs {
+ padding-top: 1px;
+ padding-bottom: 2px;
+ border-bottom: 1px solid #aaa;
+ background-color: #ddf;
+}
+#leftColumn {
+ margin: 8px 0 8px 4px;
+ border: 1px solid #999;
+ background-color: #eef;
+}
+#navcolumn {
+ padding: 6px 4px 0 6px;
+}
+#navcolumn h5 {
+ font-size: 12px;
+ border-bottom: 1px solid #aaaaaa;
+ padding-top: 2px;
+ font-weight: normal;
+}
+#navcolumn li {
+ font-size: 12px;
+ padding-left: 12px;
+ background-color: #eef;
+}
+#navcolumn a:active, #navcolumn a:hover {
+ text-decoration: none;
+}
+#lastPublished {
+ font-size: 10px;
+}
+table.bodyTable th {
+ color: white;
+ background-color: #bbb;
+ text-align: left;
+ font-weight: bold;
+ font-size: 13px;
+}
+
+table.bodyTable th, table.bodyTable td {
+ font-size: 13px;
+}
+
+table.bodyTable tr.a {
+ background-color: #ddd;
+}
+
+table.bodyTable tr.b {
+ background-color: #eee;
+}
+
+.source {
+ border: 1px solid #999;
+ padding: 8px;
+ margin: 6px;
+}
+#footer {
+ background-color: #eef;
+ border-top: 1px solid #999;
+}
+body {
+ padding-bottom: 0px;
+}
diff --git a/src/site/site.xml b/src/site/site.xml
new file mode 100644
index 0000000..921885f
--- /dev/null
+++ b/src/site/site.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="Joda-Convert">
+ <publishDate position="navigation-bottom" format="yyyy-MM-dd"/>
+ <bannerLeft>
+ <name>Joda.org</name>
+ <!--src>http://joda-convert.sourceforge.net/images/joda.png</src-->
+ <href>http://joda.sourceforge.net/</href>
+ </bannerLeft>
+ <bannerRight>
+ <name>Joda-Convert</name>
+ <!--src>http://joda-convert.sourceforge.net/images/jodaconvert.png</src-->
+ <href>http://joda-convert.sourceforge.net/</href>
+ </bannerRight>
+
+ <body>
+ <menu name="Joda Convert">
+ <item name="Overview" href="index.html"/>
+ <item name="User guide" href="userguide.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ <item name="Javadoc (Release)" href="api-release/index.html"/>
+ <item name="License" href="license.html"/>
+ <item name="Download" href="http://sourceforge.net/projects/joda-convert/files/joda-convert/"/>
+ </menu>
+
+ <menu name="Development">
+ <item name="GitHub (Source code)" href="https://github.com/JodaOrg/joda-convert"/>
+ <item name="Sourceforge" href="http://sourceforge.net/projects/joda-convert/"/>
+ <!--item name="Test results" href="/junit-report.html"/-->
+ <!--item name="Test coverage" href="/cobertura/index.html"/-->
+ <item name="Mailing lists" href="mail-lists.html"/>
+ <!--item name="Tasks" href="tasks.html"/-->
+ <!--item name="Subversion" href="http://joda-convert.svn.sourceforge.net/viewvc/joda-convert/trunk/"/-->
+ <item name="Javadoc (Development)" href="apidocs/index.html"/>
+ </menu>
+
+ <menu name="Joda">
+ <item name="Joda home" href="http://joda.sourceforge.net"/>
+ <item name="Beans" href="http://joda-beans.sourceforge.net/index.html"/>
+ <item name="Money" href="http://joda-money.sourceforge.net/index.html"/>
+ <item name="Primitives" href="http://joda-primitives.sourceforge.net/index.html"/>
+ <item name="Time" href="http://joda-time.sourceforge.net/index.html"/>
+ </menu>
+
+ <menu ref="reports"/>
+
+ <menu name="Website">
+ <item name="Privacy" href="privacy.html"/>
+ </menu>
+ </body>
+
+ <poweredBy>
+ <logo name="Sourceforge" href="http://sourceforge.net/projects/joda-convert/"
+ img="http://sflogo.sourceforge.net/sflogo.php?group_id=344317&type=13" width="120" height="30" />
+ </poweredBy>
+</project>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
new file mode 100644
index 0000000..db94440
--- /dev/null
+++ b/src/site/xdoc/index.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Joda Convert</title>
+ <author>Stephen Colebourne</author>
+ </properties>
+
+ <body>
+
+<section name="Joda Convert">
+
+<p>
+Joda-Convert provides a small set of classes to aid conversion between Objects and Strings.
+It is not intended to tackle the wider problem of Object to Object transformation.
+</p>
+<div style="border:1px solid black; padding: 0px 6px; margin: 4px;"><pre>
+// conversion to String
+String str = StringConvert.INSTANCE.convertToString(foo);
+
+// conversion from String
+Foo bar = StringConvert.INSTANCE.convertFromString(Foo.class, str);
+</pre></div>
+<p>
+Joda-Convert supports two mechanisms of extending the list of supported conversions.
+The first is to write your own converter implementing an interface.
+The second is to use annotations.
+</p>
+<p>
+The ability of Joda-Convert to use annotations to define the conversion methods is a key difference from other projects.
+For example, most value classes, like <code>Currency</code> or <code>TimeZone</code>, already have methods
+to convert to and from a standard format String.
+Consider a <code>Distance</code> class:
+</p>
+<div style="border:1px solid black; padding: 0px 6px; margin: 4px;"><pre>
+public class Distance {
+
+ @FromString
+ public static Distance parse(String str) { ... }
+
+ @ToString
+ public String getStandardOutput() { ... }
+
+}
+</pre></div>
+<p>
+As shown, the two methods may have any name. They must simply fulfil the required method signatures for conversion.
+The <code>FromString</code> annotation may also be applied to a constructor.
+</p>
+<p>
+When Joda-Convert is asked to convert between an object and a String, if there is no registered converter
+then the annotations are checked. If they are found, then the methods are called by reflection.
+</p>
+<p>
+Joda-Convert is licensed under the business-friendly <a href="license.html">Apache 2.0 licence</a>.
+</p>
+
+</section>
+
+<section name="Documentation">
+<p>
+Various documentation is available:
+<ul>
+<li>The helpful <a href="userguide.html">user guide</a></li>
+<li>The javadoc for the <a href="api-release/index.html">current release</a></li>
+<li>The javadoc for the <a href="apidocs/index.html">latest source code</a></li>
+<li>The change notes <a href="changes-report.html">for the releases</a></li>
+<!--li>A <a href="faq.html">FAQ</a> list</li-->
+<!--li>Information on <a href="installation.html">downloading and installing</a> Joda-Convert</li-->
+<li>The <a href="https://github.com/JodaOrg/joda-convert">GitHub</a> source repository</li>
+</ul>
+</p>
+</section>
+
+<section name="Releases">
+<p>
+<a href="http://sourceforge.net/projects/joda-convert/files/joda-convert/1.2/">Release 1.2</a>
+is the current latest release.
+This release is considered stable and worthy of the 1.x tag.
+It depends on JDK 1.5 or later.
+</p>
+</section>
+
+<section name="Contact">
+<p>
+If you have any questions, or want to volunteer to help, just email Stephen Colebourne
+via scolebourne.at.users.sourceforge.net.
+</p>
+<p>
+<br />
+<br />
+<br />
+<br />
+<br />
+</p>
+</section>
+</body>
+</document>
diff --git a/src/site/xdoc/privacy.xml b/src/site/xdoc/privacy.xml
new file mode 100644
index 0000000..4cb646f
--- /dev/null
+++ b/src/site/xdoc/privacy.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<document>
+ <properties>
+ <title>Privacy</title>
+ </properties>
+<body>
+
+<!-- ========================================================================= -->
+
+<section name="Privacy">
+<p>
+Information about your use of this website is collected using cookies.
+The collected information consists of the following:
+<br />
+ 1. The IP address from which you access the website;<br />
+ 2. The type of browser and operating system you use to access our site;<br />
+ 3. The date and time you access our site;<br />
+ 4. The pages you visit; and<br />
+ 5. The addresses of pages from where you followed a link to our site.<br />
+</p>
+<p>
+Part of this information is gathered using a tracking cookie set by the
+<a href="http://www.google.com/analytics/">Google Analytics</a> service
+and handled by Google as described in their
+<a href="http://www.google.com/privacy.html">privacy policy</a>. See your browser documentation for
+instructions on how to disable the cookie if you prefer not to share this data with Google.
+</p>
+<p>
+We use the gathered information to help us make our site more useful to visitors and to better
+understand how and when our site is used. We do not track or collect personally identifiable information
+or associate gathered data with any personally identifying information from other sources.
+</p>
+<p>
+By using this website, you consent to the collection of this data in the manner and for the purpose described above.
+<br />
+</p>
+<!-- <p>
+This website also makes use of targetted adverts supplied by
+<a href="https://www.google.com/adsense">Google Adsense</a>.
+To achieve this targetting, Google utilises cookies which collect the same information described above.
+The cookies identfy your usage of many different internet websites, not just this one, and may be used
+in conjunction with other advertising networks.
+For more details on the Adsense program, and to find out your options to control how the data
+is used please <a href="http://www.google.com/privacy_ads.html">click here</a>.
+</p>-->
+</section>
+</body>
+</document>
diff --git a/src/site/xdoc/userguide.xml b/src/site/xdoc/userguide.xml
new file mode 100644
index 0000000..1f19d57
--- /dev/null
+++ b/src/site/xdoc/userguide.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Joda Convert</title>
+ <author>Stephen Colebourne</author>
+ </properties>
+
+ <body>
+
+<section name="User guide">
+
+<p>
+Joda-Convert is intended for one simple task -
+Converting objects to and from strings.
+This is a common problem, particularly when communicating over textual protocols like XML or JSON.
+</p>
+
+<subsection name="Basic usage">
+<p>
+Using Joda-Convert is easy at the simplest level.
+The main access is via the class <code>StringConvert</code>.
+</p>
+<p>
+The easiest way to use the conversion is via the global constant:
+</p>
+<div style="border:1px solid black; padding: 0px 6px; margin: 4px;"><pre>
+// conversion to a String
+TimeZone zone = ...
+String str = StringConvert.INSTANCE.convertToString(zone);
+
+// conversion from a String
+TimeZone zone = StringConvert.INSTANCE.convertFromString(TimeZone.class, str);
+</pre></div>
+<p>
+In both cases, if the input is <code>null</code> then the output will also be <code>null</code>.
+</p>
+<p>
+The global constant is quick and easy to use, but is shared between all users in the <code>ClassLoader</code>.
+It also cannot be extended.
+</p>
+<p>
+The alternative approach is to instantiate your own instance of <code>StringConvert</code>.
+This would normally be stored in your own static variable, or made available as needed by dependency injection.
+This may be updated by registering your own converters.
+</p>
+</subsection>
+
+<subsection name="Converters">
+<p>
+Each instance of <code>StringConvert</code>, including the global singleton, includes a standard set of JDK-based converters.
+These cover all the standard JDK types for which conversion to and from a string is sensible.
+The set also includes JSR-310 types, but these are optional and loaded by reflection. The system will run without any dependency.
+</p>
+<p>
+Each <code>StringConvert</code> instance, other than the global singleton, may have additional converters registered manually.
+Each converter implements the <code>StringConverter</code> interface, which is self explanatory.
+</p>
+<p>
+Converters may also be manually added by method name.
+This is equivalent to using annotations, but suitable when you don't own the code to add them.
+See <code>StringConvert.registerMethods</code> and <code>StringConvert.registerMethodConstructor</code>.
+</p>
+<p>
+A converter can only be registered if one is not already registered for that type.
+</p>
+</subsection>
+
+<subsection name="Annotation based conversion">
+<p>
+If there is no registered converter for a type, then a search by annotation is performed.
+This will search for the <code>ToString</code> and <code>FromString</code> annotation on the type.
+These annotations will indicate which method should be called to perform the conversion.
+</p>
+<div style="border:1px solid black; padding: 0px 6px; margin: 4px;"><pre>
+public class Distance {
+
+ @FromString
+ public static Distance parse(String str) { ... }
+
+ @ToString
+ public String getStandardOutput() { ... }
+
+}
+</pre></div>
+<p>
+To be valid, the class must contain one <code>ToString</code> annotation and one <code>FromString</code> annotation.
+The <code>ToString</code> annotation must be an instance method taking no parameters and returning a String.
+The <code>FromString</code> annotation must be either a static method or a constructor taking a String parameter and
+returning the correct type.
+If the annotations are not found on the target class, then superclasses are searched.
+</p>
+<p>
+The concept is that other open source libraries, as well as your application code, will implement these two annotations.
+For open source projects, a key point is that adding the annotations is a compile-time only event.
+The Joda-Convert jar file is not needed by your users unless they want to.
+If they don't want to use Joda-Convert then the annotations are effectively ignored.
+</p>
+<p>
+Joda-Time v2.0 and Joda-Money will both contain the annotations.
+However, in both cases, the dependency is compile-time only, and not at runtime.
+</p>
+</subsection>
+
+</section>
+</body>
+</document>
diff --git a/src/test/java/org/joda/convert/DistanceFromStringConstructorInvalidParameter.java b/src/test/java/org/joda/convert/DistanceFromStringConstructorInvalidParameter.java
new file mode 100644
index 0000000..c250fbc
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringConstructorInvalidParameter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceFromStringConstructorInvalidParameter {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public DistanceFromStringConstructorInvalidParameter(Object amount) {
+ this.amount = 0;
+ }
+
+ public DistanceFromStringConstructorInvalidParameter(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceFromStringConstructorInvalidParameterCount.java b/src/test/java/org/joda/convert/DistanceFromStringConstructorInvalidParameterCount.java
new file mode 100644
index 0000000..91a8730
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringConstructorInvalidParameterCount.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceFromStringConstructorInvalidParameterCount {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public DistanceFromStringConstructorInvalidParameterCount(String amount, int value) {
+ this.amount = 0;
+ }
+
+ public DistanceFromStringConstructorInvalidParameterCount(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceFromStringException.java b/src/test/java/org/joda/convert/DistanceFromStringException.java
new file mode 100644
index 0000000..b8dd645
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.text.ParseException;
+
+/**
+ * Example class with annotated methods.
+ */
+public class DistanceFromStringException {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceFromStringException parse(String amount) throws ParseException {
+ throw new ParseException("Test", 2);
+ }
+
+ public DistanceFromStringException(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceFromStringInvalidParameter.java b/src/test/java/org/joda/convert/DistanceFromStringInvalidParameter.java
new file mode 100644
index 0000000..c1dee91
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringInvalidParameter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceFromStringInvalidParameter {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceFromStringInvalidParameter parse(Object amount) {
+ return null;
+ }
+
+ public DistanceFromStringInvalidParameter(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceFromStringInvalidParameterCount.java b/src/test/java/org/joda/convert/DistanceFromStringInvalidParameterCount.java
new file mode 100644
index 0000000..352cac0
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringInvalidParameterCount.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceFromStringInvalidParameterCount {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceFromStringInvalidParameterCount parse(String amount, int value) {
+ return null;
+ }
+
+ public DistanceFromStringInvalidParameterCount(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceFromStringInvalidReturnType.java b/src/test/java/org/joda/convert/DistanceFromStringInvalidReturnType.java
new file mode 100644
index 0000000..d0a5a55
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringInvalidReturnType.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceFromStringInvalidReturnType {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static Integer parse(String amount) {
+ return null;
+ }
+
+ public DistanceFromStringInvalidReturnType(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceFromStringNoToString.java b/src/test/java/org/joda/convert/DistanceFromStringNoToString.java
new file mode 100644
index 0000000..1749fcf
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceFromStringNoToString.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceFromStringNoToString {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceFromStringNoToString(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceFromStringNoToString(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceMethodAndConstructorAnnotations.java b/src/test/java/org/joda/convert/DistanceMethodAndConstructorAnnotations.java
new file mode 100644
index 0000000..d1529f0
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceMethodAndConstructorAnnotations.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceMethodAndConstructorAnnotations {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceMethodAndConstructorAnnotations parse(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ return new DistanceMethodAndConstructorAnnotations(Integer.parseInt(amount));
+ }
+
+ public DistanceMethodAndConstructorAnnotations(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceMethodAndConstructorAnnotations(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceMethodConstructor.java b/src/test/java/org/joda/convert/DistanceMethodConstructor.java
new file mode 100644
index 0000000..d559dab
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceMethodConstructor.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated constructor and method.
+ */
+public class DistanceMethodConstructor {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceMethodConstructor(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceMethodConstructor(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceMethodConstructorCharSequence.java b/src/test/java/org/joda/convert/DistanceMethodConstructorCharSequence.java
new file mode 100644
index 0000000..a7ad0ad
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceMethodConstructorCharSequence.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated constructor and method.
+ */
+public class DistanceMethodConstructorCharSequence {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceMethodConstructorCharSequence(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceMethodConstructorCharSequence(CharSequence amount) {
+ String amt = amount.toString().substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amt);
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceMethodMethod.java b/src/test/java/org/joda/convert/DistanceMethodMethod.java
new file mode 100644
index 0000000..e8ba0fc
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceMethodMethod.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated methods.
+ */
+public class DistanceMethodMethod {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceMethodMethod parse(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ return new DistanceMethodMethod(Integer.parseInt(amount));
+ }
+
+ public DistanceMethodMethod(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceMethodMethodCharSequence.java b/src/test/java/org/joda/convert/DistanceMethodMethodCharSequence.java
new file mode 100644
index 0000000..b0b2e65
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceMethodMethodCharSequence.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated methods.
+ */
+public class DistanceMethodMethodCharSequence {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceMethodMethodCharSequence parse(CharSequence amount) {
+ String amt = amount.toString().substring(0, amount.length() - 1);
+ return new DistanceMethodMethodCharSequence(Integer.parseInt(amt));
+ }
+
+ public DistanceMethodMethodCharSequence(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceNoAnnotations.java b/src/test/java/org/joda/convert/DistanceNoAnnotations.java
new file mode 100644
index 0000000..58b3b59
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceNoAnnotations.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceNoAnnotations {
+
+ /** Amount. */
+ final int amount;
+
+ public static DistanceNoAnnotations parse(String amount) {
+ return new DistanceNoAnnotations(amount);
+ }
+
+ public DistanceNoAnnotations(int amount) {
+ this.amount = amount;
+ }
+
+ public DistanceNoAnnotations(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceNoAnnotationsCharSequence.java b/src/test/java/org/joda/convert/DistanceNoAnnotationsCharSequence.java
new file mode 100644
index 0000000..a9413bc
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceNoAnnotationsCharSequence.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceNoAnnotationsCharSequence {
+
+ /** Amount. */
+ final int amount;
+
+ public static DistanceNoAnnotationsCharSequence parse(CharSequence amount) {
+ return new DistanceNoAnnotationsCharSequence(amount);
+ }
+
+ public DistanceNoAnnotationsCharSequence(int amount) {
+ this.amount = amount;
+ }
+
+ public DistanceNoAnnotationsCharSequence(CharSequence amount) {
+ String amt = amount.toString().substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amt);
+ }
+
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceToStringException.java b/src/test/java/org/joda/convert/DistanceToStringException.java
new file mode 100644
index 0000000..e29c7ab
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceToStringException.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import java.text.ParseException;
+
+/**
+ * Example class with annotated methods.
+ */
+public class DistanceToStringException {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static DistanceToStringException parse(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ return new DistanceToStringException(Integer.parseInt(amount));
+ }
+
+ public DistanceToStringException(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() throws ParseException {
+ throw new ParseException("Test", 2);
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceToStringInvalidParameters.java b/src/test/java/org/joda/convert/DistanceToStringInvalidParameters.java
new file mode 100644
index 0000000..91d36ee
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceToStringInvalidParameters.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceToStringInvalidParameters {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceToStringInvalidParameters(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceToStringInvalidParameters(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public Object print(int num) {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceToStringInvalidReturnType.java b/src/test/java/org/joda/convert/DistanceToStringInvalidReturnType.java
new file mode 100644
index 0000000..7cabbab
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceToStringInvalidReturnType.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceToStringInvalidReturnType {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceToStringInvalidReturnType(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceToStringInvalidReturnType(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public Object print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceToStringNoFromString.java b/src/test/java/org/joda/convert/DistanceToStringNoFromString.java
new file mode 100644
index 0000000..f87b7d0
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceToStringNoFromString.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceToStringNoFromString {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceToStringNoFromString(int amount) {
+ this.amount = amount;
+ }
+
+ public DistanceToStringNoFromString(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceTwoFromStringMethodAnnotations.java b/src/test/java/org/joda/convert/DistanceTwoFromStringMethodAnnotations.java
new file mode 100644
index 0000000..4a11f27
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceTwoFromStringMethodAnnotations.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceTwoFromStringMethodAnnotations {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceTwoFromStringMethodAnnotations(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public static DistanceTwoFromStringMethodAnnotations parse(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ return new DistanceTwoFromStringMethodAnnotations(Integer.parseInt(amount));
+ }
+
+ @FromString
+ public static DistanceTwoFromStringMethodAnnotations parse2(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ return new DistanceTwoFromStringMethodAnnotations(Integer.parseInt(amount));
+ }
+
+ public DistanceTwoFromStringMethodAnnotations(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/DistanceTwoToStringAnnotations.java b/src/test/java/org/joda/convert/DistanceTwoToStringAnnotations.java
new file mode 100644
index 0000000..1f3a465
--- /dev/null
+++ b/src/test/java/org/joda/convert/DistanceTwoToStringAnnotations.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with no annotations.
+ */
+public class DistanceTwoToStringAnnotations {
+
+ /** Amount. */
+ final int amount;
+
+ public DistanceTwoToStringAnnotations(int amount) {
+ this.amount = amount;
+ }
+
+ @FromString
+ public DistanceTwoToStringAnnotations(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ this.amount = Integer.parseInt(amount);
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @ToString
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/MockDistanceStringConverter.java b/src/test/java/org/joda/convert/MockDistanceStringConverter.java
new file mode 100644
index 0000000..1e75ea3
--- /dev/null
+++ b/src/test/java/org/joda/convert/MockDistanceStringConverter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Conversion between an {@code DistanceMethodMethod} and a {@code String}.
+ */
+public enum MockDistanceStringConverter implements StringConverter<DistanceMethodMethod> {
+
+ /** Singleton instance. */
+ INSTANCE;
+
+ /**
+ * Converts the {@code DistanceMethodMethod} to a {@code String}.
+ * @param object the object to convert, not null
+ * @return the converted string, may be null but generally not
+ */
+ public String convertToString(DistanceMethodMethod object) {
+ return object.print();
+ }
+
+ /**
+ * Converts the {@code String} to an {@code DistanceMethodMethod}.
+ * @param cls the class to convert to, not null
+ * @param str the string to convert, not null
+ * @return the converted integer, may be null but generally not
+ */
+ public DistanceMethodMethod convertFromString(Class<? extends DistanceMethodMethod> cls, String str) {
+ return DistanceMethodMethod.parse(str);
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/MockIntegerStringConverter.java b/src/test/java/org/joda/convert/MockIntegerStringConverter.java
new file mode 100644
index 0000000..79de32f
--- /dev/null
+++ b/src/test/java/org/joda/convert/MockIntegerStringConverter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Conversion between an {@code Integer} and a {@code String}.
+ */
+public enum MockIntegerStringConverter implements StringConverter<Integer> {
+
+ /** Singleton instance. */
+ INSTANCE;
+
+ /**
+ * Converts the {@code Integer} to a {@code String}.
+ * @param object the object to convert, not null
+ * @return the converted string, may be null but generally not
+ */
+ public String convertToString(Integer object) {
+ return object.toString();
+ }
+
+ /**
+ * Converts the {@code String} to an {@code Integer}.
+ * @param cls the class to convert to, not null
+ * @param str the string to convert, not null
+ * @return the converted integer, may be null but generally not
+ */
+ public Integer convertFromString(Class<? extends Integer> cls, String str) {
+ return new Integer(str);
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/SubMethodConstructor.java b/src/test/java/org/joda/convert/SubMethodConstructor.java
new file mode 100644
index 0000000..ce6df54
--- /dev/null
+++ b/src/test/java/org/joda/convert/SubMethodConstructor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated methods.
+ */
+public class SubMethodConstructor extends DistanceMethodConstructor {
+
+ @FromString
+ public SubMethodConstructor(String amount) {
+ super(amount);
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/SubMethodMethod.java b/src/test/java/org/joda/convert/SubMethodMethod.java
new file mode 100644
index 0000000..d3bae48
--- /dev/null
+++ b/src/test/java/org/joda/convert/SubMethodMethod.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated methods.
+ */
+public class SubMethodMethod extends DistanceMethodMethod {
+
+ @FromString
+ public static SubMethodMethod parse(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ return new SubMethodMethod(Integer.parseInt(amount));
+ }
+
+ public SubMethodMethod(int amount) {
+ super(amount);
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/SubNoAnnotations.java b/src/test/java/org/joda/convert/SubNoAnnotations.java
new file mode 100644
index 0000000..af58042
--- /dev/null
+++ b/src/test/java/org/joda/convert/SubNoAnnotations.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class with annotated methods.
+ */
+public class SubNoAnnotations extends DistanceMethodMethod {
+
+ public SubNoAnnotations(int amount) {
+ super(amount);
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/SuperFactorySub.java b/src/test/java/org/joda/convert/SuperFactorySub.java
new file mode 100644
index 0000000..6525382
--- /dev/null
+++ b/src/test/java/org/joda/convert/SuperFactorySub.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class which matches the case where a superclass acts as the sole factory.
+ */
+public class SuperFactorySub extends SuperFactorySuper {
+
+ public SuperFactorySub(int amount) {
+ super(amount);
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/SuperFactorySuper.java b/src/test/java/org/joda/convert/SuperFactorySuper.java
new file mode 100644
index 0000000..3e9be17
--- /dev/null
+++ b/src/test/java/org/joda/convert/SuperFactorySuper.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+/**
+ * Example class which matches the case where a superclass acts as the sole factory.
+ */
+public class SuperFactorySuper {
+
+ /** Amount. */
+ final int amount;
+
+ @FromString
+ public static SuperFactorySuper parse(String amount) {
+ amount = amount.substring(0, amount.length() - 1);
+ int i = Integer.parseInt(amount);
+ return i > 10 ? new SuperFactorySuper(i) : new SuperFactorySub(i);
+ }
+
+ public SuperFactorySuper(int amount) {
+ this.amount = amount;
+ }
+
+ @ToString
+ public String print() {
+ return amount + "m";
+ }
+
+ @Override
+ public String toString() {
+ return "Distance[" + amount + "m]";
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/TestJDKStringConverters.java b/src/test/java/org/joda/convert/TestJDKStringConverters.java
new file mode 100644
index 0000000..540bd0d
--- /dev/null
+++ b/src/test/java/org/joda/convert/TestJDKStringConverters.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright 2010 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URL;
+import java.util.Calendar;
+import java.util.Currency;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Test;
+
+/**
+ * Test JDKStringConverters.
+ */
+public class TestJDKStringConverters {
+
+ @Test
+ public void test_String() {
+ JDKStringConverter test = JDKStringConverter.STRING;
+ doTest(test, String.class, "Hello", "Hello");
+ }
+
+ @Test
+ public void test_StringBuffer() {
+ JDKStringConverter test = JDKStringConverter.STRING_BUFFER;
+ Object obj = new StringBuffer("Hello");
+ assertEquals(StringBuffer.class, test.getType());
+ assertEquals("Hello", test.convertToString(obj));
+ StringBuffer back = (StringBuffer) test.convertFromString(StringBuffer.class, "Hello");
+ assertEquals("Hello", back.toString());
+ }
+
+ @Test
+ public void test_StringBuilder() {
+ JDKStringConverter test = JDKStringConverter.STRING_BUILDER;
+ Object obj = new StringBuilder("Hello");
+ assertEquals(StringBuilder.class, test.getType());
+ assertEquals("Hello", test.convertToString(obj));
+ StringBuilder back = (StringBuilder) test.convertFromString(StringBuilder.class, "Hello");
+ assertEquals("Hello", back.toString());
+ }
+
+ @Test
+ public void test_CharSequence() {
+ JDKStringConverter test = JDKStringConverter.CHAR_SEQUENCE;
+ doTest(test, CharSequence.class, "Hello", "Hello");
+ doTest(test, CharSequence.class, new StringBuffer("Hello"), "Hello", "Hello");
+ doTest(test, CharSequence.class, new StringBuilder("Hello"), "Hello", "Hello");
+ }
+
+ @Test
+ public void test_Long() {
+ JDKStringConverter test = JDKStringConverter.LONG;
+ doTest(test, Long.class, Long.valueOf(12L), "12");
+ }
+
+ @Test
+ public void test_Int() {
+ JDKStringConverter test = JDKStringConverter.INTEGER;
+ doTest(test, Integer.class, Integer.valueOf(12), "12");
+ }
+
+ @Test
+ public void test_Short() {
+ JDKStringConverter test = JDKStringConverter.SHORT;
+ doTest(test, Short.class, Short.valueOf((byte) 12), "12");
+ }
+
+ @Test
+ public void test_Character() {
+ JDKStringConverter test = JDKStringConverter.CHARACTER;
+ doTest(test, Character.class, Character.valueOf('a'), "a");
+ doTest(test, Character.class, Character.valueOf('z'), "z");
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_Character_fail() {
+ JDKStringConverter.CHARACTER.convertFromString(Character.class, "RUBBISH");
+ }
+
+ @Test
+ public void test_Byte() {
+ JDKStringConverter test = JDKStringConverter.BYTE;
+ doTest(test, Byte.class, Byte.valueOf((byte) 12), "12");
+ }
+
+ @Test
+ public void test_Boolean() {
+ JDKStringConverter test = JDKStringConverter.BOOLEAN;
+ doTest(test, Boolean.class, Boolean.TRUE, "true");
+ doTest(test, Boolean.class, Boolean.FALSE, "false");
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_Boolean_fail() {
+ JDKStringConverter.BOOLEAN.convertFromString(Boolean.class, "RUBBISH");
+ }
+
+ @Test
+ public void test_Double() {
+ JDKStringConverter test = JDKStringConverter.DOUBLE;
+ doTest(test, Double.class, Double.valueOf(12.4d), "12.4");
+ }
+
+ @Test
+ public void test_Float() {
+ JDKStringConverter test = JDKStringConverter.FLOAT;
+ doTest(test, Float.class, Float.valueOf(12.2f), "12.2");
+ }
+
+ @Test
+ public void test_BigInteger() {
+ JDKStringConverter test = JDKStringConverter.BIG_INTEGER;
+ doTest(test, BigInteger.class, BigInteger.valueOf(12L), "12");
+ }
+
+ @Test
+ public void test_BigDecimal() {
+ JDKStringConverter test = JDKStringConverter.BIG_DECIMAL;
+ doTest(test, BigDecimal.class, BigDecimal.valueOf(12.23d), "12.23");
+ }
+
+ @Test
+ public void test_AtomicLong() {
+ JDKStringConverter test = JDKStringConverter.ATOMIC_LONG;
+ AtomicLong obj = new AtomicLong(12);
+ assertEquals(AtomicLong.class, test.getType());
+ assertEquals("12", test.convertToString(obj));
+ AtomicLong back = (AtomicLong) test.convertFromString(AtomicLong.class, "12");
+ assertEquals(12, back.get());
+ }
+
+ @Test
+ public void test_AtomicInteger() {
+ JDKStringConverter test = JDKStringConverter.ATOMIC_INTEGER;
+ AtomicInteger obj = new AtomicInteger(12);
+ assertEquals(AtomicInteger.class, test.getType());
+ assertEquals("12", test.convertToString(obj));
+ AtomicInteger back = (AtomicInteger) test.convertFromString(AtomicInteger.class, "12");
+ assertEquals(12, back.get());
+ }
+
+ @Test
+ public void test_AtomicBoolean_true() {
+ JDKStringConverter test = JDKStringConverter.ATOMIC_BOOLEAN;
+ AtomicBoolean obj = new AtomicBoolean(true);
+ assertEquals(AtomicBoolean.class, test.getType());
+ assertEquals("true", test.convertToString(obj));
+ AtomicBoolean back = (AtomicBoolean) test.convertFromString(AtomicBoolean.class, "true");
+ assertEquals(true, back.get());
+ }
+
+ @Test
+ public void test_AtomicBoolean_false() {
+ JDKStringConverter test = JDKStringConverter.ATOMIC_BOOLEAN;
+ AtomicBoolean obj = new AtomicBoolean(false);
+ assertEquals(AtomicBoolean.class, test.getType());
+ assertEquals("false", test.convertToString(obj));
+ AtomicBoolean back = (AtomicBoolean) test.convertFromString(AtomicBoolean.class, "false");
+ assertEquals(false, back.get());
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_AtomicBoolean_fail() {
+ JDKStringConverter.ATOMIC_BOOLEAN.convertFromString(AtomicBoolean.class, "RUBBISH");
+ }
+
+ @Test
+ public void test_Locale() {
+ JDKStringConverter test = JDKStringConverter.LOCALE;
+ doTest(test, Locale.class, new Locale("en"), "en");
+ doTest(test, Locale.class, new Locale("en", "GB"), "en_GB");
+ doTest(test, Locale.class, new Locale("en", "GB", "VARIANT_B"), "en_GB_VARIANT_B");
+ }
+
+ @Test
+ public void test_Class() {
+ JDKStringConverter test = JDKStringConverter.CLASS;
+ doTest(test, Class.class, Locale.class, "java.util.Locale");
+ doTest(test, Class.class, FromString.class, "org.joda.convert.FromString");
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Class_fail() {
+ JDKStringConverter.CLASS.convertFromString(Class.class, "RUBBISH");
+ }
+
+ @Test
+ public void test_Package() {
+ JDKStringConverter test = JDKStringConverter.PACKAGE;
+ doTest(test, Package.class, Locale.class.getPackage(), "java.util");
+ doTest(test, Package.class, FromString.class.getPackage(), "org.joda.convert");
+ }
+
+ @Test
+ public void test_Currency() {
+ JDKStringConverter test = JDKStringConverter.CURRENCY;
+ doTest(test, Currency.class, Currency.getInstance("GBP"), "GBP");
+ doTest(test, Currency.class, Currency.getInstance("USD"), "USD");
+ }
+
+ @Test
+ public void test_TimeZone() {
+ JDKStringConverter test = JDKStringConverter.TIME_ZONE;
+ doTest(test, TimeZone.class, TimeZone.getTimeZone("Europe/London"), "Europe/London");
+ doTest(test, TimeZone.class, TimeZone.getTimeZone("America/New_York"), "America/New_York");
+ }
+
+ @Test
+ public void test_UUID() {
+ JDKStringConverter test = JDKStringConverter.UUID;
+ UUID uuid = UUID.randomUUID();
+ doTest(test, UUID.class, uuid, uuid.toString());
+ }
+
+ @Test
+ public void test_URL() throws Exception {
+ JDKStringConverter test = JDKStringConverter.URL;
+ doTest(test, URL.class, new URL("http://localhost:8080/my/test"), "http://localhost:8080/my/test");
+ doTest(test, URL.class, new URL(null, "ftp:world"), "ftp:world");
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_URL_invalidFormat() {
+ JDKStringConverter.URL.convertFromString(URL.class, "RUBBISH:RUBBISH");
+ }
+
+ @Test
+ public void test_URI() {
+ JDKStringConverter test = JDKStringConverter.URI;
+ doTest(test, URI.class, URI.create("http://localhost:8080/my/test"), "http://localhost:8080/my/test");
+ doTest(test, URI.class, URI.create("/my/test"), "/my/test");
+ doTest(test, URI.class, URI.create("/my/../test"), "/my/../test");
+ doTest(test, URI.class, URI.create("urn:hello"), "urn:hello");
+ }
+
+ @Test
+ public void test_InetAddress() throws Exception {
+ JDKStringConverter test = JDKStringConverter.INET_ADDRESS;
+ doTest(test, InetAddress.class, InetAddress.getByName("1.2.3.4"), "1.2.3.4");
+ doTest(test, InetAddress.class, InetAddress.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), "2001:db8:85a3:0:0:8a2e:370:7334");
+ }
+
+// @Test(expected=RuntimeException.class)
+// public void test_InetAddress_invalidFormat() {
+// JDKStringConverter.INET_ADDRESS.convertFromString(InetAddress.class, "RUBBISH");
+// }
+
+ @Test
+ public void test_File() {
+ JDKStringConverter test = JDKStringConverter.FILE;
+ File file = new File("/path/to/file");
+ doTest(test, File.class, file, file.toString());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void test_Date() {
+ TimeZone zone = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("Europe/Paris"));
+ JDKStringConverter test = JDKStringConverter.DATE;
+ doTest(test, Date.class, new Date(2010 - 1900, 9 - 1, 3, 12, 34, 5), "2010-09-03T12:34:05.000+02:00");
+ doTest(test, Date.class, new Date(2011 - 1900, 1 - 1, 4, 12, 34, 5), "2011-01-04T12:34:05.000+01:00");
+ } finally {
+ TimeZone.setDefault(zone);
+ }
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Date_invalidLength() {
+ JDKStringConverter.DATE.convertFromString(Date.class, "2010-09-03");
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Date_invalidFormat() {
+ JDKStringConverter.DATE.convertFromString(Date.class, "2010-09-03XXX:34:05.000+02:00");
+ }
+
+ @Test
+ public void test_Calendar() {
+ JDKStringConverter test = JDKStringConverter.CALENDAR;
+ GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
+ cal.set(2010, 9 - 1, 3, 12, 34, 5);
+ cal.set(Calendar.MILLISECOND, 0);
+ doTest(test, Calendar.class, cal, "2010-09-03T12:34:05.000+02:00[Europe/Paris]");
+
+ GregorianCalendar cal2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
+ cal2.set(2011, 1 - 1, 4, 12, 34, 5);
+ cal2.set(Calendar.MILLISECOND, 0);
+ doTest(test, Calendar.class, cal2, "2011-01-04T12:34:05.000+01:00[Europe/Paris]");
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Calendar_invalidLength() {
+ JDKStringConverter.CALENDAR.convertFromString(GregorianCalendar.class, "2010-09-03");
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Calendar_invalidFormat() {
+ JDKStringConverter.CALENDAR.convertFromString(GregorianCalendar.class, "2010-09-03XXX:34:05.000+02:00[Europe/London]");
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Calendar_notGregorian() {
+ JDKStringConverter.CALENDAR.convertToString(new Calendar() {
+ private static final long serialVersionUID = 1L;
+ @Override
+ public void roll(int field, boolean up) {
+ }
+ @Override
+ public int getMinimum(int field) {
+ return 0;
+ }
+ @Override
+ public int getMaximum(int field) {
+ return 0;
+ }
+ @Override
+ public int getLeastMaximum(int field) {
+ return 0;
+ }
+ @Override
+ public int getGreatestMinimum(int field) {
+ return 0;
+ }
+ @Override
+ protected void computeTime() {
+ }
+ @Override
+ protected void computeFields() {
+ }
+ @Override
+ public void add(int field, int amount) {
+ }
+ });
+ }
+
+ @Test
+ public void test_Enum() {
+ JDKStringConverter test = JDKStringConverter.ENUM;
+ assertEquals(Enum.class, test.getType());
+ assertEquals("CEILING", test.convertToString(RoundingMode.CEILING));
+ assertEquals(RoundingMode.CEILING, test.convertFromString(RoundingMode.class, "CEILING"));
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void test_Enum_invalidConstant() {
+ JDKStringConverter.ENUM.convertFromString(RoundingMode.class, "RUBBISH");
+ }
+
+ //-----------------------------------------------------------------------
+ public void doTest(JDKStringConverter test, Class<?> cls, Object obj, String str) {
+ doTest(test, cls, obj, str, obj);
+ }
+
+ public void doTest(JDKStringConverter test, Class<?> cls, Object obj, String str, Object objFromStr) {
+ assertEquals(cls, test.getType());
+ assertEquals(str, test.convertToString(obj));
+ assertEquals(objFromStr, test.convertFromString(cls, str));
+ }
+
+}
diff --git a/src/test/java/org/joda/convert/TestStringConvert.java b/src/test/java/org/joda/convert/TestStringConvert.java
new file mode 100644
index 0000000..a893b5b
--- /dev/null
+++ b/src/test/java/org/joda/convert/TestStringConvert.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright 2010-2011 Stephen Colebourne
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.joda.convert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.math.RoundingMode;
+import java.text.ParseException;
+
+import org.junit.Test;
+
+/**
+ * Test StringConvert.
+ */
+public class TestStringConvert {
+
+ @Test
+ public void test_constructor() {
+ StringConvert test = new StringConvert();
+ StringConverter<?> conv = test.findConverter(Integer.class);
+ assertEquals(true, conv instanceof JDKStringConverter);
+ }
+
+ @Test
+ public void test_constructor_true() {
+ StringConvert test = new StringConvert(true);
+ StringConverter<?> conv = test.findConverter(Integer.class);
+ assertEquals(true, conv instanceof JDKStringConverter);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_constructor_false() {
+ StringConvert test = new StringConvert(false);
+ StringConverter<?> conv = test.findConverter(Integer.class);
+ assertEquals(null, conv);
+ }
+
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_convertToString() {
+ Integer i = 6;
+ assertEquals("6", StringConvert.INSTANCE.convertToString(i));
+ }
+
+ @Test
+ public void test_convertToString_primitive() {
+ int i = 6;
+ assertEquals("6", StringConvert.INSTANCE.convertToString(i));
+ }
+
+ @Test
+ public void test_convertToString_inherit() {
+ assertEquals("CEILING", StringConvert.INSTANCE.convertToString(RoundingMode.CEILING));
+ }
+
+ @Test
+ public void test_convertToString_null() {
+ assertEquals(null, StringConvert.INSTANCE.convertToString(null));
+ }
+
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_convertToString_withType() {
+ Integer i = 6;
+ assertEquals("6", StringConvert.INSTANCE.convertToString(Integer.class, i));
+ }
+
+ @Test
+ public void test_convertToString_withType_primitive1() {
+ int i = 6;
+ assertEquals("6", StringConvert.INSTANCE.convertToString(Integer.class, i));
+ }
+
+ @Test
+ public void test_convertToString_withType_primitive2() {
+ int i = 6;
+ assertEquals("6", StringConvert.INSTANCE.convertToString(Integer.TYPE, i));
+ }
+
+ @Test
+ public void test_convertToString_withType_inherit1() {
+ assertEquals("CEILING", StringConvert.INSTANCE.convertToString(RoundingMode.class, RoundingMode.CEILING));
+ }
+
+ @Test
+ public void test_convertToString_withType_inherit2() {
+ assertEquals("CEILING", StringConvert.INSTANCE.convertToString(Enum.class, RoundingMode.CEILING));
+ }
+
+ @Test
+ public void test_convertToString_withType_null() {
+ assertEquals(null, StringConvert.INSTANCE.convertToString(Integer.class, null));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void test_convertToString_withType_nullClass() {
+ assertEquals(null, StringConvert.INSTANCE.convertToString(null, "6"));
+ }
+
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_convertFromString() {
+ assertEquals(Integer.valueOf(6), StringConvert.INSTANCE.convertFromString(Integer.class, "6"));
+ }
+
+ @Test
+ public void test_convertFromString_primitiveInt() {
+ assertEquals(Integer.valueOf(6), StringConvert.INSTANCE.convertFromString(Integer.TYPE, "6"));
+ }
+
+ @Test
+ public void test_convertFromString_primitiveBoolean() {
+ assertEquals(Boolean.TRUE, StringConvert.INSTANCE.convertFromString(Boolean.TYPE, "true"));
+ }
+
+ @Test
+ public void test_convertFromString_inherit() {
+ assertEquals(RoundingMode.CEILING, StringConvert.INSTANCE.convertFromString(RoundingMode.class, "CEILING"));
+ }
+
+ @Test
+ public void test_convertFromString_null() {
+ assertEquals(null, StringConvert.INSTANCE.convertFromString(Integer.class, null));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void test_convertFromString_nullClass() {
+ assertEquals(null, StringConvert.INSTANCE.convertFromString(null, "6"));
+ }
+
+ //-----------------------------------------------------------------------
+ @Test(expected=IllegalArgumentException.class)
+ public void test_findConverter_null() {
+ StringConvert.INSTANCE.findConverter(null);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_findConverter_Object() {
+ StringConvert.INSTANCE.findConverter(Object.class);
+ }
+
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_convert_annotationMethodMethod() {
+ StringConvert test = new StringConvert();
+ DistanceMethodMethod d = new DistanceMethodMethod(25);
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceMethodMethod.class, "25m").amount);
+ StringConverter<DistanceMethodMethod> conv = test.findConverter(DistanceMethodMethod.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceMethodMethod.class));
+ assertEquals(true, conv.toString().startsWith("RefectionStringConverter"));
+ }
+
+ @Test
+ public void test_convert_annotationMethodMethodCharSequence() {
+ StringConvert test = new StringConvert();
+ DistanceMethodMethodCharSequence d = new DistanceMethodMethodCharSequence(25);
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceMethodMethodCharSequence.class, "25m").amount);
+ StringConverter<DistanceMethodMethodCharSequence> conv = test.findConverter(DistanceMethodMethodCharSequence.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceMethodMethodCharSequence.class));
+ assertEquals(true, conv.toString().startsWith("RefectionStringConverter"));
+ }
+
+ @Test
+ public void test_convert_annotationMethodConstructor() {
+ StringConvert test = new StringConvert();
+ DistanceMethodConstructor d = new DistanceMethodConstructor(25);
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceMethodConstructor.class, "25m").amount);
+ StringConverter<DistanceMethodConstructor> conv = test.findConverter(DistanceMethodConstructor.class);
+ assertEquals(true, conv instanceof MethodConstructorStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceMethodConstructor.class));
+ assertEquals(true, conv.toString().startsWith("RefectionStringConverter"));
+ }
+
+ @Test
+ public void test_convert_annotationMethodConstructorCharSequence() {
+ StringConvert test = new StringConvert();
+ DistanceMethodConstructorCharSequence d = new DistanceMethodConstructorCharSequence(25);
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceMethodConstructorCharSequence.class, "25m").amount);
+ StringConverter<DistanceMethodConstructorCharSequence> conv = test.findConverter(DistanceMethodConstructorCharSequence.class);
+ assertEquals(true, conv instanceof MethodConstructorStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceMethodConstructorCharSequence.class));
+ assertEquals(true, conv.toString().startsWith("RefectionStringConverter"));
+ }
+
+ @Test
+ public void test_convert_annotationSubMethodMethod() {
+ StringConvert test = new StringConvert();
+ SubMethodMethod d = new SubMethodMethod(25);
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(SubMethodMethod.class, "25m").amount);
+ StringConverter<SubMethodMethod> conv = test.findConverter(SubMethodMethod.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(SubMethodMethod.class));
+ }
+
+ @Test
+ public void test_convert_annotationSubMethodConstructor() {
+ StringConvert test = new StringConvert();
+ SubMethodConstructor d = new SubMethodConstructor("25m");
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(SubMethodConstructor.class, "25m").amount);
+ StringConverter<SubMethodConstructor> conv = test.findConverter(SubMethodConstructor.class);
+ assertEquals(true, conv instanceof MethodConstructorStringConverter<?>);
+ assertSame(conv, test.findConverter(SubMethodConstructor.class));
+ }
+
+ @Test
+ public void test_convert_annotationSuperFactorySuper() {
+ StringConvert test = new StringConvert();
+ SuperFactorySuper d = new SuperFactorySuper(25);
+ assertEquals("25m", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(SuperFactorySuper.class, "25m").amount);
+ StringConverter<SuperFactorySuper> conv = test.findConverter(SuperFactorySuper.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(SuperFactorySuper.class));
+ }
+
+ @Test
+ public void test_convert_annotationSuperFactorySubViaSuper() {
+ StringConvert test = new StringConvert();
+ SuperFactorySub d = new SuperFactorySub(8);
+ assertEquals("8m", test.convertToString(d));
+ SuperFactorySuper fromStr = test.convertFromString(SuperFactorySuper.class, "8m");
+ assertEquals(d.amount, fromStr.amount);
+ assertEquals(true, fromStr instanceof SuperFactorySub);
+ StringConverter<SuperFactorySuper> conv = test.findConverter(SuperFactorySuper.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(SuperFactorySuper.class));
+ }
+
+ @Test
+ public void test_convert_annotationSuperFactorySubViaSub1() {
+ StringConvert test = new StringConvert();
+ SuperFactorySub d = new SuperFactorySub(25);
+ assertEquals("25m", test.convertToString(d));
+ }
+
+ // TODO problem is fwks, that just request a converter baed on the type of the object
+ @Test(expected = ClassCastException.class)
+ public void test_convert_annotationSuperFactorySubViaSub2() {
+ StringConvert test = new StringConvert();
+ test.convertFromString(SuperFactorySub.class, "25m");
+ }
+
+ @Test
+ public void test_convert_annotationToStringInvokeException() {
+ StringConvert test = new StringConvert();
+ DistanceToStringException d = new DistanceToStringException(25);
+ StringConverter<DistanceToStringException> conv = test.findConverter(DistanceToStringException.class);
+ try {
+ conv.convertToString(d);
+ fail();
+ } catch (RuntimeException ex) {
+ assertEquals(ParseException.class, ex.getCause().getClass());
+ }
+ }
+
+ @Test
+ public void test_convert_annotationFromStringInvokeException() {
+ StringConvert test = new StringConvert();
+ StringConverter<DistanceFromStringException> conv = test.findConverter(DistanceFromStringException.class);
+ try {
+ conv.convertFromString(DistanceFromStringException.class, "25m");
+ fail();
+ } catch (RuntimeException ex) {
+ assertEquals(ParseException.class, ex.getCause().getClass());
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotationNoMethods() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceNoAnnotations.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedMethodAndConstructor() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceMethodAndConstructorAnnotations.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedTwoToString() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceTwoToStringAnnotations.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedToStringInvalidReturnType() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceToStringInvalidReturnType.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedToStringInvalidParameters() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceToStringInvalidParameters.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedFromStringInvalidReturnType() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceFromStringInvalidReturnType.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedFromStringInvalidParameter() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceFromStringInvalidParameter.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedFromStringInvalidParameterCount() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceFromStringInvalidParameterCount.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedFromStringConstructorInvalidParameter() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceFromStringConstructorInvalidParameter.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedFromStringConstructorInvalidParameterCount() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceFromStringConstructorInvalidParameterCount.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedToStringNoFromString() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceToStringNoFromString.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedFromStringNoToString() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceFromStringNoToString.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_convert_annotatedTwoFromStringMethod() {
+ StringConvert test = new StringConvert();
+ test.findConverter(DistanceTwoFromStringMethodAnnotations.class);
+ }
+
+ //-----------------------------------------------------------------------
+ @Test(expected=IllegalArgumentException.class)
+ public void test_register_classNotNull() {
+ StringConvert.INSTANCE.register(null, MockIntegerStringConverter.INSTANCE);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_register_converterNotNull() {
+ StringConvert.INSTANCE.register(Integer.class, null);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_register_notOnShared() {
+ StringConvert.INSTANCE.register(Integer.class, MockIntegerStringConverter.INSTANCE);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_register_classAlreadyRegistered() {
+ new StringConvert().register(Integer.class, MockIntegerStringConverter.INSTANCE);
+ }
+
+ public void test_register_distance() {
+ StringConvert test = new StringConvert();
+ test.register(DistanceMethodMethod.class, MockDistanceStringConverter.INSTANCE);
+ assertSame(MockDistanceStringConverter.INSTANCE, test.findConverter(DistanceMethodMethod.class));
+ }
+
+ //-------------------------------------------------------------------------
+ @Test
+ public void test_registerMethods() {
+ StringConvert test = new StringConvert();
+ test.registerMethods(DistanceNoAnnotations.class, "toString", "parse");
+ DistanceNoAnnotations d = new DistanceNoAnnotations(25);
+ assertEquals("Distance[25m]", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceNoAnnotations.class, "25m").amount);
+ StringConverter<DistanceNoAnnotations> conv = test.findConverter(DistanceNoAnnotations.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceNoAnnotations.class));
+ }
+
+ @Test
+ public void test_registerMethodsCharSequence() {
+ StringConvert test = new StringConvert();
+ test.registerMethods(DistanceNoAnnotationsCharSequence.class, "toString", "parse");
+ DistanceNoAnnotationsCharSequence d = new DistanceNoAnnotationsCharSequence(25);
+ assertEquals("Distance[25m]", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceNoAnnotationsCharSequence.class, "25m").amount);
+ StringConverter<DistanceNoAnnotationsCharSequence> conv = test.findConverter(DistanceNoAnnotationsCharSequence.class);
+ assertEquals(true, conv instanceof MethodsStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceNoAnnotationsCharSequence.class));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_registerMethods_nullClass() {
+ StringConvert test = new StringConvert();
+ test.registerMethods(null, "toString", "parse");
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_registerMethods_nullToString() {
+ StringConvert test = new StringConvert();
+ test.registerMethods(DistanceNoAnnotations.class, null, "parse");
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_registerMethods_nullFromString() {
+ StringConvert test = new StringConvert();
+ test.registerMethods(DistanceNoAnnotations.class, "toString", null);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_registerMethods_classAlreadyRegistered() {
+ StringConvert test = new StringConvert();
+ test.registerMethods(DistanceNoAnnotations.class, "toString", "parse");
+ test.registerMethods(DistanceNoAnnotations.class, "toString", "parse");
+ }
+
+ //-------------------------------------------------------------------------
+ @Test
+ public void test_registerMethodConstructorCharSequence() {
+ StringConvert test = new StringConvert();
+ test.registerMethodConstructor(DistanceNoAnnotationsCharSequence.class, "toString");
+ DistanceNoAnnotationsCharSequence d = new DistanceNoAnnotationsCharSequence(25);
+ assertEquals("Distance[25m]", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceNoAnnotationsCharSequence.class, "25m").amount);
+ StringConverter<DistanceNoAnnotationsCharSequence> conv = test.findConverter(DistanceNoAnnotationsCharSequence.class);
+ assertEquals(true, conv instanceof MethodConstructorStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceNoAnnotationsCharSequence.class));
+ }
+
+ @Test
+ public void test_registerMethodConstructor() {
+ StringConvert test = new StringConvert();
+ test.registerMethodConstructor(DistanceNoAnnotations.class, "toString");
+ DistanceNoAnnotations d = new DistanceNoAnnotations(25);
+ assertEquals("Distance[25m]", test.convertToString(d));
+ assertEquals(d.amount, test.convertFromString(DistanceNoAnnotations.class, "25m").amount);
+ StringConverter<DistanceNoAnnotations> conv = test.findConverter(DistanceNoAnnotations.class);
+ assertEquals(true, conv instanceof MethodConstructorStringConverter<?>);
+ assertSame(conv, test.findConverter(DistanceNoAnnotations.class));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_registerMethodConstructor_nullClass() {
+ StringConvert test = new StringConvert();
+ test.registerMethodConstructor(null, "toString");
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void test_registerMethodConstructor_nullToString() {
+ StringConvert test = new StringConvert();
+ test.registerMethodConstructor(DistanceNoAnnotations.class, null);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void test_registerMethodConstructor_classAlreadyRegistered() {
+ StringConvert test = new StringConvert();
+ test.registerMethodConstructor(DistanceNoAnnotations.class, "toString");
+ test.registerMethodConstructor(DistanceNoAnnotations.class, "toString");
+ }
+
+ //-----------------------------------------------------------------------
+ @Test
+ public void test_convert_toString() {
+ assertEquals("StringConvert", new StringConvert().toString());
+ }
+
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/joda-convert.git
More information about the pkg-java-commits
mailing list