Codebase list joda-convert / cd97ceb
Updated version 1.9.2 from 'upstream/1.9.2' with Debian dir ad682d68574aaf2c28d3b3fc601f94973f7ded0e Emmanuel Bourg 6 years ago
12 changed file(s) with 422 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
11 language: java
22 jdk:
33 - oraclejdk8
4 - oraclejdk7
5 - openjdk6
4 - openjdk7
65 cache:
76 directories:
87 - "$HOME/.m2/repository"
5151
5252
5353 ### Releases
54 [Release 1.8.3](http://www.joda.org/joda-convert/download.html) is the current latest release.
54 [Release 1.9.2](http://www.joda.org/joda-convert/download.html) is the current latest release.
5555 This release is considered stable and worthy of the 1.x tag.
5656 It depends on Java SE 6 or later.
5757
58 Available in the [Maven Central repository](http://search.maven.org/#artifactdetails|org.joda|joda-convert|1.8.3|jar)
58 Available in the [Maven Central repository](http://search.maven.org/#artifactdetails|org.joda|joda-convert|1.9.2|jar)
5959
6060
6161 ### Support
88 <artifactId>joda-convert</artifactId>
99 <packaging>jar</packaging>
1010 <name>Joda-Convert</name>
11 <version>1.8.3</version>
11 <version>1.9.2</version>
1212 <description>Library to convert Objects to and from String</description>
1313 <url>http://www.joda.org/joda-convert/</url>
1414
146146 <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
147147 <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
148148 </manifest>
149 <manifestEntries>
150 <Automatic-Module-Name>org.joda.convert</Automatic-Module-Name>
151 </manifestEntries>
149152 </archive>
150153 </configuration>
151154 </plugin>
566569 <version>1.1.1</version>
567570 <configuration>
568571 <releaseName>Release v${project.version}</releaseName>
569 <description>See the [change notes](http://www.joda.org/joda-beans/changes-report.html) for more information.</description>
572 <description>See the [change notes](http://www.joda.org/joda-convert/changes-report.html) for more information.</description>
570573 <tag>v${project.version}</tag>
571574 <overwriteArtifact>true</overwriteArtifact>
572575 <fileSets>
66
77 <body>
88 <!-- types are add, fix, remove, update -->
9 <release version="1.9.2" date="2017-09-20" description="Version 1.9.2">
10 <action dev="jodastephen" type="fix" >
11 Standard subclass of `TimeZone` must be explicitly registered.
12 </action>
13 </release>
14 <release version="1.9.1" date="2017-09-20" description="Version 1.9.1">
15 <action dev="jodastephen" type="fix" >
16 Add `Automatic-Module-Name` into `MANIFEST.MF`.
17 Locks in module name for Java SE 9.
18 Fixes #17.
19 </action>
20 </release>
21 <release version="1.9" date="2017-09-18" description="Version 1.9">
22 <action dev="jodastephen" type="fix" >
23 Change converter search to not look at superclasses and interfaces.
24 Looking at these was fine for `convertToString`, but not for `convertFromString`.
25 This change should be compatible for most use cases, but will be incompatible for others.
26 If the new release is incompatible, you will need to register an additional converter for the supertype.
27 Fixes #15.
28 </action>
29 <action dev="jodastephen" type="add" >
30 Add support for Java 8 primitive optional types - `OptionalInt`, `OptionalLong`, `OptionalDouble`.
31 These are supported by reflection - Joda-Convert still supports Java 1.6.
32 Fixes #9.
33 </action>
34 </release>
935 <release version="1.8.3" date="2017-08-21" description="Version 1.8.3">
1036 <action dev="jodastephen" type="update" >
1137 Optional Guava dependency updated to v20.0.
0 /*
1 * Copyright 2010-present Stephen Colebourne
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.joda.convert;
16
17 import java.lang.reflect.Method;
18
19 /**
20 * Parse the string format of OptionalDouble from Java 8.
21 * <p>
22 * This is loaded by reflection only when using Java 8.
23 */
24 final class OptionalDoubleStringConverter
25 extends AbstractTypeStringConverter
26 implements TypedStringConverter<Object> {
27
28 private static final Class<?> TYPE;
29 private static final Object EMPTY;
30 private static final Method METHOD_OF;
31 private static final Method METHOD_IS_PRESENT;
32 private static final Method METHOD_GET;
33 static {
34 try {
35 TYPE = Class.forName("java.util.OptionalDouble");
36 EMPTY = TYPE.getDeclaredMethod("empty").invoke(null);
37 METHOD_OF = TYPE.getDeclaredMethod("of", double.class);
38 METHOD_IS_PRESENT = TYPE.getDeclaredMethod("isPresent");
39 METHOD_GET = TYPE.getDeclaredMethod("getAsDouble");
40
41 } catch (Exception ex) {
42 throw new IllegalStateException(ex);
43 }
44 }
45
46 OptionalDoubleStringConverter() {
47 }
48
49 @Override
50 public String convertToString(Object object) {
51 try {
52 Object isPresent = METHOD_IS_PRESENT.invoke(object);
53 return Boolean.TRUE.equals(isPresent) ? String.valueOf(METHOD_GET.invoke(object)) : "";
54 } catch (Exception ex) {
55 throw new IllegalArgumentException(ex);
56 }
57 }
58
59 @Override
60 public Object convertFromString(Class<? extends Object> cls, String str) {
61 if ("".equals(str)) {
62 return EMPTY;
63 }
64 double value = Double.parseDouble(str);
65 try {
66 return METHOD_OF.invoke(null, value);
67 } catch (Exception ex) {
68 throw new IllegalArgumentException(ex);
69 }
70 }
71
72 @Override
73 public Class<?> getEffectiveType() {
74 return TYPE;
75 }
76
77 }
0 /*
1 * Copyright 2010-present Stephen Colebourne
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.joda.convert;
16
17 import java.lang.reflect.Method;
18
19 /**
20 * Parse the string format of OptionalInt from Java 8.
21 * <p>
22 * This is loaded by reflection only when using Java 8.
23 */
24 final class OptionalIntStringConverter
25 extends AbstractTypeStringConverter
26 implements TypedStringConverter<Object> {
27
28 private static final Class<?> TYPE;
29 private static final Object EMPTY;
30 private static final Method METHOD_OF;
31 private static final Method METHOD_IS_PRESENT;
32 private static final Method METHOD_GET;
33 static {
34 try {
35 TYPE = Class.forName("java.util.OptionalInt");
36 EMPTY = TYPE.getDeclaredMethod("empty").invoke(null);
37 METHOD_OF = TYPE.getDeclaredMethod("of", int.class);
38 METHOD_IS_PRESENT = TYPE.getDeclaredMethod("isPresent");
39 METHOD_GET = TYPE.getDeclaredMethod("getAsInt");
40
41 } catch (Exception ex) {
42 throw new IllegalStateException(ex);
43 }
44 }
45
46 OptionalIntStringConverter() {
47 }
48
49 @Override
50 public String convertToString(Object object) {
51 try {
52 Object isPresent = METHOD_IS_PRESENT.invoke(object);
53 return Boolean.TRUE.equals(isPresent) ? String.valueOf(METHOD_GET.invoke(object)) : "";
54 } catch (Exception ex) {
55 throw new IllegalArgumentException(ex);
56 }
57 }
58
59 @Override
60 public Object convertFromString(Class<? extends Object> cls, String str) {
61 if ("".equals(str)) {
62 return EMPTY;
63 }
64 int value = Integer.parseInt(str);
65 try {
66 return METHOD_OF.invoke(null, value);
67 } catch (Exception ex) {
68 throw new IllegalArgumentException(ex);
69 }
70 }
71
72 @Override
73 public Class<?> getEffectiveType() {
74 return TYPE;
75 }
76
77 }
0 /*
1 * Copyright 2010-present Stephen Colebourne
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.joda.convert;
16
17 import java.lang.reflect.Method;
18
19 /**
20 * Parse the string format of OptionalLong from Java 8.
21 * <p>
22 * This is loaded by reflection only when using Java 8.
23 */
24 final class OptionalLongStringConverter
25 extends AbstractTypeStringConverter
26 implements TypedStringConverter<Object> {
27
28 private static final Class<?> TYPE;
29 private static final Object EMPTY;
30 private static final Method METHOD_OF;
31 private static final Method METHOD_IS_PRESENT;
32 private static final Method METHOD_GET;
33 static {
34 try {
35 TYPE = Class.forName("java.util.OptionalLong");
36 EMPTY = TYPE.getDeclaredMethod("empty").invoke(null);
37 METHOD_OF = TYPE.getDeclaredMethod("of", long.class);
38 METHOD_IS_PRESENT = TYPE.getDeclaredMethod("isPresent");
39 METHOD_GET = TYPE.getDeclaredMethod("getAsLong");
40
41 } catch (Exception ex) {
42 throw new IllegalStateException(ex);
43 }
44 }
45
46 OptionalLongStringConverter() {
47 }
48
49 @Override
50 public String convertToString(Object object) {
51 try {
52 Object isPresent = METHOD_IS_PRESENT.invoke(object);
53 return Boolean.TRUE.equals(isPresent) ? String.valueOf(METHOD_GET.invoke(object)) : "";
54 } catch (Exception ex) {
55 throw new IllegalArgumentException(ex);
56 }
57 }
58
59 @Override
60 public Object convertFromString(Class<? extends Object> cls, String str) {
61 if ("".equals(str)) {
62 return EMPTY;
63 }
64 long value = Long.parseLong(str);
65 try {
66 return METHOD_OF.invoke(null, value);
67 } catch (Exception ex) {
68 throw new IllegalArgumentException(ex);
69 }
70 }
71
72 @Override
73 public Class<?> getEffectiveType() {
74 return TYPE;
75 }
76
77 }
1818 import java.lang.reflect.Method;
1919 import java.lang.reflect.Modifier;
2020 import java.util.Arrays;
21 import java.util.SimpleTimeZone;
22 import java.util.TimeZone;
2123 import java.util.concurrent.ConcurrentHashMap;
2224 import java.util.concurrent.ConcurrentMap;
2325 import java.util.concurrent.CopyOnWriteArrayList;
153155 registered.put(Float.TYPE, JDKStringConverter.FLOAT);
154156 registered.put(Double.TYPE, JDKStringConverter.DOUBLE);
155157 registered.put(Character.TYPE, JDKStringConverter.CHARACTER);
156 // Guava
158 // Guava and Java 8
157159 tryRegisterGuava();
160 tryRegisterJava8Optionals();
161 tryRegisterTimeZone();
158162 // JDK 1.8 classes
159163 tryRegister("java.time.Instant", "parse");
160164 tryRegister("java.time.Duration", "parse");
214218
215219 /**
216220 * Tries to register the Guava converters class.
217 *
218 * @param className the class name, not null
219221 */
220222 private void tryRegisterGuava() {
221223 try {
238240 }
239241
240242 /**
243 * Tries to register the Java 8 optional classes.
244 */
245 private void tryRegisterJava8Optionals() {
246 try {
247 RenameHandler.INSTANCE.loadType("java.util.OptionalInt");
248 @SuppressWarnings("unchecked")
249 Class<?> cls1 = (Class<TypedStringConverter<?>>) RenameHandler.INSTANCE
250 .loadType("org.joda.convert.OptionalIntStringConverter");
251 TypedStringConverter<?> conv1 = (TypedStringConverter<?>) cls1.newInstance();
252 registered.put(conv1.getEffectiveType(), conv1);
253
254 @SuppressWarnings("unchecked")
255 Class<?> cls2 = (Class<TypedStringConverter<?>>) RenameHandler.INSTANCE
256 .loadType("org.joda.convert.OptionalLongStringConverter");
257 TypedStringConverter<?> conv2 = (TypedStringConverter<?>) cls2.newInstance();
258 registered.put(conv2.getEffectiveType(), conv2);
259
260 @SuppressWarnings("unchecked")
261 Class<?> cls3 = (Class<TypedStringConverter<?>>) RenameHandler.INSTANCE
262 .loadType("org.joda.convert.OptionalDoubleStringConverter");
263 TypedStringConverter<?> conv3 = (TypedStringConverter<?>) cls3.newInstance();
264 registered.put(conv3.getEffectiveType(), conv3);
265
266 } catch (Throwable ex) {
267 // ignore
268 }
269 }
270
271 /**
272 * Tries to register the subclasses of TimeZone.
273 * Try various things, doesn't matter if the map entry gets overwritten.
274 */
275 private void tryRegisterTimeZone() {
276 try {
277 registered.put(SimpleTimeZone.class, JDKStringConverter.TIME_ZONE);
278
279 } catch (Throwable ex) {
280 // ignore
281 }
282 try {
283 TimeZone zone = TimeZone.getDefault();
284 registered.put(zone.getClass(), JDKStringConverter.TIME_ZONE);
285
286 } catch (Throwable ex) {
287 // ignore
288 }
289 try {
290 TimeZone zone = TimeZone.getTimeZone("Europe/London");
291 registered.put(zone.getClass(), JDKStringConverter.TIME_ZONE);
292
293 } catch (Throwable ex) {
294 // ignore
295 }
296 }
297
298 /**
241299 * Tries to register a class using the standard toString/parse pattern.
242300 *
243301 * @param className the class name, not null
335393 * This returns an instance of {@code StringConverter} for the specified class.
336394 * This is designed for user code where the {@code Class} object generics is known.
337395 * <p>
338 * The search algorithm first searches the registered converters in the
339 * class hierarchy and immediate parent interfaces.
396 * The search algorithm first searches the registered converters.
340397 * It then searches for {@code ToString} and {@code FromString} annotations on the
341398 * specified class, class hierarchy or immediate parent interfaces.
342399 * Finally, it handles {@code Enum} instances.
358415 * The returned type is declared with {@code Object} instead of '?' to
359416 * allow the {@link ToStringConverter} to be invoked.
360417 * <p>
361 * The search algorithm first searches the registered converters in the
362 * class hierarchy and immediate parent interfaces.
418 * The search algorithm first searches the registered converters.
363419 * It then searches for {@code ToString} and {@code FromString} annotations on the
364420 * specified class, class hierarchy or immediate parent interfaces.
365421 * Finally, it handles {@code Enum} instances.
379435 * This returns an instance of {@code TypedStringConverter} for the specified class.
380436 * This is designed for user code where the {@code Class} object generics is known.
381437 * <p>
382 * The search algorithm first searches the registered converters in the
383 * class hierarchy and immediate parent interfaces.
438 * The search algorithm first searches the registered converters.
384439 * It then searches for {@code ToString} and {@code FromString} annotations on the
385440 * specified class, class hierarchy or immediate parent interfaces.
386441 * Finally, it handles {@code Enum} instances.
414469 * The returned type is declared with {@code Object} instead of '?' to
415470 * allow the {@link ToStringConverter} to be invoked.
416471 * <p>
417 * The search algorithm first searches the registered converters in the
418 * class hierarchy and immediate parent interfaces.
472 * The search algorithm first searches the registered converters.
419473 * It then searches for {@code ToString} and {@code FromString} annotations on the
420474 * specified class, class hierarchy or immediate parent interfaces.
421475 * Finally, it handles {@code Enum} instances.
484538 */
485539 @SuppressWarnings("unchecked")
486540 private <T> TypedStringConverter<T> findAnyConverter(final Class<T> cls) {
487 TypedStringConverter<T> conv = null;
488 // check for registered on superclass
489 Class<?> loopCls = cls.getSuperclass();
490 while (loopCls != null && conv == null) {
491 conv = (TypedStringConverter<T>) registered.get(loopCls);
492 if (conv != null && conv != CACHED_NULL) {
493 return conv;
494 }
495 loopCls = loopCls.getSuperclass();
496 }
497 // check for registered on interfaces
498 for (Class<?> loopIfc : cls.getInterfaces()) {
499 conv = (TypedStringConverter<T>) registered.get(loopIfc);
500 if (conv != null && conv != CACHED_NULL) {
501 return conv;
502 }
503 }
504541 // check factories
505542 for (StringConverterFactory factory : factories) {
506543 StringConverter<T> factoryConv = (StringConverter<T>) factory.findConverter(cls);
7575
7676 ## <i></i> Releases
7777
78 [Release 1.8.3](download.html) is the current latest release.
78 [Release 1.9.2](download.html) is the current latest release.
7979 This release is considered stable and worthy of the 1.x tag.
8080
8181 Joda-Convert requires Java SE 6 or later and has [no dependencies](dependencies.html).
8282
83 Available in [Maven Central](http://search.maven.org/#artifactdetails%7Corg.joda%7Cjoda-convert%7C1.8.3%7Cjar).
83 Available in [Maven Central](http://search.maven.org/#artifactdetails%7Corg.joda%7Cjoda-convert%7C1.9.2%7Cjar).
8484
8585 ```xml
8686 <dependency>
8787 <groupId>org.joda</groupId>
8888 <artifactId>joda-convert</artifactId>
89 <version>1.8.3</version>
89 <version>1.9.2</version>
9090 </dependency>
9191 ```
9292
0 /*
1 * Copyright 2010-present Stephen Colebourne
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.joda.convert;
16
17 /**
18 * Alternate {@link CharSequence}.
19 */
20 public class AltCharSequence implements CharSequence {
21
22 @Override
23 public int length() {
24 return 1;
25 }
26
27 @Override
28 public char charAt(int index) {
29 return 'A';
30 }
31
32 @Override
33 public CharSequence subSequence(int start, int end) {
34 throw new IndexOutOfBoundsException();
35 }
36
37 }
148148 }
149149
150150 @Test
151 public void test_convertFromString_enumSubclass() {
152 assertEquals(ValidityCheck.VALID, StringConvert.INSTANCE.convertFromString(ValidityCheck.class, "VALID"));
153 }
154
155 @Test
151156 public void test_convertFromString_inherit() {
152157 assertEquals(RoundingMode.CEILING, StringConvert.INSTANCE.convertFromString(RoundingMode.class, "CEILING"));
158 }
159
160 @Test(expected=RuntimeException.class)
161 public void test_convertFromString_inheritNotSearchedFor() {
162 StringConvert.INSTANCE.convertFromString(AltCharSequence.class, "A");
153163 }
154164
155165 @Test
0 /*
1 * Copyright 2010-present Stephen Colebourne
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.joda.convert;
16
17 /**
18 * Mock enum with subclasses.
19 */
20 public enum ValidityCheck {
21
22 VALID {
23 @Override
24 public int count() {
25 return 0;
26 }
27 },
28 INVALID {
29 @Override
30 public int count() {
31 return 0;
32 }
33 };
34
35 public abstract int count();
36
37 }