joda-convert-1.8.1/ 0000775 0001750 0001750 00000000000 12603461407 013451 5 ustar ebourg ebourg joda-convert-1.8.1/.travis.yml 0000664 0001750 0001750 00000000467 12603461407 015571 0 ustar ebourg ebourg # This file enables the Travis continuous integration system, which
# automatically builds and tests joda-convert for each GitHub commit or
# pull request on three separate JDKs.
#
# For more information, see https://travis-ci.org
sudo: false
language: java
jdk:
- oraclejdk8
- oraclejdk7
- openjdk6
joda-convert-1.8.1/README.md 0000664 0001750 0001750 00000004422 12603461407 014732 0 ustar ebourg ebourg Joda-Convert
------------
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.
```java
// conversion to String
String str = StringConvert.INSTANCE.convertToString(foo);
// conversion from String
Foo bar = StringConvert.INSTANCE.convertFromString(Foo.class, str);
```
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.
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 Currency
or TimeZone
, already have methods
to convert to and from a standard format String.
Consider a Distance
class:
```java
public class Distance {
@FromString
public static Distance parse(String str) { ... }
@ToString
public String getStandardOutput() { ... }
}
```
As shown, the two methods may have any name. They must simply fulfil the required method signatures for conversion.
The FromString
annotation may also be applied to a constructor.
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.
Joda-Convert is licensed under the business-friendly [Apache 2.0 licence](http://www.joda.org/joda-convert/license.html).
### Documentation
Various documentation is available:
* The [home page](http://www.joda.org/joda-convert/)
* The helpful [user guide](http://www.joda.org/joda-convert/userguide.html)
* The [Javadoc](http://www.joda.org/joda-convert/apidocs/index.html)
* The change notes for the [releases](http://www.joda.org/joda-convert/changes-report.html)
### Releases
[Release 1.8.1](http://www.joda.org/joda-convert/download.html) is the current latest release.
This release is considered stable and worthy of the 1.x tag.
It depends on Java SE 6 or later.
Available in the [Maven Central repository](http://search.maven.org/#artifactdetails|org.joda|joda-convert|1.8.1|jar)
### Support
Please use GitHub issues and Pull Requests for support.
joda-convert-1.8.1/src/ 0000775 0001750 0001750 00000000000 12603461407 014240 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/ 0000775 0001750 0001750 00000000000 12603461407 015164 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/checkstyle/ 0000775 0001750 0001750 00000000000 12603461407 017322 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/checkstyle/checkstyle.xml 0000664 0001750 0001750 00000013516 12603461407 022210 0 ustar ebourg ebourg
joda-convert-1.8.1/src/main/java/ 0000775 0001750 0001750 00000000000 12603461407 016105 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/java/org/ 0000775 0001750 0001750 00000000000 12603461407 016674 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/java/org/joda/ 0000775 0001750 0001750 00000000000 12603461407 017611 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/java/org/joda/convert/ 0000775 0001750 0001750 00000000000 12603461407 021271 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/java/org/joda/convert/RenameHandler.java 0000664 0001750 0001750 00000016603 12603461407 024647 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* A general purpose utility for registering renames.
*
* This handles type and enum constant renames.
* For example, use as follows:
*
* RenameHandler.INSTANCE.renamedType("org.joda.OldName", NewName.class);
* RenameHandler.INSTANCE.renamedEnum("CORRECT", Status.VALID);
* RenameHandler.INSTANCE.renamedEnum("INCORRECT", Status.INVALID);
*
* The recommended usage is to edit the static singleton before using other classes.
* Editing a static is acceptable because renames are driven by bytecode which is static.
*
* This class is thread-safe with concurrent caches.
*
* @since 1.6
*/
public final class RenameHandler {
/**
* A mutable global instance.
* This is a singleton instance which is mutated.
*/
public static final RenameHandler INSTANCE = new RenameHandler();
/**
* The type renames.
*/
private final ConcurrentHashMap> typeRenames =
new ConcurrentHashMap>(16, 0.75f, 2);
/**
* The enum renames.
*/
private final ConcurrentHashMap, Map>> enumRenames =
new ConcurrentHashMap, Map>>(16, 0.75f, 2);
//-----------------------------------------------------------------------
/**
* Creates an instance.
*
* This is not normally used as the preferred option is to edit the singleton.
*
* @return a new instance, not null
*/
public static RenameHandler create() {
return new RenameHandler();
}
//-----------------------------------------------------------------------
/**
* Restricted constructor.
*/
private RenameHandler() {
}
//-----------------------------------------------------------------------
/**
* Register the fact that a type was renamed.
*
* @param oldName the old name of the type including the package name, not null
* @param currentValue the current type, not null
*/
public void renamedType(String oldName, Class> currentValue) {
if (oldName == null) {
throw new IllegalArgumentException("oldName must not be null");
}
if (currentValue == null) {
throw new IllegalArgumentException("currentValue must not be null");
}
typeRenames.put(oldName, currentValue);
}
/**
* Gets the map of renamed types.
*
* An empty map is returned if there are no renames.
*
* @return a copy of the set of enum types with renames, not null
*/
public Map> getTypeRenames() {
return new HashMap>(typeRenames);
}
/**
* Lookup a type from a name, handling renames.
*
* @param name the name of the type to lookup, not null
* @return the type, not null
* @throws ClassNotFoundException if the name is not a valid type
*/
public Class> lookupType(String name) throws ClassNotFoundException {
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
Class> type = typeRenames.get(name);
if (type == null) {
type = loadType(name);
}
return type;
}
/**
* Loads a type avoiding nulls
*
* @param fullName the full class name
* @return the loaded class
* @throws ClassNotFoundException if the class is not found
*/
Class> loadType(String fullName) throws ClassNotFoundException {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
return loader != null ? loader.loadClass(fullName) : Class.forName(fullName);
}
//-----------------------------------------------------------------------
/**
* Register the fact that an enum constant was renamed.
*
* @param oldName the old name of the enum constant, not null
* @param currentValue the current enum constant, not null
*/
public void renamedEnum(String oldName, Enum> currentValue) {
if (oldName == null) {
throw new IllegalArgumentException("oldName must not be null");
}
if (currentValue == null) {
throw new IllegalArgumentException("currentValue must not be null");
}
Class> enumType = currentValue.getDeclaringClass();
Map> perClass = enumRenames.get(enumType);
if (perClass == null) {
enumRenames.putIfAbsent(enumType, new ConcurrentHashMap>(16, 0.75f, 2));
perClass = enumRenames.get(enumType);
}
perClass.put(oldName, currentValue);
}
/**
* Gets the set of enum types that have renames.
*
* An empty set is returned if there are no renames.
*
* @return a copy of the set of enum types with renames, not null
*/
public Set> getEnumTypesWithRenames() {
return new HashSet>(enumRenames.keySet());
}
/**
* Gets the map of renamed for an enum type.
*
* An empty map is returned if there are no renames.
*
* @param type the enum type, not null
* @return a copy of the set of enum renames, not null
*/
public Map> getEnumRenames(Class> type) {
if (type == null) {
throw new IllegalArgumentException("type must not be null");
}
Map> map = enumRenames.get(type);
if (map == null) {
return new HashMap>();
}
return new HashMap>(map);
}
/**
* Lookup an enum from a name, handling renames.
*
* @param the type of the desired enum
* @param type the enum type, not null
* @param name the name of the enum to lookup, not null
* @return the enum value, not null
* @throws IllegalArgumentException if the name is not a valid enum constant
*/
public > T lookupEnum(Class type, String name) {
if (type == null) {
throw new IllegalArgumentException("type must not be null");
}
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
Map> map = getEnumRenames(type);
Enum> value = map.get(name);
if (value != null) {
return type.cast(value);
}
return Enum.valueOf(type, name);
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return "RenamedTypes" + typeRenames + ",RenamedEnumConstants" + enumRenames;
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/FromStringConverter.java 0000664 0001750 0001750 00000002401 12603461407 026113 0 ustar ebourg ebourg /*
* Copyright 2010-present 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}.
*
* FromStringConverter is an interface and must be implemented with care.
* Implementations must be immutable and thread-safe.
*
* @param the type of the converter
*/
public interface FromStringConverter {
/**
* 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);
}
joda-convert-1.8.1/src/main/java/org/joda/convert/TypedStringConverter.java 0000664 0001750 0001750 00000002614 12603461407 026303 0 ustar ebourg ebourg /*
* Copyright 2010-present 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} together with the type.
*
* TypedStringConverter is an interface and must be implemented with care.
* Implementations must be immutable and thread-safe.
*
* @param the type of the converter
* @since 1.7
*/
public interface TypedStringConverter extends StringConverter {
/**
* Gets the effective type that the converter works on.
*
* For example, if a class declares the {@code FromString} and {@code ToString}
* then the effective type of the converter is that class. If a subclass is
* queried for a converter, then the effective type is that of the superclass.
*
* @return the effective type
*/
Class> getEffectiveType();
}
joda-convert-1.8.1/src/main/java/org/joda/convert/JDKStringConverter.java 0000664 0001750 0001750 00000041247 12603461407 025633 0 ustar ebourg ebourg /*
* Copyright 2010-present 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 TypedStringConverter {
/**
* String converter.
*/
STRING(String.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return str;
}
},
/**
* CharSequence converter.
*/
CHAR_SEQUENCE(CharSequence.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return str;
}
},
/**
* StringBuffer converter.
*/
STRING_BUFFER(StringBuffer.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new StringBuffer(str);
}
},
/**
* StringBuilder converter.
*/
STRING_BUILDER(StringBuilder.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new StringBuilder(str);
}
},
/**
* Long converter.
*/
LONG(Long.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new Long(str);
}
},
/**
* Integer converter.
*/
INTEGER(Integer.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new Integer(str);
}
},
/**
* Short converter.
*/
SHORT (Short.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new Short(str);
}
},
/**
* Byte converter.
*/
BYTE(Byte.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new Byte(str);
}
},
/**
* String converter.
*/
BYTE_ARRAY(byte[].class) {
@Override
public String convertToString(Object object) {
return printBase64Binary((byte[]) object);
}
@Override
public Object convertFromString(Class> cls, String str) {
return parseBase64Binary(str);
}
},
/**
* Character converter.
*/
CHARACTER(Character.class) {
@Override
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));
}
},
/**
* String converter.
*/
CHAR_ARRAY(char[].class) {
@Override
public String convertToString(Object object) {
return new String((char[]) object);
}
@Override
public Object convertFromString(Class> cls, String str) {
return str.toCharArray();
}
},
/**
* Boolean converter.
*/
BOOLEAN(Boolean.class) {
@Override
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) {
@Override
public Object convertFromString(Class> cls, String str) {
return new Double(str);
}
},
/**
* Float converter.
*/
FLOAT(Float.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new Float(str);
}
},
/**
* BigInteger converter.
*/
BIG_INTEGER(BigInteger.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new BigInteger(str);
}
},
/**
* BigDecimal converter.
*/
BIG_DECIMAL(BigDecimal.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return new BigDecimal(str);
}
},
/**
* AtomicLong converter.
*/
ATOMIC_LONG(AtomicLong.class) {
@Override
public Object convertFromString(Class> cls, String str) {
long val = Long.parseLong(str);
return new AtomicLong(val);
}
},
/**
* AtomicLong converter.
*/
ATOMIC_INTEGER(AtomicInteger.class) {
@Override
public Object convertFromString(Class> cls, String str) {
int val = Integer.parseInt(str);
return new AtomicInteger(val);
}
},
/**
* AtomicBoolean converter.
*/
ATOMIC_BOOLEAN(AtomicBoolean.class) {
@Override
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) {
@Override
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();
}
@Override
public Object convertFromString(Class> cls, String str) {
try {
return RenameHandler.INSTANCE.lookupType(str);
} catch (ClassNotFoundException ex) {
throw new RuntimeException("Unable to create type: " + str, ex);
}
}
},
/**
* Package converter.
*/
PACKAGE(Package.class) {
@Override
public String convertToString(Object object) {
return ((Package) object).getName();
}
@Override
public Object convertFromString(Class> cls, String str) {
return Package.getPackage(str);
}
},
/**
* Currency converter.
*/
CURRENCY(Currency.class) {
@Override
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();
}
@Override
public Object convertFromString(Class> cls, String str) {
return TimeZone.getTimeZone(str);
}
},
/**
* UUID converter.
*/
UUID(UUID.class) {
@Override
public Object convertFromString(Class> cls, String str) {
return java.util.UUID.fromString(str);
}
},
/**
* URL converter.
*/
URL(URL.class) {
@Override
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) {
@Override
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();
}
@Override
public Object convertFromString(Class> cls, String str) {
try {
return InetAddress.getByName(str);
} catch (UnknownHostException ex) {
throw new RuntimeException(ex);
}
}
},
/**
* File converter.
*/
FILE(File.class) {
@Override
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);
}
@Override
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() + "]";
}
@Override
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);
}
}
},
;
/** The type. */
private Class> type;
/**
* Creates an enum.
* @param type the type, not null
*/
JDKStringConverter(Class> type) {
this.type = type;
}
/**
* Gets the type of the converter.
* @return the type, not null
*/
Class> getType() {
return type;
}
/**
* Gets the type of the converter.
* @return the type, not null
*/
@Override
public Class> getEffectiveType() {
return type;
}
//-----------------------------------------------------------------------
@Override
public String convertToString(Object object) {
return object.toString();
}
//-----------------------------------------------------------------------
private static String base64Str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
private static char[] base64Array = base64Str.toCharArray();
private static final int MASK_8BIT = 0xff;
private static final int MASK_6BIT = 0x3f;
private static String printBase64Binary(byte[] array) {
int len = array.length;
char[] buf = new char[((len + 2) / 3) * 4];
int pos = 0;
for (int i = 0; i < len; i += 3) {
int remaining = len - i;
if (remaining >= 3) {
int bits = (array[i] & MASK_8BIT) << 16 | (array[i + 1] & MASK_8BIT) << 8 | (array[i + 2] & MASK_8BIT);
buf[pos++] = base64Array[(bits >>> 18) & MASK_6BIT];
buf[pos++] = base64Array[(bits >>> 12) & MASK_6BIT];
buf[pos++] = base64Array[(bits >>> 6) & MASK_6BIT];
buf[pos++] = base64Array[bits & MASK_6BIT];
} else if (remaining == 2) {
int bits = (array[i] & MASK_8BIT) << 16 | (array[i + 1] & MASK_8BIT) << 8;
buf[pos++] = base64Array[(bits >>> 18) & MASK_6BIT];
buf[pos++] = base64Array[(bits >>> 12) & MASK_6BIT];
buf[pos++] = base64Array[(bits >>> 6) & MASK_6BIT];
buf[pos++] = '=';
} else {
int bits = (array[i] & MASK_8BIT) << 16;
buf[pos++] = base64Array[(bits >>> 18) & MASK_6BIT];
buf[pos++] = base64Array[(bits >>> 12) & MASK_6BIT];
buf[pos++] = '=';
buf[pos++] = '=';
}
}
return new String(buf);
}
private static byte[] parseBase64Binary(String str) {
// strict parser, must have length divisble by 4
if (str.length() % 4 != 0) {
throw new IllegalArgumentException("Invalid Base64 string");
}
// base64Str has 65 characters, with '=' at the end which is masked away
int parsedLen = (str.length() * 3) / 4;
byte[] decoded = new byte[parsedLen];
char[] inChars = str.toCharArray();
int pos = 0;
for (int i = 0; i < inChars.length; ) {
int bits = (base64Str.indexOf(inChars[i++]) & MASK_6BIT) << 18 |
(base64Str.indexOf(inChars[i++]) & MASK_6BIT) << 12 |
(base64Str.indexOf(inChars[i++]) & MASK_6BIT) << 6 |
(base64Str.indexOf(inChars[i++]) & MASK_6BIT);
decoded[pos++] = (byte) ((bits >>> 16) & MASK_8BIT);
decoded[pos++] = (byte) ((bits >>> 8) & MASK_8BIT);
decoded[pos++] = (byte) (bits & MASK_8BIT);
}
// fixup avoiding Arrays.copyRange
if (str.endsWith("==")) {
byte[] result = new byte[parsedLen - 2];
System.arraycopy(decoded, 0, result, 0, parsedLen - 2);
return result;
} else if (str.endsWith("=")) {
byte[] result = new byte[parsedLen - 1];
System.arraycopy(decoded, 0, result, 0, parsedLen - 1);
return result;
}
return decoded;
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/TypeTokenStringConverter.java 0000664 0001750 0001750 00000003043 12603461407 027135 0 ustar ebourg ebourg /*
* Copyright 2010-present 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 com.google.common.reflect.TypeToken;
/**
* Parse the string format of Guava TypeToken.
*
* This is loaded by reflection only when Guava is on the classpath.
* It relies on internal methods in Guava that could change in any release.
*
* This parser is incomplete, but handles common cases.
* It does not handle union types or multi-dimensional arrays.
*/
final class TypeTokenStringConverter
extends AbstractTypeStringConverter
implements TypedStringConverter> {
public TypeTokenStringConverter() {
}
@Override
public String convertToString(TypeToken> object) {
return object.toString();
}
@Override
public TypeToken> convertFromString(Class extends TypeToken>> cls, String str) {
return TypeToken.of(parse(str));
}
@Override
public Class> getEffectiveType() {
return TypeToken.class;
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/EnumStringConverterFactory.java 0000664 0001750 0001750 00000005315 12603461407 027453 0 ustar ebourg ebourg /*
* Copyright 2010-present 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;
/**
* Factory for {@code StringConverter} looking up enums.
*
* This class is immutable and thread-safe.
*
* @since 1.7
*/
final class EnumStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
static final StringConverterFactory INSTANCE = new EnumStringConverterFactory();
/**
* Restricted constructor.
*/
private EnumStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
Class> sup = cls.getSuperclass();
if (sup == Enum.class) {
return new EnumStringConverter(cls);
} else if (sup != null && sup.getSuperclass() == Enum.class) {
return new EnumStringConverter(sup);
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
final class EnumStringConverter implements TypedStringConverter> {
private final Class> effectiveType;
EnumStringConverter(Class> effectiveType) {
this.effectiveType = effectiveType;
}
@Override
public String convertToString(Enum> en) {
return en.name(); // avoid toString() as that can be overridden
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public Enum> convertFromString(Class extends Enum>> cls, String str) {
return RenameHandler.INSTANCE.lookupEnum((Class) cls, str);
}
@Override
public Class> getEffectiveType() {
return effectiveType;
}
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/TypeStringConverter.java 0000664 0001750 0001750 00000003035 12603461407 026135 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.Type;
import com.google.common.reflect.TypeToken;
/**
* Parse the string format of Type via Guava TypeToken.
*
* This is loaded by reflection only when Guava is on the classpath.
* It relies on internal methods in Guava that could change in any release.
*
* This parser is incomplete, but handles common cases.
* It does not handle union types or multi-dimensional arrays.
*/
final class TypeStringConverter
extends AbstractTypeStringConverter
implements TypedStringConverter {
public TypeStringConverter() {
}
@Override
public String convertToString(Type object) {
return TypeToken.of(object).toString();
}
@Override
public Type convertFromString(Class extends Type> cls, String str) {
return parse(str);
}
@Override
public Class> getEffectiveType() {
return Type.class;
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/ToString.java 0000664 0001750 0001750 00000002650 12603461407 023710 0 ustar ebourg ebourg /*
* Copyright 2010-present 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}.
*
* 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.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ToString {
}
joda-convert-1.8.1/src/main/java/org/joda/convert/StringConverter.java 0000664 0001750 0001750 00000001770 12603461407 025277 0 ustar ebourg ebourg /*
* Copyright 2010-present 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}.
*
* StringConverter is an interface and must be implemented with care.
* Implementations must be immutable and thread-safe.
*
* @param the type of the converter
*/
public interface StringConverter extends ToStringConverter, FromStringConverter {
}
joda-convert-1.8.1/src/main/java/org/joda/convert/AbstractTypeStringConverter.java 0000664 0001750 0001750 00000014766 12603461407 027636 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.Array;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.ImmutableMap;
/**
* Parse the string format of Guava TypeToken.
*
* This is loaded by reflection only when Guava is on the classpath.
* It relies on internal methods in Guava that could change in any release.
*
* This parser is incomplete, but handles common cases.
* It does not handle union types or multi-dimensional arrays.
*/
abstract class AbstractTypeStringConverter {
// extends
private static final String EXTENDS = "? extends ";
// super
private static final String SUPER = "? super ";
// primitive types
private static final ImmutableMap> PRIMITIVES = ImmutableMap.>builder()
.put("byte", byte.class)
.put("short", short.class)
.put("int", int.class)
.put("long", long.class)
.put("boolean", boolean.class)
.put("char", char.class)
.put("float", float.class)
.put("double", double.class)
.build();
private static final Method NEW_PARAM_TYPE;
private static final Method EXTENDS_TYPE;
private static final Method SUPER_TYPE;
static {
try {
Class> typesClass = RenameHandler.INSTANCE.loadType("com.google.common.reflect.Types");
Method newParam = typesClass.getDeclaredMethod("newParameterizedType", Class.class, Type[].class);
newParam.setAccessible(true);
NEW_PARAM_TYPE = newParam;
Method extendsType = typesClass.getDeclaredMethod("subtypeOf", Type.class);
extendsType.setAccessible(true);
EXTENDS_TYPE = extendsType;
Method superType = typesClass.getDeclaredMethod("supertypeOf", Type.class);
superType.setAccessible(true);
SUPER_TYPE = superType;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
//-----------------------------------------------------------------------
// constructor
AbstractTypeStringConverter() {
}
//-----------------------------------------------------------------------
/**
* Parses the TypeToken string format.
*
* @param str the string
* @return the token
*/
static Type parse(String str) {
try {
return doParse(str);
} catch (RuntimeException ex) {
throw ex;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
// parse an element
private static Type doParse(String str) throws Exception {
Class> token = PRIMITIVES.get(str);
if (token != null) {
return token;
}
int first = str.indexOf('<');
if (first < 0) {
return RenameHandler.INSTANCE.loadType(str);
}
int last = str.lastIndexOf('>');
String baseStr = str.substring(0, first);
Class> base = RenameHandler.INSTANCE.loadType(baseStr);
String argsStr = str.substring(first + 1, last);
List splitArgs = split(argsStr);
List types = new ArrayList();
for (String splitArg : splitArgs) {
Type argType;
if (splitArg.startsWith(EXTENDS)) {
String remainder = splitArg.substring(EXTENDS.length());
argType = wildExtendsType(doParse(remainder));
} else if (splitArg.startsWith(SUPER)) {
String remainder = splitArg.substring(SUPER.length());
argType = wildSuperType(doParse(remainder));
} else if (splitArg.equals("?")) {
argType = wildExtendsType(Object.class);
} else if (splitArg.endsWith("[]")) {
String componentStr = splitArg.substring(0, splitArg.length() - 2);
Class> componentCls = RenameHandler.INSTANCE.loadType(componentStr);
argType = Array.newInstance(componentCls, 0).getClass();
} else if (splitArg.startsWith("[L") && splitArg.endsWith(";")) {
String componentStr = splitArg.substring(2, splitArg.length() - 1);
Class> componentCls = RenameHandler.INSTANCE.loadType(componentStr);
argType = Array.newInstance(componentCls, 0).getClass();
} else {
argType = doParse(splitArg);
}
types.add(argType);
}
return newParameterizedType(base, types.toArray(new Type[types.size()]));
}
// split by comma, handling nested generified types
private static List split(String str) {
List result = new ArrayList();
int genericCount = 0;
int startPos = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ',' && genericCount == 0) {
result.add(str.substring(startPos, i).trim());
startPos = i + 1;
} else if (str.charAt(i) == '<') {
genericCount++;
} else if (str.charAt(i) == '>') {
genericCount--;
}
}
result.add(str.substring(startPos).trim());
return result;
}
// create a type representing "? extends X"
private static Type wildExtendsType(Type bound) throws Exception {
return (Type) EXTENDS_TYPE.invoke(null, bound);
}
// create a type representing "? super X"
private static Type wildSuperType(Type bound) throws Exception {
return (Type) SUPER_TYPE.invoke(null, bound);
}
// create a type representing "base"
private static ParameterizedType newParameterizedType(final Class> base, Type... args) throws Exception {
return (ParameterizedType) NEW_PARAM_TYPE.invoke(null, base, args);
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/MethodConstructorStringConverter.java 0000664 0001750 0001750 00000007022 12603461407 030702 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.
*
* The toString method must meet the following signature:
* {@code String anyName()} on Class T.
*
* The fromString constructor must take a single {@code String} parameter.
*
* MethodConstructorStringConverter is thread-safe and immutable.
*
* @param the type of the converter
*/
final class MethodConstructorStringConverter extends ReflectionStringConverter {
/** Conversion from a string. */
private final Constructor 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 cls, Method toString, Constructor 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: " + fromString);
}
if (fromString.getDeclaringClass() != cls) {
throw new IllegalStateException("FromString constructor must be defined on specified class: " + fromString);
}
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
*/
@Override
public T convertFromString(Class extends T> cls, String str) {
try {
return fromString.newInstance(str);
} catch (IllegalAccessException ex) {
throw new IllegalStateException("Constructor is not accessible: " + fromString);
} catch (InstantiationException ex) {
throw new IllegalStateException("Constructor is not valid: " + fromString);
} catch (InvocationTargetException ex) {
if (ex.getCause() instanceof RuntimeException) {
throw (RuntimeException) ex.getCause();
}
throw new RuntimeException(ex.getMessage(), ex.getCause());
}
}
//-------------------------------------------------------------------------
@Override
public Class> getEffectiveType() {
return fromString.getDeclaringClass();
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/TypedAdapter.java 0000664 0001750 0001750 00000003446 12603461407 024531 0 ustar ebourg ebourg /*
* Copyright 2010-present 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;
/**
* Adapts {@code StringConverter} to {@code TypedStringConverter}.
*
* @param the type of the converter
* @since 1.7
*/
final class TypedAdapter implements TypedStringConverter {
private final StringConverter conv;
private final Class> effectiveType;
static TypedStringConverter adapt(final Class cls, StringConverter converter) {
if (converter instanceof TypedStringConverter) {
return (TypedStringConverter) converter;
} else {
return new TypedAdapter(converter, cls);
}
}
private TypedAdapter(StringConverter conv, Class> effectiveType) {
this.conv = conv;
this.effectiveType = effectiveType;
}
@Override
public String convertToString(T object) {
return conv.convertToString(object);
}
@Override
public T convertFromString(Class extends T> cls, String str) {
return conv.convertFromString(cls, str);
}
@Override
public Class> getEffectiveType() {
return effectiveType;
}
@Override
public String toString() {
return "TypedAdapter:" + conv.toString();
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/MethodsStringConverter.java 0000664 0001750 0001750 00000007546 12603461407 026632 0 ustar ebourg ebourg /*
* Copyright 2010-present 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;
import java.lang.reflect.Modifier;
/**
* Conversion to and from a string using two methods.
*
* The toString method must meet the following signature:
* {@code String anyName()} on Class T.
*
* The fromString method must meet the following signature:
* {@code static T anyName(String)} on any class.
*
* MethodsStringConverter is thread-safe and immutable.
*
* @param the type of the converter
*/
final class MethodsStringConverter extends ReflectionStringConverter {
/** Conversion from a string. */
private final Method fromString;
/** Effective type. */
private final Class> effectiveType;
/**
* 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 cls, Method toString, Method fromString, Class> effectiveType) {
super(cls, toString);
if (Modifier.isStatic(fromString.getModifiers()) == false) {
throw new IllegalStateException("FromString method must be static: " + fromString);
}
if (fromString.getParameterTypes().length != 1) {
throw new IllegalStateException("FromString method must have one parameter: " + fromString);
}
Class> param = fromString.getParameterTypes()[0];
if (param != String.class && param != CharSequence.class) {
throw new IllegalStateException("FromString method must take a String or CharSequence: " + fromString);
}
if (fromString.getReturnType().isAssignableFrom(cls) == false && cls.isAssignableFrom(fromString.getReturnType()) == false) {
throw new IllegalStateException("FromString method must return specified class or a supertype: " + fromString);
}
this.fromString = fromString;
this.effectiveType = effectiveType;
}
//-----------------------------------------------------------------------
/**
* 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
*/
@Override
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: " + fromString);
} catch (InvocationTargetException ex) {
if (ex.getCause() instanceof RuntimeException) {
throw (RuntimeException) ex.getCause();
}
throw new RuntimeException(ex.getMessage(), ex.getCause());
}
}
//-------------------------------------------------------------------------
@Override
public Class> getEffectiveType() {
return effectiveType;
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/StringConvert.java 0000664 0001750 0001750 00000100063 12603461407 024743 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joda.convert.factory.BooleanArrayStringConverterFactory;
import org.joda.convert.factory.BooleanObjectArrayStringConverterFactory;
import org.joda.convert.factory.ByteObjectArrayStringConverterFactory;
import org.joda.convert.factory.CharObjectArrayStringConverterFactory;
import org.joda.convert.factory.NumericArrayStringConverterFactory;
import org.joda.convert.factory.NumericObjectArrayStringConverterFactory;
/**
* Manager for conversion to and from a {@code String}, acting as the main client interface.
*
* Support is provided for conversions based on the {@link StringConverter} interface
* or the {@link ToString} and {@link FromString} annotations.
*
* StringConvert is thread-safe with concurrent caches.
*/
public final class StringConvert {
/**
* An immutable global instance.
*
* 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 cached null object.
*/
private static final TypedStringConverter> CACHED_NULL = new TypedStringConverter() {
@Override
public String convertToString(Object object) {
return null;
}
@Override
public Object convertFromString(Class extends Object> cls, String str) {
return null;
}
@Override
public Class> getEffectiveType() {
return null;
}
};
/**
* The list of factories.
*/
private final CopyOnWriteArrayList factories = new CopyOnWriteArrayList();
/**
* The cache of converters.
*/
private final ConcurrentMap, TypedStringConverter>> registered = new ConcurrentHashMap, TypedStringConverter>>();
//-----------------------------------------------------------------------
/**
* Creates a new conversion manager including the extended standard set of converters.
*
* The returned converter is a new instance that includes additional converters:
*
* JDK converters
* {@link NumericArrayStringConverterFactory}
* {@link NumericObjectArrayStringConverterFactory}
* {@link CharObjectArrayStringConverterFactory}
* {@link ByteObjectArrayStringConverterFactory}
* {@link BooleanArrayStringConverterFactory}
* {@link BooleanObjectArrayStringConverterFactory}
*
*
* The convert instance is mutable in a thread-safe manner.
* Converters may be altered at any time, including the JDK converters.
* It is strongly recommended to only alter the converters before performing
* actual conversions.
*
* @return the new converter, not null
* @since 1.5
*/
public static StringConvert create() {
return new StringConvert(true,
NumericArrayStringConverterFactory.INSTANCE,
NumericObjectArrayStringConverterFactory.INSTANCE,
CharObjectArrayStringConverterFactory.INSTANCE,
ByteObjectArrayStringConverterFactory.INSTANCE,
BooleanArrayStringConverterFactory.INSTANCE,
BooleanObjectArrayStringConverterFactory.INSTANCE);
}
//-----------------------------------------------------------------------
/**
* Creates a new conversion manager including the JDK converters.
*
* The convert instance is mutable in a thread-safe manner.
* Converters may be altered at any time, including the JDK converters.
* It is strongly recommended to only alter the converters before performing
* actual conversions.
*/
public StringConvert() {
this(true);
}
/**
* Creates a new conversion manager.
*
* The convert instance is mutable in a thread-safe manner.
* Converters may be altered at any time, including the JDK converters.
* It is strongly recommended to only alter the converters before performing
* actual conversions.
*
* If specified, the factories will be queried in the order specified.
*
* @param includeJdkConverters true to include the JDK converters
* @param factories optional array of factories to use, not null
*/
public StringConvert(boolean includeJdkConverters, StringConverterFactory... factories) {
if (factories == null) {
throw new IllegalArgumentException("StringConverterFactory array must not be null");
}
for (int i = 0; i < factories.length; i++) {
if (factories[i] == null) {
throw new IllegalArgumentException("StringConverterFactory array must not contain a null element");
}
}
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);
// Guava
tryRegisterGuava();
// JDK 1.8 classes
tryRegister("java.time.Instant", "parse");
tryRegister("java.time.Duration", "parse");
tryRegister("java.time.LocalDate", "parse");
tryRegister("java.time.LocalTime", "parse");
tryRegister("java.time.LocalDateTime", "parse");
tryRegister("java.time.OffsetTime", "parse");
tryRegister("java.time.OffsetDateTime", "parse");
tryRegister("java.time.ZonedDateTime", "parse");
tryRegister("java.time.Year", "parse");
tryRegister("java.time.YearMonth", "parse");
tryRegister("java.time.MonthDay", "parse");
tryRegister("java.time.Period", "parse");
tryRegister("java.time.ZoneOffset", "of");
tryRegister("java.time.ZoneId", "of");
// ThreeTen backport classes
tryRegister("org.threeten.bp.Instant", "parse");
tryRegister("org.threeten.bp.Duration", "parse");
tryRegister("org.threeten.bp.LocalDate", "parse");
tryRegister("org.threeten.bp.LocalTime", "parse");
tryRegister("org.threeten.bp.LocalDateTime", "parse");
tryRegister("org.threeten.bp.OffsetTime", "parse");
tryRegister("org.threeten.bp.OffsetDateTime", "parse");
tryRegister("org.threeten.bp.ZonedDateTime", "parse");
tryRegister("org.threeten.bp.Year", "parse");
tryRegister("org.threeten.bp.YearMonth", "parse");
tryRegister("org.threeten.bp.MonthDay", "parse");
tryRegister("org.threeten.bp.Period", "parse");
tryRegister("org.threeten.bp.ZoneOffset", "of");
tryRegister("org.threeten.bp.ZoneId", "of");
// Old ThreeTen/JSR-310 classes v0.6.3 and beyond
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");
}
if (factories.length > 0) {
this.factories.addAll(Arrays.asList(factories));
}
this.factories.add(AnnotationStringConverterFactory.INSTANCE);
if (includeJdkConverters) {
this.factories.add(EnumStringConverterFactory.INSTANCE);
}
}
/**
* Tries to register the Guava converters class.
*
* @param className the class name, not null
*/
private void tryRegisterGuava() {
try {
RenameHandler.INSTANCE.loadType("com.google.common.reflect.Types");
@SuppressWarnings("unchecked")
Class> cls = (Class>) RenameHandler.INSTANCE
.loadType("org.joda.convert.TypeTokenStringConverter");
TypedStringConverter> conv = (TypedStringConverter>) cls.newInstance();
registered.put(conv.getEffectiveType(), conv);
@SuppressWarnings("unchecked")
Class> cls2 = (Class>) RenameHandler.INSTANCE
.loadType("org.joda.convert.TypeStringConverter");
TypedStringConverter> conv2 = (TypedStringConverter>) cls2.newInstance();
registered.put(conv2.getEffectiveType(), conv2);
} catch (Throwable ex) {
// ignore
}
}
/**
* 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 = RenameHandler.INSTANCE.lookupType(className);
registerMethods(cls, "toString", fromStringMethodName);
} catch (Throwable ex) {
// ignore
}
}
//-----------------------------------------------------------------------
/**
* Converts the specified object to a {@code String}.
*
* This uses {@link #findConverter} to provide the converter.
*
* @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 String convertToString(Object object) {
if (object == null) {
return null;
}
Class> cls = object.getClass();
StringConverter conv = findConverterNoGenerics(cls);
return conv.convertToString(object);
}
/**
* Converts the specified object to a {@code String}.
*
* This uses {@link #findConverter} to provide the converter.
* The class can be provided to select a more specific converter.
*
* @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 String convertToString(Class> cls, Object object) {
if (object == null) {
return null;
}
StringConverter conv = findConverterNoGenerics(cls);
return conv.convertToString(object);
}
/**
* Converts the specified object from a {@code String}.
*
* This uses {@link #findConverter} to provide the converter.
*
* @param 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 convertFromString(Class cls, String str) {
if (str == null) {
return null;
}
StringConverter conv = findConverter(cls);
return conv.convertFromString(cls, str);
}
//-----------------------------------------------------------------------
/**
* Checks if a suitable converter exists for the type.
*
* This performs the same checks as the {@code findConverter} methods.
* Calling this before {@code findConverter} will cache the converter.
*
* Note that all exceptions, including developer errors are caught and hidden.
*
* @param cls the class to find a converter for, null returns false
* @return true if convertible
* @since 1.5
*/
public boolean isConvertible(final Class> cls) {
try {
return cls != null && findConverterQuiet(cls) != null;
} catch (RuntimeException ex) {
return false;
}
}
/**
* Finds a suitable converter for the type.
*
* This returns an instance of {@code StringConverter} for the specified class.
* This is designed for user code where the {@code Class} object generics is known.
*
* The search algorithm first searches the registered converters in the
* class hierarchy and immediate parent interfaces.
* It then searches for {@code ToString} and {@code FromString} annotations on the
* specified class, class hierarchy or immediate parent interfaces.
* Finally, it handles {@code Enum} instances.
*
* @param 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
*/
public StringConverter findConverter(final Class cls) {
return findTypedConverter(cls);
}
/**
* Finds a suitable converter for the type with open generics.
*
* This returns an instance of {@code StringConverter} for the specified class.
* This is designed for framework usage where the {@code Class} object generics are unknown'?'.
* The returned type is declared with {@code Object} instead of '?' to
* allow the {@link ToStringConverter} to be invoked.
*
* The search algorithm first searches the registered converters in the
* class hierarchy and immediate parent interfaces.
* It then searches for {@code ToString} and {@code FromString} annotations on the
* specified class, class hierarchy or immediate parent interfaces.
* Finally, it handles {@code Enum} instances.
*
* @param cls the class to find a converter for, not null
* @return the converter, using {@code Object} to avoid generics, not null
* @throws RuntimeException (or subclass) if no converter found
* @since 1.5
*/
public StringConverter findConverterNoGenerics(final Class> cls) {
return findTypedConverterNoGenerics(cls);
}
/**
* Finds a suitable converter for the type.
*
* This returns an instance of {@code TypedStringConverter} for the specified class.
* This is designed for user code where the {@code Class} object generics is known.
*
* The search algorithm first searches the registered converters in the
* class hierarchy and immediate parent interfaces.
* It then searches for {@code ToString} and {@code FromString} annotations on the
* specified class, class hierarchy or immediate parent interfaces.
* Finally, it handles {@code Enum} instances.
*
* The returned converter may be queried for the effective type of the conversion.
* This can be used to find the best type to send in a serialized form.
*
* NOTE: Changing the method return type of {@link #findConverter(Class)}
* would be source compatible but not binary compatible. As this is a low-level
* library, binary compatibility is important, hence the addition of this method.
*
* @param 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
* @since 1.7
*/
public TypedStringConverter findTypedConverter(final Class cls) {
TypedStringConverter conv = findConverterQuiet(cls);
if (conv == null) {
throw new IllegalStateException("No registered converter found: " + cls);
}
return conv;
}
/**
* Finds a suitable converter for the type with open generics.
*
* This returns an instance of {@code TypedStringConverter} for the specified class.
* This is designed for framework usage where the {@code Class} object generics are unknown'?'.
* The returned type is declared with {@code Object} instead of '?' to
* allow the {@link ToStringConverter} to be invoked.
*
* The search algorithm first searches the registered converters in the
* class hierarchy and immediate parent interfaces.
* It then searches for {@code ToString} and {@code FromString} annotations on the
* specified class, class hierarchy or immediate parent interfaces.
* Finally, it handles {@code Enum} instances.
*
* The returned converter may be queried for the effective type of the conversion.
* This can be used to find the best type to send in a serialized form.
*
* NOTE: Changing the method return type of {@link #findConverterNoGenerics(Class)}
* would be source compatible but not binary compatible. As this is a low-level
* library, binary compatibility is important, hence the addition of this method.
*
* @param cls the class to find a converter for, not null
* @return the converter, using {@code Object} to avoid generics, not null
* @throws RuntimeException (or subclass) if no converter found
* @since 1.7
*/
@SuppressWarnings("unchecked")
public TypedStringConverter findTypedConverterNoGenerics(final Class> cls) {
TypedStringConverter conv = (TypedStringConverter) findConverterQuiet(cls);
if (conv == null) {
throw new IllegalStateException("No registered converter found: " + cls);
}
return conv;
}
/**
* Finds a converter searching registered and annotated.
*
* @param the type of the converter
* @param cls the class to find a method for, not null
* @return the converter, null if no converter
* @throws RuntimeException if invalid
*/
@SuppressWarnings("unchecked")
private TypedStringConverter findConverterQuiet(final Class cls) {
if (cls == null) {
throw new IllegalArgumentException("Class must not be null");
}
TypedStringConverter conv = (TypedStringConverter) registered.get(cls);
if (conv == CACHED_NULL) {
return null;
}
if (conv == null) {
try {
conv = findAnyConverter(cls);
} catch (RuntimeException ex) {
registered.putIfAbsent(cls, CACHED_NULL);
throw ex;
}
if (conv == null) {
registered.putIfAbsent(cls, CACHED_NULL);
return null;
}
registered.putIfAbsent(cls, conv);
}
return conv;
}
/**
* Finds a converter searching registered and annotated.
*
* @param the type of the converter
* @param cls the class to find a method for, not null
* @return the converter, not null
* @throws RuntimeException if invalid
*/
@SuppressWarnings("unchecked")
private TypedStringConverter findAnyConverter(final Class cls) {
TypedStringConverter conv = null;
// check for registered on superclass
Class> loopCls = cls.getSuperclass();
while (loopCls != null && conv == null) {
conv = (TypedStringConverter) registered.get(loopCls);
if (conv != null && conv != CACHED_NULL) {
return conv;
}
loopCls = loopCls.getSuperclass();
}
// check for registered on interfaces
for (Class> loopIfc : cls.getInterfaces()) {
conv = (TypedStringConverter) registered.get(loopIfc);
if (conv != null && conv != CACHED_NULL) {
return conv;
}
}
// check factories
for (StringConverterFactory factory : factories) {
StringConverter factoryConv = (StringConverter) factory.findConverter(cls);
if (factoryConv != null) {
return TypedAdapter.adapt(cls, factoryConv);
}
}
return null;
}
//-----------------------------------------------------------------------
/**
* Registers a converter factory.
*
* This will be registered ahead of all existing factories.
*
* No new factories may be registered for the global singleton.
*
* @param factory the converter factory, not null
* @throws IllegalStateException if trying to alter the global singleton
* @since 1.5
*/
public void registerFactory(final StringConverterFactory factory) {
if (factory == null) {
throw new IllegalArgumentException("Factory must not be null");
}
if (this == INSTANCE) {
throw new IllegalStateException("Global singleton cannot be extended");
}
factories.add(0, factory);
}
//-----------------------------------------------------------------------
/**
* Registers a converter for a specific type.
*
* The converter will be used for subclasses unless overidden.
*
* No new converters may be registered for the global singleton.
*
* @param 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 the class or converter are null
* @throws IllegalStateException if trying to alter the global singleton
*/
public void register(final Class cls, StringConverter 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");
}
registered.put(cls, TypedAdapter.adapt(cls, converter));
}
/**
* Registers a converter for a specific type using two separate converters.
*
* This method registers a converter for the specified class.
* It is primarily intended for use with JDK 1.8 method references or lambdas:
*
* sc.register(Distance.class, Distance::toString, Distance::parse);
*
* The converter will be used for subclasses unless overidden.
*
* No new converters may be registered for the global singleton.
*
* @param the type of the converter
* @param cls the class to register a converter for, not null
* @param toString the to String converter, typically a method reference, not null
* @param fromString the from String converter, typically a method reference, not null
* @throws IllegalArgumentException if the class or converter are null
* @throws IllegalStateException if trying to alter the global singleton
* @since 1.3
*/
public void register(final Class cls, final ToStringConverter toString, final FromStringConverter fromString) {
if (fromString == null || toString == null) {
throw new IllegalArgumentException("Converters must not be null");
}
register(cls, new TypedStringConverter() {
@Override
public String convertToString(T object) {
return toString.convertToString(object);
}
@Override
public T convertFromString(Class extends T> cls, String str) {
return fromString.convertFromString(cls, str);
}
@Override
public Class> getEffectiveType() {
return cls;
}
});
}
/**
* Registers a converter for a specific type by method names.
*
* 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.
*
* No new converters may be registered for the global singleton.
*
* For example, {@code convert.registerMethods(Distance.class, "toString", "parse");}
*
* @param 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 the class or method name are null or invalid
* @throws IllegalStateException if trying to alter the global singleton
*/
public void registerMethods(final Class 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 converter = new MethodsStringConverter(cls, toString, fromString, cls);
registered.putIfAbsent(cls, converter);
}
/**
* Registers a converter for a specific type by method and constructor.
*
* 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.
*
* No new converters may be registered for the global singleton.
*
* For example, {@code convert.registerMethodConstructor(Distance.class, "toString");}
*
* @param 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 the class or method name are null or invalid
* @throws IllegalStateException if trying to alter the global singleton
*/
public void registerMethodConstructor(final Class 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 fromString = findFromStringConstructorByType(cls);
MethodConstructorStringConverter converter = new MethodConstructorStringConverter(cls, toString, fromString);
registered.putIfAbsent(cls, converter);
}
/**
* 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 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 Constructor findFromStringConstructorByType(Class 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();
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/FromString.java 0000664 0001750 0001750 00000002752 12603461407 024234 0 ustar ebourg ebourg /*
* Copyright 2010-present 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}.
*
* 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)}.
*
* When applying to a constructor, this annotation should be applied to the constructor
* that takes one {@code String} parameter.
*/
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR })
@Retention(RetentionPolicy.RUNTIME)
public @interface FromString {
}
joda-convert-1.8.1/src/main/java/org/joda/convert/factory/ 0000775 0001750 0001750 00000000000 12603461407 022740 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/java/org/joda/convert/factory/ByteObjectArrayStringConverterFactory.java0000664 0001750 0001750 00000010006 12603461407 033240 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.factory;
import org.joda.convert.StringConverter;
import org.joda.convert.StringConverterFactory;
import org.joda.convert.TypedStringConverter;
/**
* Factory for {@code StringConverter} providing support for Byte object array
* as a sequence of two letter hex codes for each byte plus '--' for null.
*
* This is intended as a human readable format, not a compact format.
*
* To use, simply register the instance with a {@code StringConvert} instance.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
public final class ByteObjectArrayStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
public static final StringConverterFactory INSTANCE = new ByteObjectArrayStringConverterFactory();
/**
* Restricted constructor.
*/
private ByteObjectArrayStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
if (cls == Byte[].class) {
return ByteArrayStringConverter.INSTANCE;
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
enum ByteArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Byte[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length);
for (int i = 0; i < array.length; i++) {
if (array[i] == null) {
buf.append('-').append('-');
} else {
int b = array[i].byteValue();
buf.append(HEX.charAt((b & 0xF0) >>> 4)).append(HEX.charAt(b & 0x0F));
}
}
return buf.toString();
}
@Override
public Byte[] convertFromString(Class extends Byte[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
if (str.length() % 2 == 1) {
throw new IllegalArgumentException("Invalid Byte[] string");
}
Byte[] array = new Byte[str.length() / 2];
for (int i = 0; i < array.length; i++) {
String in = str.substring(i * 2, i * 2 + 2);
if (in.equals("--")) {
array[i] = null;
} else {
array[i] = (byte) Integer.parseInt(in, 16);
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Byte[].class;
}
};
private static final Byte[] EMPTY = new Byte[0];
private static final String HEX = "0123456789ABCDEF";
}
}
././@LongLink 0000644 0000000 0000000 00000000150 00000000000 011577 L ustar root root joda-convert-1.8.1/src/main/java/org/joda/convert/factory/BooleanObjectArrayStringConverterFactory.java joda-convert-1.8.1/src/main/java/org/joda/convert/factory/BooleanObjectArrayStringConverterFactory.j0000664 0001750 0001750 00000007533 12603461407 033237 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.factory;
import org.joda.convert.StringConverter;
import org.joda.convert.StringConverterFactory;
import org.joda.convert.TypedStringConverter;
/**
* Factory for {@code StringConverter} providing support for Boolean object array
* as a sequence of 'T', 'F' and '-' for null.
*
* This is intended as a human readable format, not a compact format.
*
* To use, simply register the instance with a {@code StringConvert} instance.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
public final class BooleanObjectArrayStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
public static final StringConverterFactory INSTANCE = new BooleanObjectArrayStringConverterFactory();
/**
* Restricted constructor.
*/
private BooleanObjectArrayStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
if (cls == Boolean[].class) {
return BooleanArrayStringConverter.INSTANCE;
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
enum BooleanArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Boolean[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length);
for (int i = 0; i < array.length; i++) {
buf.append(array[i] == null ? '-' : (array[i].booleanValue() ? 'T' : 'F'));
}
return buf.toString();
}
@Override
public Boolean[] convertFromString(Class extends Boolean[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
Boolean[] array = new Boolean[str.length()];
for (int i = 0; i < array.length; i++) {
char ch = str.charAt(i);
if (ch == 'T') {
array[i] = Boolean.TRUE;
} else if (ch == 'F') {
array[i] = Boolean.FALSE;
} else if (ch == '-') {
array[i] = null;
} else {
throw new IllegalArgumentException("Invalid Boolean[] string, must consist only of 'T', 'F' and '-'");
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Boolean[].class;
}
};
private static final Boolean[] EMPTY = new Boolean[0];
}
}
././@LongLink 0000644 0000000 0000000 00000000150 00000000000 011577 L ustar root root joda-convert-1.8.1/src/main/java/org/joda/convert/factory/NumericObjectArrayStringConverterFactory.java joda-convert-1.8.1/src/main/java/org/joda/convert/factory/NumericObjectArrayStringConverterFactory.j0000664 0001750 0001750 00000023600 12603461407 033253 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.factory;
import java.util.regex.Pattern;
import org.joda.convert.StringConverter;
import org.joda.convert.StringConverterFactory;
import org.joda.convert.TypedStringConverter;
/**
* Factory for {@code StringConverter} providing support for numeric object arrays
* as a comma separated list, using '-' for null.
*
* To use, simply register the instance with a {@code StringConvert} instance.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
public final class NumericObjectArrayStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
public static final StringConverterFactory INSTANCE = new NumericObjectArrayStringConverterFactory();
/**
* Delimiter to find.
*/
static final Pattern DELIMITER = Pattern.compile("[,]");
/**
* Restricted constructor.
*/
private NumericObjectArrayStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
if (cls.isArray()) {
if (cls == Long[].class) {
return LongArrayStringConverter.INSTANCE;
}
if (cls == Integer[].class) {
return IntArrayStringConverter.INSTANCE;
}
if (cls == Short[].class) {
return ShortArrayStringConverter.INSTANCE;
}
if (cls == Double[].class) {
return DoubleArrayStringConverter.INSTANCE;
}
if (cls == Float[].class) {
return FloatArrayStringConverter.INSTANCE;
}
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
enum LongArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Long[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
buf.append(array[0] != null ? array[0] : "-");
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i] != null ? array[i] : "-");
}
return buf.toString();
}
@Override
public Long[] convertFromString(Class extends Long[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
Long[] array = new Long[split.length];
for (int i = 0; i < split.length; i++) {
if (split[i].equals("-") == false) {
array[i] = Long.parseLong(split[i]);
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Long[].class;
}
};
private static final Long[] EMPTY = new Long[0];
}
//-----------------------------------------------------------------------
enum IntArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Integer[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 6);
buf.append(array[0] != null ? array[0] : "-");
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i] != null ? array[i] : "-");
}
return buf.toString();
}
@Override
public Integer[] convertFromString(Class extends Integer[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
Integer[] array = new Integer[split.length];
for (int i = 0; i < split.length; i++) {
if (split[i].equals("-") == false) {
array[i] = Integer.parseInt(split[i]);
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Integer[].class;
}
};
private static final Integer[] EMPTY = new Integer[0];
}
//-----------------------------------------------------------------------
enum ShortArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Short[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 3);
buf.append(array[0] != null ? array[0] : "-");
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i] != null ? array[i] : "-");
}
return buf.toString();
}
@Override
public Short[] convertFromString(Class extends Short[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
Short[] array = new Short[split.length];
for (int i = 0; i < split.length; i++) {
if (split[i].equals("-") == false) {
array[i] = Short.parseShort(split[i]);
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Short[].class;
}
};
private static final Short[] EMPTY = new Short[0];
}
//-----------------------------------------------------------------------
enum DoubleArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Double[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
buf.append(array[0] != null ? array[0] : "-");
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i] != null ? array[i] : "-");
}
return buf.toString();
}
@Override
public Double[] convertFromString(Class extends Double[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
Double[] array = new Double[split.length];
for (int i = 0; i < split.length; i++) {
if (split[i].equals("-") == false) {
array[i] = Double.parseDouble(split[i]);
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Double[].class;
}
};
private static final Double[] EMPTY = new Double[0];
}
//-----------------------------------------------------------------------
enum FloatArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Float[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
buf.append(array[0] != null ? array[0] : "-");
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i] != null ? array[i] : "-");
}
return buf.toString();
}
@Override
public Float[] convertFromString(Class extends Float[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
Float[] array = new Float[split.length];
for (int i = 0; i < split.length; i++) {
if (split[i].equals("-") == false) {
array[i] = Float.parseFloat(split[i]);
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return Float[].class;
}
};
private static final Float[] EMPTY = new Float[0];
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/factory/BooleanArrayStringConverterFactory.java 0000664 0001750 0001750 00000007252 12603461407 032576 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.factory;
import org.joda.convert.StringConverter;
import org.joda.convert.StringConverterFactory;
import org.joda.convert.TypedStringConverter;
/**
* Factory for {@code StringConverter} providing support for primitive boolean array
* as a sequence of 'T' and 'F'.
*
* This is intended as a human readable format, not a compact format.
*
* To use, simply register the instance with a {@code StringConvert} instance.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
public final class BooleanArrayStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
public static final StringConverterFactory INSTANCE = new BooleanArrayStringConverterFactory();
/**
* Restricted constructor.
*/
private BooleanArrayStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
if (cls == boolean[].class) {
return BooleanArrayStringConverter.INSTANCE;
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
enum BooleanArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(boolean[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length);
for (int i = 0; i < array.length; i++) {
buf.append(array[i] ? 'T' : 'F');
}
return buf.toString();
}
@Override
public boolean[] convertFromString(Class extends boolean[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
boolean[] array = new boolean[str.length()];
for (int i = 0; i < array.length; i++) {
char ch = str.charAt(i);
if (ch == 'T') {
array[i] = true;
} else if (ch == 'F') {
array[i] = false;
} else {
throw new IllegalArgumentException("Invalid boolean[] string, must consist only of 'T' and 'F'");
}
}
return array;
}
@Override
public Class> getEffectiveType() {
return boolean[].class;
}
};
private static final boolean[] EMPTY = new boolean[0];
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/factory/CharObjectArrayStringConverterFactory.java0000664 0001750 0001750 00000011133 12603461407 033214 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.factory;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.joda.convert.StringConverter;
import org.joda.convert.StringConverterFactory;
import org.joda.convert.TypedStringConverter;
/**
* Factory for {@code StringConverter} providing support for Character object arrays
* as a string, using backslash as an escape.
*
* Double backslash is a backslash.
* One backslash followed by a dash is null.
*
* To use, simply register the instance with a {@code StringConvert} instance.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
public final class CharObjectArrayStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
public static final StringConverterFactory INSTANCE = new CharObjectArrayStringConverterFactory();
/**
* Delimiter to find.
*/
static final Pattern DELIMITER = Pattern.compile("[,]");
/**
* Restricted constructor.
*/
private CharObjectArrayStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
if (cls == Character[].class) {
return CharecterArrayStringConverter.INSTANCE;
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
enum CharecterArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(Character[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
for (int i = 0; i < array.length; i++) {
if (array[i] == null) {
buf.append("\\-");
} else {
char ch = array[i].charValue();
if (ch == '\\') {
buf.append("\\\\");
} else {
buf.append(ch);
}
}
}
return buf.toString();
}
@Override
public Character[] convertFromString(Class extends Character[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
Character[] array = new Character[str.length()];
int arrayPos = 0;
int pos;
while ((pos = str.indexOf('\\')) >= 0) {
for (int i = 0; i < pos; i++) {
array[arrayPos++] = str.charAt(i);
}
if (str.charAt(pos + 1) == '\\') {
array[arrayPos++] = '\\';
} else if (str.charAt(pos + 1) == '-') {
array[arrayPos++] = null;
} else {
throw new IllegalArgumentException("Invalid Character[] string, incorrect escape");
}
str = str.substring(pos + 2);
}
for (int i = 0; i < str.length(); i++) {
array[arrayPos++] = str.charAt(i);
}
return Arrays.copyOf(array, arrayPos);
}
@Override
public Class> getEffectiveType() {
return Character[].class;
}
};
private static final Character[] EMPTY = new Character[0];
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/factory/NumericArrayStringConverterFactory.java 0000664 0001750 0001750 00000022274 12603461407 032622 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.factory;
import java.util.regex.Pattern;
import org.joda.convert.StringConverter;
import org.joda.convert.StringConverterFactory;
import org.joda.convert.TypedStringConverter;
/**
* Factory for {@code StringConverter} providing support for primitive arrays
* as a comma separated list.
*
* To use, simply register the instance with a {@code StringConvert} instance.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
public final class NumericArrayStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
public static final StringConverterFactory INSTANCE = new NumericArrayStringConverterFactory();
/**
* Delimiter to find.
*/
static final Pattern DELIMITER = Pattern.compile("[,]");
/**
* Restricted constructor.
*/
private NumericArrayStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
if (cls.isArray() && cls.getComponentType().isPrimitive()) {
if (cls == long[].class) {
return LongArrayStringConverter.INSTANCE;
}
if (cls == int[].class) {
return IntArrayStringConverter.INSTANCE;
}
if (cls == short[].class) {
return ShortArrayStringConverter.INSTANCE;
}
if (cls == double[].class) {
return DoubleArrayStringConverter.INSTANCE;
}
if (cls == float[].class) {
return FloatArrayStringConverter.INSTANCE;
}
}
return null;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
//-----------------------------------------------------------------------
enum LongArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(long[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
buf.append(array[0]);
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i]);
}
return buf.toString();
}
@Override
public long[] convertFromString(Class extends long[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
long[] array = new long[split.length];
for (int i = 0; i < split.length; i++) {
array[i] = Long.parseLong(split[i]);
}
return array;
}
@Override
public Class> getEffectiveType() {
return long[].class;
}
};
private static final long[] EMPTY = new long[0];
}
//-----------------------------------------------------------------------
enum IntArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(int[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 6);
buf.append(array[0]);
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i]);
}
return buf.toString();
}
@Override
public int[] convertFromString(Class extends int[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
int[] array = new int[split.length];
for (int i = 0; i < split.length; i++) {
array[i] = Integer.parseInt(split[i]);
}
return array;
}
@Override
public Class> getEffectiveType() {
return int[].class;
}
};
private static final int[] EMPTY = new int[0];
}
//-----------------------------------------------------------------------
enum ShortArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(short[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 3);
buf.append(array[0]);
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i]);
}
return buf.toString();
}
@Override
public short[] convertFromString(Class extends short[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
short[] array = new short[split.length];
for (int i = 0; i < split.length; i++) {
array[i] = Short.parseShort(split[i]);
}
return array;
}
@Override
public Class> getEffectiveType() {
return short[].class;
}
};
private static final short[] EMPTY = new short[0];
}
//-----------------------------------------------------------------------
enum DoubleArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(double[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
buf.append(array[0]);
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i]);
}
return buf.toString();
}
@Override
public double[] convertFromString(Class extends double[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
double[] array = new double[split.length];
for (int i = 0; i < split.length; i++) {
array[i] = Double.parseDouble(split[i]);
}
return array;
}
@Override
public Class> getEffectiveType() {
return double[].class;
}
};
private static final double[] EMPTY = new double[0];
}
//-----------------------------------------------------------------------
enum FloatArrayStringConverter implements TypedStringConverter {
INSTANCE {
@Override
public String convertToString(float[] array) {
if (array.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder(array.length * 8);
buf.append(array[0]);
for (int i = 1; i < array.length; i++) {
buf.append(',').append(array[i]);
}
return buf.toString();
}
@Override
public float[] convertFromString(Class extends float[]> cls, String str) {
if (str.length() == 0) {
return EMPTY;
}
String[] split = DELIMITER.split(str);
float[] array = new float[split.length];
for (int i = 0; i < split.length; i++) {
array[i] = Float.parseFloat(split[i]);
}
return array;
}
@Override
public Class> getEffectiveType() {
return float[].class;
}
};
private static final float[] EMPTY = new float[0];
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/AnnotationStringConverterFactory.java 0000664 0001750 0001750 00000022353 12603461407 030662 0 ustar ebourg ebourg /*
* Copyright 2010-present 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;
/**
* Factory for {@code StringConverter} looking up annotations.
*
* This class is immutable and thread-safe.
*
* @since 1.5
*/
final class AnnotationStringConverterFactory implements StringConverterFactory {
/**
* Singleton instance.
*/
static final StringConverterFactory INSTANCE = new AnnotationStringConverterFactory();
/**
* Restricted constructor.
*/
private AnnotationStringConverterFactory() {
}
//-----------------------------------------------------------------------
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
@Override
public StringConverter> findConverter(Class> cls) {
return findAnnotatedConverter(cls); // capture generics
}
/**
* Finds a converter searching annotated.
*
* @param the type of the converter
* @param cls the class to find a method for, not null
* @return the converter, not null
* @throws RuntimeException if none found
*/
private StringConverter findAnnotatedConverter(final Class cls) {
Method toString = findToStringMethod(cls); // checks superclasses
if (toString == null) {
return null;
}
MethodConstructorStringConverter con = findFromStringConstructor(cls, toString);
MethodsStringConverter mth = findFromStringMethod(cls, toString, con == null); // optionally checks superclasses
if (con == null && mth == null) {
throw new IllegalStateException("Class annotated with @ToString but not with @FromString: " + cls.getName());
}
if (con != null && mth != null) {
throw new IllegalStateException("Both method and constructor are annotated with @FromString: " + cls.getName());
}
return (con != null ? con : mth);
}
/**
* 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}
* @throws RuntimeException if invalid
*/
private Method findToStringMethod(Class> cls) {
Method matched = null;
// find in superclass hierarchy
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: " + cls.getName());
}
matched = method;
}
}
loopCls = loopCls.getSuperclass();
}
// find in immediate parent interfaces
if (matched == null) {
for (Class> loopIfc : eliminateEnumSubclass(cls).getInterfaces()) {
Method[] methods = loopIfc.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 on interfaces: " + cls.getName());
}
matched = method;
}
}
}
}
return matched;
}
/**
* Finds the conversion method.
*
* @param the type of the converter
* @param cls the class to find a method for, not null
* @param toString the toString method, not null
* @return the method to call, null means none found
* @throws RuntimeException if invalid
*/
private MethodConstructorStringConverter findFromStringConstructor(Class cls, Method toString) {
Constructor 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);
if (fromString == null) {
return null;
}
return new MethodConstructorStringConverter(cls, toString, con);
}
/**
* Finds the conversion method.
*
* @param cls the class to find a method for, not null
* @param toString the toString method, not null
* @param searchSuperclasses whether to search superclasses
* @return the method to call, null means not found
* @throws RuntimeException if invalid
*/
private MethodsStringConverter findFromStringMethod(Class cls, Method toString, boolean searchSuperclasses) {
// find in superclass hierarchy
Class> loopCls = cls;
while (loopCls != null) {
Method fromString = findFromString(loopCls);
if (fromString != null) {
return new MethodsStringConverter(cls, toString, fromString, loopCls);
}
if (searchSuperclasses == false) {
break;
}
loopCls = loopCls.getSuperclass();
}
// find in immediate parent interfaces
MethodsStringConverter matched = null;
if (searchSuperclasses) {
for (Class> loopIfc : eliminateEnumSubclass(cls).getInterfaces()) {
Method fromString = findFromString(loopIfc);
if (fromString != null) {
if (matched != null) {
throw new IllegalStateException("Two different interfaces are annotated with " +
"@FromString or @FromStringFactory: " + cls.getName());
}
matched = new MethodsStringConverter(cls, toString, fromString, loopIfc);
}
}
}
return matched;
}
/**
* Finds the conversion method.
*
* @param cls the class to find a method for, not null
* @param matched the matched method, may be null
* @return the method to call, null means not found
* @throws RuntimeException if invalid
*/
private Method findFromString(Class> cls) {
// find in declared methods
Method[] methods = cls.getDeclaredMethods();
Method matched = null;
for (Method method : methods) {
FromString fromString = method.getAnnotation(FromString.class);
if (fromString != null) {
if (matched != null) {
throw new IllegalStateException("Two methods are annotated with @FromString: " + cls.getName());
}
matched = method;
}
}
// check for factory
FromStringFactory factory = cls.getAnnotation(FromStringFactory.class);
if (factory != null) {
if (matched != null) {
throw new IllegalStateException("Class annotated with @FromString and @FromStringFactory: " + cls.getName());
}
Method[] factoryMethods = factory.factory().getDeclaredMethods();
for (Method method : factoryMethods) {
// handle factory containing multiple FromString for different types
if (cls.isAssignableFrom(method.getReturnType())) {
FromString fromString = method.getAnnotation(FromString.class);
if (fromString != null) {
if (matched != null) {
throw new IllegalStateException("Two methods are annotated with @FromString on the factory: " + factory.factory().getName());
}
matched = method;
}
}
}
}
return matched;
}
// eliminates enum subclass as they are pesky
private Class> eliminateEnumSubclass(Class> cls) {
Class> sup = cls.getSuperclass();
if (sup != null && sup.getSuperclass() == Enum.class) {
return sup;
}
return cls;
}
//-----------------------------------------------------------------------
@Override
public String toString() {
return getClass().getSimpleName();
}
}
joda-convert-1.8.1/src/main/java/org/joda/convert/StringConverterFactory.java 0000664 0001750 0001750 00000002224 12603461407 026622 0 ustar ebourg ebourg /*
* Copyright 2010-present 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;
/**
* Factory for {@code StringConverter} that allows converters to be
* created dynamically or easily initialised.
*
* Implementations must be immutable and thread-safe.
*
* @since 1.5
*/
public interface StringConverterFactory {
/**
* Finds a converter by type.
*
* @param cls the type to lookup, not null
* @return the converter, null if not found
* @throws RuntimeException (or subclass) if source code is invalid
*/
StringConverter> findConverter(Class> cls);
}
joda-convert-1.8.1/src/main/java/org/joda/convert/FromStringFactory.java 0000664 0001750 0001750 00000003343 12603461407 025561 0 ustar ebourg ebourg /*
* Copyright 2010-present 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 on a type to indicate that another class, the factory,
* provides the 'from string' method.
*
* This annotation is applied at the type level, typically to an interface.
* It indicates the class which contains the relevant {@code FromString}
* annotation, which follows the normal rules.
*
* For example, the interface {@code Foo} could be annotated to define its
* associated factory as being {@code FooFactory}. The {@code FooFactory}
* class would then be expected to provide a method returning {@code Foo}
* with a single {@code String} parameter, annotated with {@code FromString}.
*
* @since 1.4
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FromStringFactory {
/**
* The factory class containing the static method.
* The static method must have a return type of the type that declares
* the factory annotation.
*/
Class> factory();
}
joda-convert-1.8.1/src/main/java/org/joda/convert/ToStringConverter.java 0000664 0001750 0001750 00000002257 12603461407 025603 0 ustar ebourg ebourg /*
* Copyright 2010-present 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}.
*
* ToStringConverter is an interface and must be implemented with care.
* Implementations must be immutable and thread-safe.
*
* @param the type of the converter
*/
public interface ToStringConverter {
/**
* 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);
}
joda-convert-1.8.1/src/main/java/org/joda/convert/ReflectionStringConverter.java 0000664 0001750 0001750 00000005774 12603461407 027322 0 ustar ebourg ebourg /*
* Copyright 2010-present 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.
*
* The toString method must meet the following signature:
* {@code String anyName()} on Class T.
*
* ReflectionStringConverter is abstract, but all known implementations are thread-safe and immutable.
*
* @param the type of the converter
*/
abstract class ReflectionStringConverter implements TypedStringConverter {
/** The converted class. */
private final Class cls;
/** Conversion to a string. */
private 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 cls, Method toString) {
if (toString.getParameterTypes().length != 0) {
throw new IllegalStateException("ToString method must have no parameters: " + toString);
}
if (toString.getReturnType() != String.class) {
throw new IllegalStateException("ToString method must return a String: " + toString);
}
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
*/
@Override
public String convertToString(T object) {
try {
return (String) toString.invoke(object);
} catch (IllegalAccessException ex) {
throw new IllegalStateException("Method is not accessible: " + toString);
} 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() + "]";
}
}
joda-convert-1.8.1/src/main/assembly/ 0000775 0001750 0001750 00000000000 12603461407 017003 5 ustar ebourg ebourg joda-convert-1.8.1/src/main/assembly/dist.xml 0000664 0001750 0001750 00000001541 12603461407 020471 0 ustar ebourg ebourg
dist
tar.gz
zip
${artifactId}-${version}
checkstyle.xml
LICENSE.txt
NOTICE.txt
pom.xml
RELEASE-NOTES.txt
src
target
*.jar
joda-convert-1.8.1/src/site/ 0000775 0001750 0001750 00000000000 12603461407 015204 5 ustar ebourg ebourg joda-convert-1.8.1/src/site/resources/ 0000775 0001750 0001750 00000000000 12603461407 017216 5 ustar ebourg ebourg joda-convert-1.8.1/src/site/resources/download.html 0000664 0001750 0001750 00000000233 12603461407 021711 0 ustar ebourg ebourg
OpenGamma