You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2009/10/05 20:54:56 UTC

svn commit: r821961 [18/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...

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/IOUtil.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/IOUtil.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/IOUtil.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/IOUtil.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,813 @@
+package org.apache.geronimo.system.plugin.plexus.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.codehaus.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache Turbine" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact codehaus@codehaus.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache Turbine", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.codehaus.org/>.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+/**
+ * General IO Stream manipulation.
+ * <p>
+ * This class provides static utility methods for input/output operations, particularly buffered
+ * copying between sources (<code>InputStream</code>, <code>Reader</code>, <code>String</code> and
+ * <code>byte[]</code>) and destinations (<code>OutputStream</code>, <code>Writer</code>,
+ * <code>String</code> and <code>byte[]</code>).
+ * </p>
+ *
+ * <p>Unless otherwise noted, these <code>copy</code> methods do <em>not</em> flush or close the
+ * streams. Often, doing so would require making non-portable assumptions about the streams' origin
+ * and further use. This means that both streams' <code>close()</code> methods must be called after
+ * copying. if one omits this step, then the stream resources (sockets, file descriptors) are
+ * released when the associated Stream is garbage-collected. It is not a good idea to rely on this
+ * mechanism. For a good overview of the distinction between "memory management" and "resource
+ * management", see <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this
+ * UnixReview article</a></p>
+ *
+ * <p>For each <code>copy</code> method, a variant is provided that allows the caller to specify the
+ * buffer size (the default is 4k). As the buffer size can have a fairly large impact on speed, this
+ * may be worth tweaking. Often "large buffer -&gt; faster" does not hold, even for large data
+ * transfers.</p>
+ *
+ * <p>For byte-to-char methods, a <code>copy</code> variant allows the encoding to be selected
+ * (otherwise the platform default is used).</p>
+ *
+ * <p>The <code>copy</code> methods use an internal buffer when copying. It is therefore advisable
+ * <em>not</em> to deliberately wrap the stream arguments to the <code>copy</code> methods in
+ * <code>Buffered*</code> streams. For example, don't do the
+ * following:</p>
+ *
+ * <code>copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );</code>
+ *
+ * <p>The rationale is as follows:</p>
+ *
+ * <p>Imagine that an InputStream's read() is a very expensive operation, which would usually suggest
+ * wrapping in a BufferedInputStream. The BufferedInputStream works by issuing infrequent
+ * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to
+ * fill an internal buffer, from which further <code>read</code> requests can inexpensively get
+ * their data (until the buffer runs out).</p>
+ * <p>However, the <code>copy</code> methods do the same thing, keeping an internal buffer,
+ * populated by {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers
+ * (or three if the destination stream is also buffered) is pointless, and the unnecessary buffer
+ * management hurts performance slightly (about 3%, according to some simple experiments).</p>
+ *
+ * @author <a href="mailto:peter@codehaus.org">Peter Donald</a>
+ * @author <a href="mailto:jefft@codehaus.org">Jeff Turner</a>
+ * @version $Id: IOUtil.java 7506 2008-07-09 13:31:05Z bentmann $
+ * @since 4.0
+ */
+
+/*
+ * Behold, intrepid explorers; a map of this class:
+ *
+ *       Method      Input               Output          Dependency
+ *       ------      -----               ------          -------
+ * 1     copy        InputStream         OutputStream    (primitive)
+ * 2     copy        Reader              Writer          (primitive)
+ *
+ * 3     copy        InputStream         Writer          2
+ * 4     toString    InputStream         String          3
+ * 5     toByteArray InputStream         byte[]          1
+ *
+ * 6     copy        Reader              OutputStream    2
+ * 7     toString    Reader              String          2
+ * 8     toByteArray Reader              byte[]          6
+ *
+ * 9     copy        String              OutputStream    2
+ * 10    copy        String              Writer          (trivial)
+ * 11    toByteArray String              byte[]          9
+ *
+ * 12    copy        byte[]              Writer          3
+ * 13    toString    byte[]              String          12
+ * 14    copy        byte[]              OutputStream    (trivial)
+ *
+ *
+ * Note that only the first two methods shuffle bytes; the rest use these two, or (if possible) copy
+ * using native Java copy methods. As there are method variants to specify buffer size and encoding,
+ * each row may correspond to up to 4 methods.
+ *
+ */
+
+public final class IOUtil
+{
+    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+    /**
+     * Private constructor to prevent instantiation.
+     */
+    private IOUtil()
+    {
+    }
+
+    ///////////////////////////////////////////////////////////////
+    // Core copy methods
+    ///////////////////////////////////////////////////////////////
+
+    /**
+     * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
+     */
+    public static void copy( final InputStream input, final OutputStream output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final InputStream input,
+                             final OutputStream output,
+                             final int bufferSize )
+        throws IOException
+    {
+        final byte[] buffer = new byte[bufferSize];
+        int n = 0;
+        while ( -1 != ( n = input.read( buffer ) ) )
+        {
+            output.write( buffer, 0, n );
+        }
+    }
+
+    /**
+     * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
+     */
+    public static void copy( final Reader input, final Writer output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final Reader input, final Writer output, final int bufferSize )
+        throws IOException
+    {
+        final char[] buffer = new char[bufferSize];
+        int n = 0;
+        while ( -1 != ( n = input.read( buffer ) ) )
+        {
+            output.write( buffer, 0, n );
+        }
+        output.flush();
+    }
+
+    ///////////////////////////////////////////////////////////////
+    // Derived copy methods
+    // InputStream -> *
+    ///////////////////////////////////////////////////////////////
+
+
+    ///////////////////////////////////////////////////////////////
+    // InputStream -> Writer
+
+    /**
+     * Copy and convert bytes from an <code>InputStream</code> to chars on a
+     * <code>Writer</code>.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     */
+    public static void copy( final InputStream input, final Writer output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Copy and convert bytes from an <code>InputStream</code> to chars on a
+     * <code>Writer</code>.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final InputStream input, final Writer output, final int bufferSize )
+        throws IOException
+    {
+        final InputStreamReader in = new InputStreamReader( input );
+        copy( in, output, bufferSize );
+    }
+
+    /**
+     * Copy and convert bytes from an <code>InputStream</code> to chars on a
+     * <code>Writer</code>, using the specified encoding.
+     * @param encoding The name of a supported character encoding. See the
+     * <a href="http://www.iana.org/assignments/character-sets">IANA
+     * Charset Registry</a> for a list of valid encoding types.
+     */
+    public static void copy( final InputStream input, final Writer output, final String encoding )
+        throws IOException
+    {
+        final InputStreamReader in = new InputStreamReader( input, encoding );
+        copy( in, output );
+    }
+
+    /**
+     * Copy and convert bytes from an <code>InputStream</code> to chars on a
+     * <code>Writer</code>, using the specified encoding.
+     * @param encoding The name of a supported character encoding. See the
+     *        <a href="http://www.iana.org/assignments/character-sets">IANA
+     *        Charset Registry</a> for a list of valid encoding types.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final InputStream input,
+                             final Writer output,
+                             final String encoding,
+                             final int bufferSize )
+        throws IOException
+    {
+        final InputStreamReader in = new InputStreamReader( input, encoding );
+        copy( in, output, bufferSize );
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // InputStream -> String
+
+    /**
+     * Get the contents of an <code>InputStream</code> as a String.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     */
+    public static String toString( final InputStream input )
+        throws IOException
+    {
+        return toString( input, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of an <code>InputStream</code> as a String.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static String toString( final InputStream input, final int bufferSize )
+        throws IOException
+    {
+        final StringWriter sw = new StringWriter();
+        copy( input, sw, bufferSize );
+        return sw.toString();
+    }
+
+    /**
+     * Get the contents of an <code>InputStream</code> as a String.
+     * @param encoding The name of a supported character encoding. See the
+     *    <a href="http://www.iana.org/assignments/character-sets">IANA
+     *    Charset Registry</a> for a list of valid encoding types.
+     */
+    public static String toString( final InputStream input, final String encoding )
+        throws IOException
+    {
+        return toString( input, encoding, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of an <code>InputStream</code> as a String.
+     * @param encoding The name of a supported character encoding. See the
+     *   <a href="http://www.iana.org/assignments/character-sets">IANA
+     *   Charset Registry</a> for a list of valid encoding types.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static String toString( final InputStream input,
+                                   final String encoding,
+                                   final int bufferSize )
+        throws IOException
+    {
+        final StringWriter sw = new StringWriter();
+        copy( input, sw, encoding, bufferSize );
+        return sw.toString();
+    }
+
+    ///////////////////////////////////////////////////////////////
+    // InputStream -> byte[]
+
+    /**
+     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
+     */
+    public static byte[] toByteArray( final InputStream input )
+        throws IOException
+    {
+        return toByteArray( input, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static byte[] toByteArray( final InputStream input, final int bufferSize )
+        throws IOException
+    {
+        final ByteArrayOutputStream output = new ByteArrayOutputStream();
+        copy( input, output, bufferSize );
+        return output.toByteArray();
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // Derived copy methods
+    // Reader -> *
+    ///////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////
+    // Reader -> OutputStream
+    /**
+     * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and
+     * flush the <code>OutputStream</code>.
+     */
+    public static void copy( final Reader input, final OutputStream output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and
+     * flush the <code>OutputStream</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final Reader input, final OutputStream output, final int bufferSize )
+        throws IOException
+    {
+        final OutputStreamWriter out = new OutputStreamWriter( output );
+        copy( input, out, bufferSize );
+        // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
+        // here.
+        out.flush();
+    }
+
+    ///////////////////////////////////////////////////////////////
+    // Reader -> String
+    /**
+     * Get the contents of a <code>Reader</code> as a String.
+     */
+    public static String toString( final Reader input )
+        throws IOException
+    {
+        return toString( input, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of a <code>Reader</code> as a String.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static String toString( final Reader input, final int bufferSize )
+        throws IOException
+    {
+        final StringWriter sw = new StringWriter();
+        copy( input, sw, bufferSize );
+        return sw.toString();
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // Reader -> byte[]
+    /**
+     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
+     */
+    public static byte[] toByteArray( final Reader input )
+        throws IOException
+    {
+        return toByteArray( input, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static byte[] toByteArray( final Reader input, final int bufferSize )
+        throws IOException
+    {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        copy( input, output, bufferSize );
+        return output.toByteArray();
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // Derived copy methods
+    // String -> *
+    ///////////////////////////////////////////////////////////////
+
+
+    ///////////////////////////////////////////////////////////////
+    // String -> OutputStream
+
+    /**
+     * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and
+     * flush the <code>OutputStream</code>.
+     */
+    public static void copy( final String input, final OutputStream output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and
+     * flush the <code>OutputStream</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final String input, final OutputStream output, final int bufferSize )
+        throws IOException
+    {
+        final StringReader in = new StringReader( input );
+        final OutputStreamWriter out = new OutputStreamWriter( output );
+        copy( in, out, bufferSize );
+        // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
+        // here.
+        out.flush();
+    }
+
+
+
+    ///////////////////////////////////////////////////////////////
+    // String -> Writer
+
+    /**
+     * Copy chars from a <code>String</code> to a <code>Writer</code>.
+     */
+    public static void copy( final String input, final Writer output )
+        throws IOException
+    {
+        output.write( input );
+    }
+
+    /**
+     * Copy bytes from an <code>InputStream</code> to an
+     * <code>OutputStream</code>, with buffering.
+     * This is equivalent to passing a
+     * {@link java.io.BufferedInputStream} and
+     * {@link java.io.BufferedOutputStream} to {@link #copy(InputStream, OutputStream)},
+     * and flushing the output stream afterwards. The streams are not closed
+     * after the copy.
+     * @deprecated Buffering streams is actively harmful! See the class description as to why. Use
+     * {@link #copy(InputStream, OutputStream)} instead.
+     */
+    public static void bufferedCopy( final InputStream input, final OutputStream output )
+        throws IOException
+    {
+        final BufferedInputStream in = new BufferedInputStream( input );
+        final BufferedOutputStream out = new BufferedOutputStream( output );
+        copy( in, out );
+        out.flush();
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // String -> byte[]
+    /**
+     * Get the contents of a <code>String</code> as a <code>byte[]</code>.
+     */
+    public static byte[] toByteArray( final String input )
+        throws IOException
+    {
+        return toByteArray( input, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of a <code>String</code> as a <code>byte[]</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static byte[] toByteArray( final String input, final int bufferSize )
+        throws IOException
+    {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        copy( input, output, bufferSize );
+        return output.toByteArray();
+    }
+
+
+
+    ///////////////////////////////////////////////////////////////
+    // Derived copy methods
+    // byte[] -> *
+    ///////////////////////////////////////////////////////////////
+
+
+    ///////////////////////////////////////////////////////////////
+    // byte[] -> Writer
+
+    /**
+     * Copy and convert bytes from a <code>byte[]</code> to chars on a
+     * <code>Writer</code>.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     */
+    public static void copy( final byte[] input, final Writer output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Copy and convert bytes from a <code>byte[]</code> to chars on a
+     * <code>Writer</code>.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final byte[] input, final Writer output, final int bufferSize )
+        throws IOException
+    {
+        final ByteArrayInputStream in = new ByteArrayInputStream( input );
+        copy( in, output, bufferSize );
+    }
+
+    /**
+     * Copy and convert bytes from a <code>byte[]</code> to chars on a
+     * <code>Writer</code>, using the specified encoding.
+     * @param encoding The name of a supported character encoding. See the
+     * <a href="http://www.iana.org/assignments/character-sets">IANA
+     * Charset Registry</a> for a list of valid encoding types.
+     */
+    public static void copy( final byte[] input, final Writer output, final String encoding )
+        throws IOException
+    {
+        final ByteArrayInputStream in = new ByteArrayInputStream( input );
+        copy( in, output, encoding );
+    }
+
+    /**
+     * Copy and convert bytes from a <code>byte[]</code> to chars on a
+     * <code>Writer</code>, using the specified encoding.
+     * @param encoding The name of a supported character encoding. See the
+     *        <a href="http://www.iana.org/assignments/character-sets">IANA
+     *        Charset Registry</a> for a list of valid encoding types.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final byte[] input,
+                             final Writer output,
+                             final String encoding,
+                             final int bufferSize )
+        throws IOException
+    {
+        final ByteArrayInputStream in = new ByteArrayInputStream( input );
+        copy( in, output, encoding, bufferSize );
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // byte[] -> String
+
+    /**
+     * Get the contents of a <code>byte[]</code> as a String.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     */
+    public static String toString( final byte[] input )
+        throws IOException
+    {
+        return toString( input, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of a <code>byte[]</code> as a String.
+     * The platform's default encoding is used for the byte-to-char conversion.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static String toString( final byte[] input, final int bufferSize )
+        throws IOException
+    {
+        final StringWriter sw = new StringWriter();
+        copy( input, sw, bufferSize );
+        return sw.toString();
+    }
+
+    /**
+     * Get the contents of a <code>byte[]</code> as a String.
+     * @param encoding The name of a supported character encoding. See the
+     *    <a href="http://www.iana.org/assignments/character-sets">IANA
+     *    Charset Registry</a> for a list of valid encoding types.
+     */
+    public static String toString( final byte[] input, final String encoding )
+        throws IOException
+    {
+        return toString( input, encoding, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Get the contents of a <code>byte[]</code> as a String.
+     * @param encoding The name of a supported character encoding. See the
+     *   <a href="http://www.iana.org/assignments/character-sets">IANA
+     *   Charset Registry</a> for a list of valid encoding types.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static String toString( final byte[] input,
+                                   final String encoding,
+                                   final int bufferSize )
+        throws IOException
+    {
+        final StringWriter sw = new StringWriter();
+        copy( input, sw, encoding, bufferSize );
+        return sw.toString();
+    }
+
+
+    ///////////////////////////////////////////////////////////////
+    // byte[] -> OutputStream
+
+    /**
+     * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
+     */
+    public static void copy( final byte[] input, final OutputStream output )
+        throws IOException
+    {
+        copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    /**
+     * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
+     * @param bufferSize Size of internal buffer to use.
+     */
+    public static void copy( final byte[] input,
+                             final OutputStream output,
+                             final int bufferSize )
+        throws IOException
+    {
+        output.write( input );
+    }
+
+    /**
+     * Compare the contents of two Streams to determine if they are equal or not.
+     *
+     * @param input1 the first stream
+     * @param input2 the second stream
+     * @return true if the content of the streams are equal or they both don't exist, false otherwise
+     */
+    public static boolean contentEquals( final InputStream input1,
+                                         final InputStream input2 )
+        throws IOException
+    {
+        final InputStream bufferedInput1 = new BufferedInputStream( input1 );
+        final InputStream bufferedInput2 = new BufferedInputStream( input2 );
+
+        int ch = bufferedInput1.read();
+        while ( -1 != ch )
+        {
+            final int ch2 = bufferedInput2.read();
+            if ( ch != ch2 )
+            {
+                return false;
+            }
+            ch = bufferedInput1.read();
+        }
+
+        final int ch2 = bufferedInput2.read();
+        if ( -1 != ch2 )
+        {
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // closeXXX()
+    // ----------------------------------------------------------------------
+
+    /**
+     * Closes the input stream. The input stream can be null and any IOException's will be swallowed.
+     * 
+     * @param inputStream The stream to close.
+     */
+    public static void close( InputStream inputStream )
+    {
+        if ( inputStream == null )
+        {
+            return;
+        }
+
+        try
+        {
+            inputStream.close();
+        }
+        catch( IOException ex )
+        {
+            // ignore
+        }
+    }
+
+    /**
+     * Closes the output stream. The output stream can be null and any IOException's will be swallowed.
+     * 
+     * @param outputStream The stream to close.
+     */
+    public static void close( OutputStream outputStream )
+    {
+        if ( outputStream == null )
+        {
+            return;
+        }
+
+        try
+        {
+            outputStream.close();
+        }
+        catch( IOException ex )
+        {
+            // ignore
+        }
+    }
+
+    /**
+     * Closes the reader. The reader can be null and any IOException's will be swallowed.
+     * 
+     * @param reader The reader to close.
+     */
+    public static void close( Reader reader )
+    {
+        if ( reader == null )
+        {
+            return;
+        }
+
+        try
+        {
+            reader.close();
+        }
+        catch( IOException ex )
+        {
+            // ignore
+        }
+    }
+
+    /**
+     * Closes the writer. The writer can be null and any IOException's will be swallowed.
+     * 
+     * @param writer The writer to close.
+     */
+    public static void close( Writer writer )
+    {
+        if ( writer == null )
+        {
+            return;
+        }
+
+        try
+        {
+            writer.close();
+        }
+        catch( IOException ex )
+        {
+            // ignore
+        }
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/IOUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/IOUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/IOUtil.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/InterpolationFilterReader.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/InterpolationFilterReader.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/InterpolationFilterReader.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/InterpolationFilterReader.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,317 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.codehaus.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact codehaus@codehaus.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.codehaus.org/>.
+ */
+
+package org.apache.geronimo.system.plugin.plexus.util;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ */
+public class InterpolationFilterReader
+    extends FilterReader
+{
+    /** replacement text from a token */
+    private String replaceData = null;
+
+    /** Index into replacement data */
+    private int replaceIndex = -1;
+
+    /** Index into previous data */
+    private int previousIndex = -1;
+
+    /** Hashtable to hold the replacee-replacer pairs (String to String). */
+    private Map variables = new HashMap();
+
+    /** Character marking the beginning of a token. */
+    private String beginToken;
+
+    /** Character marking the end of a token. */
+    private String endToken;
+
+    /** Length of begin token. */
+    private int beginTokenLength;
+
+    /** Length of end token. */
+    private int endTokenLength;
+
+    /** Default begin token. */
+    private static String DEFAULT_BEGIN_TOKEN = "${";
+
+    /** Default end token. */
+    private static String DEFAULT_END_TOKEN = "}";
+
+    public InterpolationFilterReader( Reader in, Map variables, String beginToken, String endToken )
+    {
+        super( in );
+
+        this.variables = variables;
+        this.beginToken = beginToken;
+        this.endToken = endToken;
+
+        beginTokenLength = beginToken.length();
+        endTokenLength = endToken.length();
+    }
+
+    public InterpolationFilterReader( Reader in, Map variables )
+    {
+        this( in, variables, DEFAULT_BEGIN_TOKEN, DEFAULT_END_TOKEN );
+    }
+
+    /**
+     * Skips characters.  This method will block until some characters are
+     * available, an I/O error occurs, or the end of the stream is reached.
+     *
+     * @param  n  The number of characters to skip
+     *
+     * @return    the number of characters actually skipped
+     *
+     * @exception  IllegalArgumentException  If <code>n</code> is negative.
+     * @exception  IOException  If an I/O error occurs
+     */
+    public long skip( long n ) throws IOException
+    {
+        if ( n < 0L )
+        {
+            throw new IllegalArgumentException( "skip value is negative" );
+        }
+
+        for ( long i = 0; i < n; i++ )
+        {
+            if ( read() == -1 )
+            {
+                return i;
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Reads characters into a portion of an array.  This method will block
+     * until some input is available, an I/O error occurs, or the end of the
+     * stream is reached.
+     *
+     * @param      cbuf  Destination buffer to write characters to.
+     *                   Must not be <code>null</code>.
+     * @param      off   Offset at which to start storing characters.
+     * @param      len   Maximum number of characters to read.
+     *
+     * @return     the number of characters read, or -1 if the end of the
+     *             stream has been reached
+     *
+     * @exception  IOException  If an I/O error occurs
+     */
+    public int read( char cbuf[],
+                     int off,
+                     int len )
+        throws IOException
+    {
+        for ( int i = 0; i < len; i++ )
+        {
+            int ch = read();
+            if ( ch == -1 )
+            {
+                if ( i == 0 )
+                {
+                    return -1;
+                }
+                else
+                {
+                    return i;
+                }
+            }
+            cbuf[off + i] = (char) ch;
+        }
+        return len;
+    }
+
+    /**
+     * Returns the next character in the filtered stream, replacing tokens
+     * from the original stream.
+     *
+     * @return the next character in the resulting stream, or -1
+     * if the end of the resulting stream has been reached
+     *
+     * @exception IOException if the underlying stream throws an IOException
+     * during reading
+     */
+    public int read() throws IOException
+    {
+        if ( replaceIndex != -1 && replaceIndex < replaceData.length() )
+        {
+            int ch = replaceData.charAt( replaceIndex++ );
+            if ( replaceIndex >= replaceData.length() )
+            {
+                replaceIndex = -1;
+            }
+            return ch;
+        }
+
+        int ch = -1;
+        if ( previousIndex != -1 && previousIndex < endTokenLength )
+        {
+            ch = endToken.charAt( previousIndex++ );
+        }
+        else
+        {
+            ch = in.read();
+        }
+
+        if ( ch == beginToken.charAt( 0 ) )
+        {
+            StringBuffer key = new StringBuffer();
+
+            int beginTokenMatchPos = 1;
+
+            do
+            {
+                if ( previousIndex != -1 && previousIndex < endTokenLength )
+                {
+                    ch = endToken.charAt( previousIndex++ );
+                }
+                else
+                {
+                    ch = in.read();
+                }
+                if ( ch != -1 )
+                {
+                    key.append( (char) ch );
+
+                    if ( ( beginTokenMatchPos < beginTokenLength ) &&
+                            ( ch != beginToken.charAt( beginTokenMatchPos++ ) ) )
+                    {
+                        ch = -1; // not really EOF but to trigger code below
+                        break;
+                    }
+                }
+                else
+                {
+                    break;
+                }
+            }
+            while ( ch != endToken.charAt( 0 ) );
+
+            // now test endToken
+            if ( ch != -1 && endTokenLength > 1 )
+            {
+                int endTokenMatchPos = 1;
+
+                do
+                {
+                    if ( previousIndex != -1 && previousIndex < endTokenLength )
+                    {
+                        ch = endToken.charAt( previousIndex++ );
+                    }
+                    else
+                    {
+                        ch = in.read();
+                    }
+
+                    if ( ch != -1 )
+                    {
+                        key.append( (char) ch );
+
+                        if ( ch != endToken.charAt( endTokenMatchPos++ ) )
+                        {
+                            ch = -1; // not really EOF but to trigger code below
+                            break;
+                        }
+
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+                while ( endTokenMatchPos < endTokenLength );
+            }
+
+            // There is nothing left to read so we have the situation where the begin/end token
+            // are in fact the same and as there is nothing left to read we have got ourselves
+            // end of a token boundary so let it pass through.
+            if ( ch == -1 )
+            {
+                replaceData = key.toString();
+                replaceIndex = 0;
+                return beginToken.charAt( 0 );
+            }
+
+            String variableKey = key.substring( beginTokenLength - 1, key.length() - endTokenLength );
+
+            Object o = variables.get(variableKey);
+            if ( o != null )
+            {
+                String value = o.toString();
+                if ( value.length() != 0 )
+                {
+                    replaceData = value;
+                    replaceIndex = 0;
+                }
+                return read();
+            }
+            else
+            {
+                previousIndex = 0;
+                replaceData = key.substring(0, key.length() - endTokenLength );
+                replaceIndex = 0;
+                return beginToken.charAt(0);
+            }
+        }
+
+        return ch;
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/InterpolationFilterReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/InterpolationFilterReader.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/InterpolationFilterReader.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/LineOrientedInterpolatingReader.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/LineOrientedInterpolatingReader.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/LineOrientedInterpolatingReader.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/LineOrientedInterpolatingReader.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,418 @@
+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 org.apache.geronimo.system.plugin.plexus.util.reflection.Reflector;
+import org.apache.geronimo.system.plugin.plexus.util.reflection.ReflectorException;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * @author jdcasey Created on Feb 3, 2005
+ */
+public class LineOrientedInterpolatingReader
+    extends FilterReader
+{
+    public static final String DEFAULT_START_DELIM = "${";
+
+    public static final String DEFAULT_END_DELIM = "}";
+
+    public static final String DEFAULT_ESCAPE_SEQ = "\\";
+
+    private static final char CARRIAGE_RETURN_CHAR = '\r';
+
+    private static final char NEWLINE_CHAR = '\n';
+
+    private final PushbackReader pushbackReader;
+
+    private final Map context;
+
+    private final String startDelim;
+
+    private final String endDelim;
+
+    private final String escapeSeq;
+
+    private final int minExpressionSize;
+
+    private final Reflector reflector;
+
+    private int lineIdx = -1;
+
+    private String line;
+
+    public LineOrientedInterpolatingReader( Reader reader, Map context, String startDelim, String endDelim,
+                                           String escapeSeq )
+    {
+        super( reader );
+
+        this.startDelim = startDelim;
+
+        this.endDelim = endDelim;
+
+        this.escapeSeq = escapeSeq;
+
+        // Expressions have to be at least this size...
+        this.minExpressionSize = startDelim.length() + endDelim.length() + 1;
+
+        this.context = Collections.unmodifiableMap( context );
+
+        this.reflector = new Reflector();
+
+        if ( reader instanceof PushbackReader )
+        {
+            this.pushbackReader = (PushbackReader) reader;
+        }
+        else
+        {
+            this.pushbackReader = new PushbackReader( reader, 1 );
+        }
+    }
+
+    public LineOrientedInterpolatingReader( Reader reader, Map context, String startDelim, String endDelim )
+    {
+        this( reader, context, startDelim, endDelim, DEFAULT_ESCAPE_SEQ );
+    }
+
+    public LineOrientedInterpolatingReader( Reader reader, Map context )
+    {
+        this( reader, context, DEFAULT_START_DELIM, DEFAULT_END_DELIM, DEFAULT_ESCAPE_SEQ );
+    }
+
+    public int read() throws IOException
+    {
+        if ( line == null || lineIdx >= line.length() )
+        {
+            readAndInterpolateLine();
+        }
+
+        int next = -1;
+
+        if ( line != null && lineIdx < line.length() )
+        {
+            next = line.charAt( lineIdx++ );
+        }
+
+        return next;
+    }
+
+    public int read( char[] cbuf, int off, int len ) throws IOException
+    {
+        int fillCount = 0;
+
+        for ( int i = off; i < off + len; i++ )
+        {
+            int next = read();
+            if ( next > -1 )
+            {
+                cbuf[i] = (char) next;
+            }
+            else
+            {
+                break;
+            }
+
+            fillCount++;
+        }
+
+        if ( fillCount == 0 )
+        {
+            fillCount = -1;
+        }
+
+        return fillCount;
+    }
+
+    public long skip( long n ) throws IOException
+    {
+        long skipCount = 0;
+
+        for ( long i = 0; i < n; i++ )
+        {
+            int next = read();
+
+            if ( next < 0 )
+            {
+                break;
+            }
+
+            skipCount++;
+        }
+
+        return skipCount;
+    }
+
+    private void readAndInterpolateLine() throws IOException
+    {
+        String rawLine = readLine();
+
+        if(rawLine != null)
+        {
+            Set expressions = parseForExpressions( rawLine );
+
+            Map evaluatedExpressions = evaluateExpressions( expressions );
+
+            String interpolated = replaceWithInterpolatedValues( rawLine, evaluatedExpressions );
+
+            if ( interpolated != null && interpolated.length() > 0 )
+            {
+                line = interpolated;
+                lineIdx = 0;
+            }
+        }
+        else
+        {
+            line = null;
+            lineIdx = -1;
+        }
+    }
+
+    private String readLine() throws IOException
+    {
+        StringBuffer lineBuffer = new StringBuffer( 40 ); // half of the "normal" line maxsize
+        int next = -1;
+
+        boolean lastWasCR = false;
+        while ( ( next = pushbackReader.read() ) > -1 )
+        {
+            char c = (char) next;
+
+            if ( c == CARRIAGE_RETURN_CHAR )
+            {
+                lastWasCR = true;
+                lineBuffer.append( c );
+            }
+            else if ( c == NEWLINE_CHAR )
+            {
+                lineBuffer.append( c );
+                break; // end of line.
+            }
+            else if ( lastWasCR )
+            {
+                pushbackReader.unread( c );
+                break;
+            }
+            else
+            {
+                lineBuffer.append( c );
+            }
+        }
+
+        if ( lineBuffer.length() < 1 )
+        {
+            return null;
+        }
+        else
+        {
+            return lineBuffer.toString();
+        }
+    }
+
+    private String replaceWithInterpolatedValues( String rawLine, Map evaluatedExpressions )
+    {
+        String result = rawLine;
+
+        for ( Iterator it = evaluatedExpressions.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+
+            String expression = (String) entry.getKey();
+
+            String value = String.valueOf( entry.getValue() );
+
+            result = findAndReplaceUnlessEscaped( result, expression, value );
+        }
+
+        return result;
+    }
+
+    private Map evaluateExpressions( Set expressions )
+    {
+        Map evaluated = new TreeMap();
+
+        for ( Iterator it = expressions.iterator(); it.hasNext(); )
+        {
+            String rawExpression = (String) it.next();
+
+            String realExpression = rawExpression.substring( startDelim.length(), rawExpression.length()
+                - endDelim.length() );
+
+            String[] parts = realExpression.split( "\\." );
+            if ( parts.length > 0 )
+            {
+                Object value = context.get( parts[0] );
+
+                if ( value != null )
+                {
+                    for ( int i = 1; i < parts.length; i++ )
+                    {
+                        try
+                        {
+                            value = reflector.getObjectProperty( value, parts[i] );
+
+                            if ( value == null )
+                            {
+                                break;
+                            }
+                        }
+                        catch ( ReflectorException e )
+                        {
+                            // TODO: Fix this! It should report, but not interrupt.
+                            e.printStackTrace();
+
+                            break;
+                        }
+                    }
+
+                    evaluated.put( rawExpression, value );
+                }
+            }
+        }
+
+        return evaluated;
+    }
+
+    private Set parseForExpressions( String rawLine )
+    {
+        Set expressions = new HashSet();
+
+        if ( rawLine != null )
+        {
+            int placeholder = -1;
+
+            do
+            {
+                // find the beginning of the next expression.
+                int start = findDelimiter( rawLine, startDelim, placeholder );
+
+                // if we can't find a start-delimiter, then there is no valid expression. Ignore everything else.
+                if ( start < 0 )
+                {
+                    // no expression found.
+                    break;
+                }
+
+                // find the end of the next expression.
+                int end = findDelimiter( rawLine, endDelim, start + 1 );
+
+                // if we can't find an end-delimiter, then this is not a valid expression. Ignore it.
+                if ( end < 0 )
+                {
+                    // no VALID expression found.
+                    break;
+                }
+
+                // if we reach this point, we have a valid start and end position, which
+                // means we have a valid expression. So, we add it to the set of
+                // expressions in need of evaluation.
+                expressions.add( rawLine.substring( start, end + endDelim.length() ) );
+
+                // increment the placeholder so we can look beyond this expression.
+                placeholder = end + 1;
+            } while ( placeholder < rawLine.length() - minExpressionSize );
+        }
+
+        return expressions;
+    }
+
+    private int findDelimiter( String rawLine, String delimiter, int lastPos )
+    {
+        int placeholder = lastPos;
+
+        int position = -1;
+        do
+        {
+            position = rawLine.indexOf( delimiter, placeholder );
+
+            if ( position < 0 )
+            {
+                break;
+            }
+            else
+            {
+                int escEndIdx = rawLine.indexOf( escapeSeq, placeholder ) + escapeSeq.length();
+
+                if ( escEndIdx > escapeSeq.length() - 1 && escEndIdx == position )
+                {
+                    placeholder = position + 1;
+                    position = -1;
+                }
+            }
+
+        } while ( position < 0 && placeholder < rawLine.length() - endDelim.length() );
+        // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        // use length() - endDelim.length() b/c otherwise there is nothing left to search.
+
+        return position;
+    }
+
+    private String findAndReplaceUnlessEscaped(String rawLine, String search, String replace)
+    {
+        StringBuffer lineBuffer = new StringBuffer( (int)(rawLine.length() * 1.5) );
+
+        int lastReplacement = -1;
+
+        do
+        {
+            int nextReplacement = rawLine.indexOf( search, lastReplacement + 1 );
+            if(nextReplacement > -1)
+            {
+                if(lastReplacement < 0)
+                {
+                    lastReplacement = 0;
+                }
+
+                lineBuffer.append( rawLine.substring( lastReplacement, nextReplacement ) );
+
+                int escIdx = rawLine.indexOf( escapeSeq, lastReplacement + 1 );
+                if(escIdx > -1 && escIdx + escapeSeq.length() == nextReplacement)
+                {
+                    lineBuffer.setLength( lineBuffer.length() - escapeSeq.length() );
+                    lineBuffer.append( search );
+                }
+                else
+                {
+                    lineBuffer.append( replace );
+                }
+
+                lastReplacement = nextReplacement + search.length();
+            }
+            else
+            {
+                break;
+            }
+        }
+        while(lastReplacement > -1);
+
+        if( lastReplacement < rawLine.length() )
+        {
+            lineBuffer.append( rawLine.substring( lastReplacement ) );
+        }
+
+        return lineBuffer.toString();
+    }
+
+}
\ 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/LineOrientedInterpolatingReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/LineOrientedInterpolatingReader.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/LineOrientedInterpolatingReader.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/Os.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/Os.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/Os.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/Os.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,439 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.geronimo.system.plugin.plexus.util;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * Condition that tests the OS type.
+ *
+ * @author Stefan Bodewig
+ * @author Magesh Umasankar
+ * @author Brian Fox
+ * @since 1.0
+ * @version $Revision$
+ */
+public class Os
+{
+    // define the families for easier reference
+    public static final String FAMILY_DOS = "dos";
+
+    public static final String FAMILY_MAC = "mac";
+
+    public static final String FAMILY_NETWARE = "netware";
+
+    public static final String FAMILY_OS2 = "os/2";
+
+    public static final String FAMILY_TANDEM = "tandem";
+
+    public static final String FAMILY_UNIX = "unix";
+
+    public static final String FAMILY_WINDOWS = "windows";
+
+    public static final String FAMILY_WIN9X = "win9x";
+
+    public static final String FAMILY_ZOS = "z/os";
+
+    public static final String FAMILY_OS400 = "os/400";
+
+    public static final String FAMILY_OPENVMS = "openvms";
+
+    // store the valid families
+    private static final Set validFamilies = setValidFamilies();
+
+    // get the current info
+    private static final String PATH_SEP = System.getProperty( "path.separator" );
+
+    public static final String OS_NAME = System.getProperty( "os.name" ).toLowerCase( Locale.US );
+
+    public static final String OS_ARCH = System.getProperty( "os.arch" ).toLowerCase( Locale.US );
+
+    public static final String OS_VERSION = System.getProperty( "os.version" ).toLowerCase( Locale.US );
+
+    // Make sure this method is called after static fields it depends on have been set!
+    public static final String OS_FAMILY = getOsFamily();
+
+    private String family;
+
+    private String name;
+
+    private String version;
+
+    private String arch;
+
+    /**
+     * Default constructor
+     */
+    public Os()
+    {
+    }
+
+    /**
+     * Constructor that sets the family attribute
+     * 
+     * @param family a String value
+     */
+    public Os( String family )
+    {
+        setFamily( family );
+    }
+
+    /**
+     * Initializes the set of valid families.
+     */
+    private static Set setValidFamilies()
+    {
+        Set valid = new HashSet();
+        valid.add( FAMILY_DOS );
+        valid.add( FAMILY_MAC );
+        valid.add( FAMILY_NETWARE );
+        valid.add( FAMILY_OS2 );
+        valid.add( FAMILY_TANDEM );
+        valid.add( FAMILY_UNIX );
+        valid.add( FAMILY_WINDOWS );
+        valid.add( FAMILY_WIN9X );
+        valid.add( FAMILY_ZOS );
+        valid.add( FAMILY_OS400 );
+        valid.add( FAMILY_OPENVMS );
+
+        return valid;
+    }
+
+    /**
+     * Sets the desired OS family type
+     * 
+     * @param f The OS family type desired<br />
+     *            Possible values:<br />
+     *            <ul>
+     *            <li>dos</li>
+     *            <li>mac</li>
+     *            <li>netware</li>
+     *            <li>os/2</li>
+     *            <li>tandem</li>
+     *            <li>unix</li>
+     *            <li>windows</li>
+     *            <li>win9x</li>
+     *            <li>z/os</li>
+     *            <li>os/400</li>
+     *            <li>openvms</li>
+     *            </ul>
+     */
+    public void setFamily( String f )
+    {
+        family = f.toLowerCase( Locale.US );
+    }
+
+    /**
+     * Sets the desired OS name
+     * 
+     * @param name The OS name
+     */
+    public void setName( String name )
+    {
+        this.name = name.toLowerCase( Locale.US );
+    }
+
+    /**
+     * Sets the desired OS architecture
+     * 
+     * @param arch The OS architecture
+     */
+    public void setArch( String arch )
+    {
+        this.arch = arch.toLowerCase( Locale.US );
+    }
+
+    /**
+     * Sets the desired OS version
+     * 
+     * @param version The OS version
+     */
+    public void setVersion( String version )
+    {
+        this.version = version.toLowerCase( Locale.US );
+    }
+
+    /**
+     * Determines if the current OS matches the type of that
+     * set in setFamily.
+     * 
+     * @see Os#setFamily(String)
+     */
+    public boolean eval()
+        throws Exception
+    {
+        return isOs( family, name, arch, version );
+    }
+
+    /**
+     * Determines if the current OS matches the given OS
+     * family.
+     * 
+     * @param family the family to check for
+     * @return true if the OS matches
+     * @since 1.0
+     */
+    public static boolean isFamily( String family )
+    {
+        return isOs( family, null, null, null );
+    }
+
+    /**
+     * Determines if the current OS matches the given OS
+     * name.
+     * 
+     * @param name the OS name to check for
+     * @return true if the OS matches
+     * @since 1.0
+     */
+    public static boolean isName( String name )
+    {
+        return isOs( null, name, null, null );
+    }
+
+    /**
+     * Determines if the current OS matches the given OS
+     * architecture.
+     * 
+     * @param arch the OS architecture to check for
+     * @return true if the OS matches
+     * @since 1.0
+     */
+    public static boolean isArch( String arch )
+    {
+        return isOs( null, null, arch, null );
+    }
+
+    /**
+     * Determines if the current OS matches the given OS
+     * version.
+     * 
+     * @param version the OS version to check for
+     * @return true if the OS matches
+     * @since 1.0
+     */
+    public static boolean isVersion( String version )
+    {
+        return isOs( null, null, null, version );
+    }
+
+    /**
+     * Determines if the current OS matches the given OS
+     * family, name, architecture and version.
+     * 
+     * The name, archictecture and version are compared to
+     * the System properties os.name, os.version and os.arch
+     * in a case-independent way.
+     * 
+     * @param family The OS family
+     * @param name The OS name
+     * @param arch The OS architecture
+     * @param version The OS version
+     * @return true if the OS matches
+     * @since 1.0
+     */
+    public static boolean isOs( String family, String name, String arch, String version )
+    {
+        boolean retValue = false;
+
+        if ( family != null || name != null || arch != null || version != null )
+        {
+
+            boolean isFamily = true;
+            boolean isName = true;
+            boolean isArch = true;
+            boolean isVersion = true;
+
+            if ( family != null )
+            {
+                if ( family.equalsIgnoreCase( FAMILY_WINDOWS ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_WINDOWS ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_OS2 ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_OS2 ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_NETWARE ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_NETWARE ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_DOS ) )
+                {
+                    isFamily = PATH_SEP.equals( ";" ) && !isFamily( FAMILY_NETWARE );
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_MAC ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_MAC ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_TANDEM ) )
+                {
+                    isFamily = OS_NAME.indexOf( "nonstop_kernel" ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_UNIX ) )
+                {
+                    isFamily = PATH_SEP.equals( ":" ) && !isFamily( FAMILY_OPENVMS )
+                        && ( !isFamily( FAMILY_MAC ) || OS_NAME.endsWith( "x" ) );
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_WIN9X ) )
+                {
+                    isFamily = isFamily( FAMILY_WINDOWS )
+                        && ( OS_NAME.indexOf( "95" ) >= 0 || OS_NAME.indexOf( "98" ) >= 0
+                            || OS_NAME.indexOf( "me" ) >= 0 || OS_NAME.indexOf( "ce" ) >= 0 );
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_ZOS ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_ZOS ) > -1 || OS_NAME.indexOf( "os/390" ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_OS400 ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_OS400 ) > -1;
+                }
+                else if ( family.equalsIgnoreCase( FAMILY_OPENVMS ) )
+                {
+                    isFamily = OS_NAME.indexOf( FAMILY_OPENVMS ) > -1;
+                }
+                else
+                {
+                    isFamily = OS_NAME.indexOf( family.toLowerCase( Locale.US ) ) > -1;
+                }
+            }
+            if ( name != null )
+            {
+                isName = name.toLowerCase( Locale.US ).equals( OS_NAME );
+            }
+            if ( arch != null )
+            {
+                isArch = arch.toLowerCase( Locale.US ).equals( OS_ARCH );
+            }
+            if ( version != null )
+            {
+                isVersion = version.toLowerCase( Locale.US ).equals( OS_VERSION );
+            }
+            retValue = isFamily && isName && isArch && isVersion;
+        }
+        return retValue;
+    }
+
+    /**
+     * Helper method to determine the current OS family.
+     * 
+     * @return name of current OS family.
+     * @since 1.4.2
+     */
+    private static String getOsFamily()
+    {
+        // in case the order of static initialization is
+        // wrong, get the list
+        // safely.
+        Set families = null;
+        if ( !validFamilies.isEmpty() )
+        {
+            families = validFamilies;
+        }
+        else
+        {
+            families = setValidFamilies();
+        }
+        Iterator iter = families.iterator();
+        while ( iter.hasNext() )
+        {
+            String fam = (String) iter.next();
+            if ( Os.isFamily( fam ) )
+            {
+                return fam;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Helper method to check if the given family is in the
+     * following list:
+     * <ul>
+     * <li>dos</li>
+     * <li>mac</li>
+     * <li>netware</li>
+     * <li>os/2</li>
+     * <li>tandem</li>
+     * <li>unix</li>
+     * <li>windows</li>
+     * <li>win9x</li>
+     * <li>z/os</li>
+     * <li>os/400</li>
+     * <li>openvms</li>
+     * </ul>
+     * 
+     * @param theFamily the family to check.
+     * @return true if one of the valid families.
+     * @since 1.4.2
+     */
+    public static boolean isValidFamily( String theFamily )
+    {
+        return ( validFamilies.contains( theFamily ) );
+    }
+
+    /**
+     * @return a copy of the valid families
+     * @since 1.4.2
+     */
+    public static Set getValidFamilies()
+    {
+        return new HashSet( validFamilies );
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/Os.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/Os.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/Os.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain