mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 11:35:29 -04:00
Clean-up and minor changes in core classes.
Adapted new code style. No or few functional changes.
This commit is contained in:
parent
df0d3f90e8
commit
191643a36c
@ -276,19 +276,19 @@ public final class BeanUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// If this does not throw an excption, it works
|
// If this does not throw an exception, it works
|
||||||
method = pObject.getClass().getMethod(pName, pParams);
|
method = pObject.getClass().getMethod(pName, pParams);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable t) {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2: Try any supertypes of paramType, to see if we have a match
|
// 2: Try any super-types of paramType, to see if we have a match
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
while ((paramType = paramType.getSuperclass()) != null) {
|
while ((paramType = paramType.getSuperclass()) != null) {
|
||||||
pParams[0] = paramType;
|
pParams[0] = paramType;
|
||||||
try {
|
try {
|
||||||
// If this does not throw an excption, it works
|
// If this does not throw an exception, it works
|
||||||
method = pObject.getClass().getMethod(pName, pParams);
|
method = pObject.getClass().getMethod(pName, pParams);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable t) {
|
||||||
@ -365,6 +365,9 @@ public final class BeanUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Convert value to single-value array if needed
|
||||||
|
// TODO: Convert CSV String to string array (or potentially any type of array)
|
||||||
|
|
||||||
// TODO: Convert other types
|
// TODO: Convert other types
|
||||||
if (pValue instanceof String) {
|
if (pValue instanceof String) {
|
||||||
Converter converter = Converter.getInstance();
|
Converter converter = Converter.getInstance();
|
||||||
@ -596,8 +599,7 @@ public final class BeanUtil {
|
|||||||
catch (NoSuchMethodException ignore) {
|
catch (NoSuchMethodException ignore) {
|
||||||
// If invocation failed, convert lisp-style and try again
|
// If invocation failed, convert lisp-style and try again
|
||||||
if (pLispToCamel && property.indexOf('-') > 0) {
|
if (pLispToCamel && property.indexOf('-') > 0) {
|
||||||
setPropertyValue(pBean, StringUtil.lispToCamel(property, false),
|
setPropertyValue(pBean, StringUtil.lispToCamel(property, false), entry.getValue());
|
||||||
entry.getValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import java.io.IOException;
|
|||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExceptionUtil
|
* ExceptionUtil
|
||||||
*
|
*
|
||||||
@ -14,6 +16,15 @@ import java.sql.SQLException;
|
|||||||
*/
|
*/
|
||||||
public final class ExceptionUtil {
|
public final class ExceptionUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-throws an exception, either as-is if the exception was already unchecked, otherwise wrapped in
|
||||||
|
* a {@link RuntimeException}.
|
||||||
|
* "Expected" exception types are wrapped in {@link RuntimeException}s, while
|
||||||
|
* "unexpected" exception types are wrapped in {@link java.lang.reflect.UndeclaredThrowableException}s.
|
||||||
|
*
|
||||||
|
* @param pThrowable the exception to launder
|
||||||
|
* @param pExpectedTypes the types of exception the code is expected to throw
|
||||||
|
*/
|
||||||
/*public*/ static void launder(final Throwable pThrowable, Class<? extends Throwable>... pExpectedTypes) {
|
/*public*/ static void launder(final Throwable pThrowable, Class<? extends Throwable>... pExpectedTypes) {
|
||||||
if (pThrowable instanceof Error) {
|
if (pThrowable instanceof Error) {
|
||||||
throw (Error) pThrowable;
|
throw (Error) pThrowable;
|
||||||
@ -40,36 +51,38 @@ public final class ExceptionUtil {
|
|||||||
throwAs(RuntimeException.class, pThrowable);
|
throwAs(RuntimeException.class, pThrowable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler<? extends Throwable>... pHandler) {
|
@SuppressWarnings({"unchecked"})
|
||||||
handleImpl(pThrowable, pHandler);
|
/*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler<? extends Throwable>... pHandlers) {
|
||||||
|
handleImpl(pThrowable, (ThrowableHandler<Throwable>[]) pHandlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
private static void handleImpl(final Throwable pThrowable, final ThrowableHandler<Throwable>... pHandlers) {
|
||||||
private static <T extends Throwable> void handleImpl(final Throwable pThrowable, final ThrowableHandler<T>... pHandler) {
|
|
||||||
// TODO: Sort more specific throwable handlers before less specific?
|
// TODO: Sort more specific throwable handlers before less specific?
|
||||||
for (ThrowableHandler<T> handler : pHandler) {
|
for (ThrowableHandler<Throwable> handler : pHandlers) {
|
||||||
if (handler.handles(pThrowable)) {
|
if (handler.handles(pThrowable)) {
|
||||||
handler.handle((T) pThrowable);
|
handler.handle(pThrowable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not handled, re-throw
|
||||||
throwUnchecked(pThrowable);
|
throwUnchecked(pThrowable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class ThrowableHandler<T extends Throwable> {
|
public static abstract class ThrowableHandler<T extends Throwable> {
|
||||||
private Class<? extends T>[] mThrowables;
|
private final Class<? extends T>[] throwables;
|
||||||
|
|
||||||
protected ThrowableHandler(final Class<? extends T>... pThrowables) {
|
protected ThrowableHandler(final Class<? extends T>... pThrowables) {
|
||||||
// TODO: Assert not null
|
throwables = notNull(pThrowables).clone();
|
||||||
mThrowables = pThrowables.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final public boolean handles(final Throwable pThrowable) {
|
final public boolean handles(final Throwable pThrowable) {
|
||||||
for (Class<? extends T> throwable : mThrowables) {
|
for (Class<? extends T> throwable : throwables) {
|
||||||
if (throwable.isAssignableFrom(pThrowable.getClass())) {
|
if (throwable.isAssignableFrom(pThrowable.getClass())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,24 +39,24 @@ public final class Platform {
|
|||||||
/**
|
/**
|
||||||
* Normalized operating system constant
|
* Normalized operating system constant
|
||||||
*/
|
*/
|
||||||
final OperatingSystem mOS;
|
final OperatingSystem os;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unormalized operating system version constant (for completeness)
|
* Unormalized operating system version constant (for completeness)
|
||||||
*/
|
*/
|
||||||
final String mVersion;
|
final String version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalized system architecture constant
|
* Normalized system architecture constant
|
||||||
*/
|
*/
|
||||||
final Architecture mArchitecture;
|
final Architecture architecture;
|
||||||
|
|
||||||
static final private Platform INSTANCE = new Platform();
|
static final private Platform INSTANCE = new Platform();
|
||||||
|
|
||||||
private Platform() {
|
private Platform() {
|
||||||
mOS = normalizeOperatingSystem();
|
os = normalizeOperatingSystem();
|
||||||
mVersion = System.getProperty("os.version");
|
version = System.getProperty("os.version");
|
||||||
mArchitecture = normalizeArchitecture(mOS);
|
architecture = normalizeArchitecture(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperatingSystem normalizeOperatingSystem() {
|
private static OperatingSystem normalizeOperatingSystem() {
|
||||||
@ -138,21 +138,21 @@ public final class Platform {
|
|||||||
* @return this platform's OS.
|
* @return this platform's OS.
|
||||||
*/
|
*/
|
||||||
public OperatingSystem getOS() {
|
public OperatingSystem getOS() {
|
||||||
return mOS;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return this platform's OS version.
|
* @return this platform's OS version.
|
||||||
*/
|
*/
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
return mVersion;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return this platform's architecture.
|
* @return this platform's architecture.
|
||||||
*/
|
*/
|
||||||
public Architecture getArchitecture() {
|
public Architecture getArchitecture() {
|
||||||
return mArchitecture;
|
return architecture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,7 +160,7 @@ public final class Platform {
|
|||||||
* @return the current {@code OperatingSystem}.
|
* @return the current {@code OperatingSystem}.
|
||||||
*/
|
*/
|
||||||
public static OperatingSystem os() {
|
public static OperatingSystem os() {
|
||||||
return INSTANCE.mOS;
|
return INSTANCE.os;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,7 +168,7 @@ public final class Platform {
|
|||||||
* @return the current OS version.
|
* @return the current OS version.
|
||||||
*/
|
*/
|
||||||
public static String version() {
|
public static String version() {
|
||||||
return INSTANCE.mVersion;
|
return INSTANCE.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,7 +176,7 @@ public final class Platform {
|
|||||||
* @return the current {@code Architecture}.
|
* @return the current {@code Architecture}.
|
||||||
*/
|
*/
|
||||||
public static Architecture arch() {
|
public static Architecture arch() {
|
||||||
return INSTANCE.mArchitecture;
|
return INSTANCE.architecture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,14 +197,14 @@ public final class Platform {
|
|||||||
|
|
||||||
Unknown(System.getProperty("os.arch"));
|
Unknown(System.getProperty("os.arch"));
|
||||||
|
|
||||||
final String mName;// for debug only
|
final String name;// for debug only
|
||||||
|
|
||||||
private Architecture(String pName) {
|
private Architecture(String pName) {
|
||||||
mName = pName;
|
name = pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return mName;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,20 +225,20 @@ public final class Platform {
|
|||||||
|
|
||||||
Unknown(System.getProperty("os.name"), "");
|
Unknown(System.getProperty("os.name"), "");
|
||||||
|
|
||||||
final String mId;
|
final String id;
|
||||||
final String mName;// for debug only
|
final String name;// for debug only
|
||||||
|
|
||||||
private OperatingSystem(String pName, String pId) {
|
private OperatingSystem(String pName, String pId) {
|
||||||
mName = pName;
|
name = pName;
|
||||||
mId = pId;
|
id = pId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return mName;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return mId;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public final class StringUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link String} by decoding the specified subarray of bytes using the specified charset.
|
* Constructs a new {@link String} by decoding the specified sub array of bytes using the specified charset.
|
||||||
* Replacement for {@link String#String(byte[], int, int, String) new String(byte[], int, int, String)}, that does
|
* Replacement for {@link String#String(byte[], int, int, String) new String(byte[], int, int, String)}, that does
|
||||||
* not throw the checked {@link UnsupportedEncodingException},
|
* not throw the checked {@link UnsupportedEncodingException},
|
||||||
* but instead the unchecked {@link UnsupportedCharsetException} if the character set is not supported.
|
* but instead the unchecked {@link UnsupportedCharsetException} if the character set is not supported.
|
||||||
@ -1580,7 +1580,7 @@ public final class StringUtil {
|
|||||||
* Converts a string array to a string separated by the given delimiter.
|
* Converts a string array to a string separated by the given delimiter.
|
||||||
*
|
*
|
||||||
* @param pStringArray the string array
|
* @param pStringArray the string array
|
||||||
* @param pDelimiterString the delimter string
|
* @param pDelimiterString the delimiter string
|
||||||
* @return string of delimiter separated values
|
* @return string of delimiter separated values
|
||||||
* @throws IllegalArgumentException if {@code pDelimiterString == null}
|
* @throws IllegalArgumentException if {@code pDelimiterString == null}
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,8 @@ import java.util.Map;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/Validate.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/Validate.java#1 $
|
||||||
*/
|
*/
|
||||||
public final class Validate {
|
public final class Validate {
|
||||||
|
// TODO: Make it possible to throw IllegalStateException instead of IllegalArgumentException?
|
||||||
|
|
||||||
private static final String UNSPECIFIED_PARAM_NAME = "method parameter";
|
private static final String UNSPECIFIED_PARAM_NAME = "method parameter";
|
||||||
|
|
||||||
private Validate() {}
|
private Validate() {}
|
||||||
@ -121,4 +123,16 @@ public final class Validate {
|
|||||||
|
|
||||||
return pParameter;
|
return pParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isTrue(final boolean pExpression, final String pMessage) {
|
||||||
|
return isTrue(pExpression, pExpression, pMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T isTrue(final boolean condition, final T value, final String message) {
|
||||||
|
if (!condition) {
|
||||||
|
throw new IllegalArgumentException(String.format(message, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ import java.io.Serializable;
|
|||||||
/**
|
/**
|
||||||
* A {@code Map} adapter for a Java Bean.
|
* A {@code Map} adapter for a Java Bean.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Ruhtlessly stolen from
|
* Ruthlessly stolen from
|
||||||
* <a href="http://binkley.blogspot.com/2006/08/mapping-java-bean.html>Binkley's Blog</a>
|
* <a href="http://binkley.blogspot.com/2006/08/mapping-java-bean.html>Binkley's Blog</a>
|
||||||
*/
|
*/
|
||||||
public final class BeanMap extends AbstractMap<String, Object> implements Serializable, Cloneable {
|
public final class BeanMap extends AbstractMap<String, Object> implements Serializable, Cloneable {
|
||||||
|
@ -37,60 +37,31 @@ package com.twelvemonkeys.util.convert;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/convert/ConversionException.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/convert/ConversionException.java#1 $
|
||||||
*/
|
*/
|
||||||
public class ConversionException extends IllegalArgumentException {
|
public class ConversionException extends IllegalArgumentException {
|
||||||
protected Throwable mCause = this;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code ConversionException} with the given error message.
|
* Creates a {@code ConversionException} with the given error message.
|
||||||
*
|
*
|
||||||
* @param pMessage the error message
|
* @param pMessage the error message
|
||||||
*/
|
*/
|
||||||
public ConversionException(String pMessage) {
|
public ConversionException(final String pMessage) {
|
||||||
super(pMessage);
|
super(pMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code ConversionException} with the given cause.
|
* Creates a {@code ConversionException} with the given cause.
|
||||||
*
|
*
|
||||||
* @param pCause The Throwable that caused this exception
|
* @param pCause The {@link Throwable} that caused this exception
|
||||||
*/
|
*/
|
||||||
public ConversionException(Throwable pCause) {
|
public ConversionException(final Throwable pCause) {
|
||||||
super(pCause == null ? null : pCause.getMessage());
|
super(pCause != null ? pCause.getMessage() : null, pCause);
|
||||||
initCause(pCause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cause of this {@code Throwable} or {@code null} if the
|
* Creates a {@code ConversionException} with the given message and cause.
|
||||||
* cause is nonexistent or unknown.
|
|
||||||
*
|
*
|
||||||
* @return the cause of this {@code Throwable} or {@code null} if the
|
* @param pMessage the error message
|
||||||
* cause is nonexistent or unknown (the cause is the throwable that caused
|
* @param pCause The {@link Throwable} that caused this exception
|
||||||
* this throwable to get thrown).
|
|
||||||
*/
|
*/
|
||||||
public Throwable getCause() {
|
public ConversionException(final String pMessage, final Throwable pCause) {
|
||||||
if (mCause == this) {
|
super(pMessage, pCause);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return mCause;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes this ConversionException with the given cause.
|
|
||||||
*
|
|
||||||
* @param pCause The Throwable that caused this exception
|
|
||||||
*
|
|
||||||
* @throws IllegalStateException if cause is allready set
|
|
||||||
* @throws IllegalArgumentException if {@code pCause == this}
|
|
||||||
*/
|
|
||||||
public Throwable initCause(Throwable pCause) {
|
|
||||||
if (mCause != this) {
|
|
||||||
throw new IllegalStateException("Can't overwrite cause");
|
|
||||||
}
|
|
||||||
if (pCause == this) {
|
|
||||||
throw new IllegalArgumentException("Can't be caused by self");
|
|
||||||
}
|
|
||||||
|
|
||||||
mCause = pCause;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,13 +56,14 @@ import java.util.Map;
|
|||||||
// Maybe have BeanUtil act as a "proxy", and hide this class alltogheter?
|
// Maybe have BeanUtil act as a "proxy", and hide this class alltogheter?
|
||||||
// TODO: ServiceRegistry for registering 3rd party converters
|
// TODO: ServiceRegistry for registering 3rd party converters
|
||||||
// TODO: URI scheme, for implicit typing? Is that a good idea?
|
// TODO: URI scheme, for implicit typing? Is that a good idea?
|
||||||
|
// TODO: Array converters?
|
||||||
public abstract class Converter implements PropertyConverter {
|
public abstract class Converter implements PropertyConverter {
|
||||||
|
|
||||||
/** Our singleton instance */
|
/** Our singleton instance */
|
||||||
protected static Converter sInstance = new ConverterImpl(); // Thread safe & EASY
|
protected static Converter sInstance = new ConverterImpl(); // Thread safe & EASY
|
||||||
|
|
||||||
/** The conveters Map */
|
/** The conveters Map */
|
||||||
protected Map mConverters = new Hashtable();
|
protected Map converters = new Hashtable();
|
||||||
|
|
||||||
// Register our predefined converters
|
// Register our predefined converters
|
||||||
static {
|
static {
|
||||||
@ -115,7 +116,7 @@ public abstract class Converter implements PropertyConverter {
|
|||||||
* @see #unregisterConverter(Class)
|
* @see #unregisterConverter(Class)
|
||||||
*/
|
*/
|
||||||
public static void registerConverter(Class pType, PropertyConverter pConverter) {
|
public static void registerConverter(Class pType, PropertyConverter pConverter) {
|
||||||
getInstance().mConverters.put(pType, pConverter);
|
getInstance().converters.put(pType, pConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +129,7 @@ public abstract class Converter implements PropertyConverter {
|
|||||||
* @see #registerConverter(Class,PropertyConverter)
|
* @see #registerConverter(Class,PropertyConverter)
|
||||||
*/
|
*/
|
||||||
public static void unregisterConverter(Class pType) {
|
public static void unregisterConverter(Class pType) {
|
||||||
getInstance().mConverters.remove(pType);
|
getInstance().converters.remove(pType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +59,7 @@ class ConverterImpl extends Converter {
|
|||||||
// Loop until we find a suitable converter
|
// Loop until we find a suitable converter
|
||||||
do {
|
do {
|
||||||
// Have a match, return converter
|
// Have a match, return converter
|
||||||
if ((converter = getInstance().mConverters.get(cl)) != null) {
|
if ((converter = getInstance().converters.get(cl)) != null) {
|
||||||
return (PropertyConverter) converter;
|
return (PropertyConverter) converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +28,11 @@
|
|||||||
|
|
||||||
package com.twelvemonkeys.util.convert;
|
package com.twelvemonkeys.util.convert;
|
||||||
|
|
||||||
import com.twelvemonkeys.lang.*;
|
import com.twelvemonkeys.lang.BeanUtil;
|
||||||
|
import com.twelvemonkeys.lang.StringUtil;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts strings to objects and back.
|
* Converts strings to objects and back.
|
||||||
@ -67,9 +69,7 @@ public final class DefaultConverter implements PropertyConverter {
|
|||||||
* be converted into the given type, using a string constructor or static
|
* be converted into the given type, using a string constructor or static
|
||||||
* {@code valueof} method.
|
* {@code valueof} method.
|
||||||
*/
|
*/
|
||||||
public Object toObject(String pString, final Class pType, String pFormat)
|
public Object toObject(String pString, final Class pType, String pFormat) throws ConversionException {
|
||||||
throws ConversionException {
|
|
||||||
|
|
||||||
if (pString == null) {
|
if (pString == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -78,6 +78,14 @@ public final class DefaultConverter implements PropertyConverter {
|
|||||||
throw new MissingTypeException();
|
throw new MissingTypeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pType.isArray()) {
|
||||||
|
return toArray(pString, pType, pFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Separate CollectionConverter?
|
||||||
|
// should however, be simple to wrap array using Arrays.asList
|
||||||
|
// But what about generic type?! It's erased...
|
||||||
|
|
||||||
// Primitive -> wrapper
|
// Primitive -> wrapper
|
||||||
Class type;
|
Class type;
|
||||||
if (pType == Boolean.TYPE) {
|
if (pType == Boolean.TYPE) {
|
||||||
@ -113,6 +121,31 @@ public final class DefaultConverter implements PropertyConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object toArray(String pString, Class pType, String pFormat) {
|
||||||
|
String[] strings = StringUtil.toStringArray(pString, pFormat != null ? pFormat : StringUtil.DELIMITER_STRING);
|
||||||
|
Class type = pType.getComponentType();
|
||||||
|
if (type == String.class) {
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object array = Array.newInstance(type, strings.length);
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < strings.length; i++) {
|
||||||
|
Array.set(array, i, Converter.getInstance().toObject(strings[i], type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ConversionException e) {
|
||||||
|
if (pFormat != null) {
|
||||||
|
throw new ConversionException(String.format("%s for string \"%s\" with format \"%s\"", e.getMessage(), pString, pFormat), e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new ConversionException(String.format("%s for string \"%s\"", e.getMessage(), pString), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the object to a string, using {@code pObject.toString()}.
|
* Converts the object to a string, using {@code pObject.toString()}.
|
||||||
*
|
*
|
||||||
@ -126,10 +159,77 @@ public final class DefaultConverter implements PropertyConverter {
|
|||||||
throws ConversionException {
|
throws ConversionException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (pObject != null ? pObject.toString() : null);
|
return pObject == null ? null : pObject.getClass().isArray() ? arrayToString(toObjectArray(pObject), pFormat) : pObject.toString();
|
||||||
}
|
}
|
||||||
catch (RuntimeException rte) {
|
catch (RuntimeException rte) {
|
||||||
throw new ConversionException(rte);
|
throw new ConversionException(rte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String arrayToString(final Object[] pArray, final String pFormat) {
|
||||||
|
return pFormat == null ? StringUtil.toCSVString(pArray) : StringUtil.toCSVString(pArray, pFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object[] toObjectArray(Object pObject) {
|
||||||
|
// TODO: Extract util method for wrapping/unwrapping native arrays?
|
||||||
|
Object[] array;
|
||||||
|
Class<?> componentType = pObject.getClass().getComponentType();
|
||||||
|
if (componentType.isPrimitive()) {
|
||||||
|
if (int.class == componentType) {
|
||||||
|
array = new Integer[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (short.class == componentType) {
|
||||||
|
array = new Short[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (long.class == componentType) {
|
||||||
|
array = new Long[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (float.class == componentType) {
|
||||||
|
array = new Float[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (double.class == componentType) {
|
||||||
|
array = new Double[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (boolean.class == componentType) {
|
||||||
|
array = new Boolean[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (byte.class == componentType) {
|
||||||
|
array = new Byte[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (char.class == componentType) {
|
||||||
|
array = new Character[Array.getLength(pObject)];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
Array.set(array, i, Array.get(pObject, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException("Unknown type " + componentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
array = (Object[]) pObject;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,14 +39,14 @@ import java.text.*;
|
|||||||
* Converts strings to numbers and back.
|
* Converts strings to numbers and back.
|
||||||
* <p/>
|
* <p/>
|
||||||
* <small>This class has a static cache of {@code NumberFormats}, to avoid
|
* <small>This class has a static cache of {@code NumberFormats}, to avoid
|
||||||
* creation and parsing of numberformats every time one is used.</small>
|
* creation and parsing of number formats every time one is used.</small>
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
* @author last modified by $Author: haku $
|
* @author last modified by $Author: haku $
|
||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/convert/NumberConverter.java#2 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/convert/NumberConverter.java#2 $
|
||||||
*/
|
*/
|
||||||
public class NumberConverter implements PropertyConverter {
|
public class NumberConverter implements PropertyConverter {
|
||||||
// TODO: Need to either make this non-local aware, or document that it is...
|
// TODO: Need to either make this non-locale aware, or document that it is...
|
||||||
|
|
||||||
private static final DecimalFormatSymbols SYMBOLS = new DecimalFormatSymbols(Locale.US);
|
private static final DecimalFormatSymbols SYMBOLS = new DecimalFormatSymbols(Locale.US);
|
||||||
private static final NumberFormat sDefaultFormat = new DecimalFormat("#0.#", SYMBOLS);
|
private static final NumberFormat sDefaultFormat = new DecimalFormat("#0.#", SYMBOLS);
|
||||||
|
@ -45,8 +45,8 @@ import java.util.regex.PatternSyntaxException;
|
|||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/RegExTokenIterator.java#1 $
|
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/regex/RegExTokenIterator.java#1 $
|
||||||
*/
|
*/
|
||||||
public class RegExTokenIterator extends AbstractTokenIterator {
|
public class RegExTokenIterator extends AbstractTokenIterator {
|
||||||
private final Matcher mMatcher;
|
private final Matcher matcher;
|
||||||
private boolean mNext = false;
|
private boolean next = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code RegExTokenIterator}.
|
* Creates a {@code RegExTokenIterator}.
|
||||||
@ -80,7 +80,7 @@ public class RegExTokenIterator extends AbstractTokenIterator {
|
|||||||
throw new IllegalArgumentException("pattern == null");
|
throw new IllegalArgumentException("pattern == null");
|
||||||
}
|
}
|
||||||
|
|
||||||
mMatcher = Pattern.compile(pPattern).matcher(pString);
|
matcher = Pattern.compile(pPattern).matcher(pString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,18 +88,18 @@ public class RegExTokenIterator extends AbstractTokenIterator {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
mMatcher.reset();
|
matcher.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return mNext || (mNext = mMatcher.find());
|
return next || (next = matcher.find());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String next() {
|
public String next() {
|
||||||
if (!hasNext()) {
|
if (!hasNext()) {
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
mNext = false;
|
next = false;
|
||||||
return mMatcher.group();
|
return matcher.group();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -114,6 +114,7 @@ import java.io.PrintStream;
|
|||||||
* @deprecated Will probably be removed in the near future
|
* @deprecated Will probably be removed in the near future
|
||||||
*/
|
*/
|
||||||
public class WildcardStringParser {
|
public class WildcardStringParser {
|
||||||
|
// TODO: Get rid of this class
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class ServiceRegistry {
|
public class ServiceRegistry {
|
||||||
// TODO: Security issues?
|
// TODO: Security issues?
|
||||||
// TODO: Application contexts?
|
// TODO: Application contexts? Probably use instance per thread group..
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "META-INF/services/"
|
* "META-INF/services/"
|
||||||
@ -73,7 +73,7 @@ public class ServiceRegistry {
|
|||||||
public static final String SERVICES = "META-INF/services/";
|
public static final String SERVICES = "META-INF/services/";
|
||||||
|
|
||||||
// Class to CategoryRegistry mapping
|
// Class to CategoryRegistry mapping
|
||||||
private final Map<Class<?>, CategoryRegistry> mCategoryMap;
|
private final Map<Class<?>, CategoryRegistry> categoryMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code ServiceRegistry} instance with a set of categories
|
* Creates a {@code ServiceRegistry} instance with a set of categories
|
||||||
@ -98,7 +98,7 @@ public class ServiceRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Categories are constant for the lifetime of a registry
|
// NOTE: Categories are constant for the lifetime of a registry
|
||||||
mCategoryMap = Collections.unmodifiableMap(map);
|
categoryMap = Collections.unmodifiableMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void putCategory(Map<Class<?>, CategoryRegistry> pMap, Class<T> pCategory) {
|
private <T> void putCategory(Map<Class<?>, CategoryRegistry> pMap, Class<T> pCategory) {
|
||||||
@ -154,7 +154,7 @@ public class ServiceRegistry {
|
|||||||
|
|
||||||
if (!classNames.isEmpty()) {
|
if (!classNames.isEmpty()) {
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
CategoryRegistry<T> registry = mCategoryMap.get(pCategory);
|
CategoryRegistry<T> registry = categoryMap.get(pCategory);
|
||||||
|
|
||||||
Set providerClassNames = classNames.keySet();
|
Set providerClassNames = classNames.keySet();
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ public class ServiceRegistry {
|
|||||||
* @return an {@code Iterator} containing all categories in this registry.
|
* @return an {@code Iterator} containing all categories in this registry.
|
||||||
*/
|
*/
|
||||||
protected Iterator<Class<?>> categories() {
|
protected Iterator<Class<?>> categories() {
|
||||||
return mCategoryMap.keySet().iterator();
|
return categoryMap.keySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -260,18 +260,19 @@ public class ServiceRegistry {
|
|||||||
return getRegistry(pElement).contatins(pProvider);
|
return getRegistry(pElement).contatins(pProvider);
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
Class<?> mCurrent;
|
Class<?> current;
|
||||||
|
|
||||||
public Class next() {
|
public Class next() {
|
||||||
return (mCurrent = super.next());
|
return (current = super.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
if (mCurrent == null) {
|
if (current == null) {
|
||||||
throw new IllegalStateException("No current element");
|
throw new IllegalStateException("No current element");
|
||||||
}
|
}
|
||||||
getRegistry(mCurrent).deregister(pProvider);
|
|
||||||
mCurrent = null;
|
getRegistry(current).deregister(pProvider);
|
||||||
|
current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -284,7 +285,7 @@ public class ServiceRegistry {
|
|||||||
*/
|
*/
|
||||||
private <T> CategoryRegistry<T> getRegistry(final Class<T> pCategory) {
|
private <T> CategoryRegistry<T> getRegistry(final Class<T> pCategory) {
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
CategoryRegistry<T> registry = mCategoryMap.get(pCategory);
|
CategoryRegistry<T> registry = categoryMap.get(pCategory);
|
||||||
if (registry == null) {
|
if (registry == null) {
|
||||||
throw new IllegalArgumentException("No such category: " + pCategory.getName());
|
throw new IllegalArgumentException("No such category: " + pCategory.getName());
|
||||||
}
|
}
|
||||||
@ -366,17 +367,17 @@ public class ServiceRegistry {
|
|||||||
* Keeps track of each individual category.
|
* Keeps track of each individual category.
|
||||||
*/
|
*/
|
||||||
class CategoryRegistry<T> {
|
class CategoryRegistry<T> {
|
||||||
private final Class<T> mCategory;
|
private final Class<T> category;
|
||||||
private final Map<Class, T> mProviders = new LinkedHashMap<Class, T>();
|
private final Map<Class, T> providers = new LinkedHashMap<Class, T>();
|
||||||
|
|
||||||
CategoryRegistry(Class<T> pCategory) {
|
CategoryRegistry(Class<T> pCategory) {
|
||||||
Validate.notNull(pCategory, "category");
|
Validate.notNull(pCategory, "category");
|
||||||
mCategory = pCategory;
|
category = pCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCategory(final Object pProvider) {
|
private void checkCategory(final Object pProvider) {
|
||||||
if (!mCategory.isInstance(pProvider)) {
|
if (!category.isInstance(pProvider)) {
|
||||||
throw new IllegalArgumentException(pProvider + " not instance of category " + mCategory.getName());
|
throw new IllegalArgumentException(pProvider + " not instance of category " + category.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +387,7 @@ public class ServiceRegistry {
|
|||||||
// NOTE: We only register the new instance, if we don't allready
|
// NOTE: We only register the new instance, if we don't allready
|
||||||
// have an instance of pProvider's class.
|
// have an instance of pProvider's class.
|
||||||
if (!contatins(pProvider)) {
|
if (!contatins(pProvider)) {
|
||||||
mProviders.put(pProvider.getClass(), pProvider);
|
providers.put(pProvider.getClass(), pProvider);
|
||||||
processRegistration(pProvider);
|
processRegistration(pProvider);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -397,7 +398,7 @@ public class ServiceRegistry {
|
|||||||
void processRegistration(final T pProvider) {
|
void processRegistration(final T pProvider) {
|
||||||
if (pProvider instanceof RegisterableService) {
|
if (pProvider instanceof RegisterableService) {
|
||||||
RegisterableService service = (RegisterableService) pProvider;
|
RegisterableService service = (RegisterableService) pProvider;
|
||||||
service.onRegistration(ServiceRegistry.this, mCategory);
|
service.onRegistration(ServiceRegistry.this, category);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +407,7 @@ public class ServiceRegistry {
|
|||||||
|
|
||||||
// NOTE: We remove any provider of the same class, this may or may
|
// NOTE: We remove any provider of the same class, this may or may
|
||||||
// not be the same instance as pProvider.
|
// not be the same instance as pProvider.
|
||||||
T oldProvider = mProviders.remove(pProvider.getClass());
|
T oldProvider = providers.remove(pProvider.getClass());
|
||||||
|
|
||||||
if (oldProvider != null) {
|
if (oldProvider != null) {
|
||||||
processDeregistration(oldProvider);
|
processDeregistration(oldProvider);
|
||||||
@ -419,12 +420,12 @@ public class ServiceRegistry {
|
|||||||
void processDeregistration(final T pOldProvider) {
|
void processDeregistration(final T pOldProvider) {
|
||||||
if (pOldProvider instanceof RegisterableService) {
|
if (pOldProvider instanceof RegisterableService) {
|
||||||
RegisterableService service = (RegisterableService) pOldProvider;
|
RegisterableService service = (RegisterableService) pOldProvider;
|
||||||
service.onDeregistration(ServiceRegistry.this, mCategory);
|
service.onDeregistration(ServiceRegistry.this, category);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contatins(final Object pProvider) {
|
public boolean contatins(final Object pProvider) {
|
||||||
return mProviders.containsKey(pProvider.getClass());
|
return providers.containsKey(pProvider.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<T> providers() {
|
public Iterator<T> providers() {
|
||||||
@ -432,9 +433,9 @@ public class ServiceRegistry {
|
|||||||
// using the deregister method will result in
|
// using the deregister method will result in
|
||||||
// ConcurrentModificationException in the iterator..
|
// ConcurrentModificationException in the iterator..
|
||||||
// We wrap the iterator to track deregistration right.
|
// We wrap the iterator to track deregistration right.
|
||||||
final Iterator<T> iterator = mProviders.values().iterator();
|
final Iterator<T> iterator = providers.values().iterator();
|
||||||
return new Iterator<T>() {
|
return new Iterator<T>() {
|
||||||
T mCurrent;
|
T current;
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return iterator.hasNext();
|
return iterator.hasNext();
|
||||||
@ -442,12 +443,12 @@ public class ServiceRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public T next() {
|
public T next() {
|
||||||
return (mCurrent = iterator.next());
|
return (current = iterator.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
processDeregistration(mCurrent);
|
processDeregistration(current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.twelvemonkeys.util.convert;
|
package com.twelvemonkeys.util.convert;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DefaultConverterTestCase
|
* DefaultConverterTestCase
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -20,7 +23,9 @@ public class DefaultConverterTestCase extends PropertyConverterAbstractTestCase
|
|||||||
new Conversion("true", Boolean.TRUE),
|
new Conversion("true", Boolean.TRUE),
|
||||||
new Conversion("TRUE", Boolean.TRUE, null, "true"),
|
new Conversion("TRUE", Boolean.TRUE, null, "true"),
|
||||||
new Conversion("false", Boolean.FALSE),
|
new Conversion("false", Boolean.FALSE),
|
||||||
new Conversion("FALSE", new Boolean(false), null, "false"),
|
new Conversion("FALSE", false, null, "false"),
|
||||||
|
|
||||||
|
new Conversion("2", 2),
|
||||||
|
|
||||||
// Stupid but valid
|
// Stupid but valid
|
||||||
new Conversion("fooBar", "fooBar"),
|
new Conversion("fooBar", "fooBar"),
|
||||||
@ -29,6 +34,22 @@ public class DefaultConverterTestCase extends PropertyConverterAbstractTestCase
|
|||||||
// Stupid test class that reveres chars
|
// Stupid test class that reveres chars
|
||||||
new Conversion("fooBar", new FooBar("fooBar")),
|
new Conversion("fooBar", new FooBar("fooBar")),
|
||||||
|
|
||||||
|
// String array tests
|
||||||
|
new Conversion("foo, bar, baz", new String[] {"foo", "bar", "baz"}),
|
||||||
|
new Conversion("foo", new String[] {"foo"}),
|
||||||
|
new Conversion("foo;bar; baz", new String[] {"foo", "bar", "baz"}, "; ", "foo; bar; baz"),
|
||||||
|
|
||||||
|
// Native array tests
|
||||||
|
new Conversion("1, 2, 3", new int[] {1, 2, 3}),
|
||||||
|
new Conversion("-1, 42, 0", new long[] {-1, 42, 0}),
|
||||||
|
new Conversion("true, true, false", new boolean[] {true, true, false}),
|
||||||
|
new Conversion(".3, 4E7, .97", new float[] {.3f, 4e7f, .97f}, ", ", "0.3, 4.0E7, 0.97"),
|
||||||
|
|
||||||
|
// Object array test
|
||||||
|
new Conversion("foo, bar", new FooBar[] {new FooBar("foo"), new FooBar("bar")}),
|
||||||
|
new Conversion("/temp, /usr/local/bin", new File[] {new File("/temp"), new File("/usr/local/bin")}),
|
||||||
|
new Conversion("file:/temp, http://java.net/", new URI[] {URI.create("file:/temp"), URI.create("http://java.net/")}),
|
||||||
|
|
||||||
// TODO: More tests
|
// TODO: More tests
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package com.twelvemonkeys.util.convert;
|
|||||||
|
|
||||||
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
|
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PropertyConverterAbstractTestCase
|
* PropertyConverterAbstractTestCase
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -30,16 +32,28 @@ public abstract class PropertyConverterAbstractTestCase extends ObjectAbstractTe
|
|||||||
Object obj;
|
Object obj;
|
||||||
try {
|
try {
|
||||||
obj = converter.toObject(test.original(), test.type(), test.format());
|
obj = converter.toObject(test.original(), test.type(), test.format());
|
||||||
assertEquals("'" + test.original() + "' convtered to incorrect type", test.type(), obj.getClass());
|
|
||||||
|
assertEquals("'" + test.original() + "' converted to incorrect type", test.type(), obj.getClass());
|
||||||
|
if (test.type().isArray()) {
|
||||||
|
assertTrue("'" + test.original() + "' not converted", arrayEquals(test.value(), obj));
|
||||||
|
}
|
||||||
|
else {
|
||||||
assertEquals("'" + test.original() + "' not converted", test.value(), obj);
|
assertEquals("'" + test.original() + "' not converted", test.value(), obj);
|
||||||
|
}
|
||||||
|
|
||||||
String result = converter.toString(test.value(), test.format());
|
String result = converter.toString(test.value(), test.format());
|
||||||
|
|
||||||
assertEquals("'" + test.converted() + "' does not macth", test.converted(), result);
|
assertEquals("'" + test.converted() + "' does not match", test.converted(), result);
|
||||||
|
|
||||||
obj = converter.toObject(result, test.type(), test.format());
|
obj = converter.toObject(result, test.type(), test.format());
|
||||||
assertEquals("'" + test.original() + "' convtered to incorrect type", test.type(), obj.getClass());
|
assertEquals("'" + test.original() + "' converted to incorrect type", test.type(), obj.getClass());
|
||||||
assertEquals("'" + test.original() + "' did not survive roundrip conversion", test.value(), obj);
|
|
||||||
|
if (test.type().isArray()) {
|
||||||
|
assertTrue("'" + test.original() + "' did not survive round trip conversion", arrayEquals(test.value(), obj));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertEquals("'" + test.original() + "' did not survive round trip conversion", test.value(), obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ConversionException e) {
|
catch (ConversionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -48,6 +62,39 @@ public abstract class PropertyConverterAbstractTestCase extends ObjectAbstractTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Util method?
|
||||||
|
private boolean arrayEquals(final Object left, final Object right) {
|
||||||
|
if (left.getClass().getComponentType().isPrimitive()) {
|
||||||
|
if (int.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((int[]) left, (int[]) right);
|
||||||
|
}
|
||||||
|
if (short.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((short[]) left, (short[]) right);
|
||||||
|
}
|
||||||
|
if (long.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((long[]) left, (long[]) right);
|
||||||
|
}
|
||||||
|
if (float.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((float[]) left, (float[]) right);
|
||||||
|
}
|
||||||
|
if (double.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((double[]) left, (double[]) right);
|
||||||
|
}
|
||||||
|
if (boolean.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((boolean[]) left, (boolean[]) right);
|
||||||
|
}
|
||||||
|
if (byte.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((byte[]) left, (byte[]) right);
|
||||||
|
}
|
||||||
|
if (char.class == left.getClass().getComponentType()) {
|
||||||
|
return Arrays.equals((char[]) left, (char[]) right);
|
||||||
|
}
|
||||||
|
// Else blow up below...
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.equals((Object[]) left, (Object[]) right);
|
||||||
|
}
|
||||||
|
|
||||||
public static final class Conversion {
|
public static final class Conversion {
|
||||||
private final String mStrVal;
|
private final String mStrVal;
|
||||||
private final Object mObjVal;
|
private final Object mObjVal;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user