Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 97188 invoked from network); 5 Oct 2009 18:56:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 5 Oct 2009 18:56:45 -0000 Received: (qmail 63098 invoked by uid 500); 5 Oct 2009 18:56:45 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 63045 invoked by uid 500); 5 Oct 2009 18:56:45 -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 63036 invoked by uid 99); 5 Oct 2009 18:56:45 -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:56:45 +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:29 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 0A4E72388A23; 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 [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... 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.0A4E72388A23@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/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 + * . + */ + +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. + *

+ * This class provides static utility methods for input/output operations, particularly buffered + * copying between sources (InputStream, Reader, String and + * byte[]) and destinations (OutputStream, Writer, + * String and byte[]). + *

+ * + *

Unless otherwise noted, these copy methods do not 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' close() 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 this + * UnixReview article

+ * + *

For each copy 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 -> faster" does not hold, even for large data + * transfers.

+ * + *

For byte-to-char methods, a copy variant allows the encoding to be selected + * (otherwise the platform default is used).

+ * + *

The copy methods use an internal buffer when copying. It is therefore advisable + * not to deliberately wrap the stream arguments to the copy methods in + * Buffered* streams. For example, don't do the + * following:

+ * + * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); + * + *

The rationale is as follows:

+ * + *

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 read requests can inexpensively get + * their data (until the buffer runs out).

+ *

However, the copy 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).

+ * + * @author Peter Donald + * @author Jeff Turner + * @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 InputStream to an OutputStream. + */ + public static void copy( final InputStream input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy bytes from an InputStream to an OutputStream. + * @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 Reader to a Writer. + */ + public static void copy( final Reader input, final Writer output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy chars from a Reader to a Writer. + * @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 InputStream to chars on a + * Writer. + * 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 InputStream to chars on a + * Writer. + * 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 InputStream to chars on a + * Writer, using the specified encoding. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 InputStream to chars on a + * Writer, using the specified encoding. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 InputStream 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 InputStream 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 InputStream as a String. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 InputStream as a String. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 InputStream as a byte[]. + */ + public static byte[] toByteArray( final InputStream input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * Get the contents of an InputStream as a byte[]. + * @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 Reader to bytes on an OutputStream, and + * flush the OutputStream. + */ + public static void copy( final Reader input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Serialize chars from a Reader to bytes on an OutputStream, and + * flush the OutputStream. + * @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 Reader as a String. + */ + public static String toString( final Reader input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * Get the contents of a Reader 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 Reader as a byte[]. + */ + public static byte[] toByteArray( final Reader input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * Get the contents of a Reader as a byte[]. + * @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 String to bytes on an OutputStream, and + * flush the OutputStream. + */ + public static void copy( final String input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Serialize chars from a String to bytes on an OutputStream, and + * flush the OutputStream. + * @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 String to a Writer. + */ + public static void copy( final String input, final Writer output ) + throws IOException + { + output.write( input ); + } + + /** + * Copy bytes from an InputStream to an + * OutputStream, 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 String as a byte[]. + */ + public static byte[] toByteArray( final String input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * Get the contents of a String as a byte[]. + * @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 byte[] to chars on a + * Writer. + * 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 byte[] to chars on a + * Writer. + * 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 byte[] to chars on a + * Writer, using the specified encoding. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 byte[] to chars on a + * Writer, using the specified encoding. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 byte[] 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 byte[] 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 byte[] as a String. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 byte[] as a String. + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry 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 byte[] to an OutputStream. + */ + public static void copy( final byte[] input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy bytes from a byte[] to an OutputStream. + * @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 + * . + */ + +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 n 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 null. + * @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 + * . + */ + +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
+ * Possible values:
+ *
    + *
  • dos
  • + *
  • mac
  • + *
  • netware
  • + *
  • os/2
  • + *
  • tandem
  • + *
  • unix
  • + *
  • windows
  • + *
  • win9x
  • + *
  • z/os
  • + *
  • os/400
  • + *
  • openvms
  • + *
+ */ + 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: + *
    + *
  • dos
  • + *
  • mac
  • + *
  • netware
  • + *
  • os/2
  • + *
  • tandem
  • + *
  • unix
  • + *
  • windows
  • + *
  • win9x
  • + *
  • z/os
  • + *
  • os/400
  • + *
  • openvms
  • + *
+ * + * @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