You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/06/28 21:34:40 UTC
svn commit: r417856 [16/22] - in /incubator/openjpa/trunk/openjpa-lib: java/
main/ main/java/ main/java/org/apache/openjpa/lib/ant/
main/java/org/apache/openjpa/lib/conf/ main/java/org/apache/openjpa/lib/jdbc/
main/java/org/apache/openjpa/lib/log/ main...
Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/MultiClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/MultiClassLoader.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/MultiClassLoader.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/MultiClassLoader.java Wed Jun 28 12:34:33 2006
@@ -15,292 +15,280 @@
*/
package org.apache.openjpa.lib.util;
-
import java.io.*;
+
import java.net.*;
+
import java.util.*;
/**
- * <p>Class loader type that can be configured to delegate to multiple
- * internal class loaders.</p>
+ * <p>Class loader type that can be configured to delegate to multiple
+ * internal class loaders.</p>
*
- * <p>The {@link #THREAD_LOADER} constant is a marker that will be replaced
- * with the context loader of the current thread.</p>
+ * <p>The {@link #THREAD_LOADER} constant is a marker that will be replaced
+ * with the context loader of the current thread.</p>
*
- * @author Abe White
+ * @author Abe White
*/
-public class MultiClassLoader
- extends ClassLoader
-{
- /**
- * Marker that will be replaced with the context loader of the current
- * thread whenever it is discovered in the class loader list.
- */
- public static final ClassLoader THREAD_LOADER = null;
-
- /**
- * The standard system class loader.
- */
- public static final ClassLoader SYSTEM_LOADER =
- ClassLoader.getSystemClassLoader ();
-
- private List _loaders = new ArrayList (5);
-
-
- /**
- * Constructor; initializes the loader with an empty list of delegates.
- */
- public MultiClassLoader ()
- {
- super (null);
- }
-
-
- /**
- * Construct with the class loaders of another multi loader.
- */
- public MultiClassLoader (MultiClassLoader other)
- {
- super (null);
- addClassLoaders (other);
- }
-
-
- /**
- * Returns true if the list contains the given class loader or marker.
- */
- public boolean containsClassLoader (ClassLoader loader)
- {
- return _loaders.contains (loader);
- }
-
-
- /**
- * Return an array of all contained class loaders.
- */
- public ClassLoader[] getClassLoaders ()
- {
- ClassLoader[] loaders = new ClassLoader[size ()];
- ClassLoader loader;
- Iterator itr = _loaders.iterator ();
- for (int i = 0; i < loaders.length; i++)
- {
- loader = (ClassLoader) itr.next ();
- if (loader == THREAD_LOADER)
- loader = Thread.currentThread ().getContextClassLoader ();
- loaders[i] = loader;
- }
- return loaders;
- }
-
-
- /**
- * Return the class loader at the given index.
- */
- public ClassLoader getClassLoader (int index)
- {
- ClassLoader loader = (ClassLoader) _loaders.get (index);
- if (loader == THREAD_LOADER)
- loader = Thread.currentThread ().getContextClassLoader ();
- return loader;
- }
-
-
- /**
- * Add the given class loader to the set of loaders that will be tried.
- *
- * @return true if the loader was added, false if already in the list
- */
- public boolean addClassLoader (ClassLoader loader)
- {
- if (_loaders.contains (loader))
- return false;
- return _loaders.add (loader);
- }
-
-
- /**
- * Add the given class loader at the specified index.
- *
- * @return true if the loader was added, false if already in the list
- */
- public boolean addClassLoader (int index, ClassLoader loader)
- {
- if (_loaders.contains (loader))
- return false;
- _loaders.add (index, loader);
- return true;
- }
-
-
- /**
- * Set the class loaders of this loader to those of the given loader.
- */
- public void setClassLoaders (MultiClassLoader multi)
- {
- clear ();
- addClassLoaders (multi);
- }
-
-
- /**
- * Adds all class loaders from the given multi loader starting at the
- * given index.
- *
- * @return true if any loaders were added, false if all already in list
- */
- public boolean addClassLoaders (int index, MultiClassLoader multi)
- {
- if (multi == null)
- return false;
-
- // use iterator so that the thread loader is not resolved
- boolean added = false;
- for (Iterator itr = multi._loaders.iterator (); itr.hasNext ();)
- {
- if (addClassLoader (index, (ClassLoader) itr.next ()))
- {
- index++;
- added = true;
- }
- }
- return added;
- }
-
-
- /**
- * Adds all the class loaders from the given multi loader.
- *
- * @return true if any loaders were added, false if all already in list
- */
- public boolean addClassLoaders (MultiClassLoader multi)
- {
- if (multi == null)
- return false;
-
- // use iterator so that the thread loader is not resolved
- boolean added = false;
- for (Iterator itr = multi._loaders.iterator (); itr.hasNext ();)
- added = addClassLoader ((ClassLoader) itr.next ()) || added;
- return added;
- }
-
-
- /**
- * Remove the given loader from the list.
- *
- * @return true if removed, false if not in list
- */
- public boolean removeClassLoader (ClassLoader loader)
- {
- return _loaders.remove (loader);
- }
-
-
- /**
- * Clear the list of class loaders.
- */
- public void clear ()
- {
- _loaders.clear ();
- }
-
-
- /**
- * Return the number of internal class loaders.
- */
- public int size ()
- {
- return _loaders.size ();
- }
-
-
- /**
- * Return true if there are no internal class laoders.
- */
- public boolean isEmpty ()
- {
- return _loaders.isEmpty ();
- }
-
-
- protected Class findClass (String name)
- throws ClassNotFoundException
- {
- ClassLoader loader;
- for (Iterator itr = _loaders.iterator (); itr.hasNext ();)
- {
- loader = (ClassLoader) itr.next ();
- if (loader == THREAD_LOADER)
- loader = Thread.currentThread ().getContextClassLoader ();
- try
- {
- return Class.forName (name, false, loader);
- }
- catch (Throwable t)
- {
- }
- }
- throw new ClassNotFoundException (name);
- }
-
-
- protected URL findResource (String name)
- {
- ClassLoader loader;
- URL rsrc;
- for (Iterator itr = _loaders.iterator (); itr.hasNext ();)
- {
- loader = (ClassLoader) itr.next ();
- if (loader == THREAD_LOADER)
- loader = Thread.currentThread ().getContextClassLoader ();
-
- rsrc = loader.getResource (name);
- if (rsrc != null)
- return rsrc;
- }
- return null;
- }
-
-
- protected Enumeration findResources (String name)
- throws IOException
- {
- ClassLoader loader;
- Enumeration rsrcs;
- Object rsrc;
- Vector all = new Vector ();
- for (Iterator itr = _loaders.iterator (); itr.hasNext ();)
- {
- loader = (ClassLoader) itr.next ();
- if (loader == THREAD_LOADER)
- loader = Thread.currentThread ().getContextClassLoader ();
-
- rsrcs = loader.getResources (name);
- while (rsrcs.hasMoreElements ())
- {
- rsrc = rsrcs.nextElement ();
- if (!all.contains (rsrc))
- all.addElement (rsrc);
- }
- }
- return all.elements ();
- }
-
-
- public boolean equals (Object other)
- {
- if (other == this)
- return true;
- if (!(other instanceof MultiClassLoader))
- return false;
- return ((MultiClassLoader) other)._loaders.equals (_loaders);
- }
-
-
- public int hashCode ()
- {
- return _loaders.hashCode ();
- }
+public class MultiClassLoader extends ClassLoader {
+ /**
+ * Marker that will be replaced with the context loader of the current
+ * thread whenever it is discovered in the class loader list.
+ */
+ public static final ClassLoader THREAD_LOADER = null;
+
+ /**
+ * The standard system class loader.
+ */
+ public static final ClassLoader SYSTEM_LOADER = ClassLoader.getSystemClassLoader();
+ private List _loaders = new ArrayList(5);
+
+ /**
+ * Constructor; initializes the loader with an empty list of delegates.
+ */
+ public MultiClassLoader() {
+ super(null);
+ }
+
+ /**
+ * Construct with the class loaders of another multi loader.
+ */
+ public MultiClassLoader(MultiClassLoader other) {
+ super(null);
+ addClassLoaders(other);
+ }
+
+ /**
+ * Returns true if the list contains the given class loader or marker.
+ */
+ public boolean containsClassLoader(ClassLoader loader) {
+ return _loaders.contains(loader);
+ }
+
+ /**
+ * Return an array of all contained class loaders.
+ */
+ public ClassLoader[] getClassLoaders() {
+ ClassLoader[] loaders = new ClassLoader[size()];
+ ClassLoader loader;
+ Iterator itr = _loaders.iterator();
+
+ for (int i = 0; i < loaders.length; i++) {
+ loader = (ClassLoader) itr.next();
+
+ if (loader == THREAD_LOADER) {
+ loader = Thread.currentThread().getContextClassLoader();
+ }
+
+ loaders[i] = loader;
+ }
+
+ return loaders;
+ }
+
+ /**
+ * Return the class loader at the given index.
+ */
+ public ClassLoader getClassLoader(int index) {
+ ClassLoader loader = (ClassLoader) _loaders.get(index);
+
+ if (loader == THREAD_LOADER) {
+ loader = Thread.currentThread().getContextClassLoader();
+ }
+
+ return loader;
+ }
+
+ /**
+ * Add the given class loader to the set of loaders that will be tried.
+ *
+ * @return true if the loader was added, false if already in the list
+ */
+ public boolean addClassLoader(ClassLoader loader) {
+ if (_loaders.contains(loader)) {
+ return false;
+ }
+
+ return _loaders.add(loader);
+ }
+
+ /**
+ * Add the given class loader at the specified index.
+ *
+ * @return true if the loader was added, false if already in the list
+ */
+ public boolean addClassLoader(int index, ClassLoader loader) {
+ if (_loaders.contains(loader)) {
+ return false;
+ }
+
+ _loaders.add(index, loader);
+
+ return true;
+ }
+
+ /**
+ * Set the class loaders of this loader to those of the given loader.
+ */
+ public void setClassLoaders(MultiClassLoader multi) {
+ clear();
+ addClassLoaders(multi);
+ }
+
+ /**
+ * Adds all class loaders from the given multi loader starting at the
+ * given index.
+ *
+ * @return true if any loaders were added, false if all already in list
+ */
+ public boolean addClassLoaders(int index, MultiClassLoader multi) {
+ if (multi == null) {
+ return false;
+ }
+
+ // use iterator so that the thread loader is not resolved
+ boolean added = false;
+
+ for (Iterator itr = multi._loaders.iterator(); itr.hasNext();) {
+ if (addClassLoader(index, (ClassLoader) itr.next())) {
+ index++;
+ added = true;
+ }
+ }
+
+ return added;
+ }
+
+ /**
+ * Adds all the class loaders from the given multi loader.
+ *
+ * @return true if any loaders were added, false if all already in list
+ */
+ public boolean addClassLoaders(MultiClassLoader multi) {
+ if (multi == null) {
+ return false;
+ }
+
+ // use iterator so that the thread loader is not resolved
+ boolean added = false;
+
+ for (Iterator itr = multi._loaders.iterator(); itr.hasNext();)
+ added = addClassLoader((ClassLoader) itr.next()) || added;
+
+ return added;
+ }
+
+ /**
+ * Remove the given loader from the list.
+ *
+ * @return true if removed, false if not in list
+ */
+ public boolean removeClassLoader(ClassLoader loader) {
+ return _loaders.remove(loader);
+ }
+
+ /**
+ * Clear the list of class loaders.
+ */
+ public void clear() {
+ _loaders.clear();
+ }
+
+ /**
+ * Return the number of internal class loaders.
+ */
+ public int size() {
+ return _loaders.size();
+ }
+
+ /**
+ * Return true if there are no internal class laoders.
+ */
+ public boolean isEmpty() {
+ return _loaders.isEmpty();
+ }
+
+ protected Class findClass(String name) throws ClassNotFoundException {
+ ClassLoader loader;
+
+ for (Iterator itr = _loaders.iterator(); itr.hasNext();) {
+ loader = (ClassLoader) itr.next();
+
+ if (loader == THREAD_LOADER) {
+ loader = Thread.currentThread().getContextClassLoader();
+ }
+
+ try {
+ return Class.forName(name, false, loader);
+ } catch (Throwable t) {
+ }
+ }
+
+ throw new ClassNotFoundException(name);
+ }
+
+ protected URL findResource(String name) {
+ ClassLoader loader;
+ URL rsrc;
+
+ for (Iterator itr = _loaders.iterator(); itr.hasNext();) {
+ loader = (ClassLoader) itr.next();
+
+ if (loader == THREAD_LOADER) {
+ loader = Thread.currentThread().getContextClassLoader();
+ }
+
+ rsrc = loader.getResource(name);
+
+ if (rsrc != null) {
+ return rsrc;
+ }
+ }
+
+ return null;
+ }
+
+ protected Enumeration findResources(String name) throws IOException {
+ ClassLoader loader;
+ Enumeration rsrcs;
+ Object rsrc;
+ Vector all = new Vector();
+
+ for (Iterator itr = _loaders.iterator(); itr.hasNext();) {
+ loader = (ClassLoader) itr.next();
+
+ if (loader == THREAD_LOADER) {
+ loader = Thread.currentThread().getContextClassLoader();
+ }
+
+ rsrcs = loader.getResources(name);
+
+ while (rsrcs.hasMoreElements()) {
+ rsrc = rsrcs.nextElement();
+
+ if (!all.contains(rsrc)) {
+ all.addElement(rsrc);
+ }
+ }
+ }
+
+ return all.elements();
+ }
+
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MultiClassLoader)) {
+ return false;
+ }
+
+ return ((MultiClassLoader) other)._loaders.equals(_loaders);
+ }
+
+ public int hashCode() {
+ return _loaders.hashCode();
+ }
}
Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/Options.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/Options.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/Options.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/Options.java Wed Jun 28 12:34:33 2006
@@ -15,677 +15,697 @@
*/
package org.apache.openjpa.lib.util;
-
-import java.lang.reflect.*;
-import java.util.*;
-
import org.apache.commons.collections.*;
import org.apache.commons.lang.*;
+import org.apache.commons.lang.exception.*;
import serp.util.*;
+import java.lang.reflect.*;
+
+import java.util.*;
+
/**
- * <p>A specialization of the {@link Properties} map type with the added
- * abilities to read application options from the command line and to
- * use bean patterns to set an object's properties via command-line the
- * stored mappings.</p>
+ * <p>A specialization of the {@link Properties} map type with the added
+ * abilities to read application options from the command line and to
+ * use bean patterns to set an object's properties via command-line the
+ * stored mappings.</p>
*
- * <p>A typical use pattern for this class is to construct a new instance
- * in the <code>main</code> method, then call {@link #setFromCmdLine} with the
- * given args. Next, an instanceof the class being invoked is created, and
- * {@link #setInto} is called with that instance as a parameter. With this
- * pattern, the user can configure any bean properties of the class, or even
- * properties of classes reachable from the class, through the command
- * line.</p>
+ * <p>A typical use pattern for this class is to construct a new instance
+ * in the <code>main</code> method, then call {@link #setFromCmdLine} with the
+ * given args. Next, an instanceof the class being invoked is created, and
+ * {@link #setInto} is called with that instance as a parameter. With this
+ * pattern, the user can configure any bean properties of the class, or even
+ * properties of classes reachable from the class, through the command
+ * line.</p>
*
- * @author Abe White
- * @nojavadoc
- */
-public class Options
- extends TypedProperties
-{
- // maps primitive types to the appropriate wrapper class and default value
- private static Object[][] _primWrappers = new Object[][] {
- { boolean.class, Boolean.class, Boolean.FALSE },
- { byte.class, Byte.class, new Byte ((byte) 0) },
- { char.class, Character.class, new Character ((char) 0) },
- { double.class, Double.class, new Double (0D) },
- { float.class, Float.class, new Float (0F) },
- { int.class, Integer.class, new Integer (0) },
- { long.class, Long.class, new Long (0L) },
- { short.class, Short.class, new Short ((short) 0) },
- };
-
-
- /**
- * Default constructor.
- */
- public Options ()
- {
- super ();
- }
-
-
- /**
- * Construct the options instance with the given set of defaults.
- *
- * @see Properties#Properties(Properties)
- */
- public Options (Properties defaults)
- {
- super (defaults);
- }
-
-
- /**
- * Parses the given argument list into flag/value pairs, which are stored
- * as properties. Flags that are present without values are given
- * the value "true". If any flag is found for which there is already
- * a mapping present, the existing mapping will be overwritten.
- * Flags should be of the form:<br />
- * <code>java Foo -flag1 value1 -flag2 value2 ... arg1 arg2 ...</code>
- *
- * @param args the command-line arguments
- * @return all arguments in the original array beyond the
- * flag/value pair list
- * @author Patrick Linskey
- */
- public String[] setFromCmdLine (String[] args)
- {
- if (args == null || args.length == 0)
- return args;
-
- String key = null;
- String value = null;
- List remainder = new LinkedList ();
- for (int i = 0; i < args.length + 1; i++)
- {
- if (i == args.length || args[i].startsWith ("-"))
- {
- key = trimQuote (key);
- if (key != null)
- {
- if (value != null && value.length () > 0)
- setProperty (key, trimQuote (value));
- else
- setProperty (key, "true");
- }
-
- if (i == args.length)
- break;
- else
- {
- key = args[i].substring (1);
- value = null;
- }
- }
- else if (key != null)
- {
- setProperty (key, trimQuote (args[i]));
- key = null;
- }
- else
- remainder.add (args[i]);
- }
-
- return (String[]) remainder.toArray (new String[remainder.size ()]);
- }
-
-
- /**
- * This method uses reflection to set all the properties in the given
- * object that are named by the keys in this map. For a given key 'foo',
- * the algorithm will look for a 'setFoo' method in the given instance.
- * For a given key 'foo.bar', the algorithm will first look for a
- * 'getFoo' method in the given instance, then will recurse on the return
- * value of that method, now looking for the 'bar' property. This allows
- * the setting of nested object properties. If in the above example the
- * 'getFoo' method is not present or returns null, the algorithm will
- * look for a 'setFoo' method; if found it will constrct a new instance
- * of the correct type, set it using the 'setFoo' method, then recurse on
- * it as above. Property names can be nested in this way to an arbitrary
- * depth. For setter methods that take multiple parameters, the value
- * mapped to the key can use the ',' as an argument separator character.
- * If not enough values are present for a given method after splitting
- * the string on ',', the remaining arguments will receive default
- * values. All arguments are converted from string form to the
- * correct type if possible (i.e. if the type is primitive,
- * java.lang.Clas, or has a constructor that takes a single string
- * argument). Examples:
- * <ul>
- * <li>Map Entry: <code>"age"->"12"</code><br />
- * Resultant method call: <code>obj.setAge (12)</code></li>
- * <li>Map Entry: <code>"range"->"1,20"</code><br />
- * Resultant method call: <code>obj.setRange (1, 20)</code></li>
- * <li>Map Entry: <code>"range"->"10"</code><br />
- * Resultant method call: <code>obj.setRange (10, 10)</code></li>
- * <li>Map Entry: <code>"brother.name"->"Bob"</code><br />
- * Resultant method call: <code>obj.getBrother ().setName ("Bob")
- * <code></li>
- * </ul>
- *
- * Any keys present in the map for which there is no
- * corresponding property in the given object will be ignored,
- * and will be returned in the {@link Map} returned by this
- * method.
- *
- * @return a {@link Map} of key-value pairs in this object
- * for which no setters could be found.
- * @throws RuntimeException on parse error
- */
- public Map setInto (Object obj)
- {
- // set all defaults that have no explicit value
- Map.Entry entry = null;
- if (defaults != null)
- {
- for (Iterator itr = defaults.entrySet ().iterator(); itr.hasNext();)
- {
- entry = (Map.Entry) itr.next ();
- if (!containsKey (entry.getKey ()))
- setInto (obj, entry);
- }
- }
-
- // set from main map
- Map invalidEntries = null;
- Map.Entry e;
- for (Iterator itr = entrySet ().iterator (); itr.hasNext ();)
- {
- e = (Map.Entry) itr.next ();
- if (!setInto (obj, e))
- {
- if (invalidEntries == null)
- invalidEntries = new HashMap ();
- invalidEntries.put (e.getKey (), e.getValue ());
- }
- }
-
- return (invalidEntries == null) ? MapUtils.EMPTY_MAP : invalidEntries;
- }
-
-
- /**
- * Sets the property named by the key of the given entry in the
- * given object.
- *
- * @return <code>true</code> if the set succeeded, or
- * <code>false</code> if no method could be found for
- * this property.
- */
- private boolean setInto (Object obj, Map.Entry entry)
- {
- if (entry.getKey () == null)
- return false;
-
- try
- {
- // look for matching parameter of object
- Object[] match = new Object[] { obj, null };
- if (!matchOptionToMember (entry.getKey ().toString (), match))
- return false;
-
- Class[] type = getType (match[1]);
- Object[] values = new Object[type.length];
- String[] strValues;
- if (entry.getValue () == null)
- strValues = new String[1];
- else if (values.length == 1)
- strValues = new String[] { entry.getValue ().toString () };
- else
- strValues = Strings.split (entry.getValue ().toString (),
- ",", 0);
-
- // convert the string values into parameter values, if not
- // enough string values repeat last one for rest
- for (int i = 0; i < strValues.length; i++)
- values[i] = stringToObject (strValues[i].trim (), type[i]);
- for (int i = strValues.length; i < values.length; i++)
- values[i] = getDefaultValue (type[i]);
-
- // invoke the setter / set the field
- invoke (match[0], match[1], values);
- return true;
- }
- catch (Throwable t)
- {
- throw new ParseException (obj + "." + entry.getKey ()
- + " = " + entry.getValue (), t);
- }
- }
-
-
- /**
- * Removes leading and trailing single quotes from the given String,
- * if any.
- */
- private static String trimQuote (String val)
- {
- if (val != null && val.startsWith ("'") && val.endsWith ("'"))
- return val.substring (1, val.length () - 1);
- return val;
- }
-
-
- /**
- * Finds all the options that can be set on the provided class. This does
- * not look for path-traversal expressions.
- *
- * @param type The class for which available options should be listed.
- * @return The available option names in <code>type</code>. The
- * names will have initial caps. They will be ordered
- * alphabetically.
- */
- public static Collection findOptionsFor (Class type)
- {
- Collection names = new TreeSet ();
- // look for a setter method matching the key
- Method[] meths = type.getMethods ();
- Class[] params;
- for (int i = 0; i < meths.length; i++)
- {
- if (meths[i].getName ().startsWith ("set"))
- {
- params = meths[i].getParameterTypes ();
- if (params.length == 0)
- continue;
- if (params[0].isArray ())
- continue;
-
- names.add (StringUtils.capitalize (
- meths[i].getName ().substring (3)));
- }
- }
-
- // check for public fields
- Field[] fields = type.getFields ();
- for (int i = 0; i < fields.length; i++)
- names.add (StringUtils.capitalize (fields[i].getName ()));
-
- return names;
- }
-
-
- /**
- * Matches a key to an object/setter pair.
- *
- * @param key the key given at the command line; may be of the form
- * 'foo.bar' to signify the 'bar' property of the
- * 'foo' owned object
- * @param match an array of length 2, where the first index is set
- * to the object to retrieve the setter for
- * @return true if a match was made, false otherwise; additionally,
- * the first index of the match array will be set to
- * the matching object and the second index will be
- * set to the setter method or public field for the
- * property named by the key
- */
- private static boolean matchOptionToMember (String key, Object[] match)
- throws Exception
- {
- if (key == null || key.length () == 0)
- return false;
-
- // unfortunately we can't use bean properties for setters; any
- // setter with more than 1 arg is ignored; calc setter and getter
- // name to look for
- String[] find = Strings.split (key, ".", 2);
- String base = StringUtils.capitalize (find[0]);
- String set = "set" + base;
- String get = "get" + base;
-
- // look for a setter/getter matching the key; look for methods first
- Class type = match[0].getClass ();
- Method[] meths = type.getMethods ();
- Method setMeth = null;
- Method getMeth = null;
- Class[] params;
- for (int i = 0; i < meths.length; i++)
- {
- if (meths[i].getName ().equals (set))
- {
- params = meths[i].getParameterTypes ();
- if (params.length == 0)
- continue;
- if (params[0].isArray ())
- continue;
-
- // use this method if we haven't found any other setter, if
- // it has less parameters than any other setter, or if it uses
- // string parameters
- if (setMeth == null)
- setMeth = meths[i];
- else if (params.length < setMeth.getParameterTypes ().length)
- setMeth = meths[i];
- else if (params.length == setMeth.getParameterTypes ().length
- && params[0] == String.class)
- setMeth = meths[i];
- }
- else if (meths[i].getName ().equals (get))
- getMeth = meths[i];
- }
-
- // if no methods found, check for public field
- Member setter = setMeth;
- Member getter = getMeth;
- if (setter == null)
- {
- Field[] fields = type.getFields ();
- String uncapBase = StringUtils.uncapitalize (find[0]);
- for (int i = 0; i < fields.length; i++)
- {
- if (fields[i].getName ().equals (base)
- || fields[i].getName ().equals (uncapBase))
- {
- setter = fields[i];
- getter = fields[i];
- break;
- }
- }
- }
-
- // if no way to access property, give up
- if (setter == null && getter == null)
- return false;
-
- // recurse on inner object with remainder of key?
- if (find.length > 1)
- {
- Object inner = null;
- if (getter != null)
- inner = invoke (match[0], getter, null);
-
- // if no getter or current inner is null, try to create a new
- // inner instance and set it in object
- if (inner == null && setter != null)
- {
- Class innerType = getType (setter)[0];
- inner = innerType.newInstance ();
- invoke (match[0], setter, new Object[] { inner });
- }
- match[0] = inner;
- return matchOptionToMember (find[1], match);
- }
-
- // got match; find setter for property
- match[1] = setter;
- return match[1] != null;
- }
-
-
- /**
- * Return the types of the parameters needed to set the given member.
- */
- private static Class[] getType (Object member)
- {
- if (member instanceof Method)
- return ((Method) member).getParameterTypes ();
- return new Class[] { ((Field) member).getType () };
- }
-
-
- /**
- * Set the given member to the given value(s).
- */
- private static Object invoke (Object target, Object member, Object[] values)
- throws Exception
- {
- if (member instanceof Method)
- return ((Method) member).invoke (target, values);
- if (values == null || values.length == 0)
- return ((Field) member).get (target);
- ((Field) member).set (target, values[0]);
- return null;
- }
-
-
- /**
- * Converts the given string into an object of the given type, or its
- * wrapper type if it is primitive.
- */
- private Object stringToObject (String str, Class type)
- throws Exception
- {
- // special case for null and for strings
- if (str == null || type == String.class)
- return str;
-
- // special case for creating Class instances
- if (type == Class.class)
- return Class.forName (str, false, getClass ().getClassLoader ());
-
- // special case for numeric types that end in .0; strip the decimal
- // places because it can kill int, short, long parsing
- if (type.isPrimitive () || Number.class.isAssignableFrom (type))
- if (str.length () > 2 && str.endsWith (".0"))
- str = str.substring (0, str.length () - 2);
-
- // for primitives, recurse on wrapper type
- if (type.isPrimitive ())
- for (int i = 0; i < _primWrappers.length; i++)
- if (type == _primWrappers[i][0])
- return stringToObject (str, (Class) _primWrappers[i][1]);
-
- // look for a string constructor
- Exception err = null;
- try
- {
- Constructor cons = type.getConstructor
- (new Class[] { String.class });
- if (type == Boolean.class && "t".equalsIgnoreCase (str))
- str = "true";
- return cons.newInstance (new Object[] { str });
- }
- catch (Exception e)
- {
- err = e;
- }
-
- // special case: the arg value is a subtype name and a new instance
- // of that type should be set as the object
- Class subType = null;
- try
- {
- subType = Class.forName (str);
- }
- catch (Exception e)
- {
- throw err;
- }
- if (!type.isAssignableFrom (subType))
- throw err;
- return subType.newInstance ();
- }
-
-
- /**
- * Returns the default value for the given parameter type.
- */
- private Object getDefaultValue (Class type)
- {
- for (int i = 0; i < _primWrappers.length; i++)
- if (_primWrappers[i][0] == type)
- return _primWrappers[i][2];
-
- return null;
- }
-
-
- /**
- * Specialization of {@link #getBooleanProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public boolean getBooleanProperty (String key, String key2, boolean def)
- {
- String val = getProperty (key);
- if (val == null)
- val = getProperty (key2);
- if (val == null)
- return def;
- return "t".equalsIgnoreCase (val) || "true".equalsIgnoreCase (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#getFloatProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public float getFloatProperty (String key, String key2, float def)
- {
- String val = getProperty (key);
- if (val == null)
- val = getProperty (key2);
- return (val == null) ? def : Float.parseFloat (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#getDoubleProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public double getDoubleProperty (String key, String key2, double def)
- {
- String val = getProperty (key);
- if (val == null)
- val = getProperty (key2);
- return (val == null) ? def : Double.parseDouble (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#getLongProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public long getLongProperty (String key, String key2, long def)
- {
- String val = getProperty (key);
- if (val == null)
- val = getProperty (key2);
- return (val == null) ? def : Long.parseLong (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#getIntProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public int getIntProperty (String key, String key2, int def)
- {
- String val = getProperty (key);
- if (val == null)
- val = getProperty (key2);
- return (val == null) ? def : Integer.parseInt (val);
- }
-
-
- /**
- * Specialization of {@link Properties#getProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public String getProperty (String key, String key2, String def)
- {
- String val = getProperty (key);
- return (val == null) ? getProperty (key2, def) : val;
- }
-
-
- /**
- * Specialization of {@link TypedProperties#removeBooleanProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public boolean removeBooleanProperty (String key, String key2, boolean def)
- {
- String val = removeProperty (key);
- if (val == null)
- val = removeProperty (key2);
- else
- removeProperty (key2);
- if (val == null)
- return def;
- return "t".equalsIgnoreCase (val) || "true".equalsIgnoreCase (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#removeFloatProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public float removeFloatProperty (String key, String key2, float def)
- {
- String val = removeProperty (key);
- if (val == null)
- val = removeProperty (key2);
- else
- removeProperty (key2);
- return (val == null) ? def : Float.parseFloat (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#removeDoubleProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public double removeDoubleProperty (String key, String key2, double def)
- {
- String val = removeProperty (key);
- if (val == null)
- val = removeProperty (key2);
- else
- removeProperty (key2);
- return (val == null) ? def : Double.parseDouble (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#removeLongProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public long removeLongProperty (String key, String key2, long def)
- {
- String val = removeProperty (key);
- if (val == null)
- val = removeProperty (key2);
- else
- removeProperty (key2);
- return (val == null) ? def : Long.parseLong (val);
- }
-
-
- /**
- * Specialization of {@link TypedProperties#removeIntProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public int removeIntProperty (String key, String key2, int def)
- {
- String val = removeProperty (key);
- if (val == null)
- val = removeProperty (key2);
- else
- removeProperty (key2);
- return (val == null) ? def : Integer.parseInt (val);
- }
-
-
- /**
- * Specialization of {@link Properties#removeProperty} to allow
- * a value to appear under either of two keys; useful for short and
- * long versions of command-line flags.
- */
- public String removeProperty (String key, String key2, String def)
- {
- String val = removeProperty (key);
- return (val == null) ? removeProperty (key2, def) : val;
- }
+ * @author Abe White
+ * @nojavadoc */
+public class Options extends TypedProperties {
+ // maps primitive types to the appropriate wrapper class and default value
+ private static Object[][] _primWrappers = new Object[][] {
+ { boolean.class, Boolean.class, Boolean.FALSE },
+ { byte.class, Byte.class, new Byte((byte) 0) },
+ { char.class, Character.class, new Character((char) 0) },
+ { double.class, Double.class, new Double(0D) },
+ { float.class, Float.class, new Float(0F) },
+ { int.class, Integer.class, new Integer(0) },
+ { long.class, Long.class, new Long(0L) },
+ { short.class, Short.class, new Short((short) 0) },
+ };
+
+ /**
+ * Default constructor.
+ */
+ public Options() {
+ super();
+ }
+
+ /**
+ * Construct the options instance with the given set of defaults.
+ *
+ * @see Properties#Properties(Properties)
+ */
+ public Options(Properties defaults) {
+ super(defaults);
+ }
+
+ /**
+ * Parses the given argument list into flag/value pairs, which are stored
+ * as properties. Flags that are present without values are given
+ * the value "true". If any flag is found for which there is already
+ * a mapping present, the existing mapping will be overwritten.
+ * Flags should be of the form:<br />
+ * <code>java Foo -flag1 value1 -flag2 value2 ... arg1 arg2 ...</code>
+ *
+ * @param args the command-line arguments
+ * @return all arguments in the original array beyond the
+ * flag/value pair list
+ * @author Patrick Linskey
+ */
+ public String[] setFromCmdLine(String[] args) {
+ if ((args == null) || (args.length == 0)) {
+ return args;
+ }
+
+ String key = null;
+ String value = null;
+ List remainder = new LinkedList();
+
+ for (int i = 0; i < (args.length + 1); i++) {
+ if ((i == args.length) || args[i].startsWith("-")) {
+ key = trimQuote(key);
+
+ if (key != null) {
+ if ((value != null) && (value.length() > 0)) {
+ setProperty(key, trimQuote(value));
+ } else {
+ setProperty(key, "true");
+ }
+ }
+
+ if (i == args.length) {
+ break;
+ } else {
+ key = args[i].substring(1);
+ value = null;
+ }
+ } else if (key != null) {
+ setProperty(key, trimQuote(args[i]));
+ key = null;
+ } else {
+ remainder.add(args[i]);
+ }
+ }
+
+ return (String[]) remainder.toArray(new String[remainder.size()]);
+ }
+
+ /**
+ * This method uses reflection to set all the properties in the given
+ * object that are named by the keys in this map. For a given key 'foo',
+ * the algorithm will look for a 'setFoo' method in the given instance.
+ * For a given key 'foo.bar', the algorithm will first look for a
+ * 'getFoo' method in the given instance, then will recurse on the return
+ * value of that method, now looking for the 'bar' property. This allows
+ * the setting of nested object properties. If in the above example the
+ * 'getFoo' method is not present or returns null, the algorithm will
+ * look for a 'setFoo' method; if found it will constrct a new instance
+ * of the correct type, set it using the 'setFoo' method, then recurse on
+ * it as above. Property names can be nested in this way to an arbitrary
+ * depth. For setter methods that take multiple parameters, the value
+ * mapped to the key can use the ',' as an argument separator character.
+ * If not enough values are present for a given method after splitting
+ * the string on ',', the remaining arguments will receive default
+ * values. All arguments are converted from string form to the
+ * correct type if possible (i.e. if the type is primitive,
+ * java.lang.Clas, or has a constructor that takes a single string
+ * argument). Examples:
+ * <ul>
+ * <li>Map Entry: <code>"age"->"12"</code><br />
+ * Resultant method call: <code>obj.setAge (12)</code></li>
+ * <li>Map Entry: <code>"range"->"1,20"</code><br />
+ * Resultant method call: <code>obj.setRange (1, 20)</code></li>
+ * <li>Map Entry: <code>"range"->"10"</code><br />
+ * Resultant method call: <code>obj.setRange (10, 10)</code></li>
+ * <li>Map Entry: <code>"brother.name"->"Bob"</code><br />
+ * Resultant method call: <code>obj.getBrother ().setName ("Bob")
+ * <code></li>
+ * </ul>
+ *
+ * Any keys present in the map for which there is no
+ * corresponding property in the given object will be ignored,
+ * and will be returned in the {@link Map} returned by this
+ * method.
+ *
+ * @return a {@link Map} of key-value pairs in this object
+ * for which no setters could be found.
+ * @throws RuntimeException on parse error
+ */
+ public Map setInto(Object obj) {
+ // set all defaults that have no explicit value
+ Map.Entry entry = null;
+
+ if (defaults != null) {
+ for (Iterator itr = defaults.entrySet().iterator(); itr.hasNext();) {
+ entry = (Map.Entry) itr.next();
+
+ if (!containsKey(entry.getKey())) {
+ setInto(obj, entry);
+ }
+ }
+ }
+
+ // set from main map
+ Map invalidEntries = null;
+ Map.Entry e;
+
+ for (Iterator itr = entrySet().iterator(); itr.hasNext();) {
+ e = (Map.Entry) itr.next();
+
+ if (!setInto(obj, e)) {
+ if (invalidEntries == null) {
+ invalidEntries = new HashMap();
+ }
+
+ invalidEntries.put(e.getKey(), e.getValue());
+ }
+ }
+
+ return (invalidEntries == null) ? Collections.EMPTY_MAP : invalidEntries;
+ }
+
+ /**
+ * Sets the property named by the key of the given entry in the
+ * given object.
+ *
+ * @return <code>true</code> if the set succeeded, or
+ * <code>false</code> if no method could be found for
+ * this property.
+ */
+ private boolean setInto(Object obj, Map.Entry entry) {
+ if (entry.getKey() == null) {
+ return false;
+ }
+
+ try {
+ // look for matching parameter of object
+ Object[] match = new Object[] { obj, null };
+
+ if (!matchOptionToMember(entry.getKey().toString(), match)) {
+ return false;
+ }
+
+ Class[] type = getType(match[1]);
+ Object[] values = new Object[type.length];
+ String[] strValues;
+
+ if (entry.getValue() == null) {
+ strValues = new String[1];
+ } else if (values.length == 1) {
+ strValues = new String[] { entry.getValue().toString() };
+ } else {
+ strValues = Strings.split(entry.getValue().toString(), ",", 0);
+ }
+
+ // convert the string values into parameter values, if not
+ // enough string values repeat last one for rest
+ for (int i = 0; i < strValues.length; i++)
+ values[i] = stringToObject(strValues[i].trim(), type[i]);
+
+ for (int i = strValues.length; i < values.length; i++)
+ values[i] = getDefaultValue(type[i]);
+
+ // invoke the setter / set the field
+ invoke(match[0], match[1], values);
+
+ return true;
+ } catch (Throwable t) {
+ throw new ParseException(obj + "." + entry.getKey() + " = " +
+ entry.getValue(), t);
+ }
+ }
+
+ /**
+ * Removes leading and trailing single quotes from the given String,
+ * if any.
+ */
+ private static String trimQuote(String val) {
+ if ((val != null) && val.startsWith("'") && val.endsWith("'")) {
+ return val.substring(1, val.length() - 1);
+ }
+
+ return val;
+ }
+
+ /**
+ * Finds all the options that can be set on the provided class. This does
+ * not look for path-traversal expressions.
+ *
+ * @param type The class for which available options should be listed.
+ * @return The available option names in <code>type</code>. The
+ * names will have initial caps. They will be ordered
+ * alphabetically.
+ */
+ public static Collection findOptionsFor(Class type) {
+ Collection names = new TreeSet();
+
+ // look for a setter method matching the key
+ Method[] meths = type.getMethods();
+ Class[] params;
+
+ for (int i = 0; i < meths.length; i++) {
+ if (meths[i].getName().startsWith("set")) {
+ params = meths[i].getParameterTypes();
+
+ if (params.length == 0) {
+ continue;
+ }
+
+ if (params[0].isArray()) {
+ continue;
+ }
+
+ names.add(StringUtils.capitalize(meths[i].getName().substring(3)));
+ }
+ }
+
+ // check for public fields
+ Field[] fields = type.getFields();
+
+ for (int i = 0; i < fields.length; i++)
+ names.add(StringUtils.capitalize(fields[i].getName()));
+
+ return names;
+ }
+
+ /**
+ * Matches a key to an object/setter pair.
+ *
+ * @param key the key given at the command line; may be of the form
+ * 'foo.bar' to signify the 'bar' property of the
+ * 'foo' owned object
+ * @param match an array of length 2, where the first index is set
+ * to the object to retrieve the setter for
+ * @return true if a match was made, false otherwise; additionally,
+ * the first index of the match array will be set to
+ * the matching object and the second index will be
+ * set to the setter method or public field for the
+ * property named by the key
+ */
+ private static boolean matchOptionToMember(String key, Object[] match)
+ throws Exception {
+ if ((key == null) || (key.length() == 0)) {
+ return false;
+ }
+
+ // unfortunately we can't use bean properties for setters; any
+ // setter with more than 1 arg is ignored; calc setter and getter
+ // name to look for
+ String[] find = Strings.split(key, ".", 2);
+ String base = StringUtils.capitalise(find[0]);
+ String set = "set" + base;
+ String get = "get" + base;
+
+ // look for a setter/getter matching the key; look for methods first
+ Class type = match[0].getClass();
+ Method[] meths = type.getMethods();
+ Method setMeth = null;
+ Method getMeth = null;
+ Class[] params;
+
+ for (int i = 0; i < meths.length; i++) {
+ if (meths[i].getName().equals(set)) {
+ params = meths[i].getParameterTypes();
+
+ if (params.length == 0) {
+ continue;
+ }
+
+ if (params[0].isArray()) {
+ continue;
+ }
+
+ // use this method if we haven't found any other setter, if
+ // it has less parameters than any other setter, or if it uses
+ // string parameters
+ if (setMeth == null) {
+ setMeth = meths[i];
+ } else if (params.length < setMeth.getParameterTypes().length) {
+ setMeth = meths[i];
+ } else if ((params.length == setMeth.getParameterTypes().length) &&
+ (params[0] == String.class)) {
+ setMeth = meths[i];
+ }
+ } else if (meths[i].getName().equals(get)) {
+ getMeth = meths[i];
+ }
+ }
+
+ // if no methods found, check for public field
+ Member setter = setMeth;
+ Member getter = getMeth;
+
+ if (setter == null) {
+ Field[] fields = type.getFields();
+ String uncapBase = StringUtils.uncapitalise(find[0]);
+
+ for (int i = 0; i < fields.length; i++) {
+ if (fields[i].getName().equals(base) ||
+ fields[i].getName().equals(uncapBase)) {
+ setter = fields[i];
+ getter = fields[i];
+
+ break;
+ }
+ }
+ }
+
+ // if no way to access property, give up
+ if ((setter == null) && (getter == null)) {
+ return false;
+ }
+
+ // recurse on inner object with remainder of key?
+ if (find.length > 1) {
+ Object inner = null;
+
+ if (getter != null) {
+ inner = invoke(match[0], getter, null);
+ }
+
+ // if no getter or current inner is null, try to create a new
+ // inner instance and set it in object
+ if ((inner == null) && (setter != null)) {
+ Class innerType = getType(setter)[0];
+ inner = innerType.newInstance();
+ invoke(match[0], setter, new Object[] { inner });
+ }
+
+ match[0] = inner;
+
+ return matchOptionToMember(find[1], match);
+ }
+
+ // got match; find setter for property
+ match[1] = setter;
+
+ return match[1] != null;
+ }
+
+ /**
+ * Return the types of the parameters needed to set the given member.
+ */
+ private static Class[] getType(Object member) {
+ if (member instanceof Method) {
+ return ((Method) member).getParameterTypes();
+ }
+
+ return new Class[] { ((Field) member).getType() };
+ }
+
+ /**
+ * Set the given member to the given value(s).
+ */
+ private static Object invoke(Object target, Object member, Object[] values)
+ throws Exception {
+ if (member instanceof Method) {
+ return ((Method) member).invoke(target, values);
+ }
+
+ if ((values == null) || (values.length == 0)) {
+ return ((Field) member).get(target);
+ }
+
+ ((Field) member).set(target, values[0]);
+
+ return null;
+ }
+
+ /**
+ * Converts the given string into an object of the given type, or its
+ * wrapper type if it is primitive.
+ */
+ private Object stringToObject(String str, Class type)
+ throws Exception {
+ // special case for null and for strings
+ if ((str == null) || (type == String.class)) {
+ return str;
+ }
+
+ // special case for creating Class instances
+ if (type == Class.class) {
+ return Class.forName(str, false, getClass().getClassLoader());
+ }
+
+ // special case for numeric types that end in .0; strip the decimal
+ // places because it can kill int, short, long parsing
+ if (type.isPrimitive() || Number.class.isAssignableFrom(type)) {
+ if ((str.length() > 2) && str.endsWith(".0")) {
+ str = str.substring(0, str.length() - 2);
+ }
+ }
+
+ // for primitives, recurse on wrapper type
+ if (type.isPrimitive()) {
+ for (int i = 0; i < _primWrappers.length; i++)
+ if (type == _primWrappers[i][0]) {
+ return stringToObject(str, (Class) _primWrappers[i][1]);
+ }
+ }
+
+ // look for a string constructor
+ Exception err = null;
+
+ try {
+ Constructor cons = type.getConstructor(new Class[] { String.class });
+
+ if ((type == Boolean.class) && "t".equalsIgnoreCase(str)) {
+ str = "true";
+ }
+
+ return cons.newInstance(new Object[] { str });
+ } catch (Exception e) {
+ err = e;
+ }
+
+ // special case: the arg value is a subtype name and a new instance
+ // of that type should be set as the object
+ Class subType = null;
+
+ try {
+ subType = Class.forName(str);
+ } catch (Exception e) {
+ throw err;
+ }
+
+ if (!type.isAssignableFrom(subType)) {
+ throw err;
+ }
+
+ return subType.newInstance();
+ }
+
+ /**
+ * Returns the default value for the given parameter type.
+ */
+ private Object getDefaultValue(Class type) {
+ for (int i = 0; i < _primWrappers.length; i++)
+ if (_primWrappers[i][0] == type) {
+ return _primWrappers[i][2];
+ }
+
+ return null;
+ }
+
+ /**
+ * Specialization of {@link #getBooleanProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public boolean getBooleanProperty(String key, String key2, boolean def) {
+ String val = getProperty(key);
+
+ if (val == null) {
+ val = getProperty(key2);
+ }
+
+ if (val == null) {
+ return def;
+ }
+
+ return "t".equalsIgnoreCase(val) || "true".equalsIgnoreCase(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#getFloatProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public float getFloatProperty(String key, String key2, float def) {
+ String val = getProperty(key);
+
+ if (val == null) {
+ val = getProperty(key2);
+ }
+
+ return (val == null) ? def : Float.parseFloat(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#getDoubleProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public double getDoubleProperty(String key, String key2, double def) {
+ String val = getProperty(key);
+
+ if (val == null) {
+ val = getProperty(key2);
+ }
+
+ return (val == null) ? def : Double.parseDouble(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#getLongProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public long getLongProperty(String key, String key2, long def) {
+ String val = getProperty(key);
+
+ if (val == null) {
+ val = getProperty(key2);
+ }
+
+ return (val == null) ? def : Long.parseLong(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#getIntProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public int getIntProperty(String key, String key2, int def) {
+ String val = getProperty(key);
+
+ if (val == null) {
+ val = getProperty(key2);
+ }
+
+ return (val == null) ? def : Integer.parseInt(val);
+ }
+
+ /**
+ * Specialization of {@link Properties#getProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public String getProperty(String key, String key2, String def) {
+ String val = getProperty(key);
+
+ return (val == null) ? getProperty(key2, def) : val;
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#removeBooleanProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public boolean removeBooleanProperty(String key, String key2, boolean def) {
+ String val = removeProperty(key);
+
+ if (val == null) {
+ val = removeProperty(key2);
+ } else {
+ removeProperty(key2);
+ }
+
+ if (val == null) {
+ return def;
+ }
+
+ return "t".equalsIgnoreCase(val) || "true".equalsIgnoreCase(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#removeFloatProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public float removeFloatProperty(String key, String key2, float def) {
+ String val = removeProperty(key);
+
+ if (val == null) {
+ val = removeProperty(key2);
+ } else {
+ removeProperty(key2);
+ }
+
+ return (val == null) ? def : Float.parseFloat(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#removeDoubleProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public double removeDoubleProperty(String key, String key2, double def) {
+ String val = removeProperty(key);
+
+ if (val == null) {
+ val = removeProperty(key2);
+ } else {
+ removeProperty(key2);
+ }
+
+ return (val == null) ? def : Double.parseDouble(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#removeLongProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public long removeLongProperty(String key, String key2, long def) {
+ String val = removeProperty(key);
+
+ if (val == null) {
+ val = removeProperty(key2);
+ } else {
+ removeProperty(key2);
+ }
+
+ return (val == null) ? def : Long.parseLong(val);
+ }
+
+ /**
+ * Specialization of {@link TypedProperties#removeIntProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public int removeIntProperty(String key, String key2, int def) {
+ String val = removeProperty(key);
+
+ if (val == null) {
+ val = removeProperty(key2);
+ } else {
+ removeProperty(key2);
+ }
+
+ return (val == null) ? def : Integer.parseInt(val);
+ }
+
+ /**
+ * Specialization of {@link Properties#removeProperty} to allow
+ * a value to appear under either of two keys; useful for short and
+ * long versions of command-line flags.
+ */
+ public String removeProperty(String key, String key2, String def) {
+ String val = removeProperty(key);
+
+ return (val == null) ? removeProperty(key2, def) : val;
+ }
}
Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParameterTemplate.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParameterTemplate.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParameterTemplate.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParameterTemplate.java Wed Jun 28 12:34:33 2006
@@ -15,284 +15,249 @@
*/
package org.apache.openjpa.lib.util;
-
import java.io.*;
+
import java.util.*;
/**
- * <p>A template that allows parameter substitutions. Parameters should be
- * placed in the template in the form ${param-name}. Use the
- * {@link #setParameter} method to set the parameter values, which will be
- * substituted into the template on calls to {@link #write} and
- * {@link #toString}. If a parameter is encountered that hasn't been set, then
- * the parameter key is used to lookup the corresponding System property.</p>
+ * <p>A template that allows parameter substitutions. Parameters should be
+ * placed in the template in the form ${param-name}. Use the
+ * {@link #setParameter} method to set the parameter values, which will be
+ * substituted into the template on calls to {@link #write} and
+ * {@link #toString}. If a parameter is encountered that hasn't been set, then
+ * the parameter key is used to lookup the corresponding System property.</p>
*
- * @author Abe White
- * @nojavadoc
- */
-public class ParameterTemplate
-{
- private static final String SEP = System.getProperty ("line.separator");
-
- private final StringBuffer _buf = new StringBuffer ();
- private final Map _params = new HashMap ();
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (String value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (boolean value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (char value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (double value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (float value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (int value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (long value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (short value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (Object value)
- {
- _buf.append (value);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (InputStream in)
- throws IOException
- {
- return append (new InputStreamReader (in));
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (Reader reader)
- throws IOException
- {
- BufferedReader buf = new BufferedReader (reader);
- String line;
- while ((line = buf.readLine ()) != null)
- _buf.append (line).append (SEP);
- return this;
- }
-
-
- /**
- * Add the given value to the internal template.
- */
- public ParameterTemplate append (File file)
- throws IOException
- {
- FileReader reader = new FileReader (file);
- try
- {
- return append (reader);
- }
- finally
- {
- try { reader.close (); } catch (IOException ioe) {}
- }
- }
-
-
- /**
- * Return true if the given parameter has been given a value.
- */
- public boolean hasParameter (String name)
- {
- return _params.containsKey (name);
- }
-
-
- /**
- * Return the value set for the given parameter.
- */
- public Object getParameter (String name)
- {
- return _params.get (name);
- }
-
-
- /**
- * Set the value for the given parameter.
- */
- public Object setParameter (String name, Object val)
- {
- return _params.put (name, val);
- }
-
-
- /**
- * Set the values for all the parameters in the given map.
- */
- public void setParameters (Map params)
- {
- _params.putAll (params);
- }
-
-
- /**
- * Clear the recorded parameter values.
- */
- public void clearParameters ()
- {
- _params.clear ();
- }
-
-
- /**
- * Return a copy of the internal value template with all parameters
- * substituted with their current values.
- */
- public String toString ()
- {
- if (_buf.length () == 0 || _params.isEmpty ())
- return _buf.toString ();
-
- StringBuffer copy = new StringBuffer ();
- StringBuffer param = null;
- char ch, last = 0;
- for (int i = 0; i < _buf.length (); i++)
- {
- ch = _buf.charAt (i);
- if (last == '$' && ch == '{')
- {
- copy.deleteCharAt (copy.length () - 1);
- param = new StringBuffer ();
- }
- else if (ch == '}' && param != null)
- {
- if (_params.containsKey (param.toString ()))
- copy.append (_params.get (param.toString ()));
- else
- copy.append (System.getProperty (param.toString ()));
- param = null;
- }
- else if (param != null)
- param.append (ch);
- else
- copy.append (ch);
-
- last = ch;
- }
- return copy.toString ();
- }
-
-
- /**
- * Write the internal value template with all parameters
- * substituted with their current values.
- */
- public void write (OutputStream out)
- throws IOException
- {
- write (new OutputStreamWriter (out));
- }
-
-
- /**
- * Write the internal value template with all parameters
- * substituted with their current values.
- */
- public void write (Writer writer)
- throws IOException
- {
- writer.write (toString ());
- writer.flush ();
- }
-
-
- /**
- * Write the internal value template with all parameters
- * substituted with their current values.
- */
- public void write (File file)
- throws IOException
- {
- FileWriter writer = new FileWriter (file);
- try
- {
- write (writer);
- }
- finally
- {
- try { writer.close (); } catch (IOException ioe) {}
- }
- }
+ * @author Abe White
+ * @nojavadoc */
+public class ParameterTemplate {
+ private static final String SEP = System.getProperty("line.separator");
+ private final StringBuffer _buf = new StringBuffer();
+ private final Map _params = new HashMap();
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(String value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(boolean value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(char value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(double value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(float value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(int value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(long value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(short value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(Object value) {
+ _buf.append(value);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(InputStream in) throws IOException {
+ return append(new InputStreamReader(in));
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(Reader reader) throws IOException {
+ BufferedReader buf = new BufferedReader(reader);
+ String line;
+
+ while ((line = buf.readLine()) != null)
+ _buf.append(line).append(SEP);
+
+ return this;
+ }
+
+ /**
+ * Add the given value to the internal template.
+ */
+ public ParameterTemplate append(File file) throws IOException {
+ FileReader reader = new FileReader(file);
+
+ try {
+ return append(reader);
+ } finally {
+ try {
+ reader.close();
+ } catch (IOException ioe) {
+ }
+ }
+ }
+
+ /**
+ * Return true if the given parameter has been given a value.
+ */
+ public boolean hasParameter(String name) {
+ return _params.containsKey(name);
+ }
+
+ /**
+ * Return the value set for the given parameter.
+ */
+ public Object getParameter(String name) {
+ return _params.get(name);
+ }
+
+ /**
+ * Set the value for the given parameter.
+ */
+ public Object setParameter(String name, Object val) {
+ return _params.put(name, val);
+ }
+
+ /**
+ * Set the values for all the parameters in the given map.
+ */
+ public void setParameters(Map params) {
+ _params.putAll(params);
+ }
+
+ /**
+ * Clear the recorded parameter values.
+ */
+ public void clearParameters() {
+ _params.clear();
+ }
+
+ /**
+ * Return a copy of the internal value template with all parameters
+ * substituted with their current values.
+ */
+ public String toString() {
+ if ((_buf.length() == 0) || _params.isEmpty()) {
+ return _buf.toString();
+ }
+
+ StringBuffer copy = new StringBuffer();
+ StringBuffer param = null;
+ char ch;
+ char last = 0;
+
+ for (int i = 0; i < _buf.length(); i++) {
+ ch = _buf.charAt(i);
+
+ if ((last == '$') && (ch == '{')) {
+ copy.deleteCharAt(copy.length() - 1);
+ param = new StringBuffer();
+ } else if ((ch == '}') && (param != null)) {
+ if (_params.containsKey(param.toString())) {
+ copy.append(_params.get(param.toString()));
+ } else {
+ copy.append(System.getProperty(param.toString()));
+ }
+
+ param = null;
+ } else if (param != null) {
+ param.append(ch);
+ } else {
+ copy.append(ch);
+ }
+
+ last = ch;
+ }
+
+ return copy.toString();
+ }
+
+ /**
+ * Write the internal value template with all parameters
+ * substituted with their current values.
+ */
+ public void write(OutputStream out) throws IOException {
+ write(new OutputStreamWriter(out));
+ }
+
+ /**
+ * Write the internal value template with all parameters
+ * substituted with their current values.
+ */
+ public void write(Writer writer) throws IOException {
+ writer.write(toString());
+ writer.flush();
+ }
+
+ /**
+ * Write the internal value template with all parameters
+ * substituted with their current values.
+ */
+ public void write(File file) throws IOException {
+ FileWriter writer = new FileWriter(file);
+
+ try {
+ write(writer);
+ } finally {
+ try {
+ writer.close();
+ } catch (IOException ioe) {
+ }
+ }
+ }
}
Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParseException.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParseException.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParseException.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ParseException.java Wed Jun 28 12:34:33 2006
@@ -15,39 +15,28 @@
*/
package org.apache.openjpa.lib.util;
-
import org.apache.commons.lang.exception.*;
/**
- * <p>Exception type for parse errors.</p>
+ * <p>Exception type for parse errors.</p>
*
- * @author Abe White
- * @since 4.0
- * @nojavadoc
- */
-public class ParseException
- extends NestableRuntimeException
-{
- public ParseException ()
- {
- }
-
-
- public ParseException (String msg)
- {
- super (msg);
- }
-
-
- public ParseException (Throwable cause)
- {
- super (cause);
- }
-
-
- public ParseException (String msg, Throwable cause)
- {
- super (msg, cause);
- }
+ * @author Abe White
+ * @since 4.0
+ * @nojavadoc */
+public class ParseException extends NestableRuntimeException {
+ public ParseException() {
+ }
+
+ public ParseException(String msg) {
+ super(msg);
+ }
+
+ public ParseException(Throwable cause) {
+ super(cause);
+ }
+
+ public ParseException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
}
Added: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashMap.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashMap.java?rev=417856&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashMap.java (added)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashMap.java Wed Jun 28 12:34:33 2006
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.lib.util;
+
+import java.io.*;
+
+import java.lang.ref.*;
+
+import java.util.*;
+
+
+/**
+ * <p>Map in which the key, value, or both may be weak/soft references.</p>
+ *
+ * @author Abe White
+ * @since 4.0
+ * @nojavadoc */
+public class ReferenceHashMap extends org.apache.commons.collections.map.ReferenceMap
+ implements ReferenceMap, SizedMap {
+ private int _maxSize = Integer.MAX_VALUE;
+
+ public ReferenceHashMap(int keyType, int valueType) {
+ super(toReferenceConstant(keyType), toReferenceConstant(valueType));
+ }
+
+ public ReferenceHashMap(int keyType, int valueType, int capacity,
+ float loadFactor) {
+ super(toReferenceConstant(keyType), toReferenceConstant(valueType),
+ capacity, loadFactor);
+ }
+
+ /**
+ * Concver our reference constants to Apache's.
+ */
+ private static int toReferenceConstant(int type) {
+ switch (type) {
+ case ReferenceMap.HARD:
+ return org.apache.commons.collections.map.ReferenceMap.HARD;
+
+ case ReferenceMap.SOFT:
+ return org.apache.commons.collections.map.ReferenceMap.SOFT;
+
+ default:
+ return org.apache.commons.collections.map.ReferenceMap.WEAK;
+ }
+ }
+
+ public int getMaxSize() {
+ return _maxSize;
+ }
+
+ public void setMaxSize(int maxSize) {
+ _maxSize = (maxSize < 0) ? Integer.MAX_VALUE : maxSize;
+
+ if (_maxSize != Integer.MAX_VALUE) {
+ removeOverflow(_maxSize);
+ }
+ }
+
+ public boolean isFull() {
+ return size() >= _maxSize;
+ }
+
+ public void overflowRemoved(Object key, Object value) {
+ }
+
+ public void valueExpired(Object key) {
+ }
+
+ public void keyExpired(Object value) {
+ }
+
+ public void removeExpired() {
+ purge();
+ }
+
+ /**
+ * Remove any entries over max size.
+ */
+ private void removeOverflow(int maxSize) {
+ Object key;
+
+ while (size() > maxSize) {
+ key = keySet().iterator().next();
+ overflowRemoved(key, remove(key));
+ }
+ }
+
+ protected void addMapping(int hashIndex, int hashCode, Object key,
+ Object value) {
+ if (_maxSize != Integer.MAX_VALUE) {
+ removeOverflow(_maxSize - 1);
+ }
+
+ super.addMapping(hashIndex, hashCode, key, value);
+ }
+
+ protected HashEntry createEntry(HashEntry next, int hashCode, Object key,
+ Object value) {
+ return new AccessibleEntry(this, next, hashCode, key, value);
+ }
+
+ protected void purge(Reference ref) {
+ // the logic for this method is taken from the original purge method
+ // we're overriding, with added logic to track the expired key/value
+ int index = hashIndex(ref.hashCode(), data.length);
+ AccessibleEntry entry = (AccessibleEntry) data[index];
+ AccessibleEntry prev = null;
+ Object key = null;
+ Object value = null;
+
+ while (entry != null) {
+ if (purge(entry, ref)) {
+ if (isHard(keyType)) {
+ key = entry.key();
+ } else if (isHard(valueType)) {
+ value = entry.value();
+ }
+
+ if (prev == null) {
+ data[index] = entry.nextEntry();
+ } else {
+ prev.setNextEntry(entry.nextEntry());
+ }
+
+ size--;
+
+ break;
+ }
+
+ prev = entry;
+ entry = entry.nextEntry();
+ }
+
+ if (key != null) {
+ valueExpired(key);
+ } else if (value != null) {
+ keyExpired(value);
+ }
+ }
+
+ /**
+ * See the code for <code>ReferenceMap.ReferenceEntry.purge</code>.
+ */
+ private boolean purge(AccessibleEntry entry, Reference ref) {
+ boolean match = (!isHard(keyType) && (entry.key() == ref)) ||
+ (!isHard(valueType) && (entry.value() == ref));
+
+ if (match) {
+ if (!isHard(keyType)) {
+ ((Reference) entry.key()).clear();
+ }
+
+ if (!isHard(valueType)) {
+ ((Reference) entry.value()).clear();
+ } else if (purgeValues) {
+ entry.nullValue();
+ }
+ }
+
+ return match;
+ }
+
+ private static boolean isHard(int type) {
+ return type == org.apache.commons.collections.map.ReferenceMap.HARD;
+ }
+
+ protected void doWriteObject(ObjectOutputStream out)
+ throws IOException {
+ out.writeInt(_maxSize);
+ super.doWriteObject(out);
+ }
+
+ protected void doReadObject(ObjectInputStream in)
+ throws ClassNotFoundException, IOException {
+ _maxSize = in.readInt();
+ super.doReadObject(in);
+ }
+
+ /**
+ * Extension of the base entry type that allows our outer class to access
+ * protected state.
+ */
+ private static class AccessibleEntry extends ReferenceEntry {
+ public AccessibleEntry(
+ org.apache.commons.collections.map.AbstractReferenceMap map,
+ HashEntry next, int hashCode, Object key, Object value) {
+ super(map, next, hashCode, key, value);
+ }
+
+ public Object key() {
+ return key;
+ }
+
+ public Object value() {
+ return value;
+ }
+
+ public void nullValue() {
+ value = null;
+ }
+
+ public AccessibleEntry nextEntry() {
+ return (AccessibleEntry) next;
+ }
+
+ public void setNextEntry(AccessibleEntry next) {
+ this.next = next;
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashMap.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashSet.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashSet.java?rev=417856&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashSet.java (added)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashSet.java Wed Jun 28 12:34:33 2006
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.lib.util;
+
+import org.apache.commons.collections.set.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ * <p>A set whose values may be stored as weak or soft references.</p>
+ *
+ * @author Abe White
+ * @nojavadoc */
+public class ReferenceHashSet implements Set, Serializable {
+ /**
+ * Hard reference marker.
+ */
+ public static final int HARD = 0;
+
+ /**
+ * Soft reference marker.
+ */
+ public static final int SOFT = 1;
+
+ /**
+ * Weak reference marker.
+ */
+ public static final int WEAK = 2;
+ private static final Object DUMMY_VAL = new Object();
+ private final Set _set;
+
+ /**
+ * Construct a set with the given reference type.
+ */
+ public ReferenceHashSet(int refType) {
+ if (refType == HARD) {
+ _set = new HashSet();
+ } else {
+ int mapRefType = (refType == WEAK)
+ ? org.apache.commons.collections.map.ReferenceMap.WEAK
+ : org.apache.commons.collections.map.ReferenceMap.SOFT;
+ _set = MapBackedSet.decorate(new org.apache.commons.collections.map.ReferenceMap(
+ mapRefType,
+ org.apache.commons.collections.map.ReferenceMap.HARD),
+ DUMMY_VAL);
+ }
+ }
+
+ public boolean add(Object obj) {
+ return _set.add(obj);
+ }
+
+ public boolean addAll(Collection coll) {
+ return _set.addAll(coll);
+ }
+
+ public void clear() {
+ _set.clear();
+ }
+
+ public boolean contains(Object obj) {
+ return _set.contains(obj);
+ }
+
+ public boolean containsAll(Collection coll) {
+ return _set.containsAll(coll);
+ }
+
+ public boolean isEmpty() {
+ return _set.isEmpty();
+ }
+
+ public Iterator iterator() {
+ return _set.iterator();
+ }
+
+ public boolean remove(Object obj) {
+ return _set.remove(obj);
+ }
+
+ public boolean removeAll(Collection coll) {
+ return _set.removeAll(coll);
+ }
+
+ public boolean retainAll(Collection coll) {
+ return _set.retainAll(coll);
+ }
+
+ public int size() {
+ return _set.size();
+ }
+
+ public Object[] toArray() {
+ return _set.toArray();
+ }
+
+ public Object[] toArray(Object[] arr) {
+ return _set.toArray(arr);
+ }
+
+ public int hashCode() {
+ return _set.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof ReferenceHashSet) {
+ obj = ((ReferenceHashSet) obj)._set;
+ }
+
+ return _set.equals(obj);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceHashSet.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceMap.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceMap.java?rev=417856&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceMap.java (added)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceMap.java Wed Jun 28 12:34:33 2006
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.lib.util;
+
+import java.util.*;
+
+
+/**
+ * <p>A {@link Map} type that can hold its keys, values, or both with
+ * weak or soft references.</p>
+ *
+ * @author Abe White
+ */
+public interface ReferenceMap extends Map {
+ public static final int HARD = 0;
+ public static final int WEAK = 1;
+ public static final int SOFT = 2;
+
+ /**
+ * Purge stale entries.
+ */
+ public void removeExpired();
+
+ /**
+ * Overridable callback for when a key reference expires.
+ *
+ * @param value the value for the expired key
+ */
+ public void keyExpired(Object value);
+
+ /**
+ * Overridable callback for when a value reference expires.
+ *
+ * @param key the key for the expired value
+ */
+ public void valueExpired(Object key);
+}
Propchange: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ReferenceMap.java
------------------------------------------------------------------------------
svn:executable = *
Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ResourceBundleProvider.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ResourceBundleProvider.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ResourceBundleProvider.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/util/ResourceBundleProvider.java Wed Jun 28 12:34:33 2006
@@ -15,23 +15,20 @@
*/
package org.apache.openjpa.lib.util;
-
import java.util.*;
/**
- * <p>A simple mechanism for looking up ResourceBundle instances
- * across different potential sources.</p>
+ * <p>A simple mechanism for looking up ResourceBundle instances
+ * across different potential sources.</p>
*
- * @author Stephen Kim
+ * @author Stephen Kim
*/
-interface ResourceBundleProvider
-{
- /**
- * Find a ResourceBundle with the given name, locale, and class loader
- * (which may be null).
- */
- public ResourceBundle findResource (String name, Locale locale,
- ClassLoader loader);
+interface ResourceBundleProvider {
+ /**
+ * Find a ResourceBundle with the given name, locale, and class loader
+ * (which may be null).
+ */
+ public ResourceBundle findResource(String name, Locale locale,
+ ClassLoader loader);
}
-