Merge branch 'master' of github.com:threerings/samskivert
This commit is contained in:
@@ -21,17 +21,14 @@ import com.samskivert.util.ServiceWaiter;
|
||||
public class HttpPostUtil
|
||||
{
|
||||
/**
|
||||
* Return the results of a form post. Note that the http request takes
|
||||
* place on another thread, but this thread blocks until the results
|
||||
* are returned or it times out.
|
||||
* Return the results of a form post. Note that the http request takes place on another
|
||||
* thread, but this thread blocks until the results are returned or it times out.
|
||||
*
|
||||
* @param url from which to make the request.
|
||||
* @param submission the entire submission eg "foo=bar&baz=boo&futz=foo".
|
||||
* @param timeout time to wait for the response, in seconds, or -1
|
||||
* for forever.
|
||||
* @param timeout time to wait for the response, in seconds, or -1 for forever.
|
||||
*/
|
||||
public static String httpPost (final URL url, final String submission,
|
||||
int timeout)
|
||||
public static String httpPost (final URL url, final String submission, int timeout)
|
||||
throws IOException, ServiceWaiter.TimeoutException
|
||||
{
|
||||
final ServiceWaiter<String> waiter = new ServiceWaiter<String>(
|
||||
@@ -39,16 +36,13 @@ public class HttpPostUtil
|
||||
Thread tt = new Thread() {
|
||||
@Override public void run () {
|
||||
try {
|
||||
HttpURLConnection conn =
|
||||
(HttpURLConnection) url.openConnection();
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(true);
|
||||
conn.setUseCaches(false);
|
||||
conn.setRequestProperty(
|
||||
"Content-Type", "application/x-www-form-urlencoded");
|
||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
|
||||
DataOutputStream out = new DataOutputStream(
|
||||
conn.getOutputStream());
|
||||
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
|
||||
out.writeBytes(submission);
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
@@ -124,25 +124,26 @@ public class UserManager
|
||||
}
|
||||
|
||||
// register a cron job to prune the session table every hour
|
||||
_pruner = new Interval() {
|
||||
@Override public void expired () {
|
||||
try {
|
||||
_repository.pruneSessions();
|
||||
} catch (PersistenceException pe) {
|
||||
log.warning("Error pruning session table.", pe);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (pruneQueue != null) {
|
||||
_pruner.setRunQueue(pruneQueue);
|
||||
_pruner = new Interval(pruneQueue) {
|
||||
@Override public void expired () {
|
||||
try {
|
||||
_repository.pruneSessions();
|
||||
} catch (PersistenceException pe) {
|
||||
log.warning("Error pruning session table.", pe);
|
||||
}
|
||||
}
|
||||
};
|
||||
_pruner.schedule(SESSION_PRUNE_INTERVAL, true);
|
||||
}
|
||||
_pruner.schedule(SESSION_PRUNE_INTERVAL, true);
|
||||
}
|
||||
|
||||
public void shutdown ()
|
||||
{
|
||||
// cancel our session table pruning thread
|
||||
_pruner.cancel();
|
||||
if (_pruner != null) {
|
||||
_pruner.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ package com.samskivert.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Random;
|
||||
@@ -892,51 +891,6 @@ public class ArrayUtil
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the String representation of the specified Object, which may or may not be an array.
|
||||
*/
|
||||
public static String safeToString (Object o)
|
||||
{
|
||||
return ((o == null) || !o.getClass().isArray()) ? String.valueOf(o) : toString(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the String representation of the specified Object, which <em>must</em> be an array.
|
||||
*
|
||||
* @throws IllegalArgumentException if array is not actually an array.
|
||||
*/
|
||||
public static String toString (Object array)
|
||||
{
|
||||
if (array instanceof Object[]) {
|
||||
return Arrays.deepToString((Object[])array); // go deep, baby
|
||||
|
||||
} else if (array instanceof int[]) {
|
||||
return Arrays.toString((int[])array);
|
||||
|
||||
} else if (array instanceof byte[]) {
|
||||
return Arrays.toString((byte[])array);
|
||||
|
||||
} else if (array instanceof char[]) {
|
||||
return Arrays.toString((char[])array);
|
||||
|
||||
} else if (array instanceof short[]) {
|
||||
return Arrays.toString((short[])array);
|
||||
|
||||
} else if (array instanceof long[]) {
|
||||
return Arrays.toString((long[])array);
|
||||
|
||||
} else if (array instanceof float[]) {
|
||||
return Arrays.toString((float[])array);
|
||||
|
||||
} else if (array instanceof double[]) {
|
||||
return Arrays.toString((double[])array);
|
||||
|
||||
} else if (array instanceof boolean[]) {
|
||||
return Arrays.toString((boolean[])array);
|
||||
}
|
||||
throw new IllegalArgumentException("Not an array: " + array);
|
||||
}
|
||||
|
||||
/** The default random object used when shuffling an array. */
|
||||
protected static final Random _rnd = new Random();
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ public class AuditLogger
|
||||
}
|
||||
|
||||
/** The interval that rolls over the log file. */
|
||||
protected Interval _rollover = new Interval() {
|
||||
protected Interval _rollover = new Interval(Interval.RUN_DIRECT) {
|
||||
@Override public void expired () {
|
||||
checkRollOver();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,25 @@ import static com.samskivert.Log.log;
|
||||
*/
|
||||
public abstract class Interval
|
||||
{
|
||||
/** A marker {@link RunQueue} to supply when you intend for your interval to run directly on
|
||||
* the interval timer thread, rather than having the interval processed on a separate thread.
|
||||
* Warning: you must be absolutely sure your interval will complete <em>very quickly</em>,
|
||||
* otherwise you risk delaying the firing of other intervals. */
|
||||
public static RunQueue RUN_DIRECT = new RunQueue() {
|
||||
public void postRunnable (Runnable r) {
|
||||
throw new UnsupportedOperationException("dummy");
|
||||
}
|
||||
public boolean isDispatchThread () {
|
||||
throw new UnsupportedOperationException("dummy");
|
||||
}
|
||||
public boolean isRunning () {
|
||||
throw new UnsupportedOperationException("dummy");
|
||||
}
|
||||
public String toString () {
|
||||
return "<direct>";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface for entities that create, and keep track of, intervals. The intended use case
|
||||
* is for repeating intervals to be created via a factory that tracks all such intervals, and
|
||||
@@ -54,21 +73,6 @@ public abstract class Interval
|
||||
public String getIntervalClassName ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an interval that executes the supplied runnable when it expires.
|
||||
*/
|
||||
public static Interval create (final Runnable onExpired)
|
||||
{
|
||||
return new Interval() {
|
||||
@Override public void expired () {
|
||||
onExpired.run();
|
||||
}
|
||||
@Override public String toString () {
|
||||
return onExpired.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an interval that executes the supplied runnable on the specified RunQueue when it
|
||||
* expires.
|
||||
@@ -88,12 +92,9 @@ public abstract class Interval
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple interval that does not use a RunQueue to run the {@link #expired} method.
|
||||
*/
|
||||
public Interval ()
|
||||
{
|
||||
// _runQueue stays null
|
||||
/** @deprecated If direct-running is desired, pass {@link #RUN_DIRECT} explicitly. */
|
||||
@Deprecated public Interval () {
|
||||
this(RUN_DIRECT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,16 +103,14 @@ public abstract class Interval
|
||||
*/
|
||||
public Interval (RunQueue runQueue)
|
||||
{
|
||||
setRunQueue(runQueue);
|
||||
if (runQueue == null) {
|
||||
throw new NullPointerException("RunQueue must be non-null");
|
||||
}
|
||||
_runQueue = runQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the run queue to be used by this interval. This <em>must</em> be called before
|
||||
* the interval is started and a non-null queue must be provided. This exists for situations
|
||||
* where the caller needs to configure an optional run queue and thus can't easily call the
|
||||
* appropriate constructor.
|
||||
*/
|
||||
public void setRunQueue (RunQueue runQueue)
|
||||
/** @deprecated Just pass the desired run-queue to the constructor. */
|
||||
@Deprecated public void setRunQueue (RunQueue runQueue)
|
||||
{
|
||||
if (runQueue == null) {
|
||||
throw new IllegalArgumentException("Supplied RunQueue must be non-null");
|
||||
@@ -227,7 +226,7 @@ public abstract class Interval
|
||||
_timer.schedule(_task, initialDelay);
|
||||
} else if (fixedRate) {
|
||||
_timer.scheduleAtFixedRate(_task, initialDelay, repeatDelay);
|
||||
} else if (_runQueue != null) {
|
||||
} else if (_runQueue != RUN_DIRECT) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot schedule at a fixed delay when using a RunQueue.");
|
||||
} else {
|
||||
@@ -265,7 +264,7 @@ public abstract class Interval
|
||||
protected void noteRejected ()
|
||||
{
|
||||
log.warning("Interval posted to shutdown RunQueue. Cancelling.",
|
||||
"queue", _runQueue, "interval", this);
|
||||
"queue", _runQueue, "interval", this);
|
||||
}
|
||||
|
||||
protected static Timer createTimer ()
|
||||
@@ -297,7 +296,7 @@ public abstract class Interval
|
||||
if (ival == null) {
|
||||
return;
|
||||
}
|
||||
if (ival._runQueue == null) {
|
||||
if (ival._runQueue == RUN_DIRECT) {
|
||||
ival.safelyExpire(this);
|
||||
return;
|
||||
}
|
||||
@@ -328,7 +327,7 @@ public abstract class Interval
|
||||
ival._runQueue.postRunnable(_runner);
|
||||
} catch (Exception e) {
|
||||
log.warning("Failed to execute interval on run-queue",
|
||||
"queue", ival._runQueue, "interval", ival, e);
|
||||
"queue", ival._runQueue, "interval", ival, e);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -352,7 +351,8 @@ public abstract class Interval
|
||||
|
||||
} // end: static class IntervalTask
|
||||
|
||||
/** If non-null, the RunQueue used to run the expired() method for each Interval. */
|
||||
/** The RunQueue used to run the expired() method for this Interval, or {@link #RUN_DIRECT} to
|
||||
* indicate that the interval should be executed directly on the Inteval timer thread. */
|
||||
protected RunQueue _runQueue;
|
||||
|
||||
/** The task that actually schedules our execution with the static Timer. */
|
||||
|
||||
@@ -48,7 +48,7 @@ public class LogBuilder
|
||||
}
|
||||
_log.append(args[ii]).append('=');
|
||||
try {
|
||||
_log.append(ArrayUtil.safeToString(args[ii + 1]));
|
||||
_log.append(StringUtil.toString(args[ii + 1]));
|
||||
} catch (Throwable t) {
|
||||
_log.append("<toString() failure: ").append(t).append('>');
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ public abstract class Logger
|
||||
}
|
||||
buf.append(args[ii]).append('=');
|
||||
try {
|
||||
buf.append(ArrayUtil.safeToString(args[ii + 1]));
|
||||
buf.append(StringUtil.toString(args[ii + 1]));
|
||||
} catch (Throwable t) {
|
||||
buf.append("<toString() failure: ").append(t).append(">");
|
||||
}
|
||||
|
||||
@@ -135,9 +135,8 @@ public class SerialExecutor
|
||||
final ExecutorThread thread = new ExecutorThread(task);
|
||||
thread.start();
|
||||
|
||||
// start up a timer that will abort this thread after the specified
|
||||
// timeout
|
||||
new Interval() {
|
||||
// start up a timer that will abort this thread after the specified timeout
|
||||
new Interval(Interval.RUN_DIRECT) {
|
||||
@Override public void expired () {
|
||||
// this will NOOP if the task has already completed
|
||||
thread.abort();
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
package com.samskivert.util;
|
||||
|
||||
/**
|
||||
* A handy base class for issuing server-side service requests and
|
||||
* awaiting their responses from within a servlet.
|
||||
* A handy base class for issuing server-side service requests and awaiting their responses from
|
||||
* within a servlet.
|
||||
*
|
||||
* <em>Note:</em> You might think that it would be keen to use this
|
||||
* anonymously like so:
|
||||
* <em>Note:</em> You might think that it would be keen to use this anonymously like so:
|
||||
*
|
||||
* <pre>
|
||||
* ServiceWaiter waiter = new ServiceWaiter() {
|
||||
@@ -21,24 +20,21 @@ package com.samskivert.util;
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* But that won't work because public methods in anonymous inner classes
|
||||
* do not have public visibility and so the invocation manager will not be
|
||||
* able to reflect your response methods when the time comes to deliver
|
||||
* the response. Unfortunately, there appears to be no manner in which to
|
||||
* instruct the Java compiler to give public scope to an anonymous inner
|
||||
* class rather than default scope. Sigh.
|
||||
* But that won't work because public methods in anonymous inner classes do not have public
|
||||
* visibility and so the invocation manager will not be able to reflect your response methods
|
||||
* when the time comes to deliver the response. Unfortunately, there appears to be no manner in
|
||||
* which to instruct the Java compiler to give public scope to an anonymous inner class rather
|
||||
* than default scope. Sigh.
|
||||
*/
|
||||
public class ServiceWaiter<T>
|
||||
implements ResultListener<T>
|
||||
{
|
||||
/** Timeout to specify when you don't want a timeout. Use at your own
|
||||
* risk. */
|
||||
/** Timeout to specify when you don't want a timeout. Use at your own risk. */
|
||||
public static final int NO_TIMEOUT = -1;
|
||||
|
||||
public static class TimeoutException extends Exception
|
||||
{
|
||||
public TimeoutException ()
|
||||
{
|
||||
public TimeoutException () {
|
||||
super("Timeout! Pow!");
|
||||
}
|
||||
}
|
||||
@@ -62,8 +58,7 @@ public class ServiceWaiter<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the timeout being used for this ServiceWaiter after it
|
||||
* has been constructed.
|
||||
* Change the timeout being used for this ServiceWaiter after it has been constructed.
|
||||
*/
|
||||
public void setTimeout (int timeout)
|
||||
{
|
||||
@@ -80,8 +75,8 @@ public class ServiceWaiter<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the request as successful and posts the supplied response
|
||||
* argument for perusal by the caller.
|
||||
* Marks the request as successful and posts the supplied response argument for perusal by the
|
||||
* caller.
|
||||
*/
|
||||
public synchronized void postSuccess (T arg)
|
||||
{
|
||||
@@ -101,8 +96,7 @@ public class ServiceWaiter<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the argument posted by the waiter when the response
|
||||
* arrived.
|
||||
* Returns the argument posted by the waiter when the response arrived.
|
||||
*/
|
||||
public T getArgument ()
|
||||
{
|
||||
@@ -120,8 +114,7 @@ public class ServiceWaiter<T>
|
||||
/**
|
||||
* Blocks waiting for the response.
|
||||
*
|
||||
* @return true if a success response was posted, false if a failure
|
||||
* repsonse was posted.
|
||||
* @return true if a success response was posted, false if a failure response was posted.
|
||||
*/
|
||||
public boolean waitForResponse ()
|
||||
throws TimeoutException
|
||||
@@ -136,8 +129,7 @@ public class ServiceWaiter<T>
|
||||
} else {
|
||||
wait(1000L * _timeout);
|
||||
}
|
||||
// if we get here without some sort of response, then
|
||||
// we've timed out
|
||||
// if we get here without some sort of response, then we've timed out
|
||||
if (_success == 0) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
@@ -164,9 +156,8 @@ public class ServiceWaiter<T>
|
||||
postFailure(cause);
|
||||
}
|
||||
|
||||
/** Whether or not the response succeeded; positive for success,
|
||||
* negative for failure, zero means we haven't received the response
|
||||
* yet. */
|
||||
/** Whether or not the response succeeded; positive for success, negative for failure, zero
|
||||
* means we haven't received the response yet. */
|
||||
protected int _success = 0;
|
||||
|
||||
/** The argument posted by the waiter upon receipt of the response. */
|
||||
@@ -178,8 +169,7 @@ public class ServiceWaiter<T>
|
||||
/** How many seconds to wait before giving up the ghost. */
|
||||
protected int _timeout;
|
||||
|
||||
/** If a response is not received within the specified timeout, an
|
||||
* exception is thrown which redirects the user to an internal error
|
||||
* page. */
|
||||
/** If a response is not received within the specified timeout, an exception is thrown which
|
||||
* redirects the user to an internal error page. */
|
||||
protected static final int DEFAULT_WAITER_TIMEOUT = 30;
|
||||
}
|
||||
|
||||
@@ -355,16 +355,8 @@ public class StringUtil
|
||||
* Converts the supplied object to a string. Normally this is accomplished via the object's
|
||||
* built in <code>toString()</code> method, but in the case of arrays, <code>toString()</code>
|
||||
* is called on each element and the contents are listed like so:
|
||||
*
|
||||
* <pre>
|
||||
* (value, value, value)
|
||||
* </pre>
|
||||
*
|
||||
* Arrays of ints, longs, floats and doubles are also handled for convenience.
|
||||
*
|
||||
* <p> Additionally, <code>Enumeration</code> or <code>Iterator</code> objects can be passed
|
||||
* and they will be enumerated and output in a similar manner to arrays. Bear in mind that this
|
||||
* uses up the enumeration or iterator in question.
|
||||
* <pre>(value, value, value)</pre>
|
||||
* Arrays of primitive types are also handled for convenience.
|
||||
*
|
||||
* <p> Also note that passing null will result in the string "null" being returned.
|
||||
*/
|
||||
@@ -375,10 +367,29 @@ public class StringUtil
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the supplied value to a string and appends it to the supplied string buffer. See
|
||||
* {@link #toString()} for more information.
|
||||
*
|
||||
* @param buf the string buffer to which we will append the string.
|
||||
* @param val the value from which to generate the string.
|
||||
*/
|
||||
public static void toString (StringBuilder buf, Object val)
|
||||
{
|
||||
// these boxes+sep will only be used for arrays
|
||||
toString(buf, val, "(", ")", ", ", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the single argument {@link #toString(Object)} with the additional function of
|
||||
* specifying the characters that are used to box in list and array types. For example, if "["
|
||||
* and "]" were supplied, an int array might be formatted like so: <code>[1, 3, 5]</code>.
|
||||
* specifying the characters that are used to box in collection and array types. For example,
|
||||
* if "[" and "]" were supplied, an int array might be formatted like so: <code>[1, 3,
|
||||
* 5]</code>.
|
||||
*
|
||||
* <p> Note: in this method (unlike {@link #toString()}), <code>Enumeration</code> or
|
||||
* <code>Iterator</code> objects can be passed and they will be enumerated and output in a
|
||||
* similar manner to arrays. Bear in mind that this uses up the enumeration or iterator in
|
||||
* question.
|
||||
*/
|
||||
public static String toString (Object val, String openBox, String closeBox)
|
||||
{
|
||||
@@ -387,23 +398,16 @@ public class StringUtil
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the supplied value to a string and appends it to the supplied string buffer. See
|
||||
* the single argument version for more information.
|
||||
*
|
||||
* @param buf the string buffer to which we will append the string.
|
||||
* @param val the value from which to generate the string.
|
||||
*/
|
||||
public static void toString (StringBuilder buf, Object val)
|
||||
{
|
||||
toString(buf, val, "(", ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the supplied value to a string and appends it to the supplied string buffer. The
|
||||
* specified boxing characters are used to enclose list and array types. For example, if "["
|
||||
* and "]" were supplied, an int array might be formatted like so: <code>[1, 3, 5]</code>.
|
||||
*
|
||||
* <p> Note: in this method (unlike {@link #toString()}), <code>Enumeration</code> or
|
||||
* <code>Iterator</code> objects can be passed and they will be enumerated and output in a
|
||||
* similar manner to arrays. Bear in mind that this uses up the enumeration or iterator in
|
||||
* question.
|
||||
*
|
||||
* @param buf the string buffer to which we will append the string.
|
||||
* @param val the value from which to generate the string.
|
||||
* @param openBox the opening box character.
|
||||
@@ -419,150 +423,21 @@ public class StringUtil
|
||||
* specified boxing characters are used to enclose list and array types. For example, if "["
|
||||
* and "]" were supplied, an int array might be formatted like so: <code>[1, 3, 5]</code>.
|
||||
*
|
||||
* <p> Note: in this method (unlike {@link #toString()}), <code>Enumeration</code> or
|
||||
* <code>Iterator</code> objects can be passed and they will be enumerated and output in a
|
||||
* similar manner to arrays. Bear in mind that this uses up the enumeration or iterator in
|
||||
* question.
|
||||
*
|
||||
* @param buf the string buffer to which we will append the string.
|
||||
* @param val the value from which to generate the string.
|
||||
* @param openBox the opening box character.
|
||||
* @param closeBox the closing box character.
|
||||
* @param sep the separator string.
|
||||
*/
|
||||
public static void toString (
|
||||
StringBuilder buf, Object val, String openBox, String closeBox, String sep)
|
||||
public static void toString (StringBuilder buf, Object val, String openBox, String closeBox,
|
||||
String sep)
|
||||
{
|
||||
if (val instanceof byte[]) {
|
||||
buf.append(openBox);
|
||||
byte[] v = (byte[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof short[]) {
|
||||
buf.append(openBox);
|
||||
short[] v = (short[])val;
|
||||
for (short i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof int[]) {
|
||||
buf.append(openBox);
|
||||
int[] v = (int[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof long[]) {
|
||||
buf.append(openBox);
|
||||
long[] v = (long[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof float[]) {
|
||||
buf.append(openBox);
|
||||
float[] v = (float[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof double[]) {
|
||||
buf.append(openBox);
|
||||
double[] v = (double[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Object[]) {
|
||||
buf.append(openBox);
|
||||
Object[] v = (Object[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
toString(buf, v[i], openBox, closeBox);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof boolean[]) {
|
||||
buf.append(openBox);
|
||||
boolean[] v = (boolean[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i] ? "t" : "f");
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Iterable<?>) {
|
||||
toString(buf, ((Iterable<?>)val).iterator(), openBox, closeBox);
|
||||
|
||||
} else if (val instanceof Iterator<?>) {
|
||||
buf.append(openBox);
|
||||
Iterator<?> iter = (Iterator<?>)val;
|
||||
for (int i = 0; iter.hasNext(); i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
toString(buf, iter.next(), openBox, closeBox);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Enumeration<?>) {
|
||||
buf.append(openBox);
|
||||
Enumeration<?> enm = (Enumeration<?>)val;
|
||||
for (int i = 0; enm.hasMoreElements(); i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
toString(buf, enm.nextElement(), openBox, closeBox);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Point2D) {
|
||||
Point2D p = (Point2D)val;
|
||||
buf.append(openBox);
|
||||
coordsToString(buf, (int)p.getX(), (int)p.getY());
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Dimension2D) {
|
||||
Dimension2D d = (Dimension2D)val;
|
||||
buf.append(openBox);
|
||||
buf.append(d.getWidth()).append("x").append(d.getHeight());
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Rectangle2D) {
|
||||
Rectangle2D r = (Rectangle2D)val;
|
||||
buf.append(openBox);
|
||||
buf.append(r.getWidth()).append("x").append(r.getHeight());
|
||||
coordsToString(buf, (int)r.getX(), (int)r.getY());
|
||||
buf.append(closeBox);
|
||||
|
||||
} else {
|
||||
buf.append(val);
|
||||
}
|
||||
toString(buf, val, openBox, closeBox, sep, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1378,6 +1253,165 @@ public class StringUtil
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for the various {@link #toString} methods.
|
||||
*/
|
||||
protected static void toString (StringBuilder buf, Object val, String openBox, String closeBox,
|
||||
String sep, boolean traverseCollections)
|
||||
{
|
||||
if (val instanceof byte[]) {
|
||||
buf.append(openBox);
|
||||
byte[] v = (byte[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof short[]) {
|
||||
buf.append(openBox);
|
||||
short[] v = (short[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof char[]) {
|
||||
buf.append(openBox);
|
||||
char[] v = (char[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof int[]) {
|
||||
buf.append(openBox);
|
||||
int[] v = (int[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof long[]) {
|
||||
buf.append(openBox);
|
||||
long[] v = (long[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof float[]) {
|
||||
buf.append(openBox);
|
||||
float[] v = (float[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof double[]) {
|
||||
buf.append(openBox);
|
||||
double[] v = (double[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i]);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Object[]) {
|
||||
buf.append(openBox);
|
||||
Object[] v = (Object[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
toString(buf, v[i], openBox, closeBox, sep, traverseCollections);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof boolean[]) {
|
||||
buf.append(openBox);
|
||||
boolean[] v = (boolean[])val;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
buf.append(v[i] ? "t" : "f");
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Point2D) {
|
||||
Point2D p = (Point2D)val;
|
||||
buf.append(openBox);
|
||||
coordsToString(buf, (int)p.getX(), (int)p.getY());
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Dimension2D) {
|
||||
Dimension2D d = (Dimension2D)val;
|
||||
buf.append(openBox);
|
||||
buf.append(d.getWidth()).append("x").append(d.getHeight());
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Rectangle2D) {
|
||||
Rectangle2D r = (Rectangle2D)val;
|
||||
buf.append(openBox);
|
||||
buf.append(r.getWidth()).append("x").append(r.getHeight());
|
||||
coordsToString(buf, (int)r.getX(), (int)r.getY());
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (traverseCollections) {
|
||||
if (val instanceof Iterable<?>) {
|
||||
toString(buf, ((Iterable<?>)val).iterator(), openBox, closeBox, sep, true);
|
||||
|
||||
} else if (val instanceof Iterator<?>) {
|
||||
buf.append(openBox);
|
||||
Iterator<?> iter = (Iterator<?>)val;
|
||||
for (int i = 0; iter.hasNext(); i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
toString(buf, iter.next(), openBox, closeBox, sep, true);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else if (val instanceof Enumeration<?>) {
|
||||
buf.append(openBox);
|
||||
Enumeration<?> enm = (Enumeration<?>)val;
|
||||
for (int i = 0; enm.hasMoreElements(); i++) {
|
||||
if (i > 0) {
|
||||
buf.append(sep);
|
||||
}
|
||||
toString(buf, enm.nextElement(), openBox, closeBox, sep, true);
|
||||
}
|
||||
buf.append(closeBox);
|
||||
|
||||
} else {
|
||||
buf.append(val);
|
||||
}
|
||||
|
||||
} else {
|
||||
buf.append(val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for the various <code>join</code> methods.
|
||||
*/
|
||||
|
||||
@@ -36,9 +36,8 @@ public class ValueMarshaller
|
||||
// look up an argument parser for the field type
|
||||
Parser parser = _parsers.get(type);
|
||||
if (parser == null) {
|
||||
String errmsg = "Don't know how to convert strings into " +
|
||||
"values of type '" + type + "'.";
|
||||
throw new Exception(errmsg);
|
||||
throw new Exception(
|
||||
"Don't know how to convert strings into values of type '" + type + "'.");
|
||||
}
|
||||
return parser.parse(source);
|
||||
}
|
||||
@@ -48,7 +47,7 @@ public class ValueMarshaller
|
||||
public Object parse (String source) throws Exception;
|
||||
}
|
||||
|
||||
protected static Map<Class<?>,Parser> _parsers = new HashMap<Class<?>,Parser>();
|
||||
protected static Map<Class<?>, Parser> _parsers = new HashMap<Class<?>, Parser>();
|
||||
static {
|
||||
Parser p;
|
||||
// we can parse strings
|
||||
|
||||
Reference in New Issue
Block a user