From scm-return-38717-apmail-geronimo-scm-archive=geronimo.apache.org@geronimo.apache.org Mon Oct 05 18:57:00 2009 Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 97657 invoked from network); 5 Oct 2009 18:57:00 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 5 Oct 2009 18:57:00 -0000 Received: (qmail 64254 invoked by uid 500); 5 Oct 2009 18:57:00 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 64182 invoked by uid 500); 5 Oct 2009 18:57:00 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 64163 invoked by uid 99); 5 Oct 2009 18:57:00 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Oct 2009 18:57:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Oct 2009 18:56:45 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 1EF002388A2D; Mon, 5 Oct 2009 18:55:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r821961 [21/30] - in /geronimo/sandbox/djencks/osgi/framework: ./ buildsupport/ buildsupport/car-maven-plugin/ buildsupport/car-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/car/ buildsupport/geronimo-maven-plugin/src/main/jav... Date: Mon, 05 Oct 2009 18:54:56 -0000 To: scm@geronimo.apache.org From: djencks@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091005185503.1EF002388A2D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,366 @@ +package org.apache.geronimo.system.plugin.plexus.util; + +/* + * Copyright The Codehaus 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. + */ + +import java.util.ArrayList; + + +/** + * Pools a bunch of objects . Runs a sweeper periodically to + * keep it down to size. The objects in the pool first get disposed first. + * + * @author Bert van Brakel + * @version $Id: SweeperPool.java 8010 2009-01-07 12:59:50Z vsiveton $ + */ +public class SweeperPool +{ + /***/ + private static final boolean DEBUG = false; + + /** Sweeps the pool periodically to trim it's size */ + private transient Sweeper sweeper; + + /** Absolute maxiumuim size of the pool.*/ + private transient int maxSize; + + /** The size the pool gets trimmed down to */ + private transient int minSize; + + /** When the sweeper runs + * and the pool is over this size, then the pool is trimmed */ + private int triggerSize; + + /** Holds the pooled objects */ + private ArrayList pooledObjects; + + /** Flag indicating this pool is shuting down */ + private boolean shuttingDown = false; + + //private Vector used; + + /** + * + *

There are a number of settings to control how the pool operates. + *

    + *
  • minSize - this is the size the pool is trimmed to
  • + *
  • triggerSize - this determines if the pool is trimmed when + * the sweeper runs. If the pool size is greater or equal than this value then + * the pool is trimmed to minSize. + *
  • maxSize - if the pool has reached this size, any objects added + * are immediatley disposed. If the pool is this size when the sweeper runs, then + * the pool is also trimmed to minSize irrespective of the triggerSize. + *
  • + *
  • sweepInterval - how often the sweeper runs. Is actually the + * time since the sweeper last finished a pass. 0 if the sweeper should not run. + *
  • + *
+ *

+ * + *

Any value less than 0 is automatically converted to 0

+ */ + public SweeperPool( int maxSize, int minSize, int intialCapacity, + int sweepInterval, int triggerSize ) + { + super(); + this.maxSize = saneConvert( maxSize ); + this.minSize = saneConvert( minSize ); + this.triggerSize = saneConvert( triggerSize ); + pooledObjects = new ArrayList( intialCapacity ); + + //only run a sweeper if sweep interval is positive + if ( sweepInterval > 0 ) + { + sweeper = new Sweeper( this, sweepInterval ); + sweeper.start(); + } + } + + private int saneConvert( int value ) + { + if ( value < 0 ) + { + return 0; + } + else + { + return value; + } + } + + /** + * Return the pooled object + */ + public synchronized Object get() + { + if ( ( pooledObjects.size() == 0 ) || shuttingDown ) + { + return null; + } + else + { + Object obj = pooledObjects.remove( 0 ); + objectRetrieved( obj ); + + //used.add(obj); + return obj; + } + } + + /** + * Add an object to the pool + * + * @param obj the object to pool. Can be null. + * + * @return true if the object was added to the pool, false if it was disposed or null + * + */ + public synchronized boolean put( Object obj ) + { + objectAdded( obj ); + + if ( ( obj != null ) && ( pooledObjects.size() < maxSize ) + && ( shuttingDown == false ) ) + { + pooledObjects.add( obj ); + + return true; + } + else if ( obj != null ) + { + //no longer need the object, so dispose it + objectDisposed( obj ); + } + + return false; + } + + /** + * Return the number of pooled objects. This is never + * greater than t maximuim size of the pool + * + * @return the number of pooled objects + */ + public synchronized int getSize() + { + return pooledObjects.size(); + } + + /** + * Dispose of this pool. Stops the sweeper and disposes each object in the pool + * + */ + public void dispose() + { + shuttingDown = true; + + if ( sweeper != null ) + { + sweeper.stop(); + try + { + sweeper.join(); + } + catch ( InterruptedException e ) + { + System.err.println( "Unexpected execption occurred: " ); + e.printStackTrace(); + } + } + + synchronized ( this ) + { + // use an array here as objects may still be being put back in the pool + // and we don't want to throw a ConcurrentModificationException + Object[] objects = pooledObjects.toArray(); + + for ( int i = 0; i < objects.length; i++ ) + { + objectDisposed( objects[i] ); + } + + pooledObjects.clear(); + } + } + + /** + * A pool has been disposed if has been shutdown and the sweeper has completed running. + * + * @return true if the pool has been disposed, false otherwise + */ + boolean isDisposed() + { + if ( !shuttingDown ) + { + return false; + } + + // A null sweeper means one was never started. + if ( sweeper == null ) + { + return true; + } + + return sweeper.hasStopped(); + } + + /** + * Trim the pool down to min size + * + */ + public synchronized void trim() + { + if ( ( ( triggerSize > 0 ) && ( pooledObjects.size() >= triggerSize ) ) + || ( ( maxSize > 0 ) && ( pooledObjects.size() >= maxSize ) ) ) + { + while ( pooledObjects.size() > minSize ) + { + objectDisposed( pooledObjects.remove( 0 ) ); + } + } + } + + /** + * Override this to be notified of object disposal. Called + * after the object has been removed. Occurs when the pool + * is trimmed. + * + * @param obj + */ + public void objectDisposed( Object obj ) + { + } + + /** + * Override this to be notified of object addition. + * Called before object is to be added. + * + * @param obj + */ + public void objectAdded( Object obj ) + { + } + + /** + * Override this to be notified of object retrieval. + * Called after object removed from the pool, but + * before returned to the client. + * + * @param obj + */ + public void objectRetrieved( Object obj ) + { + } + + /** + * Periodically at sweepInterval goes through + * and tests if the pool should be trimmed. + * + * @author bert + * + */ + private static class Sweeper implements Runnable + { + private final transient SweeperPool pool; + private transient boolean service = false; + private final transient int sweepInterval; + private transient Thread t = null; + + /** + * + */ + public Sweeper( SweeperPool pool, int sweepInterval ) + { + super(); + this.sweepInterval = sweepInterval; + this.pool = pool; + } + + /** + * Run the seeper. + * + * @see java.lang.Runnable#run() + */ + public void run() + { + debug( "started" ); + + if ( sweepInterval > 0 ) + { + synchronized ( this ) + { + while ( service ) + { + try + { + //wait specified number of seconds + //before running next sweep + wait( sweepInterval * 1000 ); + } + catch ( InterruptedException e ) + { + } + runSweep(); + } + } + } + + debug( "stopped" ); + } + + public void start() + { + if ( !service ) + { + service = true; + t = new Thread( this ); + t.setName( "Sweeper" ); + t.start(); + } + } + + public synchronized void stop() + { + service = false; + notifyAll(); + } + + void join() + throws InterruptedException + { + t.join(); + } + + boolean hasStopped() + { + return !service && !t.isAlive(); + } + + private final void debug( String msg ) + { + if ( DEBUG ) + { + System.err.println( this + ":" + msg ); + } + } + + private void runSweep() + { + debug( "runningSweep. time=" + System.currentTimeMillis() ); + pool.trim(); + } + } +} Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/SweeperPool.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,866 @@ +/* + * J.A.D.E. Java(TM) Addition to Default Environment. + * Latest release available at http://jade.dautelle.com/ + * This class is public domain (not copyrighted). + */ +package org.apache.geronimo.system.plugin.plexus.util; + +/** + *

This class provides utility methods to parse CharSequence + * into primitive types and to format primitive types into + * StringBuffer.

+ * + *

Methods from this utility class do not create temporary objects + * and are typically faster than standard library methods (e.g {@link + * #parseDouble} is up to 15x faster than Double.parseDouble). + *

+ * + *

For class instances, formatting is typically performed using specialized + * java.text.Format (Locale sensitive) + * and/or using conventional methods (class sensitive). For example:

+ *     public class Foo {
+ *         public static Foo valueOf(CharSequence chars) {...} // Parses.
+ *         public StringBuffer appendTo(StringBuffer sb) {...} // Formats.
+ *         public String toString() {
+ *             return appendTo(new StringBuffer()).toString();
+ *         }
+ *     }

+ * + *

This class is public domain (not copyrighted).

+ * + * @author Jean-Marie Dautelle + * @version 4.6, June 22, 2003 + */ +public final class TypeFormat { + + /** + * Holds the characters used to represent numbers. + */ + private final static char[] DIGITS = { + '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , + 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , + 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , + 'u' , 'v' , 'w' , 'x' , 'y' , 'z' }; + + /** + * Default constructor (forbids derivation). + */ + private TypeFormat() {} + + /** + * Searches for a particular sequence within a character sequence + * (general purpose parsing function). + * + * @param pattern the character sequence to search for. + * @param chars the character sequence being searched. + * @param fromIndex the index in chars to start the search + * from. + * @return the index in the range + * [fromIndex, chars.length()-pattern.length()] + * or -1 if the character sequence is not found. + */ + public static int indexOf(CharSequence pattern, CharSequence chars, + int fromIndex) { + int patternLength = pattern.length(); + fromIndex = Math.max(0, fromIndex); + if (patternLength != 0) { // At least one character to search for. + char firstChar = pattern.charAt(0); + int last = chars.length() - patternLength; + for (int i=fromIndex; i <= last; i++) { + if (chars.charAt(i) == firstChar) { + boolean match = true; + for (int j=1; j < patternLength; j++) { + if (chars.charAt(i+j) != pattern.charAt(j)) { + match = false; + break; + } + } + if (match) { + return i; + } + } + } + return -1; + } else { + return Math.min(0, fromIndex); + } + } + + /** + * Parses the specified CharSequence as a boolean. + * + * @param chars the character sequence to parse. + * @return the corresponding boolean. + */ + public static boolean parseBoolean(CharSequence chars) { + return (chars.length() == 4) && + (chars.charAt(0) == 't' || chars.charAt(0) == 'T') && + (chars.charAt(1) == 'r' || chars.charAt(1) == 'R') && + (chars.charAt(2) == 'u' || chars.charAt(2) == 'U') && + (chars.charAt(3) == 'e' || chars.charAt(3) == 'E'); + } + + /** + * Parses the specified CharSequence as a signed decimal + * short. + * + * @param chars the character sequence to parse. + * @return parseShort(chars, 10) + * @throws NumberFormatException if the specified character sequence + * does not contain a parsable short. + * @see #parseShort(CharSequence, int) + */ + public static short parseShort(CharSequence chars) { + return parseShort(chars, 10); + } + + /** + * Parses the specified CharSequence as a signed + * short in the specified radix. The characters in the string + * must all be digits of the specified radix, except the first character + * which may be a plus sign '+' or a minus sign + * '-'. + * + * @param chars the character sequence to parse. + * @param radix the radix to be used while parsing. + * @return the corresponding short. + * @throws NumberFormatException if the specified character sequence + * does not contain a parsable short. + */ + public static short parseShort(CharSequence chars, int radix) { + try { + boolean isNegative = (chars.charAt(0) == '-') ? true : false; + int result = 0; + int limit = (isNegative) ? Short.MIN_VALUE : -Short.MAX_VALUE; + int multmin = limit / radix; + int length = chars.length(); + int i = (isNegative || (chars.charAt(0) == '+')) ? 1 : 0; + while (true) { + int digit = Character.digit(chars.charAt(i), radix); + int tmp = result * radix; + if ((digit < 0) || (result < multmin) || + (tmp < limit + digit)) { // Overflow. + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + // Accumulates negatively. + result = tmp - digit; + if (++i >= length) { + break; + } + } + return (short) (isNegative ? result : -result); + } catch (IndexOutOfBoundsException e) { + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + } + + /** + * Parses the specified CharSequence as a signed decimal + * int. + * + * @param chars the character sequence to parse. + * @return parseInt(chars, 10) + * @throws NumberFormatException if the specified character sequence + * does not contain a parsable int. + * @see #parseInt(CharSequence, int) + */ + public static int parseInt(CharSequence chars) { + return parseInt(chars, 10); + } + + /** + * Parses the specified CharSequence as a signed + * int in the specified radix. The characters in the string + * must all be digits of the specified radix, except the first character + * which may be a plus sign '+' or a minus sign + * '-'. + * + * @param chars the character sequence to parse. + * @param radix the radix to be used while parsing. + * @return the corresponding int. + * @throws NumberFormatException if the specified character sequence + * does not contain a parsable int. + */ + public static int parseInt(CharSequence chars, int radix) { + try { + boolean isNegative = (chars.charAt(0) == '-') ? true : false; + int result = 0; + int limit = (isNegative) ? Integer.MIN_VALUE : -Integer.MAX_VALUE; + int multmin = limit / radix; + int length = chars.length(); + int i = (isNegative || (chars.charAt(0) == '+')) ? 1 : 0; + while (true) { + int digit = Character.digit(chars.charAt(i), radix); + int tmp = result * radix; + if ((digit < 0) || (result < multmin) || + (tmp < limit + digit)) { // Overflow. + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + // Accumulates negatively to avoid surprises near MAX_VALUE + result = tmp - digit; + if (++i >= length) { + break; + } + } + return isNegative ? result : -result; + } catch (IndexOutOfBoundsException e) { + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + } + + /** + * Parses the specified CharSequence as a signed decimal + * long. + * + * @param chars the character sequence to parse. + * @return parseLong(chars, 10) + * @throws NumberFormatException if the specified character sequence + * does not contain a parsable long. + * @see #parseLong(CharSequence, int) + */ + public static long parseLong(CharSequence chars) { + return parseLong(chars, 10); + } + + /** + * Parses the specified CharSequence as a signed + * long in the specified radix. The characters in the string + * must all be digits of the specified radix, except the first character + * which may be a plus sign '+' or a minus sign + * '-'. + * + * @param chars the character sequence to parse. + * @param radix the radix to be used while parsing. + * @return the corresponding long. + * @throws NumberFormatException if the specified character sequence + * does not contain a parsable long. + */ + public static long parseLong(CharSequence chars, int radix) { + try { + boolean isNegative = (chars.charAt(0) == '-') ? true : false; + long result = 0; + long limit = (isNegative) ? Long.MIN_VALUE : -Long.MAX_VALUE; + long multmin = limit / radix; + int length = chars.length(); + int i = (isNegative || (chars.charAt(0) == '+')) ? 1 : 0; + while (true) { + int digit = Character.digit(chars.charAt(i), radix); + long tmp = result * radix; + if ((digit < 0) || (result < multmin) || + (tmp < limit + digit)) { // Overflow. + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + // Accumulates negatively to avoid surprises near MAX_VALUE + result = tmp - digit; + if (++i >= length) { + break; + } + } + return isNegative ? result : -result; + } catch (IndexOutOfBoundsException e) { + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + } + + /** + * Parses this CharSequence as a float. + * + * @param chars the character sequence to parse. + * @return the float number represented by the specified character sequence. + * @throws NumberFormatException if the character sequence does not contain + * a parsable float. + */ + public static float parseFloat(CharSequence chars) { + double d = parseDouble(chars); + if ( (d >= Float.MIN_VALUE) && (d <= Float.MAX_VALUE)) { + return (float) d; + } else { + throw new NumberFormatException( + "Float overflow for input characters: \"" + + chars.toString() + "\""); + } + } + + /** + * Parses this CharSequence as a double. + * + * @param chars the character sequence to parse. + * @return the double number represented by this character sequence. + * @throws NumberFormatException if the character sequence does not contain + * a parsable double. + */ + public static double parseDouble(CharSequence chars) + throws NumberFormatException { + try { + int length = chars.length(); + double result = 0.0; + int exp = 0; + + boolean isNegative = (chars.charAt(0) == '-') ? true : false; + int i = (isNegative || (chars.charAt(0) == '+')) ? 1 : 0; + + // Checks special cases NaN or Infinity. + if ((chars.charAt(i) == 'N') || (chars.charAt(i) == 'I')) { + if (chars.toString().equals("NaN")) { + return Double.NaN; + } else if (chars.subSequence(i, length).toString(). + equals("Infinity")) { + return isNegative ? Double.NEGATIVE_INFINITY : + Double.POSITIVE_INFINITY; + } + } + + // Reads decimal number. + boolean fraction = false; + while (true) { + char c = chars.charAt(i); + if ( (c == '.') && (!fraction)) { + fraction = true; + } else if ((c == 'e') || (c == 'E')) { + break; + } else if ((c >= '0') && (c <= '9')) { + result = result * 10 + (c - '0'); + if (fraction) { + exp--; + } + } else { + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + if (++i >= length) { + break; + } + } + result = isNegative ? - result : result; + + // Reads exponent (if any). + if (i < length) { + i++; + boolean negE = (chars.charAt(i) == '-') ? true : false; + i = (negE || (chars.charAt(i) == '+')) ? i+1 : i; + int valE = 0; + while (true) { + char c = chars.charAt(i); + if ((c >= '0') && (c <= '9')) { + valE = valE * 10 + (c - '0'); + if (valE > 10000000) { // Hard-limit to avoid overflow. + valE = 10000000; + } + } else { + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + + "\""); + } + if (++i >= length) { + break; + } + } + exp += negE ? -valE : valE; + } + + // Returns product decimal number with exponent. + return multE(result, exp); + + } catch (IndexOutOfBoundsException e) { + throw new NumberFormatException( + "For input characters: \"" + chars.toString() + "\""); + } + } + /** + * Formats the specified boolean and appends the resulting + * text to the StringBuffer argument. + * + * @param b a boolean. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseBoolean + */ + public static StringBuffer format(boolean b, StringBuffer sb) { + return b ? sb.append("true") : sb.append("false"); + } + + /** + * Formats the specified short and appends the resulting + * text (decimal representation) to the StringBuffer argument. + * + *

Note: This method is preferred to StringBuffer.append(short) + * as it does not create temporary String + * objects (several times faster for small numbers).

+ * + * @param s the short number. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseShort + */ + public static StringBuffer format(short s, StringBuffer sb) { + return format((int)s, sb); // Forwards to int formatting (fast). + } + + /** + * Formats the specified short in the specified radix and + * appends the resulting text to the StringBuffer argument. + * + * @param s the short number. + * @param radix the radix. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseShort(CharSequence, int) + * throws IllegalArgumentException if radix is not in [2 .. 36] range. + */ + public static StringBuffer format(short s, int radix, StringBuffer sb) { + return format((int)s, radix, sb); // Forwards to int formatting (fast). + } + + /** + * Formats the specified int and appends the resulting + * text (decimal representation) to the StringBuffer argument. + * + *

Note: This method is preferred to StringBuffer.append(int) + * as it does not create temporary String + * objects (several times faster for small numbers).

+ * + * @param i the int number. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseInt + */ + public static StringBuffer format(int i, StringBuffer sb) { + if (i <= 0) { + if (i == Integer.MIN_VALUE) { // Negation would overflow. + return sb.append("-2147483648"); // 11 char max. + } else if (i == 0) { + return sb.append('0'); + } + i = -i; + sb.append('-'); + } + int j = 1; + for (; (j < 10) && (i >= INT_POW_10[j]); j++) {} + // POW_10[j] > i >= POW_10[j-1] + for (j--; j >= 0; j--) { + int pow10 = INT_POW_10[j]; + int digit = i / pow10; + i -= digit * pow10; + sb.append(DIGITS[digit]); + } + return sb; + } + private static final int[] INT_POW_10 = new int[10]; + static { + int pow = 1; + for (int i=0; i < 10; i++) { + INT_POW_10[i] = pow; + pow *= 10; + } + } + + /** + * Formats the specified int in the specified radix and appends + * the resulting text to the StringBuffer argument. + * + * @param i the int number. + * @param radix the radix. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseInt(CharSequence, int) + * throws IllegalArgumentException if radix is not in [2 .. 36] range. + */ + public static StringBuffer format(int i, int radix, StringBuffer sb) { + if (radix == 10) { + return format(i, sb); // Faster version. + } else if (radix < 2 || radix > 36) { + throw new IllegalArgumentException("radix: " + radix); + } + if (i < 0) { + sb.append('-'); + } else { + i = -i; + } + format2(i, radix, sb); + return sb; + } + private static void format2(int i, int radix, StringBuffer sb) { + if (i <= -radix) { + format2(i / radix, radix, sb); + sb.append(DIGITS[-(i % radix)]); + } else { + sb.append(DIGITS[-i]); + } + } + + /** + * Formats the specified long and appends the resulting + * text (decimal representation) to the StringBuffer argument. + * + *

Note: This method is preferred to StringBuffer.append(long) + * as it does not create temporary String + * objects (several times faster for small numbers).

+ * + * @param l the long number. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseLong + */ + public static StringBuffer format(long l, StringBuffer sb) { + if (l <= 0) { + if (l == Long.MIN_VALUE) { // Negation would overflow. + return sb.append("-9223372036854775808"); // 20 characters max. + } else if (l == 0) { + return sb.append('0'); + } + l = -l; + sb.append('-'); + } + int j = 1; + for (; (j < 19) && (l >= LONG_POW_10[j]); j++) {} + // POW_10[j] > l >= POW_10[j-1] + for (j--; j >= 0; j--) { + long pow10 = LONG_POW_10[j]; + int digit = (int) (l / pow10); + l -= digit * pow10; + sb.append(DIGITS[digit]); + } + return sb; + } + private static final long[] LONG_POW_10 = new long[19]; + static { + long pow = 1; + for (int i=0; i < 19; i++) { + LONG_POW_10[i] = pow; + pow *= 10; + } + } + + /** + * Formats the specified long in the specified radix and + * appends the resulting text to the StringBuffer argument. + * + * @param l the long number. + * @param radix the radix. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @see #parseLong(CharSequence, int) + * throws IllegalArgumentException if radix is not in [2 .. 36] range. + */ + public static StringBuffer format(long l, int radix, StringBuffer sb) { + if (radix == 10) { + return format(l, sb); // Faster version. + } else if (radix < 2 || radix > 36) { + throw new IllegalArgumentException("radix: " + radix); + } + if (l < 0) { + sb.append('-'); + } else { + l = -l; + } + format2(l, radix, sb); + return sb; + } + private static void format2(long l, int radix, StringBuffer sb) { + if (l <= -radix) { + format2(l / radix, radix, sb); + sb.append(DIGITS[(int)-(l % radix)]); + } else { + sb.append(DIGITS[(int)-l]); + } + } + + /** + * Formats the specified float and appends the resulting + * text to the StringBuffer argument. + * + * @param f the float number. + * @param sb the StrinBuffer to append. + * @return format(f, 0.0f, sb) + * @see #format(float, float, StringBuffer) + */ + public static StringBuffer format(float f, StringBuffer sb) { + return format(f, 0.0f, sb); + } + + /** + * Formats the specified float and appends the resulting text + * to the StringBuffer argument; the number of significative + * digits is deduced from the specifed precision. All digits at least as + * significant as the specified precision are represented. For example: + *
    + *
  • format(5.6f, 0.01f, sb) appends "5.60"
  • + *
  • format(5.6f, 0.1f, sb) appends "5.6"
  • + *
  • format(5.6f, 1f, sb) appends "6"
  • + *
+ * If the precision is 0.0f, the precision is assumed to be + * the intrinsic float precision (64 bits IEEE 754 format); + * no formatting is performed, all significant digits are displayed and + * trailing zeros are removed. + * + * @param f the float number. + * @param precision the maximum weight of the last digit represented. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @throws IllegalArgumentException if the specified precision is negative + * or would result in too many digits (19+). + */ + public static StringBuffer format(float f, float precision, + StringBuffer sb) { + // Adjusts precision. + boolean precisionOnLastDigit; + if (precision > 0.0f) { + precisionOnLastDigit = true; + } else if (precision == 0.0f) { + if (f != 0.0f) { + precisionOnLastDigit = false; + precision = Math.max(Math.abs(f * FLOAT_RELATIVE_ERROR), + Float.MIN_VALUE); + } else { + return sb.append("0.0"); // Exact zero. + } + } else { + throw new IllegalArgumentException( + "precision: Negative values not allowed"); + } + return format(f, precision, precisionOnLastDigit, sb); + } + + /** + * Formats the specified double and appends the resulting + * text to the StringBuffer argument. + * + *

Note : This method is preferred to StringBuffer.append(double) + * or even String.valueOf(double) as it + * does not create temporary String or + * FloatingDecimal objects (several times faster, + * e.g. 15x faster for Double.MAX_VALUE).

+ * + * @param d the double number. + * @param sb the StrinBuffer to append. + * @return format(d, 0.0, sb) + * @see #format(double, double, StringBuffer) + */ + public static StringBuffer format(double d, StringBuffer sb) { + return format(d, 0.0, sb); + } + + /** + * Formats the specified double and appends the resulting text + * to the StringBuffer argument; the number of significand + * digits is specified as integer argument. + * + * @param d the double number. + * @param digits the number of significand digits (excludes exponent). + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @throws IllegalArgumentException if the number of digits is not in + * range [1..19]. + */ + public static StringBuffer format(double d, int digits, + StringBuffer sb) { + if ((digits >= 1) && (digits <= 19)) { + double precision = Math.abs(d / DOUBLE_POW_10[digits-1]); + return format(d, precision, sb); + } else { + throw new java.lang.IllegalArgumentException( + "digits: " + digits + " is not in range [1 .. 19]"); + } + } + + /** + * Formats the specified double and appends the resulting text + * to the StringBuffer argument; the number of significative + * digits is deduced from the specifed precision. All digits at least as + * significant as the specified precision are represented. For example: + *
    + *
  • format(5.6, 0.01, sb) appends "5.60"
  • + *
  • format(5.6, 0.1, sb) appends "5.6"
  • + *
  • format(5.6, 1, sb) appends "6"
  • + *
+ * If the precision is 0.0, the precision is assumed to be + * the intrinsic double precision (64 bits IEEE 754 format); + * no formatting is performed, all significant digits are displayed and + * trailing zeros are removed. + * + * @param d the double number. + * @param precision the maximum weight of the last digit represented. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + * @throws IllegalArgumentException if the specified precision is negative + * or would result in too many digits (19+). + */ + public static StringBuffer format(double d, double precision, + StringBuffer sb) { + // Adjusts precision. + boolean precisionOnLastDigit = false; + if (precision > 0.0) { + precisionOnLastDigit = true; + } else if (precision == 0.0) { + if (d != 0.0) { + precision = Math.max(Math.abs(d * DOUBLE_RELATIVE_ERROR), + Double.MIN_VALUE); + } else { + return sb.append("0.0"); // Exact zero. + } + } else if (precision < 0.0) { // Not NaN + throw new IllegalArgumentException( + "precision: Negative values not allowed"); + } + return format(d, precision, precisionOnLastDigit, sb); + } + + /** + * Formats the specified double and appends the resulting text + * to the StringBuffer argument; the number of significative + * digits is deduced from the specifed precision. + * + * @param d the double number. + * @param precision the maximum weight of the last digit represented. + * @param precisionOnLastDigit indicates if the number of digits is + * deduced from the specified precision. + * @param sb the StrinBuffer to append. + * @return the specified StringBuffer object. + */ + private static StringBuffer format(double d, double precision, + boolean precisionOnLastDigit, + StringBuffer sb) { + // Special cases. + if (Double.isNaN(d)) { + return sb.append("NaN"); + } else if (Double.isInfinite(d)) { + return (d >= 0) ? sb.append("Infinity") : sb.append("-Infinity"); + } + if (d < 0) { + d = -d; + sb.append('-'); + } + + // Formats decimal part. + int rank = (int) Math.floor(Math.log(precision) / LOG_10); + double digitValue = multE(d, -rank); + if (digitValue >= Long.MAX_VALUE) { + throw new IllegalArgumentException( + "Specified precision would result in too many digits"); + } + int digitStart = sb.length(); + format(Math.round(digitValue), sb); + int digitLength = sb.length() - digitStart; + int dotPos = digitLength + rank; + boolean useScientificNotation = false; + + // Inserts dot ('.') + if ((dotPos <= -LEADING_ZEROS.length) || (dotPos > digitLength)) { + // Scientific notation has to be used ("x.xxxEyy"). + sb.insert(digitStart + 1, '.'); + useScientificNotation = true; + } else if (dotPos > 0) { + // Dot within the string ("xxxx.xxxxx"). + sb.insert(digitStart + dotPos, '.'); + } else { + // Leading zeros ("0.xxxxx"). + sb.insert(digitStart, LEADING_ZEROS[-dotPos]); + } + + // Removes trailing zeros. + if (!precisionOnLastDigit) { + int newLength = sb.length(); + do { + newLength--; + } while (sb.charAt(newLength) == '0'); + sb.setLength(newLength+1); + } + + // Avoids trailing '.' + if (sb.charAt(sb.length()-1) == '.') { + if (precisionOnLastDigit) { + sb.setLength(sb.length()-1); // Prefers "xxx" to "xxx." + } else { + sb.append('0'); // Prefer "xxx.0" to "xxx." + } + } + + // Writes exponent. + if (useScientificNotation) { + sb.append('E'); + format(dotPos - 1, sb); + } + + return sb; + } + private static final double LOG_10 = Math.log(10); + private static final float FLOAT_RELATIVE_ERROR = (float) Math.pow(2, -24); + private static final double DOUBLE_RELATIVE_ERROR = Math.pow(2, -53); + private static String[] LEADING_ZEROS = {"0.", "0.0", "0.00"}; + + + /** + * Returns the product of the specified value with 10 raised + * at the specified power exponent. + * + * @param value the value. + * @param E the exponent. + * @return value * 10^E + */ + private static final double multE(double value, int E) { + if (E >= 0) { + if (E <= 308) { + // Max: 1.7976931348623157E+308 + return value * DOUBLE_POW_10[E]; + } else { + value *= 1E21; // Exact multiplicand. + E = Math.min(308, E-21); + return value * DOUBLE_POW_10[E]; + } + } else { + if (E >= -308) { + return value / DOUBLE_POW_10[-E]; + } else { + // Min: 4.9E-324 + value /= 1E21; // Exact divisor. + E = Math.max(-308, E+21); + return value / DOUBLE_POW_10[-E]; + } + } + } + + // Note: Approximation for exponents > 21. This may introduce round-off + // errors (e.g. 1E23 represented as "9.999999999999999E22"). + private static final double[] DOUBLE_POW_10 = new double[] { + + 1E000, 1E001, 1E002, 1E003, 1E004, 1E005, 1E006, 1E007, 1E008, 1E009, + 1E010, 1E011, 1E012, 1E013, 1E014, 1E015, 1E016, 1E017, 1E018, 1E019, + 1E020, 1E021, 1E022, 1E023, 1E024, 1E025, 1E026, 1E027, 1E028, 1E029, + 1E030, 1E031, 1E032, 1E033, 1E034, 1E035, 1E036, 1E037, 1E038, 1E039, + 1E040, 1E041, 1E042, 1E043, 1E044, 1E045, 1E046, 1E047, 1E048, 1E049, + 1E050, 1E051, 1E052, 1E053, 1E054, 1E055, 1E056, 1E057, 1E058, 1E059, + 1E060, 1E061, 1E062, 1E063, 1E064, 1E065, 1E066, 1E067, 1E068, 1E069, + 1E070, 1E071, 1E072, 1E073, 1E074, 1E075, 1E076, 1E077, 1E078, 1E079, + 1E080, 1E081, 1E082, 1E083, 1E084, 1E085, 1E086, 1E087, 1E088, 1E089, + 1E090, 1E091, 1E092, 1E093, 1E094, 1E095, 1E096, 1E097, 1E098, 1E099, + + 1E100, 1E101, 1E102, 1E103, 1E104, 1E105, 1E106, 1E107, 1E108, 1E109, + 1E110, 1E111, 1E112, 1E113, 1E114, 1E115, 1E116, 1E117, 1E118, 1E119, + 1E120, 1E121, 1E122, 1E123, 1E124, 1E125, 1E126, 1E127, 1E128, 1E129, + 1E130, 1E131, 1E132, 1E133, 1E134, 1E135, 1E136, 1E137, 1E138, 1E139, + 1E140, 1E141, 1E142, 1E143, 1E144, 1E145, 1E146, 1E147, 1E148, 1E149, + 1E150, 1E151, 1E152, 1E153, 1E154, 1E155, 1E156, 1E157, 1E158, 1E159, + 1E160, 1E161, 1E162, 1E163, 1E164, 1E165, 1E166, 1E167, 1E168, 1E169, + 1E170, 1E171, 1E172, 1E173, 1E174, 1E175, 1E176, 1E177, 1E178, 1E179, + 1E180, 1E181, 1E182, 1E183, 1E184, 1E185, 1E186, 1E187, 1E188, 1E189, + 1E190, 1E191, 1E192, 1E193, 1E194, 1E195, 1E196, 1E197, 1E198, 1E199, + + 1E200, 1E201, 1E202, 1E203, 1E204, 1E205, 1E206, 1E207, 1E208, 1E209, + 1E210, 1E211, 1E212, 1E213, 1E214, 1E215, 1E216, 1E217, 1E218, 1E219, + 1E220, 1E221, 1E222, 1E223, 1E224, 1E225, 1E226, 1E227, 1E228, 1E229, + 1E230, 1E231, 1E232, 1E233, 1E234, 1E235, 1E236, 1E237, 1E238, 1E239, + 1E240, 1E241, 1E242, 1E243, 1E244, 1E245, 1E246, 1E247, 1E248, 1E249, + 1E250, 1E251, 1E252, 1E253, 1E254, 1E255, 1E256, 1E257, 1E258, 1E259, + 1E260, 1E261, 1E262, 1E263, 1E264, 1E265, 1E266, 1E267, 1E268, 1E269, + 1E270, 1E271, 1E272, 1E273, 1E274, 1E275, 1E276, 1E277, 1E278, 1E279, + 1E280, 1E281, 1E282, 1E283, 1E284, 1E285, 1E286, 1E287, 1E288, 1E289, + 1E290, 1E291, 1E292, 1E293, 1E294, 1E295, 1E296, 1E297, 1E298, 1E299, + + 1E300, 1E301, 1E302, 1E303, 1E304, 1E305, 1E306, 1E307, 1E308 }; +} \ No newline at end of file Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/TypeFormat.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,177 @@ +package org.apache.geronimo.system.plugin.plexus.util; + +/* + * Copyright The Codehaus 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. + */ + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.nio.charset.Charset; + +import org.apache.geronimo.system.plugin.plexus.util.xml.XmlStreamWriter; + +/** + * Utility to create Writers, with explicit encoding choice: platform default, + * XML, or specified. + * + * @author Herve Boutemy + * @see Charset + * @see Supported encodings + * @version $Id: WriterFactory.java 8289 2009-07-18 17:27:30Z hboutemy $ + * @since 1.4.4 + */ +public class WriterFactory +{ + /** + * ISO Latin Alphabet #1, also known as ISO-LATIN-1. + * Every implementation of the Java platform is required to support this character encoding. + * @see Charset + */ + public static final String ISO_8859_1 = "ISO-8859-1"; + + /** + * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of the Unicode character set. + * Every implementation of the Java platform is required to support this character encoding. + * @see Charset + */ + public static final String US_ASCII = "US-ASCII"; + + /** + * Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark (either + * order accepted on input, big-endian used on output). + * Every implementation of the Java platform is required to support this character encoding. + * @see Charset + */ + public static final String UTF_16 = "UTF-16"; + + /** + * Sixteen-bit Unicode Transformation Format, big-endian byte order. + * Every implementation of the Java platform is required to support this character encoding. + * @see Charset + */ + public static final String UTF_16BE = "UTF-16BE"; + + /** + * Sixteen-bit Unicode Transformation Format, little-endian byte order. + * Every implementation of the Java platform is required to support this character encoding. + * @see Charset + */ + public static final String UTF_16LE = "UTF-16LE"; + + /** + * Eight-bit Unicode Transformation Format. + * Every implementation of the Java platform is required to support this character encoding. + * @see Charset + */ + public static final String UTF_8 = "UTF-8"; + + /** + * The file.encoding System Property. + */ + public static final String FILE_ENCODING = System.getProperty( "file.encoding" ); + + /** + * Create a new Writer with XML encoding detection rules. + * + * @param out not null output stream. + * @return an XML writer instance for the output stream. + * @throws IOException if any. + * @see XmlStreamWriter + */ + public static XmlStreamWriter newXmlWriter( OutputStream out ) + throws IOException + { + return new XmlStreamWriter( out ); + } + + /** + * Create a new Writer with XML encoding detection rules. + * + * @param file not null file. + * @return an XML writer instance for the output file. + * @throws IOException if any. + * @see XmlStreamWriter + */ + public static XmlStreamWriter newXmlWriter( File file ) + throws IOException + { + return new XmlStreamWriter( file ); + } + + /** + * Create a new Writer with default plaform encoding. + * + * @param out not null output stream. + * @return a writer instance for the output stream using the default platform charset. + * @throws IOException if any. + * @see Charset#defaultCharset() + */ + public static Writer newPlatformWriter( OutputStream out ) + { + return new OutputStreamWriter( out ); + } + + /** + * Create a new Writer with default plaform encoding. + * + * @param file not null file. + * @return a writer instance for the output file using the default platform charset. + * @throws IOException if any. + * @see Charset#defaultCharset() + */ + public static Writer newPlatformWriter( File file ) + throws IOException + { + return new FileWriter( file ); + } + + /** + * Create a new Writer with specified encoding. + * + * @param out not null output stream. + * @param encoding not null supported encoding. + * @return a writer instance for the output stream using the given encoding. + * @throws UnsupportedEncodingException if any. + * @see Supported encodings + */ + public static Writer newWriter( OutputStream out, String encoding ) + throws UnsupportedEncodingException + { + return new OutputStreamWriter( out, encoding ); + } + + /** + * Create a new Writer with specified encoding. + * + * @param file not null file. + * @param encoding not null supported encoding. + * @return a writer instance for the output file using the given encoding. + * @throws UnsupportedEncodingException if any. + * @throws FileNotFoundException if any. + * @see Supported encodings + */ + public static Writer newWriter( File file, String encoding ) + throws UnsupportedEncodingException, FileNotFoundException + { + return newWriter( new FileOutputStream( file ), encoding ); + } +} Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/WriterFactory.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,30 @@ +package org.apache.geronimo.system.plugin.plexus.util.cli; + +/* + * Copyright The Codehaus 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. + */ + +import java.io.File; + +public interface Arg +{ + void setValue( String value ); + + void setLine( String line ); + + void setFile( File value ); + + String[] getParts(); +} Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/Arg.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,35 @@ +package org.apache.geronimo.system.plugin.plexus.util.cli; + +/* + * Copyright The Codehaus 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. + */ + +/** + * @author Trygve Laugstøl + * @version $Id: CommandLineException.java 8010 2009-01-07 12:59:50Z vsiveton $ + */ +public class CommandLineException + extends Exception +{ + public CommandLineException( String message ) + { + super( message ); + } + + public CommandLineException( String message, Throwable cause ) + { + super( message, cause ); + } +} Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,49 @@ +package org.apache.geronimo.system.plugin.plexus.util.cli; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/** + * + * @author olamy + * @since 1.5.9 + * @version $Id: CommandLineTimeOutException.java 8153 2009-04-25 22:07:51Z olamy $ + */ +public class CommandLineTimeOutException + extends CommandLineException +{ + + /** + * @param message + */ + public CommandLineTimeOutException( String message ) + { + super( message ); + } + + /** + * @param message + * @param cause + */ + public CommandLineTimeOutException( String message, Throwable cause ) + { + super( message, cause ); + } + +} Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineTimeOutException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java?rev=821961&view=auto ============================================================================== --- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java (added) +++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java Mon Oct 5 18:54:50 2009 @@ -0,0 +1,582 @@ +package org.apache.geronimo.system.plugin.plexus.util.cli; + +/* + * Copyright The Codehaus 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. + */ + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.apache.geronimo.system.plugin.plexus.util.Os; +import org.apache.geronimo.system.plugin.plexus.util.StringUtils; + +/** + * @author Trygve Laugstøl + * @version $Id: CommandLineUtils.java 8253 2009-06-05 00:18:27Z igorife $ + */ +public abstract class CommandLineUtils +{ + private static Map processes = Collections.synchronizedMap( new HashMap() ); + + private static Thread shutdownHook = new Thread( "CommandlineUtil shutdown" ) + { + public void run() + { + if ( ( processes != null ) && ( processes.size() > 0 ) ) + { + System.err.println( "Destroying " + processes.size() + " processes" ); + for ( Iterator it = processes.values().iterator(); it.hasNext(); ) + { + System.err.println( "Destroying process.." ); + ( (Process) it.next() ).destroy(); + + } + System.err.println( "Destroyed " + processes.size() + " processes" ); + } + } + }; + + static + { + shutdownHook.setContextClassLoader( null ); + addShutdownHook(); + } + + public static void addShutdownHook() + { + Runtime.getRuntime().addShutdownHook( shutdownHook ); + } + + public static void removeShutdownHook( boolean execute ) + { + Runtime.getRuntime().removeShutdownHook( shutdownHook ); + + if ( execute ) + { + shutdownHook.run(); + } + } + + public static class StringStreamConsumer + implements StreamConsumer + { + private StringBuffer string = new StringBuffer(); + + private String ls = System.getProperty( "line.separator" ); + + public void consumeLine( String line ) + { + string.append( line ).append( ls ); + } + + public String getOutput() + { + return string.toString(); + } + } + + public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr ) + throws CommandLineException + { + return executeCommandLine( cl, null, systemOut, systemErr, 0 ); + } + + public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr, + int timeoutInSeconds ) + throws CommandLineException + { + return executeCommandLine( cl, null, systemOut, systemErr, timeoutInSeconds ); + } + + public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut, + StreamConsumer systemErr ) + throws CommandLineException + { + return executeCommandLine( cl, systemIn, systemOut, systemErr, 0 ); + } + + /** + * @param cl + * @param systemIn + * @param systemOut + * @param systemErr + * @param timeoutInSeconds + * @return + * @throws CommandLineException or CommandLineTimeOutException if time out occurs + */ + public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut, + StreamConsumer systemErr, int timeoutInSeconds ) + throws CommandLineException + { + if ( cl == null ) + { + throw new IllegalArgumentException( "cl cannot be null." ); + } + + Process p; + + p = cl.execute(); + + processes.put( new Long( cl.getPid() ), p ); + + StreamFeeder inputFeeder = null; + + if ( systemIn != null ) + { + inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() ); + } + + StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut ); + + StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr ); + + if ( inputFeeder != null ) + { + inputFeeder.start(); + } + + outputPumper.start(); + + errorPumper.start(); + + try + { + int returnValue; + if ( timeoutInSeconds <= 0 ) + { + returnValue = p.waitFor(); + } + else + { + long now = System.currentTimeMillis(); + long timeoutInMillis = 1000L * timeoutInSeconds; + long finish = now + timeoutInMillis; + while ( isAlive( p ) && ( System.currentTimeMillis() < finish ) ) + { + Thread.sleep( 10 ); + } + if ( isAlive( p ) ) + { + throw new InterruptedException( "Process timeout out after " + timeoutInSeconds + " seconds" ); + } + returnValue = p.exitValue(); + } + + if ( inputFeeder != null ) + { + synchronized ( inputFeeder ) + { + while ( !inputFeeder.isDone() ) + { + inputFeeder.wait(); + } + } + } + + synchronized ( outputPumper ) + { + while ( !outputPumper.isDone() ) + { + outputPumper.wait(); + } + } + + synchronized ( errorPumper ) + { + while ( !errorPumper.isDone() ) + { + errorPumper.wait(); + } + } + + processes.remove( new Long( cl.getPid() ) ); + + return returnValue; + } + catch ( InterruptedException ex ) + { + killProcess( cl.getPid() ); + throw new CommandLineTimeOutException( "Error while executing external command, process killed.", ex ); + } + finally + { + if ( inputFeeder != null ) + { + inputFeeder.close(); + } + + outputPumper.close(); + + errorPumper.close(); + + p.destroy(); + + if ( processes.get( new Long( cl.getPid() ) ) != null ) + { + processes.remove( new Long( cl.getPid() ) ); + } + } + } + + /** + * Gets the shell environment variables for this process. Note that the returned mapping from variable names to + * values will always be case-sensitive regardless of the platform, i.e. getSystemEnvVars().get("path") + * and getSystemEnvVars().get("PATH") will in general return different values. However, on platforms + * with case-insensitive environment variables like Windows, all variable names will be normalized to upper case. + * + * @return The shell environment variables, can be empty but never null. + * @throws IOException If the environment variables could not be queried from the shell. + */ + public static Properties getSystemEnvVars() + throws IOException + { + return getSystemEnvVars( !Os.isFamily( Os.FAMILY_WINDOWS ) ); + } + + /** + * Return the shell environment variables. If caseSensitive == true, then envar + * keys will all be upper-case. + * + * @param caseSensitive Whether environment variable keys should be treated case-sensitively. + * @return Properties object of (possibly modified) envar keys mapped to their values. + * @throws IOException + */ + public static Properties getSystemEnvVars( boolean caseSensitive ) + throws IOException + { + Process p = null; + + try + { + Properties envVars = new Properties(); + + Runtime r = Runtime.getRuntime(); + + //If this is windows set the shell to command.com or cmd.exe with correct arguments. + if ( Os.isFamily( Os.FAMILY_WINDOWS ) ) + { + if ( Os.isFamily( Os.FAMILY_WIN9X ) ) + { + p = r.exec( "command.com /c set" ); + } + else + { + p = r.exec( "cmd.exe /c set" ); + } + } + else + { + p = r.exec( "env" ); + } + + BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) ); + + String line; + + String lastKey = null; + String lastVal = null; + + while ( ( line = br.readLine() ) != null ) + { + int idx = line.indexOf( '=' ); + + if ( idx > 0 ) + { + lastKey = line.substring( 0, idx ); + + if ( !caseSensitive ) + { + lastKey = lastKey.toUpperCase( Locale.ENGLISH ); + } + + lastVal = line.substring( idx + 1 ); + + envVars.setProperty( lastKey, lastVal ); + } + else if ( lastKey != null ) + { + lastVal += "\n" + line; + + envVars.setProperty( lastKey, lastVal ); + } + } + + return envVars; + } + finally + { + if ( p != null ) + { + p.destroy(); + } + } + } + + /** + * Kill a process launched by executeCommandLine methods. + * Doesn't work correctly on windows, only the cmd process will be destroy but not the sub process (Bug ID 4770092) + * + * @param pid The pid of command return by Commandline.getPid() + */ + public static void killProcess( long pid ) + { + Process p = (Process) processes.get( new Long( pid ) ); + + if ( p != null ) + { + p.destroy(); + System.out.println( "Process " + pid + " is killed." ); + processes.remove( new Long( pid ) ); + } + else + { + System.out.println( "don't exist." ); + } + } + + public static boolean isAlive( long pid ) + { + return ( processes.get( new Long( pid ) ) != null ); + } + + public static boolean isAlive( Process p ) + { + if ( p == null ) + { + return false; + } + + try + { + p.exitValue(); + return false; + } + catch ( IllegalThreadStateException e ) + { + return true; + } + } + + public static String[] translateCommandline( String toProcess ) + throws Exception + { + if ( ( toProcess == null ) || ( toProcess.length() == 0 ) ) + { + return new String[0]; + } + + // parse with a simple finite state machine + + final int normal = 0; + final int inQuote = 1; + final int inDoubleQuote = 2; + int state = normal; + StringTokenizer tok = new StringTokenizer( toProcess, "\"\' ", true ); + Vector v = new Vector(); + StringBuffer current = new StringBuffer(); + + while ( tok.hasMoreTokens() ) + { + String nextTok = tok.nextToken(); + switch ( state ) + { + case inQuote: + if ( "\'".equals( nextTok ) ) + { + state = normal; + } + else + { + current.append( nextTok ); + } + break; + case inDoubleQuote: + if ( "\"".equals( nextTok ) ) + { + state = normal; + } + else + { + current.append( nextTok ); + } + break; + default: + if ( "\'".equals( nextTok ) ) + { + state = inQuote; + } + else if ( "\"".equals( nextTok ) ) + { + state = inDoubleQuote; + } + else if ( " ".equals( nextTok ) ) + { + if ( current.length() != 0 ) + { + v.addElement( current.toString() ); + current.setLength( 0 ); + } + } + else + { + current.append( nextTok ); + } + break; + } + } + + if ( current.length() != 0 ) + { + v.addElement( current.toString() ); + } + + if ( ( state == inQuote ) || ( state == inDoubleQuote ) ) + { + throw new CommandLineException( "unbalanced quotes in " + toProcess ); + } + + String[] args = new String[v.size()]; + v.copyInto( args ); + return args; + } + + /** + *

Put quotes around the given String if necessary.

+ *

If the argument doesn't include spaces or quotes, return it + * as is. If it contains double quotes, use single quotes - else + * surround the argument by double quotes.

+ * + * @throws CommandLineException if the argument contains both, single + * and double quotes. + * @deprecated Use {@link StringUtils#quoteAndEscape(String, char, char[], char[], char, boolean)}, + * {@link StringUtils#quoteAndEscape(String, char, char[], char, boolean)}, or + * {@link StringUtils#quoteAndEscape(String, char)} instead. + */ + public static String quote( String argument ) + throws CommandLineException + { + return quote( argument, false, false, true ); + } + + /** + *

Put quotes around the given String if necessary.

+ *

If the argument doesn't include spaces or quotes, return it + * as is. If it contains double quotes, use single quotes - else + * surround the argument by double quotes.

+ * + * @throws CommandLineException if the argument contains both, single + * and double quotes. + * @deprecated Use {@link StringUtils#quoteAndEscape(String, char, char[], char[], char, boolean)}, + * {@link StringUtils#quoteAndEscape(String, char, char[], char, boolean)}, or + * {@link StringUtils#quoteAndEscape(String, char)} instead. + */ + public static String quote( String argument, boolean wrapExistingQuotes ) + throws CommandLineException + { + return quote( argument, false, false, wrapExistingQuotes ); + } + + /** + * @deprecated Use {@link StringUtils#quoteAndEscape(String, char, char[], char[], char, boolean)}, + * {@link StringUtils#quoteAndEscape(String, char, char[], char, boolean)}, or + * {@link StringUtils#quoteAndEscape(String, char)} instead. + */ + public static String quote( String argument, boolean escapeSingleQuotes, boolean escapeDoubleQuotes, + boolean wrapExistingQuotes ) + throws CommandLineException + { + if ( argument.indexOf( "\"" ) > -1 ) + { + if ( argument.indexOf( "\'" ) > -1 ) + { + throw new CommandLineException( "Can't handle single and double quotes in same argument" ); + } + else + { + if ( escapeSingleQuotes ) + { + return "\\\'" + argument + "\\\'"; + } + else if ( wrapExistingQuotes ) + { + return '\'' + argument + '\''; + } + } + } + else if ( argument.indexOf( "\'" ) > -1 ) + { + if ( escapeDoubleQuotes ) + { + return "\\\"" + argument + "\\\""; + } + else if ( wrapExistingQuotes ) + { + return '\"' + argument + '\"'; + } + } + else if ( argument.indexOf( " " ) > -1 ) + { + if ( escapeDoubleQuotes ) + { + return "\\\"" + argument + "\\\""; + } + else + { + return '\"' + argument + '\"'; + } + } + + return argument; + } + + public static String toString( String[] line ) + { + // empty path return empty string + if ( ( line == null ) || ( line.length == 0 ) ) + { + return ""; + } + + // path containing one or more elements + final StringBuffer result = new StringBuffer(); + for ( int i = 0; i < line.length; i++ ) + { + if ( i > 0 ) + { + result.append( ' ' ); + } + try + { + result.append( StringUtils.quoteAndEscape( line[i], '\"' ) ); + } + catch ( Exception e ) + { + System.err.println( "Error quoting argument: " + e.getMessage() ); + } + } + return result.toString(); + } + +} Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/cli/CommandLineUtils.java ------------------------------------------------------------------------------ svn:mime-type = text/plain