de.intarsys.tools.functor.ArgTools Maven / Gradle / Ivy
Show all versions of isrt Show documentation
/*
* Copyright (c) 2007, intarsys consulting GmbH
*
* 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 of intarsys 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 de.intarsys.tools.functor;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import de.intarsys.tools.enumeration.EnumItem;
import de.intarsys.tools.enumeration.EnumMeta;
import de.intarsys.tools.locator.FileLocator;
import de.intarsys.tools.locator.ILocator;
import de.intarsys.tools.locator.ILocatorFactory;
import de.intarsys.tools.reflect.ClassTools;
import de.intarsys.tools.string.Converter;
import de.intarsys.tools.string.StringTools;
/**
* Tool class to ease handling of arguments.
*
*/
public class ArgTools {
static private int nesting = 0;
public static final IFunctor toString = new IFunctor() {
public Object perform(IFunctorCall call)
throws FunctorInvocationException {
Args args = (Args) call.getReceiver();
StringBuilder sb = new StringBuilder();
if (args.isNamed()) {
for (Iterator it = args.names().iterator(); it.hasNext();) {
String name = (String) it.next();
sb.append(name);
sb.append(" = ");
sb.append(args.get(name));
sb.append("\n");
}
} else {
for (int i = 0; i < args.size(); i++) {
sb.append(i);
sb.append(" = ");
sb.append(args.get(i));
sb.append("\n");
}
}
return sb.toString();
}
};
private static Set visited;
protected static ILocator createLocator(Object optionValue,
ILocator defaultValue, ILocatorFactory factory) {
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof ILocator) {
return (ILocator) optionValue;
}
if (optionValue instanceof File) {
try {
return factory.createLocator(((File) optionValue)
.getAbsolutePath());
} catch (IOException e) {
return defaultValue;
}
}
if (optionValue instanceof String) {
if (StringTools.isEmpty((String) optionValue)) {
return defaultValue;
}
try {
return factory.createLocator((String) optionValue);
} catch (IOException e) {
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as an {@link IArgs} instance. If
* the argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link IArgs}, {@link String}, {@link Map}
* and {@link List}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as an {@link IArgs}
* instance.
*/
public static IArgs getArgs(IArgs args, String name, IArgs defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof IArgs) {
return (IArgs) optionValue;
}
if (optionValue instanceof String) {
optionValue = Converter.asMap((String) optionValue);
}
if (optionValue instanceof Map) {
return new Args((Map) optionValue);
}
if (optionValue instanceof List) {
return new Args((List) optionValue);
}
return defaultValue;
}
/**
* The argument value at name
as a boolean. If the argument
* value is not provided or not convertible, defaultValue
is
* returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Boolean}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a boolean
*/
public static boolean getBool(IArgs args, String name, boolean defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof Boolean) {
return ((Boolean) optionValue).booleanValue();
}
if (optionValue instanceof String) {
String optionString = (String) optionValue;
return Converter.asBoolean(optionString, defaultValue);
}
return defaultValue;
}
/**
* The argument value at name
as a byte. If the argument value
* is not provided or not convertible, defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Number}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a byte.
*/
public static byte getByte(IArgs args, String name, byte defaultValue) {
if (args == null) {
return defaultValue;
}
Object value = args.get(name);
if (value instanceof Number) {
return ((Number) value).byteValue();
}
if (value instanceof String) {
try {
return Byte.parseByte((String) value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as a char. If the argument value
* is not provided or not convertible, defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Character}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a char.
*/
public static char getChar(IArgs args, String name, char defaultValue) {
if (args == null) {
return defaultValue;
}
Object value = args.get(name);
if (value instanceof Character) {
return ((Character) value).charValue();
}
if (value instanceof String) {
String valueString = (String) value;
if (valueString.length() > 0) {
return valueString.charAt(0);
}
}
return defaultValue;
}
/**
* The argument value at name
as a char[]. If the argument
* value is not provided or not convertible, defaultValue
is
* returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link String}, char[]. Unlike the other
* conversion methods, this one throws an IllegalArgumentException, if the
* value is not of type String
or char[]
.
*
* @param args
* @param name
* @param defaultValue
* @exception IllegalArgumentException
* if value is not of type String
or
* char[]
* @return The argument value at name
as a {@link String}.
*/
public static char[] getCharArray(IArgs args, String name,
char[] defaultValue) throws IllegalArgumentException {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof char[]) {
return (char[]) optionValue;
}
if (optionValue instanceof String) {
return ((String) optionValue).toCharArray();
}
throw new IllegalArgumentException("argument '" + name //$NON-NLS-1$
+ "' must be of type string or char[]"); //$NON-NLS-1$
}
/**
* The argument value at name
as a {@link Class}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Boolean}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link Class}.
*/
public static Class getClass(IArgs args, String name, Class defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof Class) {
return (Class) optionValue;
}
if (optionValue instanceof String) {
String optionString = (String) optionValue;
try {
return ClassTools.createClass(optionString, Object.class, null);
} catch (Exception e) {
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as a {@link Date}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Date}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link Date}.
*/
public static Date getDate(IArgs args, String name, Date defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof Date) {
return (Date) optionValue;
}
if (optionValue instanceof String) {
String optionString = (String) optionValue;
try {
return DateFormat.getInstance().parse(optionString);
} catch (ParseException e) {
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as a {@link EnumItem}. If the
* argument value is not provided or not convertible, the enumeration
* default value is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link EnumItem}, {@link String}.
*
* @param args
* @param meta
* @param name
* @return The argument value at name
as a {@link EnumItem}.
*/
public static T getEnumItem(IArgs args,
EnumMeta meta, String name) {
if (args == null) {
return meta.getDefault();
}
Object optionValue = args.get(name);
if (optionValue == null) {
return meta.getDefault();
}
if (optionValue instanceof EnumItem) {
return (T) optionValue;
}
if (optionValue instanceof String) {
String optionString = (String) optionValue;
return meta.getItemOrDefault(optionString);
}
return meta.getDefault();
}
/**
* The argument value at name
as a {@link EnumItem}. If the
* argument value is not provided or not convertible, the enumeration item
* with the id defaultValuee
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link EnumItem}, {@link String}.
*
* @param args
* @param meta
* @param name
* @return The argument value at name
as a {@link EnumItem}.
*/
public static T getEnumItem(IArgs args,
EnumMeta meta, String name, String defaultValue) {
if (args == null) {
return meta.getItemOrDefault(defaultValue);
}
Object optionValue = args.get(name);
if (optionValue == null) {
return meta.getItemOrDefault(defaultValue);
}
if (optionValue instanceof EnumItem) {
return (T) optionValue;
}
if (optionValue instanceof String) {
String optionString = (String) optionValue;
return meta.getItemOrDefault(optionString);
}
return meta.getItemOrDefault(defaultValue);
}
/**
* The argument value at name
as a {@link File}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link File}, {@link String},
* {@link ILocator}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link Date}.
*/
public static File getFile(IArgs args, String name, File defaultValue) {
if (args == null) {
return defaultValue;
}
Object value = args.get(name);
if (value instanceof File) {
return (File) value;
}
if (value instanceof String) {
return new File((String) value);
}
if (value instanceof FileLocator) {
return ((FileLocator) value).getFile();
}
if (value instanceof ILocator) {
return new File(((ILocator) value).getFullName());
}
return defaultValue;
}
/**
* The argument value at name
as a float. If the argument value
* is not provided or not convertible, defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Number}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a float.
*/
public static float getFloat(IArgs args, String name, float defaultValue) {
if (args == null) {
return defaultValue;
}
Object value = args.get(name);
if (value instanceof Number) {
return ((Number) value).floatValue();
}
if (value instanceof String) {
String stringValue = (String) value;
if (stringValue.indexOf("%") != -1) { //$NON-NLS-1$
try {
Number result = NumberFormat.getPercentInstance().parse(
stringValue);
return result.floatValue();
} catch (ParseException e) {
// todo log warning
return defaultValue;
}
}
try {
return Float.parseFloat(stringValue);
} catch (NumberFormatException e) {
// todo log warning
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as a int. If the argument value
* is not provided or not convertible, defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Number}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a int.
*/
public static int getInt(IArgs args, String name, int defaultValue) {
if (args == null) {
return defaultValue;
}
Object value = args.get(name);
if (value instanceof Number) {
return ((Number) value).intValue();
}
if (value instanceof String) {
try {
return Integer.parseInt((String) value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as a {@link ILocator}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link ILocator}, {@link String},
* {@link File}
*
* @param args
* @param name
* @param defaultValue
* @param factory
* @return The argument value at name
as a {@link ILocator}.
*/
public static ILocator getLocator(IArgs args, String name,
ILocator defaultValue, ILocatorFactory factory) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
return createLocator(optionValue, defaultValue, factory);
}
/**
* The argument value at name
as a List. If the
* argument value is not provided, null
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are {@link Collection} of {@link ILocator}, {@link String} and
* {@link File}.
*
* @param args
* @param name
* @param factory
* @return The argument value at name
as a {@link List}.
*/
public static List getLocators(IArgs args, String name,
ILocatorFactory factory) {
if (args == null) {
return null;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return null;
}
List locators = new ArrayList();
if (optionValue instanceof Collection) {
for (Iterator i = ((Collection) optionValue).iterator(); i
.hasNext();) {
Object candidate = i.next();
ILocator locator = createLocator(candidate, null, factory);
if (locator != null) {
locators.add(locator);
}
}
} else {
ILocator locator = createLocator(optionValue, null, factory);
if (locator != null) {
locators.add(locator);
}
}
return locators;
}
/**
* The argument value at name
as a {@link Map}. If the argument
* value is not provided or not convertible, defaultValue
is
* returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Map}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link Map}.
*/
public static Map getMap(IArgs args, String name, Map defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof Map) {
return (Map) optionValue;
}
if (optionValue instanceof String) {
return Converter.asMap((String) optionValue);
}
return defaultValue;
}
/**
* The argument value at name
as a {@link Object}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Object}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link Object}.
*/
public static Object getObject(IArgs args, String name, Object defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
return optionValue;
}
/**
* The argument value at name
as a {@link Point2D}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link Point2D}, {@link String}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link Point2D}.
*/
public static Point2D getPoint(IArgs args, String name, Point2D defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof Point2D) {
return (Point2D) optionValue;
}
if (optionValue instanceof String) {
String optionString = (String) optionValue;
String[] coords = optionString.split("[x*@]"); //$NON-NLS-1$
if ((coords == null) || (coords.length != 2)) {
return defaultValue;
}
try {
float x = Float.parseFloat(coords[0]);
float y = Float.parseFloat(coords[1]);
return new Point2D.Float(x, y);
} catch (NumberFormatException e) {
return defaultValue;
}
}
return defaultValue;
}
/**
* The argument value at name
as a {@link String}. If the
* argument value is not provided or not convertible,
* defaultValue
is returned.
*
* This method performs the necessary casts and conversions. Supported input
* types are null
, {@link String}, {@link Object}.
*
* @param args
* @param name
* @param defaultValue
* @return The argument value at name
as a {@link String}.
*/
public static String getString(IArgs args, String name, String defaultValue) {
if (args == null) {
return defaultValue;
}
Object optionValue = args.get(name);
if (optionValue == null) {
return defaultValue;
}
if (optionValue instanceof String) {
return (String) optionValue;
}
if (optionValue instanceof char[]) {
return new String((char[]) optionValue);
}
return String.valueOf(optionValue);
}
/**
* Create a new argument name from name
by prefixing with
* prefix
.
*
* @param prefix
* @param name
* @return The new argument name.
*/
public static String prefix(String prefix, String name) {
if (name == null) {
return null;
}
if ((prefix == null) || (prefix.length() == 0)) {
return name;
}
return prefix + Character.toUpperCase(name.charAt(0))
+ name.substring(1);
}
/**
* Cast or convert value
to an {@link IArgs}.
*
* @param value
* @return The {@link IArgs} created from value
.
*/
public static IArgs toArgs(Object value) {
if (value instanceof IArgs) {
return (IArgs) value;
}
if (value instanceof String) {
value = Converter.asMap((String) value);
}
if (value instanceof Map) {
return new Args((Map) value);
}
if (value instanceof List) {
return new Args((List) value);
}
return Args.EMPTY;
}
/**
* Convert the args
to a {@link List}.
*
* @param args
* @return The {@link List} representation of the args
*/
public static List toList(IArgs args) {
List result = new ArrayList();
int i = args.size();
while (i > 0) {
i--;
result.add(args.get(i));
}
return result;
}
/**
* Convert the args
to a {@link Map}.
*
* @param args
* @return The {@link Map} representation of the args
*/
public static Map toMap(IArgs args) {
Map result = new HashMap();
if (args != null) {
for (Iterator it = args.names().iterator(); it.hasNext();) {
String name = (String) it.next();
result.put(name, args.get(name));
}
}
return result;
}
/**
* Create a printable {@link String} for args
.
*
* @param args
* @param prefix
* @return
*/
synchronized public static String toString(IArgs args, String prefix) {
if (visited == null) {
visited = new HashSet();
nesting = 0;
}
if (visited.contains(args)) {
return "...recursive...";
}
if (nesting == 4) {
return "...nested to deeply...";
}
visited.add(args);
nesting++;
try {
StringBuilder sb = new StringBuilder();
if (args.isNamed()) {
// flat ones....
for (Iterator it = args.names().iterator(); it.hasNext();) {
String name = (String) it.next();
Object value = args.get(name);
if (!(value instanceof IArgs)) {
toStringPlain(prefix, sb, name, value);
}
}
// nested ones...
for (Iterator it = args.names().iterator(); it.hasNext();) {
String name = (String) it.next();
Object value = args.get(name);
if (value instanceof IArgs) {
toStringArgs(prefix, sb, name, (IArgs) value);
}
}
} else {
for (int i = 0; i < args.size(); i++) {
Object value = args.get(i);
if (value instanceof IArgs) {
toStringArgs(prefix, sb, "" + i, (IArgs) value);
} else {
toStringPlain(prefix, sb, "" + i, value);
}
}
}
return sb.toString();
} finally {
nesting--;
if (nesting == 0) {
visited = null;
}
}
}
protected static void toStringArgs(String prefix, StringBuilder sb,
String name, IArgs value) {
for (int i = 1; i < nesting; i++) {
sb.append(" ");
}
sb.append(name);
sb.append(" = ");
sb.append("{");
sb.append("\n");
sb.append(toString(value, prefix));
sb.append("\n");
for (int i = 1; i < nesting; i++) {
sb.append(" ");
}
sb.append("}");
sb.append("\n");
}
protected static void toStringPlain(String prefix, StringBuilder sb,
String name, Object value) {
for (int i = 1; i < nesting; i++) {
sb.append(" ");
}
sb.append(name);
sb.append(" = ");
sb.append(StringTools.safeString(value));
sb.append("\n");
}
}