You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oodt.apache.org by ke...@apache.org on 2010/07/15 01:04:26 UTC
svn commit: r964250 -
/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/
Author: kelly
Date: Wed Jul 14 23:04:25 2010
New Revision: 964250
URL: http://svn.apache.org/viewvc?rev=964250&view=rev
Log:
WIP OODT-15
Import OODT Commons I/O features: log, byte-counting streams, null streams, round-robin fixed buffer streams, base64 enc/dec strams.
Added:
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64DecodingInputStream.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64EncodingOutputStream.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/CountingOutputStream.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/FixedBufferOutputStream.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Log.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogEvent.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogFilter.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogListener.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogWriter.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullInputStream.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullOutputStream.java
incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/WriterLogger.java
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64DecodingInputStream.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64DecodingInputStream.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64DecodingInputStream.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64DecodingInputStream.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,164 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import org.apache.oodt.commons.util.Base64;
+
+/** An input stream that decodes its data from the RFC-1512 base 64 format.
+ *
+ * Wrap this input stream around another input stream, and all the bytes will be converted
+ * from their base-64 format when you read from it.
+ *
+ * @author Kelly
+ */
+public class Base64DecodingInputStream extends FilterInputStream {
+ /** Construct a base-64 decoding input stream.
+ *
+ * @param inputStream The input stream to decode.
+ */
+ public Base64DecodingInputStream(InputStream inputStream) {
+ super(inputStream);
+ }
+
+ /** Read the next byte.
+ *
+ * Decode more base-64 data and return the next decoded byte.
+ *
+ * @return The byte, or -1 on end of stream.
+ * @throws IOException If an I/O error occurs.
+ */
+ public int read() throws IOException {
+ if (in == null) throw new IOException("Can't read from a closed stream");
+
+ // If we've used up the decoded data buffer, read 4 more bytes and decode 'em.
+ if (buffer == null || index == buffer.length) {
+ byte[] streamBuf = new byte[4];
+ int toRead = 4;
+ int atIndex = 0;
+ int actuallyGot;
+ boolean firstRead = true;
+ while (toRead > 0) {
+ actuallyGot = in.read(streamBuf, atIndex, toRead);
+ if (actuallyGot == -1) {
+ if (firstRead) return -1;
+ else break;
+ }
+ firstRead = false;
+ atIndex += actuallyGot;
+ toRead -= actuallyGot;
+ }
+ buffer = Base64.decode(streamBuf);
+ if (buffer.length == 0) {
+ buffer = null;
+ return -1;
+ }
+ index = 0;
+ }
+ return buffer[index++] & 0xff;
+ }
+
+ /** Read a bunch of bytes.
+ *
+ * This decodes base-64 data from the underlying stream and puts the result into
+ * the given array.
+ *
+ * @param b The buffer to fill with decoded base-64 data.
+ * @param offset Where in the buffer to start filling.
+ * @param length How many bytes to fill.
+ * @return The actual number of decoded bytes.
+ * @throws IOException If an I/O error occurs.
+ */
+ public int read(byte[] b, int offset, int length) throws IOException {
+ if (b == null) throw new IllegalArgumentException("Can't read data into a null array");
+ if (offset < 0 || offset >= b.length)
+ throw new IndexOutOfBoundsException("Can't read data into an array with indexes 0.." + (b.length-1)
+ + " at index " + offset);
+ if (length < 0) throw new IllegalArgumentException("Can't read a negative amount of data");
+ if (offset + length > b.length)
+ throw new IndexOutOfBoundsException("Can't read data past the right edge of an array");
+ if (in == null) throw new IOException("Can't read from a closed stream");
+
+ int c = read();
+ if (c == -1) return -1;
+ b[offset] = (byte) c;
+ int i = 1;
+ try {
+ for (; i < length; ++i) {
+ c = read();
+ if (c == -1) break;
+ b[offset + i] = (byte) c;
+ }
+ } catch (IOException ignore) {}
+ return i;
+ }
+
+ /** Skip bytes.
+ *
+ * This method skips and discards <var>n</var> decoded bytes on the input stream.
+ *
+ * @param n Number of bytes to skip.
+ * @return Actual number of bytes skipped.
+ * @throws IOException If an I/O error occurs.
+ */
+ public long skip(long n) throws IOException {
+ if (in == null) throw new IOException("Can't skip past data on a closed stream");
+ int actuallySkipped = 0;
+ while (n > 0) {
+ if (read() == -1) return actuallySkipped;
+ --n;
+ ++actuallySkipped;
+ }
+ return actuallySkipped;
+ }
+
+ /** Return bytes available for reading or skipping without blocking.
+ *
+ * @return The number of bytes that can be read from this stream or skipped over
+ * on the stream without blocking.
+ * @throws IOException If an I/O error occurs.
+ */
+ public int available() throws IOException {
+ if (in == null) throw new IOException("Can't see how many bytes are available on a closed stream");
+ if (buffer != null && index < buffer.length)
+ return buffer.length - index;
+ return in.available() >= 4? 1 : 0;
+ }
+
+ /** Close this stream.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ public void close() throws IOException {
+ if (in == null) throw new IOException("Can't close a closed stream");
+ in.close();
+ in = null;
+ buffer = null;
+ }
+
+ /** Buffer for decoded data.
+ */
+ private byte[] buffer;
+
+ /** Where we'll next read out of the buffer.
+ *
+ * Since we always read 4 bytes at a time (a base-64 block), we can decode that
+ * into as many as 3 bytes, so start out the index in an invalid location.
+ */
+ private int index = 3;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64EncodingOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64EncodingOutputStream.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64EncodingOutputStream.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Base64EncodingOutputStream.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,136 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.oodt.commons.util.Base64;
+
+/** An output stream that encodes its data into RFC-1512 base 64 format.
+ *
+ * Wrap this input stream around another output stream, and all the bytes will be
+ * converted into their base-64 format when you write to it.
+ *
+ * @author Kelly
+ */
+public class Base64EncodingOutputStream extends FilterOutputStream {
+ /** Construct a base-64 encoding output stream.
+ *
+ * @param outputStream The output stream to which to write.
+ */
+ public Base64EncodingOutputStream(OutputStream outputStream) {
+ super(outputStream);
+ }
+
+ /** Write a byte of data.
+ *
+ * The byte will be encoded into base-64 format on the output.
+ *
+ * @param b The byte.
+ * @throws IOException If an I/O error occurs.
+ */
+ public void write(int b) throws IOException {
+ if (buffer == null)
+ throw new IOException("Can't write onto a closed stream");
+ buffer[index++] = (byte) b;
+ if (index == buffer.length) shipout();
+ }
+
+ /** Write a bunch of bytes.
+ *
+ * The given array of bytes will be encoded into base-64 on the output.
+ *
+ * @param b The array to write.
+ * @param offset Where in the data to start writing.
+ * @param length How many bytes to write.
+ * @throws IOException If an I/O error occurs.
+ */
+ public void write(byte[] b, int offset, int length) throws IOException {
+ if (b == null) throw new IllegalArgumentException("Can't write a null array");
+ if (offset < 0 || offset >= b.length)
+ throw new IndexOutOfBoundsException("Can't get bytes at " + offset + " in array with indexes 0.."
+ + (b.length - 1));
+ if (length < 0) throw new IllegalArgumentException("Can't write a negative amount of bytes");
+ if (offset + length > b.length)
+ throw new IndexOutOfBoundsException("Can't get bytes beyond edge of array");
+ if (buffer == null)
+ throw new IOException("Can't write onto a closed stream");
+ while (length > 0) {
+ int avail = buffer.length - index;
+ int amount = avail < length? avail : length;
+ System.arraycopy(b, offset, buffer, index, amount);
+ index += amount;
+ offset += amount;
+ length -= amount;
+ if (index == buffer.length) shipout();
+ }
+ }
+
+ /** Flush the stream.
+ *
+ * This causes any buffered bytes to be encoded and shipped out to the underlying
+ * stream, which is also flushed.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ public void flush() throws IOException {
+ if (buffer == null)
+ throw new IOException("Can't flush a closed stream");
+ shipout();
+ out.flush();
+ }
+
+ /** Close the stream.
+ *
+ * This writes out any unflushed data in base-64 format and closes the underlying
+ * stream.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ public void close() throws IOException {
+ if (buffer == null)
+ throw new IOException("Can't close an already closed stream");
+ flush();
+ out.close();
+ out = null;
+ buffer = null;
+ }
+
+ /** Ship out a bunch of buffered data in base-64 format.
+ *
+ * This resets the index of the next byte to insert back to zero.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ private void shipout() throws IOException {
+ byte[] encoded = Base64.encode(buffer, 0, index);
+ out.write(encoded);
+ index = 0;
+ }
+
+ /** Size of the output data buffer. Must be a multiple of 3.
+ */
+ private static final int BUFFER_SIZE = 300;
+
+ /** Buffer for output data.
+ */
+ private byte[] buffer = new byte[BUFFER_SIZE];
+
+ /** Where we are in the buffer.
+ */
+ private int index = 0;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/CountingOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/CountingOutputStream.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/CountingOutputStream.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/CountingOutputStream.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An output stream that counts the number bytes it passes on.
+ *
+ * @author Kelly
+ * @version $Revision: 1.1.1.1 $
+ */
+public class CountingOutputStream extends FilterOutputStream {
+ /**
+ * Creates a new <code>CountingOutputStream</code> instance.
+ *
+ * @param out Where to send bytes onto.
+ */
+ public CountingOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ public void write(int b) throws IOException {
+ out.write(b);
+ ++written;
+ }
+
+ public void write(byte[] b) throws IOException {
+ out.write(b);
+ written += b.length;
+ }
+
+ public void write(byte[] b, int offset, int length) throws IOException {
+ out.write(b, offset, length);
+ written += length;
+ }
+
+ /**
+ * Get the number of bytes written so far.
+ *
+ * @return a <code>long</code> value.
+ */
+ public long getBytesWritten() {
+ return written;
+ }
+
+ /** Number of bytes written so far. */
+ private long written = 0L;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/FixedBufferOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/FixedBufferOutputStream.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/FixedBufferOutputStream.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/FixedBufferOutputStream.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,119 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** This stream writes its output into a byte buffer of fixed length.
+ *
+ * For a buffer of size <var>n</var>, only the last <var>n</var> bytes written are ever
+ * available.
+ *
+ * @author Kelly
+ */
+public class FixedBufferOutputStream extends OutputStream {
+ /** Construct a fixed buffer output stream.
+ *
+ * @param n Size of the buffer.
+ */
+ public FixedBufferOutputStream(int n) {
+ if (n < 0) throw new IllegalArgumentException("Buffer size must be nonnegative");
+ buffer = new byte[n];
+ length = n;
+ size = 0;
+ start = 0;
+ }
+
+ public void write(int b) throws IOException {
+ checkIfClosed();
+ if (length == 0) return;
+ if (size < length)
+ buffer[size++] = (byte) b;
+ else {
+ buffer[start] = (byte) b;
+ start = (start + 1) % length;
+ }
+ }
+
+ public void write(byte[] a, int off, int len) throws IOException {
+ checkIfClosed();
+ if (a == null) throw new NullPointerException("Can't write from a null array");
+ else if ((off < 0) || (off > a.length) || (len < 0) || ((off + len) > a.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException("Offset " + off + " and length " + len + " not within array bounds");
+ } else if (len == 0) {
+ return;
+ }
+ if (len > length) {
+ off += len - length;
+ len = length;
+ }
+ int capacity = length - size;
+ int insertionIndex = size < length? size : start;
+ int insertionLength = Math.min(length - insertionIndex, len);
+ int remaining = len - insertionLength;
+ System.arraycopy(a, off, buffer, insertionIndex, insertionLength);
+ if (remaining > 0) {
+ System.arraycopy(a, off + insertionLength, buffer, 0, remaining);
+ start = remaining;
+ } else if (capacity == 0)
+ start = insertionIndex + insertionLength;
+ size = Math.min(length, size + len);
+ }
+
+ public void flush() {
+ // Nothing need be done here
+ }
+
+ public void close() {
+ start = -1;
+ }
+
+ /** Get the buffer.
+ *
+ * This method constructs a new array whose contents is the data written. Its
+ * size is equal to the smaller of the number of bytes written or the size of the
+ * fixed buffer passed to the constructor of this class.
+ *
+ * @return The buffer.
+ */
+ public byte[] getBuffer() {
+ byte[] rc = new byte[Math.min(size, length)];
+ System.arraycopy(buffer, start, rc, 0, size - start);
+ System.arraycopy(buffer, 0, rc, size - start, start);
+ return rc;
+ }
+
+ /** Throw an exception if we've been closed.
+ *
+ * @throws IOException If this stream has been closed.
+ */
+ private void checkIfClosed() throws IOException {
+ if (start == -1) throw new IOException("Can't write to closed stream");
+ }
+
+ /** Length of the buffer. */
+ private int length;
+
+ /** Current size of the data in the buffer. */
+ private int size;
+
+ /** Current start offset of the data in the buffer. If negative, buffer is closed. */
+ private int start;
+
+ /** The buffer. */
+ private byte[] buffer;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Log.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Log.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Log.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/Log.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,280 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/** The log.
+ *
+ * This class represents the application- or applet-wide logging facility. If your
+ * application needs to log messages, here's your class.
+ *
+ * <p>To log a message, you call one of the <code>get</code> methods of this class to
+ * yield a {@link LogWriter} object. You can then call methods like {@link
+ * LogWriter#println(String)} to log a line of text. A typical invocation is
+ *
+ * <pre>Log.get().println("Buffer of length " + length + " allocated.");</pre>
+ *
+ * <p>This logs the given text using the default source string, and under the default
+ * category, and timestamped with the current time. You can reuse the
+ * <code>LogWriter</code>, but the timestamp, source, and category won't change. You
+ * should get a fresh <code>LogWriter</code>.
+ *
+ * <p><strong>Sources</strong> identify independent origins of log messages, such as
+ * independent threads in a program, or independent programs. Sources are just strings.
+ * If you don't specify a source, you get a default source. You can set the default
+ * source with {@link #setDefaultSource}. You <em>always</em> get a source with every
+ * message, even if it's a default source. If you don't otherwise set a default source
+ * string, the source is "app".
+ *
+ * <p><strong>Categories</strong> identify different classes or priorites of messages.
+ * Categories can be simple strings like "warning" or "debug", or they can be complex
+ * objects. You get to define your categories. Your group ought to agree on categories,
+ * though. If you don't specify a category, you get a default category. You can set the
+ * default category with {@link #setDefaultCategory}. If you don't call that method, the
+ * default category is the String object "message".
+ *
+ * <p><strong>Streams</strong> identify independent activities within a program, which
+ * often have transient lifespans. They're <em>not</em> separate output streams, but
+ * instead are separate, named entities representing separate activities (although a
+ * {@link LogListener} may put messages into separate output streams identified by each
+ * stream). Activity streams are identified by strings. To indicate the start and stop
+ * of streams, call {@link #startStream} and {@link #stopStream}. These send
+ * stream-started and stream-stopped events to the log listeners, who may choose to pay
+ * attention to them or ignore them. You can use streams to indicate to the log the start
+ * and the stop of activities such as an analyst examining the system, or a server
+ * handling a particular client.
+ *
+ * <p>All messages logged with this class go to one or more {@link LogListener} objects.
+ * A LogListener accepts logging events, such as a message being logged, and does
+ * something with it, such as writing the message to a file. Call {@link #addLogListener}
+ * to add a log listener. Logging of a message, starting a stream, and stopping a stream
+ * all get turned into {@link LogEvent}s and are multicasted to every registered listener.
+ *
+ * <p>The logging facility bootstraps itself with one or more log listeners specified by
+ * the system property <code>org.apache.oodt.commons.io.Log.loggers</code>. This property must be a
+ * space-separated list of complete class names. The logging facility will create an
+ * object of each class listed and add it as if you had called
+ * <code>addLogListener</code>. (You can specify system properties on the command line or
+ * in the applet tag.)
+ *
+ * @see LogListener
+ * @see LogWriter
+ * @author Kelly
+ */
+public class Log {
+ /** Currently registered LogListeners.
+ */
+ private static Vector listeners;
+
+ static {
+ listeners = new Vector();
+ String loggers = System.getProperty("org.apache.oodt.commons.io.Log.loggers", "");
+ StringTokenizer tokenizer = new StringTokenizer(loggers);
+ while (tokenizer.hasMoreTokens()) {
+ String className = tokenizer.nextToken();
+ try {
+ Class clazz = Class.forName(className);
+ LogListener listener = (LogListener) clazz.newInstance();
+ addLogListener(listener);
+ } catch (Exception e) {
+ System.err.println("Can't create log listener object from class " + className + ": " + e);
+ System.exit(1);
+ }
+ }
+ }
+
+ /** Get a writer to log messages.
+ *
+ * The writer will log messages with the current time, default category, and
+ * default source. Messages will go into the general log.
+ *
+ * @return A writer with which you can log messages.
+ */
+ public static LogWriter get() {
+ if (lastWriter != null && !lastWriter.isFlushed())
+ return lastWriter;
+ else
+ return get(new Date(), getDefaultSource(), getDefaultCategory());
+ }
+
+ /** Get a writer to log messages.
+ *
+ * The writer will log messages with the current time, specified category, and
+ * default source. Messages will go into the general log.
+ *
+ * @param category The messages' category.
+ * @return A writer with which you can log messages.
+ */
+ public static LogWriter get(Object category) {
+ return get(new Date(), getDefaultSource(), category);
+ }
+
+ /** Get a writer to log messages.
+ *
+ * The writer will log messages with the specified time, specified category, and
+ * specified source.
+ *
+ * @param timestamp The time for messages logged with the returned writer.
+ * @param source The source of the log message.
+ * @param category The messages' category.
+ * @return A writer with which you can log messages.
+ */
+ public static synchronized LogWriter get(Date timestamp, String source, Object category) {
+ lastWriter = new LogWriter(timestamp, source, category);
+ return lastWriter;
+ }
+
+ /** Start a new log stream.
+ *
+ * This method notifies the {@link LogListener}s that a new logging stream has
+ * started.
+ *
+ * @param stream The name of the stream.
+ * @param timestamp The time the stream started. To use the current time, pass a new {@link Date} object.
+ * @param source A string identifying who or what started the stream.
+ */
+ public static void startStream(String stream, Date timestamp, String source) {
+ LogEvent event = null;
+ for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
+ // Lazily create the event.
+ if (event == null)
+ event = new LogEvent(stream, timestamp, source);
+ ((LogListener) e.nextElement()).streamStarted(event);
+ }
+ }
+
+ /** Stop a stream.
+ *
+ * This method notifies the {@link LogListener}s that a logging stream has stopped.
+ *
+ * @param stream The name of the stream that stopped.
+ */
+ public static void stopStream(String stream) {
+ LogEvent event = null;
+ for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
+ // Lazily create the event.
+ if (event == null)
+ event = new LogEvent(stream);
+ ((LogListener) e.nextElement()).streamStopped(event);
+ }
+ }
+
+ /** Log a message.
+ *
+ * The {@link LogWriter}s call this when they've built up a complete message and
+ * want it multicasted to the {@link LogListener}s.
+ *
+ * @param timestamp The message's timestamp.
+ * @param source The source label of the message.
+ * @param category The message's category.
+ * @param message The message.
+ */
+ static void logMessage(Date timestamp, String source, Object category, String message) {
+ LogEvent event = null;
+ for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
+ // Lazily create the event.
+ if (event == null)
+ event = new LogEvent(timestamp, source, category, message);
+ ((LogListener) e.nextElement()).messageLogged(event);
+ }
+ }
+
+ /** Set the default source.
+ *
+ * This sets the default source label used for logging.
+ *
+ * @param source The new default source label.
+ */
+ public static void setDefaultSource(String source) {
+ if (source == null)
+ throw new IllegalArgumentException("Can't set a null default source");
+ defaultSource = source;
+ }
+
+ /** Get the default source.
+ *
+ * @return The default source label.
+ */
+ public static String getDefaultSource() {
+ return defaultSource;
+ }
+
+ /** Set the default category.
+ *
+ * This sets the category object that's used by default for logging.
+ *
+ * @param category The new default category object.
+ */
+ public static void setDefaultCategory(Object category) {
+ if (category == null)
+ throw new IllegalArgumentException("Can't set a null default category");
+ defaultCategory = category;
+ }
+
+ /** Get the default category.
+ *
+ * @return The default category object.
+ */
+ public static Object getDefaultCategory() {
+ return defaultCategory;
+ }
+
+ /** Add a log listener.
+ *
+ * The listener will be notified whenever a message is logged, a stream started,
+ * or a stream stopped.
+ *
+ * @param listener The listener to add.
+ */
+ public static void addLogListener(LogListener listener) {
+ if (listener == null)
+ throw new IllegalArgumentException("Can't add a null log listener");
+ listeners.addElement(listener);
+ }
+
+ /** Remove a log listener.
+ *
+ * The listener won't receive anymore events unless it's added back.
+ *
+ * @param listener The listener to remove.
+ */
+ public static void removeLogListener(LogListener listener) {
+ if (listener == null)
+ throw new IllegalArgumentException("Can't remove a null log listener");
+ listeners.removeElement(listener);
+ }
+
+ /** The default source label.
+ */
+ private static String defaultSource = "app";
+
+ /** The default category object.
+ */
+ private static Object defaultCategory = "message";
+
+ /** Last log writer created so it can be reused. */
+ private static LogWriter lastWriter;
+
+ /** Don't allow instantiation.
+ *
+ * When we convert to Java 2, this should throw UnsupportedOperationException.
+ */
+ private Log() {}
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogEvent.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogEvent.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogEvent.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogEvent.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,172 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.util.Date;
+import java.util.EventObject;
+
+/** Logging event.
+ *
+ * A logging event is generated and delivered to all registered log listeners when a
+ * message was logged, a logging stream was started, or when a logging stream was stopped.
+ *
+ * <p>Use the various query methods to determine the details of the event. The event
+ * source (from {@link EventObject#getSource}) is always a {@link String}.
+ *
+ * @see Log
+ * @see LogListener
+ * @author Kelly
+ */
+public class LogEvent extends EventObject {
+ /** Create a "message logged" event.
+ *
+ * @param timestamp The message's timestamp.
+ * @param source The source label of the message.
+ * @param category The message's category.
+ * @param message The message.
+ */
+ public LogEvent(Date timestamp, String source, Object category, String message) {
+ super(source);
+ type = MSG_LOGGED;
+ this.timestamp = timestamp;
+ this.category = category;
+ this.message = message;
+ }
+
+ /** Create a "stream started" event.
+ *
+ * @param stream The name of the stream.
+ * @param timestamp The time the stream started.
+ * @param source A string identifying who or what started the stream.
+ */
+ public LogEvent(String stream, Date timestamp, String source) {
+ super(source);
+ type = STREAM_STARTED;
+ this.stream = stream;
+ this.timestamp = timestamp;
+ }
+
+ /** Create a "stream stopped" event.
+ *
+ * @param stream The name of the stream.
+ */
+ public LogEvent(String stream) {
+ super(stream);
+ type = STREAM_STOPPED;
+ this.stream = stream;
+ }
+
+ /** Get the category.
+ *
+ * For message logged events, this is the category for the message. For all other
+ * events, this returns null.
+ *
+ * @return The category, or null.
+ */
+ public Object getCategory() {
+ return category;
+ }
+
+ /** Get the message.
+ *
+ * For message logged events, this is the actual message text. For all other
+ * events, this returns null.
+ *
+ *@return The message, or null.
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /** Get the stream.
+ *
+ * For stream started and stopped events, this is the name of the stream that was
+ * started or stopped. For message logged events, this is null.
+ *
+ * @return The stream, or null.
+ */
+ public String getStream() {
+ return stream;
+ }
+
+ /** Get the timestamp.
+ *
+ * For message logged and stream started events, this is the timestamp of the
+ * event. For stream stopped events, this is null.
+ *
+ * @return The timestamp, or null.
+ */
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ /** Return a string representation of this event.
+ *
+ * @return A string identifying the type of the event.
+ */
+ public String toString() {
+ switch (type) {
+ case MSG_LOGGED:
+ return "Log Event (message logged)";
+ case STREAM_STARTED:
+ return "Log Event (stream started)";
+ case STREAM_STOPPED:
+ return "Log Event (stream stopped)";
+ default:
+ return "Unknown Log Event Type";
+ }
+ }
+
+ /** The timestamp: null if this is a "stream stopped" event.
+ */
+ private Date timestamp;
+
+ /** The stream: null for logging.
+ */
+ private String stream;
+
+ /** The category: null for stream started/stopped events.
+ */
+ private Object category;
+
+ /** The message: nonnull only for "message logged" events.
+ */
+ private String message;
+
+ /** The type of event this is.
+ *
+ * This gets one of the values <code>MSG_LOGGED</code>, <code>STREAM_STARTED</code>, or <code>STREAM_STOPPED</code>.
+ */
+ private int type;
+
+ /** The "message logged" event type.
+ *
+ * @see #type
+ */
+ private static final int MSG_LOGGED = 1;
+
+ /** The "stream started" event type.
+ *
+ * @see #type
+ */
+ private static final int STREAM_STARTED = 2;
+
+ /** The "stream stopped" event type.
+ *
+ * @see #type
+ */
+ private static final int STREAM_STOPPED = 3;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogFilter.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogFilter.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogFilter.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogFilter.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,144 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.util.Hashtable;
+
+/** A filter for log messages.
+ *
+ * This is a {@link LogListener} that filters out and passes through certain categories of
+ * log messages to another <code>LogListener</code>. When you construct this listener,
+ * you pass a boolean flag that indicates its pass-through mode: if true, it passes log
+ * messages by default and filters out specified categories; if false, it filters out
+ * messages by default and passes through specified categories.
+ *
+ * <p>Note that this filter only affects events sent to {@link LogListener#messageLogged}.
+ * Events sent to {@link LogListener#streamStarted} and {@link LogListener#streamStopped}
+ * are passed through regardless.
+ *
+ * <p>Categories used by this filter should implement their {@link Object#hashCode} and
+ * {@link Object#equals} methods.
+ *
+ * @see Log
+ * @author Kelly
+ */
+public class LogFilter implements LogListener {
+ /** Create a log filter.
+ *
+ * The log filter passes through and filters out messages before sending them onto
+ * the given log listener.
+ *
+ * @param listener What object will get filtered log messages.
+ * @param passThrough If true, pass messages through by default and filter out the
+ * specified <var>categories</var> of messages. If false, filter out messages by
+ * default and pass through the specified <var>categories</var>.
+ * @param categories Categories of messages to filter out (if
+ * <var>passThrough</var> is true) or to pass through (if <var>passThrough</var>
+ * is false).
+ */
+ public LogFilter(LogListener listener, boolean passThrough, Object[] categories) {
+ if (listener == null)
+ throw new IllegalArgumentException("Can't filter messages to a null listener");
+ this.listener = listener;
+ this.passThrough = passThrough;
+ if (categories == null) return;
+ for (int i = 0; i < categories.length; ++i)
+ this.categories.put(categories[i], DUMMY);
+ }
+
+ /** Create a log filter.
+ *
+ * The log filter passes through and filters out messages before sending them onto
+ * the given log listener. The filter starts out empty (with no categories).
+ *
+ * @param listener What object will get filtered log messages.
+ * @param passThrough If true, pass messages through by default. If false, filter out messages by default.
+ */
+ public LogFilter(LogListener listener, boolean passThrough) {
+ this(listener, passThrough, /*categories*/null);
+ }
+
+ /** Add an additional category.
+ *
+ * If the filter is in pass-through mode, messages in this category will be
+ * filtered out. If the filter is in filter mode, messages in this category will
+ * be passed through.
+ *
+ * @param category The category to add.
+ */
+ public void addCategory(Object category) {
+ categories.put(category, DUMMY);
+ }
+
+ /** Remove a category.
+ *
+ * If the category isn't in the filter, nothing happens.
+ *
+ * @param category The category to remove.
+ */
+ public void removeCategory(Object category) {
+ categories.remove(category);
+ }
+
+ /** Pass on the event unmodified to the registered listener.
+ *
+ * @param event The event to pass.
+ */
+ public void streamStarted(LogEvent event) {
+ listener.streamStarted(event);
+ }
+
+ /** Pass on the event unmodified to the registered listener.
+ *
+ * @param event The event to pass.
+ */
+ public void streamStopped(LogEvent event) {
+ listener.streamStopped(event);
+ }
+
+ /** Filter the event, and possibly pass it onto the registered listener.
+ *
+ * @param event The event to filter.
+ */
+ public void messageLogged(LogEvent event) {
+ boolean found = categories.containsKey(event.getCategory());
+ if ((passThrough && !found) || (!passThrough && found))
+ listener.messageLogged(event);
+ }
+
+ /** Ignore this event.
+ */
+ public void propertyChange(java.beans.PropertyChangeEvent ignore) {}
+
+ /** If true, pass through by default, otherwise filter out by default.
+ */
+ protected boolean passThrough;
+
+ /** Table of categories to filter/pass.
+ *
+ * This table maps all values to {@link #DUMMY}. In Java2, we can get rid of
+ * <code>DUMMY</code> and use a {@link java.util.HashSet} instead.
+ */
+ protected Hashtable categories = new Hashtable();
+
+ /** The DUMMY value for all mappings in the {@link #categories} table.
+ */
+ protected static final Object DUMMY = new Object();
+
+ /** The listener on whose behalf we filter.
+ */
+ protected LogListener listener;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogListener.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogListener.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogListener.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogListener.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,69 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.util.EventObject;
+
+/** Listener for logging events.
+ *
+ * Objects of classes that implement this interface are notified when messages are logged
+ * and when other logging events occur.
+ *
+ * @see Log
+ * @see LogEvent
+ * @author Kelly
+ */
+public interface LogListener extends java.beans.PropertyChangeListener {
+ /** A message got logged.
+ *
+ * The <var>event</var> contains the details of the message, including
+ *
+ * <ul>
+ * <li>The timestamp of the message, from {@link LogEvent#getTimestamp}.</li>
+ * <li>The source of the message, from {@link EventObject#getSource}, which is always
+ * a {@link String}.</li>
+ * <li>The category of the message, from {@link LogEvent#getCategory}.</li>
+ * <li>The message text, from {@link LogEvent#getMessage}.</li>
+ * </ul>
+ *
+ * @param event The logging event.
+ */
+ void messageLogged(LogEvent event);
+
+ /** A stream got started.
+ *
+ * The <var>event</var> contains the details of stream start, including
+ *
+ * <ul>
+ * <li>The name of the stream, from {@link LogEvent#getStream}.</li>
+ * <li>The time the stream got started, from {@link LogEvent#getTimestamp}</li>
+ * <li>The source of the new stream start, from {@link EventObject#getSource} (always a {@link String}).</li>
+ * </ul>
+ *
+ * @param event The logging event.
+ */
+ void streamStarted(LogEvent event);
+
+ /** A stream was stopped.
+ *
+ * The <var>event</var> contains the detail of the stream stop, which is the name
+ * of the stream, from {@link LogEvent#getStream} or {@link EventObject#getSource}
+ * (always a {@link String}).
+ *
+ * @param event The logging event.
+ */
+ void streamStopped(LogEvent event);
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogWriter.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogWriter.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogWriter.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/LogWriter.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,375 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.util.Date;
+
+/** A writer for log messages.
+ *
+ * Objects of this class let you write messages into the logging facility. You get these
+ * objects by calling one of the <code>get</code> methods of class {@link Log} and use it
+ * as you would use a {@link java.io.PrintWriter}. This class automatically flushes a message to
+ * the logging facility whenever you call one of the <code>println</code> methods, or
+ * {@link #flush}. It prints all values and objects using the platform's default character
+ * encoding.
+ *
+ * <p>Note that the <code>println</code> methods of this class don't actually write
+ * <em>any</em> line separation characters into the log. Log listeners will want the
+ * messages without such characters anyway, so this is the correct behavior.
+ *
+ * @see Log
+ * @author Kelly
+ */
+public class LogWriter extends java.io.Writer {
+ /** Constructor.
+ *
+ * @param timestamp The time for messages logged with the returned writer.
+ * @param source The source of the log message.
+ * @param category The messages' category.
+ */
+ LogWriter(Date timestamp, String source, Object category) {
+ buf = new StringBuffer(/*length*/ 80);
+ lock = buf;
+ this.timestamp = timestamp;
+ this.source = source;
+ this.category = category;
+ flushed = false;
+ }
+
+ /** Write a single character.
+ *
+ * This writes a single character (the low order 16 bits of c) to the log
+ * writer. The character isn't flushed to the logging facility until you call one
+ * of the <code>println</code> methods or {@link #flush}.
+ *
+ * @param c The character to write.
+ */
+ public void write(int c) {
+ if (buf == null) return;
+ buf.append((char) c);
+ }
+
+ /** Write a portion of an array of characters.
+ *
+ * This writes the given character array starting at offset and going for length bytes.
+ *
+ * @param array The character array to write.
+ * @param offset Where in the array to get characters to write.
+ * @param length How many characters to write.
+ */
+ public void write(char[] array, int offset, int length) {
+ if (buf == null || length == 0) return;
+ if (offset < 0 || offset > array.length || length < 0 || (offset+length) > array.length || (offset+length) < 0)
+ throw new IndexOutOfBoundsException("Can't write " + length + " characters at " + offset
+ + " from array whose length is " + array.length);
+ buf.append(array, offset, length);
+ }
+
+ /** Write an array of characters.
+ *
+ * This writes the entire given array.
+ *
+ * @param array Array of characters to write.
+ */
+ public void write(char[] array) {
+ write(array, 0, array.length);
+ }
+
+ /** Write a portion of a string.
+ *
+ * This writes length characters from the given string, starting offset characters
+ * into it.
+ *
+ * @param string The string to write.
+ * @param offset Where in the string to get characters to write.
+ * @param length How many characters to write.
+ */
+ public void write(String string, int offset, int length) {
+ if (buf == null || length == 0) return;
+ buf.append(string.substring(offset, offset + length));
+ }
+
+ /** Write a string.
+ *
+ * This writes the entire given string.
+ *
+ * @param string String to write.
+ */
+ public void write(String string) {
+ write(string, 0, string.length());
+ }
+
+ /** Flush the log writer.
+ *
+ * This sends any text sent to the writer on its way to the logging facility, and beyond.
+ */
+ public void flush() {
+ if (buf == null) return;
+ Log.logMessage(timestamp, source, category, buf.toString());
+ buf.setLength(0);
+ flushed = true;
+ }
+
+ /** Close the log writer.
+ *
+ * <p>This flushes any remaining text to the logging facility and then shuts down
+ * the log writer. You can't use it again after that (but closing a previously
+ * closed log writer is OK).
+ */
+ public void close() {
+ flush();
+ buf = null;
+ }
+
+ /** Print a boolean value.
+ *
+ * This prints a boolean value ("true" or "false") into the log.
+ *
+ * @param b The <code>boolean</code> to print.
+ */
+ public void print(boolean b) {
+ write(b? "true" : "false");
+ }
+
+ /** Print a character.
+ *
+ * The character is translated into one or more bytes according to the platform's
+ * default character encoding.
+ *
+ * @param c The <code>char</code> to print.
+ */
+ public void print(char c) {
+ write(String.valueOf(c));
+ }
+
+ /** Print an integer.
+ *
+ * @param i The <code>int</code> to print.
+ */
+ public void print(int i) {
+ write(String.valueOf(i));
+ }
+
+ /** Print a long integer.
+ *
+ * @param l The <code>long</code> to print.
+ */
+ public void print(long l) {
+ write(String.valueOf(l));
+ }
+
+ /** Print a floating-point number.
+ *
+ * @param f The <code>float</code> to print.
+ */
+ public void print(float f) {
+ write(String.valueOf(f));
+ }
+
+ /** Print a double-precision floating-point number.
+ *
+ * @param d The <code>double</code> to print.
+ */
+ public void print(double d) {
+ write(String.valueOf(d));
+ }
+
+ /** Print an array of characters.
+ *
+ * @param a The array of chars to print.
+ */
+ public void print(char[] a) {
+ write(a);
+ }
+
+ /** Print a string.
+ *
+ * If the argument is <code>null</code> then the string
+ * "null" is printed.
+ *
+ * @param s The <code>String</code> to print.
+ */
+ public void print(String s) {
+ if (s == null) s = "null";
+ write(s);
+ }
+
+ /** Print an object.
+ *
+ * @param obj The <code>Object</code> to print.
+ */
+ public void print(Object obj) {
+ write(String.valueOf(obj));
+ }
+
+ /** Print a boolean value and terminate the message.
+ *
+ * This prints a boolean into the log, and flushes the message to the logging
+ * facility.
+ *
+ * @param b The <code>boolean</code> to print.
+ */
+ public void println(boolean b) {
+ print(b);
+ println();
+ }
+
+ /** Print a character value and terminate the message.
+ *
+ * This prints a character into the log, and flushes the message to the logging
+ * facility.
+ *
+ * @param c The <code>char</code> to print.
+ */
+ public void println(char c) {
+ print(c);
+ println();
+ }
+
+ /** Print an integer value and terminate the message.
+ *
+ * This prints an integer into the log, and flushes the message to the logging
+ * facility.
+ *
+ * @param i The <code>int</code> to print.
+ */
+ public void println(int i) {
+ print(i);
+ println();
+ }
+
+ /** Print a long integer value and terminate the message.
+ *
+ * This prints a long integer into the log, and flushes the message to the logging
+ * facility.
+ *
+ * @param l The <code>long</code> to print.
+ */
+ public void println(long l) {
+ print(l);
+ println();
+ }
+
+ /** Print a floating-point value and terminate the message.
+ *
+ * This prints a floating-point value into the log, and flushes the message to the
+ * logging facility.
+ *
+ * @param f The <code>float</code> to print.
+ */
+ public void println(float f) {
+ print(f);
+ println();
+ }
+
+ /** Print a double-precision floating-point value and terminate the message.
+ *
+ * This prints a double-precision floating-point into the log, and flushes the
+ * message to the logging facility.
+ *
+ * @param d The <code>double</code> to print.
+ */
+ public void println(double d) {
+ print(d);
+ println();
+ }
+
+ /** Print a character array and terminate the message.
+ *
+ * This prints a character array into the log, and flushes the message to the
+ * logging facility.
+ *
+ * @param a The array of chars to print.
+ */
+ public void println(char[] a) {
+ print(a);
+ println();
+ }
+
+ /** Print a String and terminate the message.
+ *
+ * This prints a String into the log, and flushes the message to the logging
+ * facility.
+ *
+ * @param s The <code>String</code> to print.
+ */
+ public void println(String s) {
+ print(s);
+ println();
+ }
+
+ public void println(Throwable t) {
+ if (t == null)
+ println("Null throwable");
+ else {
+ StackTraceElement[] frames = t.getStackTrace();
+ if (frames == null)
+ println("Null stack trace in " + t.getClass().getName());
+ else {
+ println(t.getClass().getName() + ":");
+ for (int i = 0; i < frames.length; ++i)
+ println(frames[i]);
+ }
+ }
+ }
+
+ /** Print an Object and terminate the message.
+ *
+ * This prints an Object into the log, and flushes the message to the logging
+ * facility.
+ *
+ * @param obj The <code>Object</code> to print.
+ */
+ public void println(Object obj) {
+ print(obj);
+ println();
+ }
+
+ /** Terminate the current message.
+ *
+ * This terminates any message text built up and sends it to the logging facility.
+ */
+ public void println() {
+ flush();
+ }
+
+ /** Are we flushed yet?
+ *
+ * @return True if flushed, false otherwise.
+ */
+ public boolean isFlushed() {
+ return flushed;
+ }
+
+ /** The buffer used to build up the message. If this is null, then the writer is closed.
+ */
+ private StringBuffer buf;
+
+ /** The timestamp this LogWriter will use for log messages.
+ */
+ private Date timestamp;
+
+ /** The source label.
+ */
+ private String source;
+
+ /** The category of messages generated by this writer.
+ */
+ private Object category;
+
+ /** Flushed yet? */
+ private boolean flushed;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullInputStream.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullInputStream.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullInputStream.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullInputStream.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * An input stream that's always empty.
+ *
+ * @author Kelly
+ * @version $Revision: 1.1.1.1 $
+ */
+public final class NullInputStream extends InputStream {
+ /**
+ * Construct a null input stream.
+ */
+ public NullInputStream() {
+ open = true;
+ }
+
+ /**
+ * Read a byte, which you can't do, so you always get -1 to indicate end-of-file.
+ *
+ * @return -1 to indicate end of file.
+ * @throws IOException If the stream is closed.
+ */
+ public int read() throws IOException {
+ checkOpen();
+ return -1;
+ }
+
+ public void close() throws IOException {
+ checkOpen();
+ open = false;
+ }
+
+ /**
+ * Check if we're open.
+ *
+ * @throws IOException If we're not open.
+ */
+ private void checkOpen() throws IOException {
+ if (!open) throw new IOException("Stream closed");
+ }
+
+ /** Is the stream open? */
+ private boolean open;
+}
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullOutputStream.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullOutputStream.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/NullOutputStream.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,88 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.*;
+import java.util.*;
+
+/** A null output stream.
+ *
+ * This output stream throws away all data it gets.
+ *
+ * @author Kelly
+ */
+public class NullOutputStream extends OutputStream {
+ /** Construct a null output stream.
+ */
+ public NullOutputStream() {
+ open = true;
+ }
+
+ /** Write a byte to the output stream, which is thrown away.
+ *
+ * @param b The byte to toss.
+ * @throws IOException If the stream is closed.
+ */
+ public void write(int b) throws IOException {
+ checkOpen();
+ }
+
+ /** Write a byte array to the output stream, which is thrown away.
+ *
+ * @param a The array to write.
+ * @param offset Where in the array to ignore bytes to write.
+ * @param length How many bytes to ignore.
+ * @throws IOException If the stream is closed.
+ */
+ public void write(byte[] a, int offset, int length) throws IOException {
+ if (a == null)
+ throw new NullPointerException("Can't write a null array");
+ else if ((offset < 0) || (offset > a.length) || (length < 0) || ((offset + length) > a.length)
+ || ((offset + length) < 0))
+ throw new IndexOutOfBoundsException("Offset " + offset + " and length " + length
+ + " not in array of length " + a.length);
+ checkOpen();
+ }
+
+ /** Flush an output stream, which does nothing.
+ *
+ * @throws IOException If the stream is closed.
+ */
+ public void flush() throws IOException {
+ checkOpen();
+ }
+
+ /** Close an output stream.
+ *
+ * @throws IOException If the stream is already closed.
+ */
+ public void close() throws IOException {
+ checkOpen();
+ open = false;
+ }
+
+ /** Check if we're open.
+ *
+ * @throws IOException If we're not open.
+ */
+ private void checkOpen() throws IOException {
+ if (!open) throw new IOException("Stream closed");
+ }
+
+ /** Is the output stream open? */
+ private boolean open;
+}
+
Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/WriterLogger.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/WriterLogger.java?rev=964250&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/WriterLogger.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/io/WriterLogger.java Wed Jul 14 23:04:25 2010
@@ -0,0 +1,166 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership. The ASF licenses this
+// file to you under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package org.apache.oodt.commons.io;
+
+import java.io.Writer;
+import java.io.IOException;
+import org.apache.oodt.commons.util.*;
+
+/** Log messages to a <code>Writer</code>.
+ *
+ * This class defines a {@link LogListener} that logs its messages to a character stream
+ * {@link Writer}. This formats and writes to the output stream all log events passed to
+ * {@link LogListener#messageLogged}, one per line. Each line is separated with the
+ * system's line separator characters, specified by the <code>line.separator</code> system
+ * property.
+ *
+ * <p>It ignores all events passed to {@link LogListener#streamStarted} and
+ * {@link LogListener#streamStopped}.
+ *
+ * <p>It quietly hides all IO errors that may occur during writing.
+ *
+ * @see Log
+ * @author Kelly
+ */
+public class WriterLogger implements LogListener {
+ /** Constructor given an output stream.
+ *
+ * Construct a writer logger that writes message events to the given output stream
+ * and flushes the stream after every logged message.
+ *
+ * @param outputStream The output stream to which to write events.
+ */
+ public WriterLogger(java.io.OutputStream outputStream) {
+ this(new java.io.BufferedWriter(new java.io.OutputStreamWriter(outputStream)), /*autoFlush*/ true);
+ }
+
+ /** Constructor given a writer.
+ *
+ * Construct a writer logger that writes message events to the given writer and
+ * flushes the stream after every logged message.
+ *
+ * @param writer The writer to which to write events.
+ */
+ public WriterLogger(Writer writer) {
+ this(writer, /*autoFlush*/ true);
+ }
+
+ /** General constructor.
+ *
+ * Construct a writer logger that writes message events to the given writer and
+ * optionally flushes the stream after every logged message.
+ *
+ * @param writer The writer to which to write events.
+ * @param autoFlush If true, call flush on the writer after every message
+ * logged. If false, don't call flush.
+ */
+ public WriterLogger(Writer writer, boolean autoFlush) {
+ if (writer == null)
+ throw new IllegalArgumentException("Can't write to a null writer");
+ this.writer = writer;
+ this.autoFlush = autoFlush;
+ this.lineSep = System.getProperty("line.separator", "\n");
+ }
+
+ /** Close the writer.
+ *
+ * This closes the writer to which this logger was logging. Future message events
+ * are ignored and not written.
+ */
+ public final void close() {
+ if (writer == null) return;
+ try {
+ writer.close();
+ } catch (IOException ignore) {}
+ writer = null;
+ }
+
+ /** Log a message to the writer.
+ *
+ * This method first calls {@link #formatMessage} to format the message, and then
+ * writes the message to the output stream.
+ *
+ * @param event The event describing the message that was logged.
+ */
+ public final void messageLogged(LogEvent event) {
+ if (writer == null) return;
+ try {
+ writer.write(formatMessage(event.getTimestamp(), (String) event.getSource(), event.getCategory(),
+ event.getMessage()) + lineSep);
+ if (autoFlush) writer.flush();
+ } catch (IOException ignore) {}
+ }
+
+ /** Format a message for logging.
+ *
+ * This method formats a message as follows:
+ *
+ * <p><code><var>epochTime</var> (<var>time</var>) <var>source</var> <var>category</var>:
+ * <var>message</var>
+ *
+ * <p>where <var>epochTime</var> is the time in milliseconds since midnight, 1st
+ * January 1970 GMT, <var>time</var> is human-readable time, <var>source</var> is
+ * the source of the message, <var>category</var> is the category under which the
+ * message was logged, and <var>message</var> is the message.
+ *
+ * <p>You can override this method and provide your own formatting.
+ *
+ * @param timestamp Timestamp for the message.
+ * @param source Source of the message.
+ * @param category Category of the message.
+ * @param message The message text.
+ */
+ protected String formatMessage(java.util.Date timestamp, String source, Object category, String message) {
+ return ("\n" + DateConvert.isoFormat(timestamp) + " " + source + " " + category + ": " + message);
+ }
+
+ /** Ignore the stream started event.
+ *
+ * @param event The event to ignore.
+ */
+ public void streamStarted(LogEvent event) {
+ return;
+ }
+
+ /** Ignore the stream stopped event.
+ *
+ * @param event The event to ignore.
+ */
+ public void streamStopped(LogEvent event) {
+ return;
+ }
+
+ public void propertyChange(java.beans.PropertyChangeEvent ignore) {}
+
+ /** The writer to which we write log messages.
+ *
+ * If null, then we were closed. This is protected so you can extend this class
+ * and log other events normally ignored.
+ */
+ protected Writer writer;
+
+ /** If true, flush after every message logged.
+ *
+ * This is protected so you can extend this class and log other events normally ignored.
+ */
+ protected boolean autoFlush;
+
+ /** What the line separator is.
+ *
+ * This is protected so you can extend this class and log other events normally ignored.
+ */
+ protected String lineSep;
+}