mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-02 11:05: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 {
|
||||
// If this does not throw an excption, it works
|
||||
// If this does not throw an exception, it works
|
||||
method = pObject.getClass().getMethod(pName, pParams);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
// 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) {
|
||||
while ((paramType = paramType.getSuperclass()) != null) {
|
||||
pParams[0] = paramType;
|
||||
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);
|
||||
}
|
||||
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
|
||||
if (pValue instanceof String) {
|
||||
Converter converter = Converter.getInstance();
|
||||
@ -596,8 +599,7 @@ public final class BeanUtil {
|
||||
catch (NoSuchMethodException ignore) {
|
||||
// If invocation failed, convert lisp-style and try again
|
||||
if (pLispToCamel && property.indexOf('-') > 0) {
|
||||
setPropertyValue(pBean, StringUtil.lispToCamel(property, false),
|
||||
entry.getValue());
|
||||
setPropertyValue(pBean, StringUtil.lispToCamel(property, false), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import java.io.IOException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
|
||||
/**
|
||||
* ExceptionUtil
|
||||
*
|
||||
@ -14,6 +16,15 @@ import java.sql.SQLException;
|
||||
*/
|
||||
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) {
|
||||
if (pThrowable instanceof Error) {
|
||||
throw (Error) pThrowable;
|
||||
@ -40,36 +51,38 @@ public final class ExceptionUtil {
|
||||
throwAs(RuntimeException.class, pThrowable);
|
||||
}
|
||||
|
||||
/*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler<? extends Throwable>... pHandler) {
|
||||
handleImpl(pThrowable, pHandler);
|
||||
@SuppressWarnings({"unchecked"})
|
||||
/*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler<? extends Throwable>... pHandlers) {
|
||||
handleImpl(pThrowable, (ThrowableHandler<Throwable>[]) pHandlers);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private static <T extends Throwable> void handleImpl(final Throwable pThrowable, final ThrowableHandler<T>... pHandler) {
|
||||
private static void handleImpl(final Throwable pThrowable, final ThrowableHandler<Throwable>... pHandlers) {
|
||||
// TODO: Sort more specific throwable handlers before less specific?
|
||||
for (ThrowableHandler<T> handler : pHandler) {
|
||||
for (ThrowableHandler<Throwable> handler : pHandlers) {
|
||||
if (handler.handles(pThrowable)) {
|
||||
handler.handle((T) pThrowable);
|
||||
handler.handle(pThrowable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Not handled, re-throw
|
||||
throwUnchecked(pThrowable);
|
||||
}
|
||||
|
||||
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) {
|
||||
// TODO: Assert not null
|
||||
mThrowables = pThrowables.clone();
|
||||
throwables = notNull(pThrowables).clone();
|
||||
}
|
||||
|
||||
final public boolean handles(final Throwable pThrowable) {
|
||||
for (Class<? extends T> throwable : mThrowables) {
|
||||
for (Class<? extends T> throwable : throwables) {
|
||||
if (throwable.isAssignableFrom(pThrowable.getClass())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -39,24 +39,24 @@ public final class Platform {
|
||||
/**
|
||||
* Normalized operating system constant
|
||||
*/
|
||||
final OperatingSystem mOS;
|
||||
final OperatingSystem os;
|
||||
|
||||
/**
|
||||
* Unormalized operating system version constant (for completeness)
|
||||
*/
|
||||
final String mVersion;
|
||||
final String version;
|
||||
|
||||
/**
|
||||
* Normalized system architecture constant
|
||||
*/
|
||||
final Architecture mArchitecture;
|
||||
final Architecture architecture;
|
||||
|
||||
static final private Platform INSTANCE = new Platform();
|
||||
|
||||
private Platform() {
|
||||
mOS = normalizeOperatingSystem();
|
||||
mVersion = System.getProperty("os.version");
|
||||
mArchitecture = normalizeArchitecture(mOS);
|
||||
os = normalizeOperatingSystem();
|
||||
version = System.getProperty("os.version");
|
||||
architecture = normalizeArchitecture(os);
|
||||
}
|
||||
|
||||
private static OperatingSystem normalizeOperatingSystem() {
|
||||
@ -138,21 +138,21 @@ public final class Platform {
|
||||
* @return this platform's OS.
|
||||
*/
|
||||
public OperatingSystem getOS() {
|
||||
return mOS;
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return this platform's OS version.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return mVersion;
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return this platform's architecture.
|
||||
*/
|
||||
public Architecture getArchitecture() {
|
||||
return mArchitecture;
|
||||
return architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +160,7 @@ public final class Platform {
|
||||
* @return the current {@code OperatingSystem}.
|
||||
*/
|
||||
public static OperatingSystem os() {
|
||||
return INSTANCE.mOS;
|
||||
return INSTANCE.os;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,7 +168,7 @@ public final class Platform {
|
||||
* @return the current OS version.
|
||||
*/
|
||||
public static String version() {
|
||||
return INSTANCE.mVersion;
|
||||
return INSTANCE.version;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,7 +176,7 @@ public final class Platform {
|
||||
* @return the current {@code Architecture}.
|
||||
*/
|
||||
public static Architecture arch() {
|
||||
return INSTANCE.mArchitecture;
|
||||
return INSTANCE.architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,14 +197,14 @@ public final class Platform {
|
||||
|
||||
Unknown(System.getProperty("os.arch"));
|
||||
|
||||
final String mName;// for debug only
|
||||
final String name;// for debug only
|
||||
|
||||
private Architecture(String pName) {
|
||||
mName = pName;
|
||||
name = pName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return mName;
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,20 +225,20 @@ public final class Platform {
|
||||
|
||||
Unknown(System.getProperty("os.name"), "");
|
||||
|
||||
final String mId;
|
||||
final String mName;// for debug only
|
||||
final String id;
|
||||
final String name;// for debug only
|
||||
|
||||
private OperatingSystem(String pName, String pId) {
|
||||
mName = pName;
|
||||
mId = pId;
|
||||
name = pName;
|
||||
id = pId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
return name;
|
||||
}
|
||||
|
||||
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
|
||||
* not throw the checked {@link UnsupportedEncodingException},
|
||||
* 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.
|
||||
*
|
||||
* @param pStringArray the string array
|
||||
* @param pDelimiterString the delimter string
|
||||
* @param pDelimiterString the delimiter string
|
||||
* @return string of delimiter separated values
|
||||
* @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 $
|
||||
*/
|
||||
public final class Validate {
|
||||
// TODO: Make it possible to throw IllegalStateException instead of IllegalArgumentException?
|
||||
|
||||
private static final String UNSPECIFIED_PARAM_NAME = "method parameter";
|
||||
|
||||
private Validate() {}
|
||||
@ -121,4 +123,16 @@ public final class Validate {
|
||||
|
||||
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.
|
||||
* <p/>
|
||||
* Ruhtlessly stolen from
|
||||
* Ruthlessly stolen from
|
||||
* <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 {
|
||||
|
@ -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 $
|
||||
*/
|
||||
public class ConversionException extends IllegalArgumentException {
|
||||
protected Throwable mCause = this;
|
||||
|
||||
/**
|
||||
* Creates a {@code ConversionException} with the given error message.
|
||||
*
|
||||
* @param pMessage the error message
|
||||
*/
|
||||
public ConversionException(String pMessage) {
|
||||
public ConversionException(final String pMessage) {
|
||||
super(pMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
super(pCause == null ? null : pCause.getMessage());
|
||||
initCause(pCause);
|
||||
public ConversionException(final Throwable pCause) {
|
||||
super(pCause != null ? pCause.getMessage() : null, pCause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cause of this {@code Throwable} or {@code null} if the
|
||||
* cause is nonexistent or unknown.
|
||||
* Creates a {@code ConversionException} with the given message and cause.
|
||||
*
|
||||
* @return the cause of this {@code Throwable} or {@code null} if the
|
||||
* cause is nonexistent or unknown (the cause is the throwable that caused
|
||||
* this throwable to get thrown).
|
||||
* @param pMessage the error message
|
||||
* @param pCause The {@link Throwable} that caused this exception
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
if (mCause == this) {
|
||||
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;
|
||||
public ConversionException(final String pMessage, final Throwable pCause) {
|
||||
super(pMessage, pCause);
|
||||
}
|
||||
}
|
||||
|
@ -56,13 +56,14 @@ import java.util.Map;
|
||||
// Maybe have BeanUtil act as a "proxy", and hide this class alltogheter?
|
||||
// TODO: ServiceRegistry for registering 3rd party converters
|
||||
// TODO: URI scheme, for implicit typing? Is that a good idea?
|
||||
// TODO: Array converters?
|
||||
public abstract class Converter implements PropertyConverter {
|
||||
|
||||
/** Our singleton instance */
|
||||
protected static Converter sInstance = new ConverterImpl(); // Thread safe & EASY
|
||||
|
||||
/** The conveters Map */
|
||||
protected Map mConverters = new Hashtable();
|
||||
protected Map converters = new Hashtable();
|
||||
|
||||
// Register our predefined converters
|
||||
static {
|
||||
@ -115,7 +116,7 @@ public abstract class Converter implements PropertyConverter {
|
||||
* @see #unregisterConverter(Class)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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
|
||||
do {
|
||||
// Have a match, return converter
|
||||
if ((converter = getInstance().mConverters.get(cl)) != null) {
|
||||
if ((converter = getInstance().converters.get(cl)) != null) {
|
||||
return (PropertyConverter) converter;
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,11 @@
|
||||
|
||||
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.
|
||||
@ -67,9 +69,7 @@ public final class DefaultConverter implements PropertyConverter {
|
||||
* be converted into the given type, using a string constructor or static
|
||||
* {@code valueof} method.
|
||||
*/
|
||||
public Object toObject(String pString, final Class pType, String pFormat)
|
||||
throws ConversionException {
|
||||
|
||||
public Object toObject(String pString, final Class pType, String pFormat) throws ConversionException {
|
||||
if (pString == null) {
|
||||
return null;
|
||||
}
|
||||
@ -78,6 +78,14 @@ public final class DefaultConverter implements PropertyConverter {
|
||||
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
|
||||
Class 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()}.
|
||||
*
|
||||
@ -126,10 +159,77 @@ public final class DefaultConverter implements PropertyConverter {
|
||||
throws ConversionException {
|
||||
|
||||
try {
|
||||
return (pObject != null ? pObject.toString() : null);
|
||||
return pObject == null ? null : pObject.getClass().isArray() ? arrayToString(toObjectArray(pObject), pFormat) : pObject.toString();
|
||||
}
|
||||
catch (RuntimeException 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.
|
||||
* <p/>
|
||||
* <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 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 $
|
||||
*/
|
||||
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 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 $
|
||||
*/
|
||||
public class RegExTokenIterator extends AbstractTokenIterator {
|
||||
private final Matcher mMatcher;
|
||||
private boolean mNext = false;
|
||||
private final Matcher matcher;
|
||||
private boolean next = false;
|
||||
|
||||
/**
|
||||
* Creates a {@code RegExTokenIterator}.
|
||||
@ -80,7 +80,7 @@ public class RegExTokenIterator extends AbstractTokenIterator {
|
||||
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() {
|
||||
mMatcher.reset();
|
||||
matcher.reset();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return mNext || (mNext = mMatcher.find());
|
||||
return next || (next = matcher.find());
|
||||
}
|
||||
|
||||
public String next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
mNext = false;
|
||||
return mMatcher.group();
|
||||
next = false;
|
||||
return matcher.group();
|
||||
}
|
||||
}
|
@ -114,6 +114,7 @@ import java.io.PrintStream;
|
||||
* @deprecated Will probably be removed in the near future
|
||||
*/
|
||||
public class WildcardStringParser {
|
||||
// TODO: Get rid of this class
|
||||
|
||||
// Constants
|
||||
|
||||
|
@ -65,7 +65,7 @@ import java.util.*;
|
||||
*/
|
||||
public class ServiceRegistry {
|
||||
// TODO: Security issues?
|
||||
// TODO: Application contexts?
|
||||
// TODO: Application contexts? Probably use instance per thread group..
|
||||
|
||||
/**
|
||||
* "META-INF/services/"
|
||||
@ -73,7 +73,7 @@ public class ServiceRegistry {
|
||||
public static final String SERVICES = "META-INF/services/";
|
||||
|
||||
// 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
|
||||
@ -98,7 +98,7 @@ public class ServiceRegistry {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -154,7 +154,7 @@ public class ServiceRegistry {
|
||||
|
||||
if (!classNames.isEmpty()) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
CategoryRegistry<T> registry = mCategoryMap.get(pCategory);
|
||||
CategoryRegistry<T> registry = categoryMap.get(pCategory);
|
||||
|
||||
Set providerClassNames = classNames.keySet();
|
||||
|
||||
@ -213,7 +213,7 @@ public class ServiceRegistry {
|
||||
* @return an {@code Iterator} containing all categories in this registry.
|
||||
*/
|
||||
protected Iterator<Class<?>> categories() {
|
||||
return mCategoryMap.keySet().iterator();
|
||||
return categoryMap.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,18 +260,19 @@ public class ServiceRegistry {
|
||||
return getRegistry(pElement).contatins(pProvider);
|
||||
}
|
||||
}) {
|
||||
Class<?> mCurrent;
|
||||
Class<?> current;
|
||||
|
||||
public Class next() {
|
||||
return (mCurrent = super.next());
|
||||
return (current = super.next());
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (mCurrent == null) {
|
||||
if (current == null) {
|
||||
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) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
CategoryRegistry<T> registry = mCategoryMap.get(pCategory);
|
||||
CategoryRegistry<T> registry = categoryMap.get(pCategory);
|
||||
if (registry == null) {
|
||||
throw new IllegalArgumentException("No such category: " + pCategory.getName());
|
||||
}
|
||||
@ -366,17 +367,17 @@ public class ServiceRegistry {
|
||||
* Keeps track of each individual category.
|
||||
*/
|
||||
class CategoryRegistry<T> {
|
||||
private final Class<T> mCategory;
|
||||
private final Map<Class, T> mProviders = new LinkedHashMap<Class, T>();
|
||||
private final Class<T> category;
|
||||
private final Map<Class, T> providers = new LinkedHashMap<Class, T>();
|
||||
|
||||
CategoryRegistry(Class<T> pCategory) {
|
||||
Validate.notNull(pCategory, "category");
|
||||
mCategory = pCategory;
|
||||
category = pCategory;
|
||||
}
|
||||
|
||||
private void checkCategory(final Object pProvider) {
|
||||
if (!mCategory.isInstance(pProvider)) {
|
||||
throw new IllegalArgumentException(pProvider + " not instance of category " + mCategory.getName());
|
||||
if (!category.isInstance(pProvider)) {
|
||||
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
|
||||
// have an instance of pProvider's class.
|
||||
if (!contatins(pProvider)) {
|
||||
mProviders.put(pProvider.getClass(), pProvider);
|
||||
providers.put(pProvider.getClass(), pProvider);
|
||||
processRegistration(pProvider);
|
||||
return true;
|
||||
}
|
||||
@ -397,7 +398,7 @@ public class ServiceRegistry {
|
||||
void processRegistration(final T pProvider) {
|
||||
if (pProvider instanceof RegisterableService) {
|
||||
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
|
||||
// not be the same instance as pProvider.
|
||||
T oldProvider = mProviders.remove(pProvider.getClass());
|
||||
T oldProvider = providers.remove(pProvider.getClass());
|
||||
|
||||
if (oldProvider != null) {
|
||||
processDeregistration(oldProvider);
|
||||
@ -419,12 +420,12 @@ public class ServiceRegistry {
|
||||
void processDeregistration(final T pOldProvider) {
|
||||
if (pOldProvider instanceof RegisterableService) {
|
||||
RegisterableService service = (RegisterableService) pOldProvider;
|
||||
service.onDeregistration(ServiceRegistry.this, mCategory);
|
||||
service.onDeregistration(ServiceRegistry.this, category);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contatins(final Object pProvider) {
|
||||
return mProviders.containsKey(pProvider.getClass());
|
||||
return providers.containsKey(pProvider.getClass());
|
||||
}
|
||||
|
||||
public Iterator<T> providers() {
|
||||
@ -432,9 +433,9 @@ public class ServiceRegistry {
|
||||
// using the deregister method will result in
|
||||
// ConcurrentModificationException in the iterator..
|
||||
// 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>() {
|
||||
T mCurrent;
|
||||
T current;
|
||||
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
@ -442,12 +443,12 @@ public class ServiceRegistry {
|
||||
}
|
||||
|
||||
public T next() {
|
||||
return (mCurrent = iterator.next());
|
||||
return (current = iterator.next());
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
iterator.remove();
|
||||
processDeregistration(mCurrent);
|
||||
processDeregistration(current);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.twelvemonkeys.util.convert;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* DefaultConverterTestCase
|
||||
* <p/>
|
||||
@ -20,7 +23,9 @@ public class DefaultConverterTestCase extends PropertyConverterAbstractTestCase
|
||||
new Conversion("true", Boolean.TRUE),
|
||||
new Conversion("TRUE", Boolean.TRUE, null, "true"),
|
||||
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
|
||||
new Conversion("fooBar", "fooBar"),
|
||||
@ -29,6 +34,22 @@ public class DefaultConverterTestCase extends PropertyConverterAbstractTestCase
|
||||
// Stupid test class that reveres chars
|
||||
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
|
||||
};
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package com.twelvemonkeys.util.convert;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PropertyConverterAbstractTestCase
|
||||
* <p/>
|
||||
@ -30,16 +32,28 @@ public abstract class PropertyConverterAbstractTestCase extends ObjectAbstractTe
|
||||
Object obj;
|
||||
try {
|
||||
obj = converter.toObject(test.original(), test.type(), test.format());
|
||||
assertEquals("'" + test.original() + "' convtered to incorrect type", test.type(), obj.getClass());
|
||||
assertEquals("'" + test.original() + "' not converted", test.value(), obj);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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());
|
||||
assertEquals("'" + test.original() + "' convtered to incorrect type", test.type(), obj.getClass());
|
||||
assertEquals("'" + test.original() + "' did not survive roundrip conversion", test.value(), obj);
|
||||
assertEquals("'" + test.original() + "' converted to incorrect type", test.type(), obj.getClass());
|
||||
|
||||
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) {
|
||||
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 {
|
||||
private final String mStrVal;
|
||||
private final Object mObjVal;
|
||||
|
Loading…
x
Reference in New Issue
Block a user