Moving files around

This commit is contained in:
Erlend Hamnaberg
2009-11-06 21:26:32 +01:00
parent ba5f0a2f5f
commit 9b615de8ed
86 changed files with 0 additions and 0 deletions
@@ -0,0 +1,612 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.lang;
import com.twelvemonkeys.util.convert.ConversionException;
import com.twelvemonkeys.util.convert.Converter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Arrays;
/**
* A utility class with some useful bean-related functions.
* <p/>
* <em>NOTE: This class is not considered part of the public API and may be
* changed without notice</em>
*
* @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/lang/BeanUtil.java#2 $
*/
public final class BeanUtil {
// Disallow creating objects of this type
private BeanUtil() {
}
/**
* Gets a property value from the given object, using reflection.
* Now supports getting values from properties of properties
* (recursive).
*
* @param pObject The object to get the property from
* @param pProperty The name of the property
*
* @return A string containing the value of the given property, or null
* if it can not be found.
* @todo Remove System.err's... Create new Exception? Hmm..
*/
public static Object getPropertyValue(Object pObject, String pProperty) {
//
// TODO: Support get(Object) method of Collections!
// Handle lists and arrays with [] (index) operator
//
if (pObject == null || pProperty == null || pProperty.length() < 1) {
return null;
}
Class objClass = pObject.getClass();
Object result = pObject;
// Method for method...
String subProp;
int begIdx = 0;
int endIdx = begIdx;
while (begIdx < pProperty.length() && begIdx >= 0) {
endIdx = pProperty.indexOf(".", endIdx + 1);
if (endIdx > 0) {
subProp = pProperty.substring(begIdx, endIdx);
begIdx = endIdx + 1;
}
else {
// The final property!
// If there's just the first-level property, subProp will be
// equal to property
subProp = pProperty.substring(begIdx);
begIdx = -1;
}
// Check for "[" and "]"
Object[] param = null;
Class[] paramClass = new Class[0];
int begBracket;
if ((begBracket = subProp.indexOf("[")) > 0) {
// An error if there is no matching bracket
if (!subProp.endsWith("]")) {
return null;
}
String between = subProp.substring(begBracket + 1,
subProp.length() - 1);
subProp = subProp.substring(0, begBracket);
// If brackets exist, check type of argument between brackets
param = new Object[1];
paramClass = new Class[1];
//try {
// TODO: isNumber returns true, even if too big for integer...
if (StringUtil.isNumber(between)) {
// We have a number
// Integer -> array subscript -> getXXX(int i)
try {
// Insert param and it's Class
param[0] = Integer.valueOf(between);
paramClass[0] = Integer.TYPE; // int.class
}
catch (NumberFormatException e) {
// ??
// Probably too small or too large value..
}
}
else {
//catch (NumberFormatException e) {
// Not a number... Try String
// String -> Hashtable key -> getXXX(String str)
// Insert param and it's Class
param[0] = between.toLowerCase();
paramClass[0] = String.class;
}
}
Method method;
String methodName = "get" + StringUtil.capitalize(subProp);
try {
// Try to get the "get" method for the given property
method = objClass.getMethod(methodName, paramClass);
}
catch (NoSuchMethodException e) {
System.err.print("No method named \"" + methodName + "()\"");
// The array might be of size 0...
if (paramClass != null && paramClass.length > 0) {
System.err.print(" with the parameter "
+ paramClass[0].getName());
}
System.err.println(" in class " + objClass.getName() + "!");
return null;
}
// If method for some reason should be null, give up
if (method == null) {
return null;
}
try {
// We have a method, try to invoke it
// The resutling object will be either the property we are
// Looking for, or the parent
// System.err.println("Trying " + objClass.getName() + "." + method.getName() + "(" + ((param != null && param.length > 0) ? param[0] : "") + ")");
result = method.invoke(result, param);
}
catch (InvocationTargetException e) {
System.err.println("property=" + pProperty + " & result="
+ result + " & param=" + Arrays.toString(param));
e.getTargetException().printStackTrace();
e.printStackTrace();
return null;
}
catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
catch (NullPointerException e) {
System.err.println(objClass.getName() + "." + method.getName()
+ "(" + ((paramClass != null && paramClass.length > 0) ? paramClass[0].getName() : "") + ")");
e.printStackTrace();
return null;
}
if (result != null) {
// Get the class of the reulting object
objClass = result.getClass();
}
else {
return null;
}
} // while
return result;
}
/**
* Sets the property value to an object using reflection.
* Supports setting values of properties that are properties of
* properties (recursive).
*
* @param pObject The object to get a property from
* @param pProperty The name of the property
* @param pValue The property value
*
* @throws NoSuchMethodException if there's no write method for the
* given property
* @throws InvocationTargetException if invoking the write method failed
* @throws IllegalAccessException if the caller class has no access to the
* write method
*/
public static void setPropertyValue(Object pObject, String pProperty,
Object pValue)
throws NoSuchMethodException, InvocationTargetException,
IllegalAccessException {
//
// TODO: Support set(Object, Object)/put(Object, Object) methods
// of Collections!
// Handle lists and arrays with [] (index) operator
Class paramType = pValue != null ? pValue.getClass() : Object.class;
// Preserve references
Object obj = pObject;
String property = pProperty;
// Recurse and find real parent if property contains a '.'
int dotIdx = property.indexOf('.');
if (dotIdx >= 0) {
// Get real parent
obj = getPropertyValue(obj, property.substring(0, dotIdx));
// Get the property of the parent
property = property.substring(dotIdx + 1);
}
// Find method
Object[] params = {pValue};
Method method = getMethodMayModifyParams(obj, "set" + StringUtil.capitalize(property),
new Class[] {paramType}, params);
// Invoke it
method.invoke(obj, params);
}
private static Method getMethodMayModifyParams(Object pObject, String pName, Class[] pParams, Object[] pValues) throws NoSuchMethodException {
// NOTE: This method assumes pParams.length == 1 && pValues.length == 1
Method method = null;
Class paramType = pParams[0];
try {
method = pObject.getClass().getMethod(pName, pParams);
}
catch (NoSuchMethodException e) {
// No direct match
// 1: If primitive wrapper, try unwrap conversion first
/*if (paramType.isPrimitive()) { // NOTE: Can't be primitive type
params[0] = ReflectUtil.wrapType(paramType);
}
else*/ if (ReflectUtil.isPrimitiveWrapper(paramType)) {
pParams[0] = ReflectUtil.unwrapType(paramType);
}
try {
// If this does not throw an excption, 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
if (method == null) {
while ((paramType = paramType.getSuperclass()) != null) {
pParams[0] = paramType;
try {
// If this does not throw an excption, it works
method = pObject.getClass().getMethod(pName, pParams);
}
catch (Throwable t) {
// Ignore/Continue
continue;
}
break;
}
}
// 3: Try to find a different method with the same name, that has
// a parameter type we can convert to...
// NOTE: There's no ordering here..
// TODO: Should we try to do that? What would the ordering be?
if (method == null) {
Method[] methods = pObject.getClass().getMethods();
for (Method candidate : methods) {
if (Modifier.isPublic(candidate.getModifiers())
&& candidate.getName().equals(pName)
&& candidate.getReturnType() == Void.TYPE
&& candidate.getParameterTypes().length == 1) {
// NOTE: Assumes paramTypes.length == 1
Class type = candidate.getParameterTypes()[0];
try {
pValues[0] = convertValueToType(pValues[0], type);
}
catch (Throwable t) {
continue;
}
// We were able to convert the parameter, let's try
method = candidate;
break;
}
}
}
// Give up...
if (method == null) {
throw e;
}
}
return method;
}
private static Object convertValueToType(Object pValue, Class pType) throws ConversionException {
if (pType.isPrimitive()) {
if (pType == Boolean.TYPE && pValue instanceof Boolean) {
return pValue;
}
else if (pType == Byte.TYPE && pValue instanceof Byte) {
return pValue;
}
else if (pType == Character.TYPE && pValue instanceof Character) {
return pValue;
}
else if (pType == Double.TYPE && pValue instanceof Double) {
return pValue;
}
else if (pType == Float.TYPE && pValue instanceof Float) {
return pValue;
}
else if (pType == Integer.TYPE && pValue instanceof Integer) {
return pValue;
}
else if (pType == Long.TYPE && pValue instanceof Long) {
return pValue;
}
else if (pType == Short.TYPE && pValue instanceof Short) {
return pValue;
}
}
// TODO: Convert other types
if (pValue instanceof String) {
Converter converter = Converter.getInstance();
return converter.toObject((String) pValue, pType);
}
else if (pType == String.class) {
Converter converter = Converter.getInstance();
return converter.toString(pValue);
}
else {
throw new ConversionException("Cannot convert " + pValue.getClass().getName() + " to " + pType.getName());
}
}
/**
* Creates an object from the given class' single argument constructor.
*
* @param pClass The class to create instance from
* @param pParam The parameters to the constructor
*
* @return The object created from the constructor.
* If the constructor could not be invoked for any reason, null is
* returned.
*
* @throws InvocationTargetException if the constructor failed
*/
// TODO: Move to ReflectUtil
public static Object createInstance(Class pClass, Object pParam)
throws InvocationTargetException {
return createInstance(pClass, new Object[] {pParam});
}
/**
* Creates an object from the given class' constructor that matches
* the given paramaters.
*
* @param pClass The class to create instance from
* @param pParams The parameters to the constructor
*
* @return The object created from the constructor.
* If the constructor could not be invoked for any reason, null is
* returned.
*
* @throws InvocationTargetException if the constructor failed
*/
// TODO: Move to ReflectUtil
public static Object createInstance(Class pClass, Object... pParams)
throws InvocationTargetException {
Object value;
try {
// Create param and argument arrays
Class[] paramTypes = null;
if (pParams != null && pParams.length > 0) {
paramTypes = new Class[pParams.length];
for (int i = 0; i < pParams.length; i++) {
paramTypes[i] = pParams[i].getClass();
}
}
// Get constructor
//Constructor constructor = pClass.getDeclaredConstructor(paramTypes);
Constructor constructor = pClass.getConstructor(paramTypes);
// Invoke and create instance
value = constructor.newInstance(pParams);
}
/* All this to let InvocationTargetException pass on */
catch (NoSuchMethodException nsme) {
return null;
}
catch (IllegalAccessException iae) {
return null;
}
catch (IllegalArgumentException iarge) {
return null;
}
catch (InstantiationException ie) {
return null;
}
catch (ExceptionInInitializerError err) {
return null;
}
return value;
}
/**
* Gets an object from any given static method, with the given parameter.
*
* @param pClass The class to invoke method on
* @param pMethod The name of the method to invoke
* @param pParam The parameter to the method
*
* @return The object returned by the static method.
* If the return type of the method is a primitive type, it is wrapped in
* the corresponding wrapper object (int is wrapped in an Integer).
* If the return type of the method is void, null is returned.
* If the method could not be invoked for any reason, null is returned.
*
* @throws InvocationTargetException if the invocaton failed
*/
// TODO: Move to ReflectUtil
// TODO: Rename to invokeStatic?
public static Object invokeStaticMethod(Class pClass, String pMethod,
Object pParam)
throws InvocationTargetException {
return invokeStaticMethod(pClass, pMethod, new Object[] {pParam});
}
/**
* Gets an object from any given static method, with the given parameter.
*
* @param pClass The class to invoke method on
* @param pMethod The name of the method to invoke
* @param pParams The parameters to the method
*
* @return The object returned by the static method.
* If the return type of the method is a primitive type, it is wrapped in
* the corresponding wrapper object (int is wrapped in an Integer).
* If the return type of the method is void, null is returned.
* If the method could not be invoked for any reason, null is returned.
*
* @throws InvocationTargetException if the invocaton failed
*/
// TODO: Move to ReflectUtil
// TODO: Rename to invokeStatic?
public static Object invokeStaticMethod(Class pClass, String pMethod,
Object[] pParams)
throws InvocationTargetException {
Object value = null;
try {
// Create param and argument arrays
Class[] paramTypes = new Class[pParams.length];
for (int i = 0; i < pParams.length; i++) {
paramTypes[i] = pParams[i].getClass();
}
// Get method
// *** If more than one such method is found in the class, and one
// of these methods has a RETURN TYPE that is more specific than
// any of the others, that method is reflected; otherwise one of
// the methods is chosen ARBITRARILY.
// java/lang/Class.html#getMethod(java.lang.String, java.lang.Class[])
Method method = pClass.getMethod(pMethod, paramTypes);
// Invoke public static method
if (Modifier.isPublic(method.getModifiers())
&& Modifier.isStatic(method.getModifiers())) {
value = method.invoke(null, pParams);
}
}
/* All this to let InvocationTargetException pass on */
catch (NoSuchMethodException nsme) {
return null;
}
catch (IllegalAccessException iae) {
return null;
}
catch (IllegalArgumentException iarge) {
return null;
}
return value;
}
/**
* Configures the bean according to the given mapping.
* For each {@code Map.Entry} in {@code Map.values()},
* a method named
* {@code set + capitalize(entry.getKey())} is called on the bean,
* with {@code entry.getValue()} as its argument.
* <p/>
* Properties that has no matching set-method in the bean, are simply
* discarded.
*
* @param pBean The bean to configure
* @param pMapping The mapping for the bean
*
* @throws NullPointerException if any of the parameters are null.
* @throws InvocationTargetException if an error occurs when invoking the
* setter-method.
*/
// TODO: Add a version that takes a ConfigurationErrorListener callback interface
// TODO: ...or a boolean pFailOnError parameter
// TODO: ...or return Exceptions as an array?!
// TODO: ...or something whatsoever that makes clients able to determine something's not right
public static void configure(final Object pBean, final Map<String, ?> pMapping) throws InvocationTargetException {
configure(pBean, pMapping, false);
}
/**
* Configures the bean according to the given mapping.
* For each {@code Map.Entry} in {@code Map.values()},
* a method named
* {@code set + capitalize(entry.getKey())} is called on the bean,
* with {@code entry.getValue()} as its argument.
* <p/>
* Optionally, lisp-style names are allowed, and automatically converted
* to Java-style camel-case names.
* <p/>
* Properties that has no matching set-method in the bean, are simply
* discarded.
*
* @see StringUtil#lispToCamel(String)
*
* @param pBean The bean to configure
* @param pMapping The mapping for the bean
* @param pLispToCamel Allow lisp-style names, and automatically convert
* them to Java-style camel-case.
*
* @throws NullPointerException if any of the parameters are null.
* @throws InvocationTargetException if an error occurs when invoking the
* setter-method.
*/
public static void configure(final Object pBean, final Map<String, ?> pMapping, final boolean pLispToCamel) throws InvocationTargetException {
// Loop over properties in mapping
for (final Map.Entry<String, ?> entry : pMapping.entrySet()) {
try {
// Configure each property in turn
final String property = StringUtil.valueOf(entry.getKey());
try {
setPropertyValue(pBean, property, entry.getValue());
}
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());
}
}
}
catch (NoSuchMethodException nsme) {
// This property was not configured
}
catch (IllegalAccessException iae) {
// This property was not configured
}
}
}
}
@@ -0,0 +1,210 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.lang;
import java.util.Date;
import java.util.TimeZone;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
/**
* A utility class with useful date manipulation methods and constants.
* <p/>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/DateUtil.java#1 $
*/
public final class DateUtil {
/** One second: 1000 milliseconds. */
public static final long SECOND = 1000l;
/** One minute: 60 seconds (60 000 milliseconds). */
public static final long MINUTE = 60l * SECOND;
/**
* One hour: 60 minutes (3 600 000 milliseconds).
* 60 minutes = 3 600 seconds = 3 600 000 milliseconds
*/
public static final long HOUR = 60l * MINUTE;
/**
* One day: 24 hours (86 400 000 milliseconds).
* 24 hours = 1 440 minutes = 86 400 seconds = 86 400 000 milliseconds.
*/
public static final long DAY = 24l * HOUR;
/**
* One calendar year: 365.2425 days (31556952000 milliseconds).
* 365.2425 days = 8765.82 hours = 525949.2 minutes = 31556952 seconds
* = 31556952000 milliseconds.
*/
public static final long CALENDAR_YEAR = 3652425l * 24l * 60l * 6l;
private DateUtil() {
}
/**
* Returns the time between the given start time and now (as defined by
* {@link System#currentTimeMillis()}).
*
* @param pStart the start time
*
* @return the time between the given start time and now.
*/
public static long delta(long pStart) {
return System.currentTimeMillis() - pStart;
}
/**
* Returns the time between the given start time and now (as defined by
* {@link System#currentTimeMillis()}).
*
* @param pStart the start time
*
* @return the time between the given start time and now.
*/
public static long delta(Date pStart) {
return System.currentTimeMillis() - pStart.getTime();
}
/**
* Gets the current time, rounded down to the closest second.
* Equivalent to invoking
* {@code roundToSecond(System.currentTimeMillis())}.
*
* @return the current time, rounded to the closest second.
*/
public static long currentTimeSecond() {
return roundToSecond(System.currentTimeMillis());
}
/**
* Gets the current time, rounded down to the closest minute.
* Equivalent to invoking
* {@code roundToMinute(System.currentTimeMillis())}.
*
* @return the current time, rounded to the closest minute.
*/
public static long currentTimeMinute() {
return roundToMinute(System.currentTimeMillis());
}
/**
* Gets the current time, rounded down to the closest hour.
* Equivalent to invoking
* {@code roundToHour(System.currentTimeMillis())}.
*
* @return the current time, rounded to the closest hour.
*/
public static long currentTimeHour() {
return roundToHour(System.currentTimeMillis());
}
/**
* Gets the current time, rounded down to the closest day.
* Equivalent to invoking
* {@code roundToDay(System.currentTimeMillis())}.
*
* @return the current time, rounded to the closest day.
*/
public static long currentTimeDay() {
return roundToDay(System.currentTimeMillis());
}
/**
* Rounds the given time down to the closest second.
*
* @param pTime time
* @return the time rounded to the closest second.
*/
public static long roundToSecond(long pTime) {
return (pTime / SECOND) * SECOND;
}
/**
* Rounds the given time down to the closest minute.
*
* @param pTime time
* @return the time rounded to the closest minute.
*/
public static long roundToMinute(long pTime) {
return (pTime / MINUTE) * MINUTE;
}
/**
* Rounds the given time down to the closest hour, using the default timezone.
*
* @param pTime time
* @return the time rounded to the closest hour.
*/
public static long roundToHour(long pTime) {
// TODO: What if timezone offset is sub hour? Are there any? I think so...
return ((pTime / HOUR) * HOUR);
}
/**
* Rounds the given time down to the closest day, using the default timezone.
*
* @param pTime time
* @return the time rounded to the closest day.
*/
public static long roundToDay(long pTime) {
return roundToDay(pTime, TimeZone.getDefault());
}
/**
* Rounds the given time down to the closest day, using the given timezone.
*
* @param pTime time
* @param pTimeZone the timezone to use when rounding
* @return the time rounded to the closest day.
*/
public static long roundToDay(long pTime, TimeZone pTimeZone) {
int offset = pTimeZone.getOffset(pTime);
return (((pTime + offset) / DAY) * DAY) - offset;
}
public static void main(String[] pArgs) throws ParseException {
DateFormat format = new SimpleDateFormat("yyyy.MM.dd HH.mm.ss S");
long time = pArgs.length > 0 ? format.parse(pArgs[0]).getTime() : System.currentTimeMillis();
System.out.println(time + ": " + format.format(new Date(time)));
time = roundToSecond(time);
System.out.println(time + ": " + format.format(new Date(time)));
time = roundToMinute(time);
System.out.println(time + ": " + format.format(new Date(time)));
time = roundToHour(time);
System.out.println(time + ": " + format.format(new Date(time)));
time = roundToDay(time);
System.out.println(time + ": " + format.format(new Date(time)));
}
}
@@ -0,0 +1,129 @@
package com.twelvemonkeys.lang;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.sql.SQLException;
/**
* ExceptionUtil
*
* @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/lang/ExceptionUtil.java#2 $
*/
public final class ExceptionUtil {
/*public*/ static void launder(final Throwable pThrowable, Class<? extends Throwable>... pExpectedTypes) {
if (pThrowable instanceof Error) {
throw (Error) pThrowable;
}
if (pThrowable instanceof RuntimeException) {
throw (RuntimeException) pThrowable;
}
for (Class<? extends Throwable> expectedType : pExpectedTypes) {
if (expectedType.isInstance(pThrowable)) {
throw new RuntimeException(pThrowable);
}
}
throw new UndeclaredThrowableException(pThrowable);
}
@SuppressWarnings({"unchecked", "UnusedDeclaration"})
static <T extends Throwable> void throwAs(final Class<T> pType, final Throwable pThrowable) throws T {
throw (T) pThrowable;
}
public static void throwUnchecked(final Throwable pThrowable) {
throwAs(RuntimeException.class, pThrowable);
}
/*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler<? extends Throwable>... pHandler) {
handleImpl(pThrowable, pHandler);
}
@SuppressWarnings({"unchecked"})
private static <T extends Throwable> void handleImpl(final Throwable pThrowable, final ThrowableHandler<T>... pHandler) {
// TODO: Sort more specific throwable handlers before less specific?
for (ThrowableHandler<T> handler : pHandler) {
if (handler.handles(pThrowable)) {
handler.handle((T) pThrowable);
return;
}
}
throwUnchecked(pThrowable);
}
public static abstract class ThrowableHandler<T extends Throwable> {
private Class<? extends T>[] mThrowables;
protected ThrowableHandler(final Class<? extends T>... pThrowables) {
// TODO: Assert not null
mThrowables = pThrowables.clone();
}
final public boolean handles(final Throwable pThrowable) {
for (Class<? extends T> throwable : mThrowables) {
if (throwable.isAssignableFrom(pThrowable.getClass())) {
return true;
}
}
return false;
}
public abstract void handle(T pThrowable);
}
@SuppressWarnings({"InfiniteLoopStatement"})
public static void main(String[] pArgs) {
while (true) {
foo();
}
}
private static void foo() {
try {
bar();
}
catch (Throwable t) {
handle(t,
new ThrowableHandler<IOException>(IOException.class) {
public void handle(final IOException pThrowable) {
System.out.println("IOException: " + pThrowable + " handled");
}
},
new ThrowableHandler<Exception>(SQLException.class, NumberFormatException.class) {
public void handle(final Exception pThrowable) {
System.out.println("Exception: " + pThrowable + " handled");
}
},
new ThrowableHandler<Throwable>(Throwable.class) {
public void handle(final Throwable pThrowable) {
System.err.println("Generic throwable: " + pThrowable + " NOT handled");
throwUnchecked(pThrowable);
}
}
);
}
}
private static void bar() {
baz();
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
private static void baz() {
double random = Math.random();
if (random < (1.0 / 3.0)) {
throwUnchecked(new FileNotFoundException("FNF Boo"));
}
if (random < (2.0 / 3.0)) {
throwUnchecked(new SQLException("SQL Boo"));
}
else {
throwUnchecked(new Exception("Some Boo"));
}
}
}
@@ -0,0 +1,168 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.lang;
/**
* The class MathUtil contains methods for performing basic numeric operations
* such as the elementary exponential, logarithm, square root, and
* trigonometric functions.
*
* @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/lang/MathUtil.java#1 $
*/
public final class MathUtil {
/** */
private MathUtil() {
}
/**
* Converts an angle measured in degrees to the equivalent angle measured
* in radians.
* This method is a replacement for the Math.toRadians() method in
* Java versions < 1.2 (typically for Applets).
*
* @param pAngDeg an angle, in degrees
* @return the measurement of the angle {@code angdeg} in radians.
*
* @see java.lang.Math#toRadians(double)
*/
public static double toRadians(final double pAngDeg) {
return pAngDeg * Math.PI / 180.0;
}
/**
* Converts an angle measured in radians to the equivalent angle measured
* in degrees.
* This method is a replacement for the Math.toDegrees() method in
* Java versions < 1.2 (typically for Applets).
*
* @param pAngRad an angle, in radians
* @return the measurement of the angle {@code angrad} in degrees.
*
* @see java.lang.Math#toDegrees(double)
*/
public static double toDegrees(final double pAngRad) {
return pAngRad * 180.0 / Math.PI;
}
/**
* Returns the natural logarithm (base <I>e</I>) of a double value.
* Equivalent to {@code java.lang.Math.log}, just with a proper name.
*
* @param pArg a number greater than 0.0.
* @return the value ln {@code pArg}, the natural logarithm of
* {@code pArg}.
*
* @see java.lang.Math#log(double)
*/
public static double ln(final double pArg) {
return Math.log(pArg);
}
private final static double LN_10 = Math.log(10);
/**
* Returns the base 10 logarithm of a double value.
*
* @param pArg a number greater than 0.0.
* @return the value log {@code pArg}, the base 10 logarithm of
* {@code pArg}.
*/
public static double log(final double pArg) {
return Math.log(pArg) / LN_10;
}
private final static double LN_2 = Math.log(10);
/**
* Returns the base 2 logarithm of a double value.
*
* @param pArg a number greater than 0.0.
* @return the value log<SUB>2</SUB> {@code pArg}, the base 2
* logarithm of {@code pArg}.
*/
public static double log2(final double pArg) {
return Math.log(pArg) / LN_2;
}
/**
* Returns the base <i>N</i> logarithm of a double value, for a given base
* <i>N</i>.
*
* @param pArg a number greater than 0.0.
* @param pBase a number greater than 0.0.
*
* @return the value log<SUB>pBase</SUB> {@code pArg}, the base
* {@code pBase} logarithm of {@code pArg}.
*/
public static double log(final double pArg, final double pBase) {
return Math.log(pArg) / Math.log(pBase);
}
/**
* A replacement for {@code Math.abs}, that never returns negative values.
* {@code Math.abs(long)} does this for {@code Long.MIN_VALUE}.
*
* @see Math#abs(long)
* @see Long#MIN_VALUE
*
* @param pNumber
* @return the absolute value of {@code pNumber}
*
* @throws ArithmeticException if {@code pNumber == Long.MIN_VALUE}
*/
public static long abs(final long pNumber) {
if (pNumber == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow: 9223372036854775808");
}
return (pNumber < 0) ? -pNumber : pNumber;
}
/**
* A replacement for {@code Math.abs}, that never returns negative values.
* {@code Math.abs(int)} does this for {@code Integer.MIN_VALUE}.
*
* @see Math#abs(int)
* @see Integer#MIN_VALUE
*
* @param pNumber
* @return the absolute value of {@code pNumber}
*
* @throws ArithmeticException if {@code pNumber == Integer.MIN_VALUE}
*/
public static int abs(final int pNumber) {
if (pNumber == Integer.MIN_VALUE) {
throw new ArithmeticException("int overflow: 2147483648");
}
return (pNumber < 0) ? -pNumber : pNumber;
}
}
@@ -0,0 +1,244 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.lang;
/**
* Platform
*
* @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/lang/Platform.java#1 $
*/
public final class Platform {
/**
* Normalized operating system constant
*/
final OperatingSystem mOS;
/**
* Unormalized operating system version constant (for completeness)
*/
final String mVersion;
/**
* Normalized system architecture constant
*/
final Architecture mArchitecture;
static final private Platform INSTANCE = new Platform();
private Platform() {
mOS = normalizeOperatingSystem();
mVersion = System.getProperty("os.version");
mArchitecture = normalizeArchitecture(mOS);
}
private static OperatingSystem normalizeOperatingSystem() {
String os = System.getProperty("os.name");
if (os == null) {
throw new IllegalStateException("System property \"os.name\" == null");
}
os = os.toLowerCase();
if (os.startsWith("windows")) {
return OperatingSystem.Windows;
}
else if (os.startsWith("linux")) {
return OperatingSystem.Linux;
}
else if (os.startsWith("mac os")) {
return OperatingSystem.MacOS;
}
else if (os.startsWith("solaris") || os.startsWith("sunos")) {
return OperatingSystem.Solaris;
}
return OperatingSystem.Unknown;
}
private static Architecture normalizeArchitecture(final OperatingSystem pOsName) {
String arch = System.getProperty("os.arch");
if (arch == null) {
throw new IllegalStateException("System property \"os.arch\" == null");
}
arch = arch.toLowerCase();
if (pOsName == OperatingSystem.Windows
&& (arch.startsWith("x86") || arch.startsWith("i386"))) {
return Architecture.X86;
// TODO: 64 bit
}
else if (pOsName == OperatingSystem.Linux) {
if (arch.startsWith("x86") || arch.startsWith("i386")) {
return Architecture.I386;
}
else if (arch.startsWith("i686")) {
return Architecture.I686;
}
// TODO: More Linux options?
// TODO: 64 bit
}
else if (pOsName == OperatingSystem.MacOS) {
if (arch.startsWith("power") || arch.startsWith("ppc")) {
return Architecture.PPC;
}
else if (arch.startsWith("i386")) {
return Architecture.I386;
}
}
else if (pOsName == OperatingSystem.Solaris) {
if (arch.startsWith("sparc")) {
return Architecture.SPARC;
}
if (arch.startsWith("x86")) {
// TODO: Should we use i386 as Linux and Mac does?
return Architecture.X86;
}
// TODO: 64 bit
}
return Architecture.Unknown;
}
/**
* Returns the current {@code Platform}.
* @return the current {@code Platform}.
*/
public static Platform get() {
return INSTANCE;
}
/**
* @return this platform's OS.
*/
public OperatingSystem getOS() {
return mOS;
}
/**
* @return this platform's OS version.
*/
public String getVersion() {
return mVersion;
}
/**
* @return this platform's architecture.
*/
public Architecture getArchitecture() {
return mArchitecture;
}
/**
* Shorthand for {@code Platform.get().getOS()}.
* @return the current {@code OperatingSystem}.
*/
public static OperatingSystem os() {
return INSTANCE.mOS;
}
/**
* Shorthand for {@code Platform.get().getVersion()}.
* @return the current OS version.
*/
public static String version() {
return INSTANCE.mVersion;
}
/**
* Shorthand for {@code Platform.get().getArchitecture()}.
* @return the current {@code Architecture}.
*/
public static Architecture arch() {
return INSTANCE.mArchitecture;
}
/**
* Enumeration of common System {@code Architecture}s.
* <p/>
* For {@link #Unknown unknown architectures}, {@code toString()} will return
* the the same value as {@code System.getProperty("os.arch")}.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/Platform.java#1 $
*/
public static enum Architecture {
X86("x86"),
I386("i386"),
I686("i686"),
PPC("ppc"),
SPARC("sparc"),
Unknown(System.getProperty("os.arch"));
final String mName;// for debug only
private Architecture(String pName) {
mName = pName;
}
public String toString() {
return mName;
}
}
/**
* Enumeration of common {@code OperatingSystem}s.
* <p/>
* For {@link #Unknown unknown operating systems}, {@code getName()} will return
* the the same value as {@code System.getProperty("os.name")}.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/Platform.java#1 $
*/
public static enum OperatingSystem {
Windows("Windows", "win"),
Linux("Linux", "lnx"),
Solaris("Solaris", "sun"),
MacOS("Mac OS", "osx"),
Unknown(System.getProperty("os.name"), "");
final String mId;
final String mName;// for debug only
private OperatingSystem(String pName, String pId) {
mName = pName;
mId = pId;
}
public String getName() {
return mName;
}
public String toString() {
return mId;
}
}
}
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.lang;
/**
* Util class for various reflection-based operations.
* <p/>
* <em>NOTE: This class is not considered part of the public API and may be
* changed without notice</em>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/ReflectUtil.java#1 $
*/
public final class ReflectUtil {
/** Don't allow instances */
private ReflectUtil() {}
/**
* Returns the primitive type for the given wrapper type.
*
* @param pType the wrapper type
*
* @return the primitive type
*
* @throws IllegalArgumentException if {@code pType} is not a primitive
* wrapper
*/
public static Class unwrapType(Class pType) {
if (pType == Boolean.class) {
return Boolean.TYPE;
}
else if (pType == Byte.class) {
return Byte.TYPE;
}
else if (pType == Character.class) {
return Character.TYPE;
}
else if (pType == Double.class) {
return Double.TYPE;
}
else if (pType == Float.class) {
return Float.TYPE;
}
else if (pType == Integer.class) {
return Integer.TYPE;
}
else if (pType == Long.class) {
return Long.TYPE;
}
else if (pType == Short.class) {
return Short.TYPE;
}
throw new IllegalArgumentException("Not a primitive wrapper: " + pType);
}
/**
* Returns the wrapper type for the given primitive type.
*
* @param pType the primitive tpye
*
* @return the wrapper type
*
* @throws IllegalArgumentException if {@code pType} is not a primitive
* type
*/
public static Class wrapType(Class pType) {
if (pType == Boolean.TYPE) {
return Boolean.class;
}
else if (pType == Byte.TYPE) {
return Byte.class;
}
else if (pType == Character.TYPE) {
return Character.class;
}
else if (pType == Double.TYPE) {
return Double.class;
}
else if (pType == Float.TYPE) {
return Float.class;
}
else if (pType == Integer.TYPE) {
return Integer.class;
}
else if (pType == Long.TYPE) {
return Long.class;
}
else if (pType == Short.TYPE) {
return Short.class;
}
throw new IllegalArgumentException("Not a primitive type: " + pType);
}
/**
* Returns {@code true} if the given type is a primitive wrapper.
*
* @param pType
*
* @return {@code true} if the given type is a primitive wrapper, otherwise
* {@code false}
*/
public static boolean isPrimitiveWrapper(Class pType) {
return pType == Boolean.class || pType == Byte.class
|| pType == Character.class || pType == Double.class
|| pType == Float.class || pType == Integer.class
|| pType == Long.class || pType == Short.class;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,693 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.lang;
import com.twelvemonkeys.util.XMLProperties;
import java.io.*;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* A utility class with some useful system-related functions.
* <p/>
* <em>NOTE: This class is not considered part of the public API and may be
* changed without notice</em>
*
* @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/lang/SystemUtil.java#3 $
*
*/
public final class SystemUtil {
/** {@code ".xml"} */
public static String XML_PROPERTIES = ".xml";
/** {@code ".properties"} */
public static String STD_PROPERTIES = ".properties";
// Disallow creating objects of this type
private SystemUtil() {
}
/** This class marks an inputstream as containing XML, does nothing */
private static class XMLPropertiesInputStream extends FilterInputStream {
public XMLPropertiesInputStream(InputStream pIS) {
super(pIS);
}
}
/**
* Gets the named resource as a stream from the given Class' Classoader.
* If the pGuessSuffix parameter is true, the method will try to append
* typical properties file suffixes, such as ".properties" or ".xml".
*
* @param pClassLoader the class loader to use
* @param pName name of the resource
* @param pGuessSuffix guess suffix
*
* @return an input stream reading from the resource
*/
private static InputStream getResourceAsStream(ClassLoader pClassLoader, String pName,
boolean pGuessSuffix) {
InputStream is;
if (!pGuessSuffix) {
is = pClassLoader.getResourceAsStream(pName);
// If XML, wrap stream
if (is != null && pName.endsWith(XML_PROPERTIES)) {
is = new XMLPropertiesInputStream(is);
}
}
else {
// Try normal properties
is = pClassLoader.getResourceAsStream(pName + STD_PROPERTIES);
// Try XML
if (is == null) {
is = pClassLoader.getResourceAsStream(pName + XML_PROPERTIES);
// Wrap stream
if (is != null) {
is = new XMLPropertiesInputStream(is);
}
}
}
// Return stream
return is;
}
/**
* Gets the named file as a stream from the current directory.
* If the pGuessSuffix parameter is true, the method will try to append
* typical properties file suffixes, such as ".properties" or ".xml".
*
* @param pName name of the resource
* @param pGuessSuffix guess suffix
*
* @return an input stream reading from the resource
*/
private static InputStream getFileAsStream(String pName,
boolean pGuessSuffix) {
InputStream is = null;
File propertiesFile;
try {
if (!pGuessSuffix) {
// Get file
propertiesFile = new File(pName);
if (propertiesFile.exists()) {
is = new FileInputStream(propertiesFile);
// If XML, wrap stream
if (pName.endsWith(XML_PROPERTIES)) {
is = new XMLPropertiesInputStream(is);
}
}
}
else {
// Try normal properties
propertiesFile = new File(pName + STD_PROPERTIES);
if (propertiesFile.exists()) {
is = new FileInputStream(propertiesFile);
}
else {
// Try XML
propertiesFile = new File(pName + XML_PROPERTIES);
if (propertiesFile.exists()) {
// Wrap stream
is = new XMLPropertiesInputStream(new FileInputStream(propertiesFile));
}
}
}
}
catch (FileNotFoundException fnf) {
// Should not happen, as we always test that the file .exists()
// before creating InputStream
// assert false;
}
return is;
}
/**
* Utility method for loading a named properties-file for a class.
* <P>
* The properties-file is loaded through either:
* <OL>
* <LI>The given class' class loader (from classpath)</LI>
* <LI>Or, the system class loader (from classpath)</LI>
* <LI>Or, if it cannot be found in the classpath, an attempt to read from
* the current directory (or full path if given).</LI>
* </OL>
* <P>
* Both normal java.util.Properties and com.twelvemonkeys.util.XMLProperties
* are supported (XML-properties must have ".xml" as its file extension).
*
* @param pClass The class to load properties for. If this parameter is
* {@code null}, the method will work exactly as
* {@link #loadProperties(String)}
* @param pName The name of the properties-file. If this parameter is
* {@code null}, the method will work exactly as
* {@link #loadProperties(Class)}
*
* @return A Properties mapping read from the given file or for the given
* class. <!--If no properties-file was found, an empty Properties object is
* returned.-->
*
* @throws NullPointerException if both {@code pName} and
* {@code pClass} paramters are {@code null}
* @throws IOException if an error occurs during load.
* @throws FileNotFoundException if no properties-file could be found.
*
* @see #loadProperties(String)
* @see #loadProperties(Class)
* @see java.lang.ClassLoader#getResourceAsStream
* @see java.lang.ClassLoader#getSystemResourceAsStream
*
* @todo Reconsider ever using the System ClassLoader: http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html
* @todo Consider using Context Classloader instead?
*/
public static Properties loadProperties(Class pClass, String pName)
throws IOException
{
// Convert to name the classloader understands
String name = !StringUtil.isEmpty(pName) ? pName : pClass.getName().replace('.', '/');
// Should we try to guess suffix?
boolean guessSuffix = (pName == null || pName.indexOf('.') < 0);
InputStream is;
// TODO: WHAT IF MULTIPLE RESOURCES EXISTS?!
// Try loading resource through the current class' classloader
if (pClass != null
&& (is = getResourceAsStream(pClass.getClassLoader(), name, guessSuffix)) != null) {
//&& (is = getResourceAsStream(pClass, name, guessSuffix)) != null) {
// Nothing to do
//System.out.println(((is instanceof XMLPropertiesInputStream) ?
// "XML-properties" : "Normal .properties")
// + " from Class' ClassLoader");
}
// If that fails, try the system classloader
else if ((is = getResourceAsStream(ClassLoader.getSystemClassLoader(),
name, guessSuffix)) != null) {
//else if ((is = getSystemResourceAsStream(name, guessSuffix)) != null) {
// Nothing to do
//System.out.println(((is instanceof XMLPropertiesInputStream) ?
// "XML-properties" : "Normal .properties")
// + " from System ClassLoader");
}
// All failed, try loading from file
else if ((is = getFileAsStream(name, guessSuffix)) != null) {
//System.out.println(((is instanceof XMLPropertiesInputStream) ?
// "XML-properties" : "Normal .properties")
// + " from System ClassLoader");
}
else {
if (guessSuffix) {
// TODO: file extension iterator or something...
throw new FileNotFoundException(name + ".properties or " + name + ".xml");
}
else {
throw new FileNotFoundException(name);
}
}
// We have inputstream now, load...
try {
return loadProperties(is);
}
finally {
// NOTE: If is == null, a FileNotFoundException must have been thrown above
try {
is.close();
}
catch (IOException ioe) {
// Not critical...
}
}
}
/**
* Utility method for loading a properties-file for a given class.
* The properties are searched for on the form
* "com/package/ClassName.properties" or
* "com/package/ClassName.xml".
* <P>
* The properties-file is loaded through either:
* <OL>
* <LI>The given class' class loader (from classpath)</LI>
* <LI>Or, the system class loader (from classpath)</LI>
* <LI>Or, if it cannot be found in the classpath, an attempt to read from
* the current directory (or full path if given).</LI>
* </OL>
* <P>
* Both normal java.util.Properties and com.twelvemonkeys.util.XMLProperties
* are supported (XML-properties must have ".xml" as its file extension).
*
* @param pClass The class to load properties for
* @return A Properties mapping for the given class. <!--If no properties-
* file was found, an empty Properties object is returned.-->
*
* @throws NullPointerException if the {@code pClass} paramters is
* {@code null}
* @throws IOException if an error occurs during load.
* @throws FileNotFoundException if no properties-file could be found.
*
* @see #loadProperties(String)
* @see #loadProperties(Class, String)
* @see java.lang.ClassLoader#getResourceAsStream
* @see java.lang.ClassLoader#getSystemResourceAsStream
*
*/
public static Properties loadProperties(Class pClass) throws IOException {
return loadProperties(pClass, null);
}
/**
* Utility method for loading a named properties-file.
* <P>
* The properties-file is loaded through either:
* <OL>
* <LI>The system class loader (from classpath)</LI>
* <LI>Or, if it cannot be found in the classpath, an attempt to read from
* the current directory.</LI>
* </OL>
* <P>
* Both normal java.util.Properties and com.twelvemonkeys.util.XMLProperties
* are supported (XML-properties must have ".xml" as its file extension).
*
* @param pName The name of the properties-file.
* @return A Properties mapping read from the given file. <!--If no properties-
* file was found, an empty Properties object is returned.-->
*
* @throws NullPointerException if the {@code pName} paramters is
* {@code null}
* @throws IOException if an error occurs during load.
* @throws FileNotFoundException if no properties-file could be found.
*
* @see #loadProperties(Class)
* @see #loadProperties(Class, String)
* @see java.lang.ClassLoader#getSystemResourceAsStream
*
*/
public static Properties loadProperties(String pName) throws IOException {
return loadProperties(null, pName);
}
/*
* Utility method for loading a properties-file.
* <P>
* The properties files may also be contained in a zip/jar-file named
* by the {@code com.twelvemonkeys.util.Config} system property (use "java -D"
* to override). Default is "config.zip" in the current directory.
*
* @param pName The name of the file to loaded
* @return A Properties mapping for the given class. If no properties-
* file was found, an empty Properties object is returned.
*
*/
/*
public static Properties loadProperties(String pName) throws IOException {
// Use XML?
boolean useXML = pName.endsWith(XML_PROPERTIES) ? true : false;
InputStream is = null;
File file = new File(pName);
String configName = System.getProperty("com.twelvemonkeys.util.Config");
File configArchive = new File(!StringUtil.isEmpty(configName)
? configName : DEFAULT_CONFIG);
// Get input stream to the file containing the properties
if (file.exists()) {
// Try reading from file, normal way
is = new FileInputStream(file);
}
else if (configArchive.exists()) {
// Try reading properties from zip-file
ZipFile zip = new ZipFile(configArchive);
ZipEntry ze = zip.getEntry(pName);
if (ze != null) {
is = zip.getInputStream(ze);
}
}
// Do the loading
try {
// Load the properties
return loadProperties(is, useXML);
}
finally {
// Try closing the archive to free resources
if (is != null) {
try {
is.close();
}
catch (IOException ioe) {
// Not critical...
}
}
}
}
*/
/**
* Returns a Properties, loaded from the given inputstream. If the given
* inputstream is null, then an empty Properties object is returned.
*
* @param pInput the inputstream to read from
*
* @return a Properties object read from the given stream, or an empty
* Properties mapping, if the stream is null.
*
* @throws IOException if an error occurred when reading from the input
* stream.
*
*/
private static Properties loadProperties(InputStream pInput)
throws IOException {
if (pInput == null) {
throw new IllegalArgumentException("InputStream == null!");
}
Properties mapping;
if (pInput instanceof XMLPropertiesInputStream) {
mapping = new XMLProperties();
}
else {
mapping = new Properties();
}
// Load the properties
mapping.load(pInput);
return mapping;
}
@SuppressWarnings({"SuspiciousSystemArraycopy"})
public static Object clone(final Cloneable pObject) throws CloneNotSupportedException {
if (pObject == null) {
return null; // Null is clonable.. Easy. ;-)
}
// All arrays does have a clone method, but it's invisible for reflection...
// By luck, multi-dimensional primitive arrays are instances of Object[]
if (pObject instanceof Object[]) {
return ((Object[]) pObject).clone();
}
else if (pObject.getClass().isArray()) {
// One-dimensional primitive array, cloned manually
int lenght = Array.getLength(pObject);
Object clone = Array.newInstance(pObject.getClass().getComponentType(), lenght);
System.arraycopy(pObject, 0, clone, 0, lenght);
return clone;
}
try {
// Find the clone method
Method clone = null;
Class clazz = pObject.getClass();
do {
try {
clone = clazz.getDeclaredMethod("clone");
break; // Found, or throws exception above
}
catch (NoSuchMethodException ignore) {
// Ignore
}
}
while ((clazz = clazz.getSuperclass()) != null);
// NOTE: This should never happen
if (clone == null) {
throw new CloneNotSupportedException(pObject.getClass().getName());
}
// Override access if needed
if (!clone.isAccessible()) {
clone.setAccessible(true);
}
// Invoke clone method on original object
return clone.invoke(pObject);
}
catch (SecurityException e) {
CloneNotSupportedException cns = new CloneNotSupportedException(pObject.getClass().getName());
cns.initCause(e);
throw cns;
}
catch (IllegalAccessException e) {
throw new CloneNotSupportedException(pObject.getClass().getName());
}
catch (InvocationTargetException e) {
if (e.getTargetException() instanceof CloneNotSupportedException) {
throw (CloneNotSupportedException) e.getTargetException();
}
else if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
}
else if (e.getTargetException() instanceof Error) {
throw (Error) e.getTargetException();
}
throw new CloneNotSupportedException(pObject.getClass().getName());
}
}
// public static void loadLibrary(String pLibrary) {
// NativeLoader.loadLibrary(pLibrary);
// }
//
// public static void loadLibrary(String pLibrary, ClassLoader pLoader) {
// NativeLoader.loadLibrary(pLibrary, pLoader);
// }
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("clone: " + args.clone().length + " (" + args.length + ")");
System.out.println("copy: " + ((String[]) clone(args)).length + " (" + args.length + ")");
int[] ints = {1,2,3};
int[] copies = (int[]) clone(ints);
System.out.println("Copies: " + copies.length + " (" + ints.length + ")");
int[][] intsToo = {{1}, {2,3}, {4,5,6}};
int[][] copiesToo = (int[][]) clone(intsToo);
System.out.println("Copies: " + copiesToo.length + " (" + intsToo.length + ")");
System.out.println("Copies0: " + copiesToo[0].length + " (" + intsToo[0].length + ")");
System.out.println("Copies1: " + copiesToo[1].length + " (" + intsToo[1].length + ")");
System.out.println("Copies2: " + copiesToo[2].length + " (" + intsToo[2].length + ")");
Map<String, String> map = new HashMap<String, String>();
for (String arg : args) {
map.put(arg, arg);
}
Map copy = (Map) clone((Cloneable) map);
System.out.println("Map : " + map);
System.out.println("Copy: " + copy);
/*
SecurityManager sm = System.getSecurityManager();
try {
System.setSecurityManager(new SecurityManager() {
public void checkPermission(Permission perm) {
if (perm.getName().equals("suppressAccessChecks")) {
throw new SecurityException();
}
//super.checkPermission(perm);
}
});
*/
Cloneable cloneable = new Cloneable() {}; // No public clone method
Cloneable clone = (Cloneable) clone(cloneable);
System.out.println("cloneable: " + cloneable);
System.out.println("clone: " + clone);
/*
}
finally {
System.setSecurityManager(sm);
}
*/
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
return null;
}
}, AccessController.getContext());
//String string = args.length > 0 ? args[0] : "jaffa";
//clone(string);
}
/**
* Tests if a named class is generally available.
* If a class is considered available, a call to
* {@code Class.forName(pClassName)} will not result in an exception.
*
* @param pClassName the class name to test
* @return {@code true} if available
*/
public static boolean isClassAvailable(String pClassName) {
return isClassAvailable(pClassName, (ClassLoader) null);
}
/**
* Tests if a named class is available from another class.
* If a class is considered available, a call to
* {@code Class.forName(pClassName, true, pFromClass.getClassLoader())}
* will not result in an exception.
*
* @param pClassName the class name to test
* @param pFromClass the class to test from
* @return {@code true} if available
*/
public static boolean isClassAvailable(String pClassName, Class pFromClass) {
ClassLoader loader = pFromClass != null ? pFromClass.getClassLoader() : null;
return isClassAvailable(pClassName, loader);
}
private static boolean isClassAvailable(String pClassName, ClassLoader pLoader) {
try {
// TODO: Sometimes init is not needed, but need to find a way to know...
getClass(pClassName, true, pLoader);
return true;
}
catch (SecurityException ignore) {
// Ignore
}
catch (ClassNotFoundException ignore) {
// Ignore
}
catch (LinkageError ignore) {
// Ignore
}
return false;
}
public static boolean isFieldAvailable(final String pClassName, final String pFieldName) {
return isFieldAvailable(pClassName, pFieldName, (ClassLoader) null);
}
public static boolean isFieldAvailable(final String pClassName, final String pFieldName, final Class pFromClass) {
ClassLoader loader = pFromClass != null ? pFromClass.getClassLoader() : null;
return isFieldAvailable(pClassName, pFieldName, loader);
}
private static boolean isFieldAvailable(final String pClassName, final String pFieldName, final ClassLoader pLoader) {
try {
Class cl = getClass(pClassName, false, pLoader);
Field field = cl.getField(pFieldName);
if (field != null) {
return true;
}
}
catch (ClassNotFoundException ignore) {
// Ignore
}
catch (LinkageError ignore) {
// Ignore
}
catch (NoSuchFieldException ignore) {
// Ignore
}
return false;
}
public static boolean isMethodAvailable(String pClassName, String pMethodName) {
// Finds void only
return isMethodAvailable(pClassName, pMethodName, null, (ClassLoader) null);
}
public static boolean isMethodAvailable(String pClassName, String pMethodName, Class[] pParams) {
return isMethodAvailable(pClassName, pMethodName, pParams, (ClassLoader) null);
}
public static boolean isMethodAvailable(String pClassName, String pMethodName, Class[] pParams, Class pFromClass) {
ClassLoader loader = pFromClass != null ? pFromClass.getClassLoader() : null;
return isMethodAvailable(pClassName, pMethodName, pParams, loader);
}
private static boolean isMethodAvailable(String pClassName, String pMethodName, Class[] pParams, ClassLoader pLoader) {
try {
Class cl = getClass(pClassName, false, pLoader);
Method method = cl.getMethod(pMethodName, pParams);
if (method != null) {
return true;
}
}
catch (ClassNotFoundException ignore) {
// Ignore
}
catch (LinkageError ignore) {
// Ignore
}
catch (NoSuchMethodException ignore) {
// Ignore
}
return false;
}
private static Class getClass(String pClassName, boolean pInitialize, ClassLoader pLoader) throws ClassNotFoundException {
// NOTE: We need the context classloader, as SystemUtil's
// classloader may have a totally different classloader than
// the original caller class (as in Class.forName(cn, false, null)).
ClassLoader loader = pLoader != null ? pLoader :
Thread.currentThread().getContextClassLoader();
return Class.forName(pClassName, pInitialize, loader);
}
}
@@ -0,0 +1,124 @@
package com.twelvemonkeys.lang;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
/**
* Kind of like {@code org.apache.commons.lang.Validate}. Just smarter. ;-)
* <p/>
* Uses type parameterized return values, thus making it possible to check
* constructor arguments before
* they are passed on to {@code super} or {@code this} type constructors.
*
* @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/lang/Validate.java#1 $
*/
public final class Validate {
private static final String UNSPECIFIED_PARAM_NAME = "method parameter";
private Validate() {}
// Not null...
public static <T> T notNull(final T pParameter) {
return notNull(pParameter, null);
}
public static <T> T notNull(final T pParameter, final String pParamName) {
if (pParameter == null) {
throw new IllegalArgumentException(String.format("%s may not be null", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
return pParameter;
}
// Not empty...
public static <T extends CharSequence> T notEmpty(final T pParameter) {
return notEmpty(pParameter, null);
}
public static <T extends CharSequence> T notEmpty(final T pParameter, final String pParamName) {
if (pParameter == null || pParameter.length() == 0) {
throw new IllegalArgumentException(String.format("%s may not be empty", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
return pParameter;
}
public static <T> T[] notEmpty(final T[] pParameter) {
return notEmpty(pParameter, null);
}
public static <T> T[] notEmpty(final T[] pParameter, final String pParamName) {
if (pParameter == null || pParameter.length == 0) {
throw new IllegalArgumentException(String.format("%s may not be empty", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
return pParameter;
}
public static <T> Collection<T> notEmpty(final Collection<T> pParameter) {
return notEmpty(pParameter, null);
}
public static <T> Collection<T> notEmpty(final Collection<T> pParameter, final String pParamName) {
if (pParameter == null || pParameter.isEmpty()) {
throw new IllegalArgumentException(String.format("%s may not be empty", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
return pParameter;
}
public static <K, V> Map<K, V> notEmpty(final Map<K, V> pParameter) {
return notEmpty(pParameter, null);
}
public static <K, V> Map<K, V> notEmpty(final Map<K, V> pParameter, final String pParamName) {
if (pParameter == null || pParameter.isEmpty()) {
throw new IllegalArgumentException(String.format("%s may not be empty", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
return pParameter;
}
// No null elements
public static <T> T[] noNullElements(final T[] pParameter) {
return noNullElements(pParameter, null);
}
public static <T> T[] noNullElements(final T[] pParameter, final String pParamName) {
noNullElements(Arrays.asList(pParameter), pParamName);
return pParameter;
}
public static <T> Collection<T> noNullElements(final Collection<T> pParameter) {
return noNullElements(pParameter, null);
}
public static <T> Collection<T> noNullElements(final Collection<T> pParameter, final String pParamName) {
for (T element : pParameter) {
if (element == null) {
throw new IllegalArgumentException(String.format("%s may not contain null elements", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
}
return pParameter;
}
public static <K, V> Map<K, V> noNullElements(final Map<K, V> pParameter) {
return noNullElements(pParameter, null);
}
public static <K, V> Map<K, V> noNullElements(final Map<K, V> pParameter, final String pParamName) {
for (V element : pParameter.values()) {
if (element == null) {
throw new IllegalArgumentException(String.format("%s may not contain null elements", pParamName == null ? UNSPECIFIED_PARAM_NAME : pParamName));
}
}
return pParameter;
}
}
@@ -0,0 +1,4 @@
/**
*Contains utils/helpers for classes in {@code java.lang}.
*/
package com.twelvemonkeys.lang;