logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grobme...@apache.org
Subject svn commit: r1345524 [9/17] - in /logging/log4j/branches/log4j12-bz53299: ./ contribs/ contribs/CekiGulcu/ contribs/EirikLygre/ contribs/JamesHouse/ contribs/Jamie Tsao/ contribs/JimMoore/ contribs/KevinSteppe/ contribs/KitchingSimon/ contribs/LeosLite...
Date Sat, 02 Jun 2012 15:36:26 GMT
Added: logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.chainsaw;
+
+import java.util.StringTokenizer;
+import org.apache.log4j.Level;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A content handler for document containing Log4J events logged using the
+ * XMLLayout class. It will create events and add them to a supplied model.
+ *
+ * @author <a href="mailto:oliver@puppycrawl.com">Oliver Burn</a>
+ * @version 1.0
+ */
+class XMLFileHandler
+    extends DefaultHandler
+{
+    /** represents the event tag **/
+    private static final String TAG_EVENT = "log4j:event";
+    /** represents the message tag **/
+    private static final String TAG_MESSAGE = "log4j:message";
+    /** represents the ndc tag **/
+    private static final String TAG_NDC = "log4j:NDC";
+    /** represents the throwable tag **/
+    private static final String TAG_THROWABLE = "log4j:throwable";
+    /** represents the location info tag **/
+    private static final String TAG_LOCATION_INFO = "log4j:locationInfo";
+
+    /** where to put the events **/
+    private final MyTableModel mModel;
+    /** the number of events in the document **/
+    private int mNumEvents;
+
+    /** the time of the event **/
+    private long mTimeStamp;
+    /** the priority (level) of the event **/
+    private Level mLevel;
+    /** the category of the event **/
+    private String mCategoryName;
+    /** the NDC for the event **/
+    private String mNDC;
+    /** the thread for the event **/
+    private String mThreadName;
+    /** the msg for the event **/
+    private String mMessage;
+    /** the throwable details the event **/
+    private String[] mThrowableStrRep;
+    /** the location details for the event **/
+    private String mLocationDetails;
+    /** buffer for collecting text **/
+    private final StringBuffer mBuf = new StringBuffer();
+
+    /**
+     * Creates a new <code>XMLFileHandler</code> instance.
+     *
+     * @param aModel where to add the events
+     */
+    XMLFileHandler(MyTableModel aModel) {
+        mModel = aModel;
+    }
+
+    /** @see DefaultHandler **/
+    public void startDocument()
+        throws SAXException
+    {
+        mNumEvents = 0;
+    }
+
+    /** @see DefaultHandler **/
+    public void characters(char[] aChars, int aStart, int aLength) {
+        mBuf.append(String.valueOf(aChars, aStart, aLength));
+    }
+
+    /** @see DefaultHandler **/
+    public void endElement(String aNamespaceURI,
+                           String aLocalName,
+                           String aQName)
+    {
+        if (TAG_EVENT.equals(aQName)) {
+            addEvent();
+            resetData();
+        } else if (TAG_NDC.equals(aQName)) {
+            mNDC = mBuf.toString();
+        } else if (TAG_MESSAGE.equals(aQName)) {
+            mMessage = mBuf.toString();
+        } else if (TAG_THROWABLE.equals(aQName)) {
+            final StringTokenizer st =
+                new StringTokenizer(mBuf.toString(), "\n\t");
+            mThrowableStrRep = new String[st.countTokens()];
+            if (mThrowableStrRep.length > 0) {
+                mThrowableStrRep[0] = st.nextToken();
+                for (int i = 1; i < mThrowableStrRep.length; i++) {
+                    mThrowableStrRep[i] = "\t" + st.nextToken();
+                }
+            }
+        }
+    }
+
+    /** @see DefaultHandler **/
+    public void startElement(String aNamespaceURI,
+                             String aLocalName,
+                             String aQName,
+                             Attributes aAtts)
+    {
+        mBuf.setLength(0);
+
+        if (TAG_EVENT.equals(aQName)) {
+            mThreadName = aAtts.getValue("thread");
+            mTimeStamp = Long.parseLong(aAtts.getValue("timestamp"));
+            mCategoryName = aAtts.getValue("logger");
+            mLevel = Level.toLevel(aAtts.getValue("level"));
+        } else if (TAG_LOCATION_INFO.equals(aQName)) {
+            mLocationDetails = aAtts.getValue("class") + "."
+                + aAtts.getValue("method")
+                + "(" + aAtts.getValue("file") + ":" + aAtts.getValue("line")
+                + ")";
+        }
+    }
+
+    /** @return the number of events in the document **/
+    int getNumEvents() {
+        return mNumEvents;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Private methods
+    ////////////////////////////////////////////////////////////////////////////
+
+    /** Add an event to the model **/
+    private void addEvent() {
+        mModel.addEvent(new EventDetails(mTimeStamp,
+                                         mLevel,
+                                         mCategoryName,
+                                         mNDC,
+                                         mThreadName,
+                                         mMessage,
+                                         mThrowableStrRep,
+                                         mLocationDetails));
+        mNumEvents++;
+    }
+
+    /** Reset the data for an event **/
+    private void resetData() {
+        mTimeStamp = 0;
+        mLevel = null;
+        mCategoryName = null;
+        mNDC = null;
+        mThreadName = null;
+        mMessage = null;
+        mThrowableStrRep = null;
+        mLocationDetails = null;
+    }
+}

Propchange: logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/java/org/apache/log4j/chainsaw/XMLFileHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png?rev=1345524&view=auto
==============================================================================
Binary file - no diff available.

Propchange: logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/docFiles/screen_01.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html Sat Jun  2 15:35:46 2012
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+
+<HTML>
+  <HEAD>
+    <TITLE>Chainsaw Tool</TITLE>
+  </head>
+    
+  <BODY>
+
+    <P>Chainsaw is a GUI log viewer and filter for the log4j
+package. By default it listens for <a
+href="../spi/LoggingEvent.html">LoggingEvent</A> objects sent using
+the <A href="../net/SocketAppender.html">SocketAppender</A> and
+displays them in a table. The events can be filtered based on:</P>
+
+    <UL>
+      <LI>Level </li>
+
+      <LI>Thread name</li>
+
+      <LI>Logger</li>
+      <LI>Message</li>
+
+      <LI>NDC</LI>
+    </UL>
+
+    <P>All the details for each event can be displayed by selecting
+      the event in the table.</P> 
+
+    <P>Chainsaw also supports loading a events logged to a file using
+      the <A href="../xml/XMLLayout.html">XMLLayout</A> format. This
+      is great for analysing log files, and means you do not need to
+      keep Chainsaw running continously. It is easy to add support
+      for loading events from other sources like JDBC.</P> 
+
+    <P>A picture is worth a thousand words: </P>
+
+    <P align=center><A
+      href="doc-files/screen_01.png"><IMG
+      height="50%" alt="Screen shot of chainsaw"
+      src="doc-files/screen_01.png"
+      width="50%"></A>.</P> 
+
+    <P>Finally, why is it called chainsaw?
+      Because it cuts your log (file) down to size. :-)
+    </P>
+
+
+    <H2>Requirements</H2> 
+
+    <P>Chainsaw is based on the Swing API which requires JDK 1.2 or later.</P>
+
+
+    <H2>Running chainsaw</H2>
+
+    <H3>Setup</H3>
+    <P>You need to include the <code>log4j.jar</code> in the classpath.
+
+    <H3>Usage</H3>
+
+    <P>The command line usage is:</P>
+
+    <PRE>  java -D&lt;property&gt;=&lt;value&gt; org.apache.log4j.chainsaw.Main </PRE>
+
+    <P>The default behaviour of chainsaw can be changed by setting system properties 
+      using the <CODE>-D&lt;property&gt;=&lt;value&gt;</CODE> arguments to java. The 
+      following table describes what properties can be set:</P>
+
+    <TABLE cellSpacing=0 cellPadding=2 border=1>
+
+      <TR>
+	<TD vAlign=top><B>Property</B></TD>
+	<TD vAlign=top><B>Description</B></TD></TR>
+      <TR>
+	<TD vAlign=top>chainsaw.port</TD>
+	<TD vAlign=top>Indicates which port to listen for connections on. Defaults 
+	  to <SPAN class=default>"4445"</SPAN>.
+	</TD>
+      </TR>
+    </TBODY>
+    </TABLE>
+
+    <H2>Configuring Log4J</H2>
+
+    <P>You will need to configure log4j to send logging events to
+      Chainsaw.  Here is a sample <CODE>log4j.properties</CODE> file
+      for sending logging events to Chainsaw.</P>
+
+<PRE>
+log4j.rootLogger=DEBUG, CHAINSAW_CLIENT
+
+log4j.appender.CHAINSAW_CLIENT=org.apache.log4j.net.SocketAppender
+log4j.appender.CHAINSAW_CLIENT.RemoteHost=localhost
+log4j.appender.CHAINSAW_CLIENT.Port=4445
+log4j.appender.CHAINSAW_CLIENT.LocationInfo=true
+</PRE>
+
+
+
+  </body>
+</html>
\ No newline at end of file

Propchange: logging/log4j/branches/log4j12-bz53299/modules/chainsaw/src/main/resources/org/apache/log4j/chainsaw/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/CONTENTS (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/CONTENTS)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/CONTENTS?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/CONTENTS&p1=logging/log4j/branches/log4j12-bz53299/contribs/CONTENTS&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/pom.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/pom.xml?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/pom.xml (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/pom.xml Sat Jun  2 15:35:46 2012
@@ -0,0 +1,60 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+      <groupId>org.apache.log4j</groupId>
+      <artifactId>log4j-modules</artifactId>
+      <version>1.4.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.log4j</groupId>
+  <artifactId>log4j-contribs</artifactId>
+  <name>Apache Log4j-Contribtutions</name>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.log4j</groupId>
+    	<artifactId>log4j-net</artifactId>
+    	<version>1.4.0-SNAPSHOT</version>
+    	<type>bundle</type>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.0.1</version>
+        <extensions>true</extensions>
+        <configuration>
+            <instructions>
+                <Export-Package>org.apache.log4j.contribs.*</Export-Package>
+            </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j;
+
+import java.io.*;
+import org.apache.log4j.*;
+
+
+/**
+ * An OutputStream that flushes out to a Category.<p>
+ * 
+ * Note that no data is written out to the Category until the stream is
+ *   flushed or closed.<p>
+ * 
+ * Example:<pre>
+ * // make sure everything sent to System.err is logged
+ * System.setErr(new PrintStream(new LoggingOutputStream(Category.getRoot(), Priority.WARN), true));
+ * 
+ * // make sure everything sent to System.out is also logged
+ * System.setOut(new PrintStream(new LoggingOutputStream(Category.getRoot(), Priority.INFO), true));
+ * </pre>
+ * 
+ * @author <a href="mailto://Jim.Moore@rocketmail.com">Jim Moore</a>
+ * @see Category
+ */
+public class LoggingOutputStream extends OutputStream {
+  protected static final String LINE_SEPERATOR = System.getProperty("line.separator");
+
+
+  /**
+   * Used to maintain the contract of {@link #close()}.
+   */
+  protected boolean hasBeenClosed = false;
+
+  /**
+   * The internal buffer where data is stored. 
+   */
+  protected byte[] buf;
+
+  /**
+   * The number of valid bytes in the buffer. This value is always 
+   *   in the range <tt>0</tt> through <tt>buf.length</tt>; elements 
+   *   <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid 
+   *   byte data.
+   */
+  protected int count;
+
+
+  /**
+   * Remembers the size of the buffer for speed.
+   */
+  private int bufLength;
+
+  /**
+   * The default number of bytes in the buffer. =2048
+   */
+  public static final int DEFAULT_BUFFER_LENGTH = 2048;
+
+
+  /**
+   * The category to write to.
+   */
+  protected Category category;
+
+  /**
+   * The priority to use when writing to the Category.
+   */
+  protected Priority priority;
+
+
+  private LoggingOutputStream() {
+    // illegal
+  }
+
+
+  /**
+   * Creates the LoggingOutputStream to flush to the given Category.
+   * 
+   * @param cat        the Category to write to
+   * 
+   * @param priority   the Priority to use when writing to the Category
+   * 
+   * @exception IllegalArgumentException
+   *                   if cat == null or priority == null
+   */
+  public LoggingOutputStream(Category cat, Priority priority)
+  throws IllegalArgumentException {
+    if (cat == null) {
+      throw new IllegalArgumentException("cat == null");
+    }
+    if (priority == null) {
+      throw new IllegalArgumentException("priority == null");
+    }
+
+    this.priority = priority;
+    category = cat;
+    bufLength = DEFAULT_BUFFER_LENGTH;
+    buf = new byte[DEFAULT_BUFFER_LENGTH];
+    count = 0;
+  }
+
+
+  /**
+   * Closes this output stream and releases any system resources
+   *   associated with this stream. The general contract of <code>close</code>
+   *   is that it closes the output stream. A closed stream cannot perform
+   *   output operations and cannot be reopened.
+   */
+  public void close() {
+    flush();
+    hasBeenClosed = true;
+  }
+
+
+  /**
+   * Writes the specified byte to this output stream. The general
+   * contract for <code>write</code> is that one byte is written
+   * to the output stream. The byte to be written is the eight
+   * low-order bits of the argument <code>b</code>. The 24
+   * high-order bits of <code>b</code> are ignored.
+   * 
+   * @param b          the <code>byte</code> to write
+   * 
+   * @exception IOException
+   *                   if an I/O error occurs. In particular,
+   *                   an <code>IOException</code> may be thrown if the
+   *                   output stream has been closed.
+   */
+  public void write(final int b) throws IOException {
+    if (hasBeenClosed) {
+      throw new IOException("The stream has been closed.");
+    }
+
+    // don't log nulls
+    if (b == 0) {
+      return;
+    }
+
+    // would this be writing past the buffer?
+    if (count == bufLength) {
+      // grow the buffer
+      final int newBufLength = bufLength+DEFAULT_BUFFER_LENGTH;
+      final byte[] newBuf = new byte[newBufLength];
+
+      System.arraycopy(buf, 0, newBuf, 0, bufLength);
+
+      buf = newBuf;
+      bufLength = newBufLength;
+    }
+
+    buf[count] = (byte)b;
+    count++;
+  }
+
+
+  /**
+   * Flushes this output stream and forces any buffered output bytes
+   *   to be written out. The general contract of <code>flush</code> is
+   *   that calling it is an indication that, if any bytes previously
+   *   written have been buffered by the implementation of the output
+   *   stream, such bytes should immediately be written to their
+   *   intended destination.
+   */
+  public void flush() {
+    if (count == 0) {
+      return;
+    }
+
+    // don't print out blank lines; flushing from PrintStream puts out these
+    if (count == LINE_SEPERATOR.length()) {
+      if ( ((char)buf[0]) == LINE_SEPERATOR.charAt(0)  &&
+           ( ( count == 1 ) ||  // <- Unix & Mac, -> Windows
+             ( (count == 2) && ((char)buf[1]) == LINE_SEPERATOR.charAt(1) ) ) ) {
+        reset();
+        return;
+      }
+    }
+
+    final byte[] theBytes = new byte[count];
+
+    System.arraycopy(buf, 0, theBytes, 0, count);
+
+    category.log(priority, new String(theBytes));
+
+    reset();
+  }
+
+
+  private void reset() {
+    // not resetting the buffer -- assuming that if it grew that it
+    //   will likely grow similarly again
+    count = 0;
+  }
+
+}
+

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/LoggingOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/EirikLygre/mail-2001-01-18 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/EirikLygre/mail-2001-01-18)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/EirikLygre/mail-2001-01-18?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/EirikLygre/mail-2001-01-18&p1=logging/log4j/branches/log4j12-bz53299/contribs/EirikLygre/mail-2001-01-18&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JamesHouse/mail-2001-01-23 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/JamesHouse/mail-2001-01-23)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JamesHouse/mail-2001-01-23?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JamesHouse/mail-2001-01-23&p1=logging/log4j/branches/log4j12-bz53299/contribs/JamesHouse/mail-2001-01-23&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JamieTsao/mail-2001-06-20 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/Jamie Tsao/mail-2001-06-20)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JamieTsao/mail-2001-06-20?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JamieTsao/mail-2001-06-20&p1=logging/log4j/branches/log4j12-bz53299/contribs/Jamie%20Tsao/mail-2001-06-20&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1326 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/JimMoore/mail-2001-03-12T1326)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1326?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1326&p1=logging/log4j/branches/log4j12-bz53299/contribs/JimMoore/mail-2001-03-12T1326&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1454 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/JimMoore/mail-2001-03-12T1454)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1454?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-12T1454&p1=logging/log4j/branches/log4j12-bz53299/contribs/JimMoore/mail-2001-03-12T1454&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-13T0646 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/JimMoore/mail-2001-03-13T0646)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-13T0646?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/JimMoore/mail-2001-03-13T0646&p1=logging/log4j/branches/log4j12-bz53299/contribs/JimMoore/mail-2001-03-13T0646&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2001-02-01 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/KevinSteppe/mail-2001-02-01)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2001-02-01?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2001-02-01&p1=logging/log4j/branches/log4j12-bz53299/contribs/KevinSteppe/mail-2001-02-01&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/KevinSteppe/mail-2002-03-27.txt)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt&p1=logging/log4j/branches/log4j12-bz53299/contribs/KevinSteppe/mail-2002-03-27.txt&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KevinSteppe/mail-2002-03-27.txt
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KitchingSimon/mail-2001-02-07 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/KitchingSimon/mail-2001-02-07)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KitchingSimon/mail-2001-02-07?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/KitchingSimon/mail-2001-02-07&p1=logging/log4j/branches/log4j12-bz53299/contribs/KitchingSimon/mail-2001-02-07&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/LeosLiterak/mail (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/LeosLiterak/mail)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/LeosLiterak/mail?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/LeosLiterak/mail&p1=logging/log4j/branches/log4j12-bz53299/contribs/LeosLiterak/mail&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/MarkDouglas/Log.txt)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt&p1=logging/log4j/branches/log4j12-bz53299/contribs/MarkDouglas/Log.txt&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/Log.txt
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/mail-2001-01-17 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/MarkDouglas/mail-2001-01-17)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/mail-2001-01-17?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/MarkDouglas/mail-2001-01-17&p1=logging/log4j/branches/log4j12-bz53299/contribs/MarkDouglas/mail-2001-01-17&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/VolkerMentzner/mail-03-05-2001 (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/VolkerMentzner/mail-03-05-2001)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/VolkerMentzner/mail-03-05-2001?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/contribs/VolkerMentzner/mail-03-05-2001&p1=logging/log4j/branches/log4j12-bz53299/contribs/VolkerMentzner/mail-03-05-2001&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j.gui;
+
+import org.apache.log4j.helpers.CyclicBuffer;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.Layout;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.spi.LoggingEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JButton;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.JScrollPane;
+import javax.swing.BoxLayout;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.Container;
+
+/**
+   The AppenderTable illustrates one possible implementation of
+   an Table possibly containing a great many number of rows.
+
+   <p>In this particular example we use a fixed size buffer
+   (CyclicBuffer) although this data structure could be easily
+   replaced by dynamically growing one, such as a Vector. The required
+   properties of the data structure is 1) support for indexed element
+   access 2) support for the insertion of new elements at the end.
+
+   <p>Experimentation on my 1400Mhz AMD machine show that it takes
+   about 45 micro-seconds to insert an element in the table. This
+   number does not depend on the size of the buffer. It takes as much
+   (or as little) time to insert one million elements to a buffer of
+   size 10 as to a buffer of size 10'000. It takes about 4 seconds to
+   insert a total of 100'000 elements into the table.
+
+   <p>On windows NT the test will run about twice as fast if you give
+   the focus to the window that runs "java AppenderTable" and not the
+   window that contains the Swing JFrame.  
+   
+   @author CekiGulcu */
+public class AppenderTable extends JTable {
+
+
+  static Logger logger = Logger.getLogger(AppenderTable.class);
+
+  static public void main(String[] args) {
+
+    if(args.length != 2) {
+      System.err.println(
+      "Usage: java AppenderTable bufferSize runLength\n"
+      +"  where bufferSize is the size of the cyclic buffer in the TableModel\n"
+      +"  and runLength is the total number of elements to add to the table in\n"
+      +"  this test run.");
+      return;
+    }
+
+    JFrame frame = new JFrame("JTableAppennder test");
+    Container container = frame.getContentPane();
+
+    AppenderTable tableAppender = new AppenderTable();
+    
+    int bufferSize = Integer.parseInt(args[0]);
+    AppenderTableModel model = new AppenderTableModel(bufferSize);
+    tableAppender.setModel(model);
+
+    int runLength = Integer.parseInt(args[1]);
+
+    JScrollPane sp = new JScrollPane(tableAppender);
+    sp.setPreferredSize(new Dimension(250, 80));
+    
+    container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
+    container.add(sp);
+
+    // The "ADD" button is intended for manual testing. It will
+    // add one new logging event to the table.
+    JButton button = new JButton("ADD");
+    container.add(button);
+    button.addActionListener(new AppTableJTableAddAction(tableAppender));
+
+    frame.setSize(new Dimension(500,300));
+    frame.setVisible(true);
+
+    long before = System.currentTimeMillis();
+
+    int i = 0;
+    while(i++ < runLength) {      
+      LoggingEvent event = new LoggingEvent("x", logger, Level.ERROR, 
+					    "Message "+i, null);
+      tableAppender.doAppend(event);
+    }
+
+    long after = System.currentTimeMillis();
+
+    long totalTime = (after-before);
+    
+    System.out.println("Total time :"+totalTime+ " milliseconds for "+
+		       "runLength insertions.");
+    System.out.println("Average time per insertion :"
+		       +(totalTime*1000/runLength)+ " micro-seconds.");
+
+
+  }
+
+  public
+  AppenderTable() {
+    this.setDefaultRenderer(Object.class, new Renderer());
+  }
+
+  /**
+     When asked to append we just insert directly into the model. In a
+     real appender we would use two buffers one for accumulating
+     events and another to accumalte events but after filtering. Only
+     the second buffer would be displayed in the table and made
+     visible to the user.*/
+  public
+  void doAppend(LoggingEvent event) {
+    ((AppenderTableModel)getModel()).insert(event);
+  }
+
+  /**
+     The Renderer is required to display object in a friendlier from.
+     This particular renderer is just a JTextArea.
+
+     <p>The important point to note is that we only need *one*
+     renderer. */
+  class Renderer extends JTextArea implements TableCellRenderer {
+
+    PatternLayout layout;
+
+    public
+    Renderer() {
+      layout = new PatternLayout("%r %p %c [%t] -  %m");
+    }
+
+    public Component getTableCellRendererComponent(JTable table,
+						   Object value,
+						   boolean isSelected,
+						   boolean hasFocus,
+						   int row,
+						   int column) {
+
+      // If its a LoggingEvent than format it using our layout.
+      if(value instanceof LoggingEvent) {
+	LoggingEvent event = (LoggingEvent) value;
+	String str = layout.format(event);
+	setText(str);
+      } else {
+	setText(value.toString());
+      }
+      return this;
+    }
+  }
+}
+
+class AppenderTableModel extends AbstractTableModel {
+
+  CyclicBuffer cb;
+  
+  AppenderTableModel(int size) {
+    cb = new CyclicBuffer(size);
+  }
+
+  /**
+     Insertion to the model always results in a fireTableDataChanged
+     method call. Suprisingly enough this has no crippling impact on
+     performance.  */
+  public
+  void insert(LoggingEvent event) {
+    cb.add(event);
+    fireTableDataChanged();
+  }
+
+  /**
+     We assume only one column.
+  */
+  public 
+  int getColumnCount() { 
+    return 1; 
+  }
+  
+  /**
+     The row count is given by the number of elements in the
+     buffer. This number is guaranteed to be between 0 and the buffer
+     size (inclusive). */
+  public int getRowCount() { 
+    return cb.length();
+  }
+  
+  /**
+     Get the value in a given row and column. We suppose that there is
+     only one colemn so we are only concerned with the row.
+
+     <p>Interesting enough this method returns an object. This leaves
+     the door open for a TableCellRenderer to render the object in
+     a variety of ways.
+  */
+  public 
+  Object getValueAt(int row, int col) {
+    return cb.get(row);
+  }
+}
+
+
+/**
+   The JTableAddAction is called when the user clicks on the "ADD"
+   button.
+*/
+class AppTableJTableAddAction implements ActionListener {
+    
+  AppenderTable appenderTable;
+  Logger dummy = Logger.getLogger("x");
+  int counter = 0;
+  public
+  AppTableJTableAddAction(AppenderTable appenderTable) {
+    this.appenderTable = appenderTable;
+  }
+    
+  public
+  void actionPerformed(ActionEvent e) {
+    counter++;
+    LoggingEvent event = new LoggingEvent("x", dummy, Level.DEBUG, 
+					  "Message "+counter, null);    
+    appenderTable.doAppend(event);
+  }
+}

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/AppenderTable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,368 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.log4j.gui;
+
+import org.apache.log4j.helpers.CyclicBuffer;
+import org.apache.log4j.helpers.LogLog;
+import org.apache.log4j.Priority;
+import org.apache.log4j.Category;
+import org.apache.log4j.Layout;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.spi.LoggingEvent;
+
+import javax.swing.JList;
+import javax.swing.AbstractListModel;
+import javax.swing.JFrame;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.JScrollPane;
+import javax.swing.ListCellRenderer;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import javax.swing.BoxLayout;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.Container;
+import javax.swing.ImageIcon;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.net.URL;
+import java.awt.Rectangle;
+
+/**
+ * @author Sven Reimers
+ */
+public class JListView extends JList {
+
+
+  static Category cat = Category.getInstance(JListView.class.getName());
+
+
+  //JListViewModel model;
+  PatternLayout layout;
+
+  static LoggingEvent proto = new LoggingEvent("x", cat, Priority.ERROR, 
+					       "Message ", new Throwable());
+
+  public
+  JListView(JListViewModel model) {
+    super(model);
+    layout = new PatternLayout("%r %p %c [%t] -  %m");
+    //this.setModel(model);
+    this.setCellRenderer(new MyCellRenderer());
+    //    setFixedCellWidth(10);
+    //setFixedCellHeight(20);
+
+  }
+
+  public
+  void add(LoggingEvent event) {
+    ((JListViewModel)getModel()).add(event);
+  }
+
+  /*
+  public
+  Dimension getPreferredSize() {
+    System.out.println("getPreferredSize() called");
+    return super.getPreferredSize();
+  }
+
+
+  public
+  int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
+				 int direction) {
+    System.out.println("getScrollableUnitIncrement called with " + visibleRect +
+		       "orientation: "+orientation+", direction: "+direction);
+    return super.getScrollableUnitIncrement(visibleRect, orientation, 
+    				    direction);
+  }
+
+  public
+  int getScrollableBlockIncrement(Rectangle visibleRect, int orientation,
+				  int direction) {
+    System.out.println("getScrollableBlockIncrement called with " + 
+		       visibleRect + "orientation: "+orientation+
+		       ", direction: "+direction);
+    return super.getScrollableBlockIncrement(visibleRect, orientation, 
+    				     direction);
+  }
+  */
+
+  //public
+  //boolean getScrollableTracksViewportWidth() {
+  //System.out.println("getScrollableTracksViewportWidth called.");
+  //return true;
+    //boolean b = super.getScrollableTracksViewportWidth();
+    //System.out.println("result is: "+b);
+    //return b;
+  //}
+  
+  //public
+  //boolean getScrollableTracksViewportHeight() { 
+  // System.out.println("getScrollableTracksViewportHeight called.");
+  // return true;
+     //boolean b = super.getScrollableTracksViewportHeight();
+     //System.out.println("result is: "+b);
+     //return b;
+  //}
+
+  //public 
+  //int getFirstVisibleIndex() {
+  //int r = getFirstVisibleIndex(); 
+  // System.out.println("----------getFirstVisibleIndex called, result: "+r);
+  //return r;
+  //}
+
+  //public
+  //Object getPrototypeCellValue() {
+  //return proto;
+  //}
+
+  
+  
+  static public void main(String[] args) {
+
+    JFrame frame = new JFrame("JListView test");
+    Container container = frame.getContentPane();
+
+    JListView view = new JListView(new JListViewModel(Integer.parseInt(args[0])));
+
+
+    JScrollPane sp = new JScrollPane(view);
+    sp.setPreferredSize(new Dimension(250, 80));
+    
+    container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
+    //container.add(view);
+    container.add(sp);
+
+    JButton b1 = new JButton("Add 1");
+    JButton b10 = new JButton("Add 10");
+    JButton b100 = new JButton("Add 100");
+    JButton b1000 = new JButton("Add 1000");
+    JButton b10000 = new JButton("Add 10000");
+
+    JPanel panel = new JPanel(new GridLayout(0,1));
+    container.add(panel);
+
+    panel.add(b1);
+    panel.add(b10);
+    panel.add(b100);
+    panel.add(b1000);
+    panel.add(b10000);
+    
+
+    AddAction a1 = new AddAction(view, 1);
+    AddAction a10 = new AddAction(view, 10);
+    AddAction a100 = new AddAction(view, 100);
+    AddAction a1000 = new AddAction(view, 1000);
+    AddAction a10000 = new AddAction(view, 10000);
+
+    b1.addActionListener(a1);
+    b10.addActionListener(a10);
+    b100.addActionListener(a100);
+    b1000.addActionListener(a1000);
+    b10000.addActionListener(a10000);
+
+    frame.setVisible(true);
+    frame.setSize(new Dimension(700,700));
+
+    long before = System.currentTimeMillis();
+
+    int RUN = 1000;
+    int i = 0;
+    while(i++ < RUN) {      
+      LoggingEvent event0 = new LoggingEvent("x", cat, Priority.ERROR, 
+					     "Message "+i, null);
+      
+      Throwable t = new Exception("hello "+i);
+      LoggingEvent event1 = new LoggingEvent("x", cat, Priority.ERROR, 
+					     "Message "+i, t);
+      
+
+      if(i % 10 == 0) {	
+	event1.getThreadName();
+	view.add(event1);
+      } else {
+	event0.getThreadName();
+	view.add(event0);
+      }
+    }
+
+    long after = System.currentTimeMillis();
+    System.out.println("Time taken :"+ ((after-before)*1000/RUN));
+
+  }
+
+  class MyCellRenderer extends JTextArea implements ListCellRenderer {
+
+    Object o = new Object();
+    int i = 0;
+    final ImageIcon longIcon = new ImageIcon("RedFlag.gif");
+
+    public
+    MyCellRenderer() {
+      System.out.println("----------------------");
+      
+    }
+
+
+
+    public
+    int getTabSize()  {
+      return 2;
+    }
+
+    public Image loadIcon ( String path ) {
+    Image img = null;
+    try {
+      URL url = ClassLoader.getSystemResource(path);
+      img = (Image) (Toolkit.getDefaultToolkit()).getImage(url);
+    } catch (Exception e) {
+      System.out.println("Exception occured: " + e.getMessage() + 
+			 " - " + e );   
+    }	
+    return (img);
+  }
+
+    public Component getListCellRendererComponent(JList list,
+						Object value, 
+						int index, // cell index
+						boolean isSelected, 
+						boolean cellHasFocus) {
+
+      //      System.out.println(o + " ============== " + i++);
+      //LogLog.error("=======", new Exception());
+      //setIcon(longIcon);
+      if(value instanceof LoggingEvent) {
+	LoggingEvent event = (LoggingEvent) value;
+	String str = layout.format(event);
+	String t = event.getThrowableInformation().toString();
+
+	if(t != null) {
+	  setText(str + Layout.LINE_SEP + t);
+	} else {	
+	  setText(str);
+	}
+	
+      } else {
+	setText(value.toString());
+      }
+
+
+      return this;
+    }
+  }
+}
+
+
+
+class JListViewModel extends AbstractListModel {
+
+  CyclicBuffer cb;
+  
+  JListViewModel(int size) {
+    cb = new CyclicBuffer(size);
+  }
+
+  public
+  void add(LoggingEvent event) {
+    //System.out.println("JListViewModel.add called");
+    cb.add(event);
+    int j = cb.length();
+    fireContentsChanged(this, 0, j);
+  }
+    
+
+
+  public
+  Object getElementAt(int index) {
+    return cb.get(index);
+  }
+
+  public
+  int getSize() {
+    return cb.length();
+  }
+  
+}
+
+class AddAction implements ActionListener {
+
+  Thread t;
+
+  static int counter = 0;
+
+  public
+  AddAction(JListView view, int burst) {
+    this.t = new AddThread(view, burst);
+    t.start();
+  }
+    
+  public
+  void actionPerformed(ActionEvent e) {
+    System.out.println("Action occured");
+    synchronized(t) {
+      t.notify();
+    }
+  }
+
+  class AddThread extends Thread {
+    int burst;
+    JListView view;
+
+    Category cat = Category.getInstance("x");
+    
+    AddThread(JListView view, int burst) {
+      super();
+      this.burst = burst;
+      this.view = view;
+      setName("AddThread"+burst);
+    }
+
+    public
+    void run() {
+
+      while(true) {
+	synchronized(this) {
+	  try {
+	    this.wait();
+	  } catch(Exception e) {
+	  }
+	}
+	for(int i = 0; i < burst; i++) {
+	  LoggingEvent event = new LoggingEvent("x", cat, Priority.DEBUG, 
+						"Message "+counter, null);
+
+	  event.getThreadName();    
+	  if(counter % 50 == 0) {
+	    //event.throwable = new Exception("hello "+counter);
+	  }
+	  counter++;
+	  view.add(event);
+	}
+      }
+    }
+  }
+}

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JListView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.log4j.gui;
+
+import org.apache.log4j.helpers.CyclicBuffer;
+import org.apache.log4j.helpers.LogLog;
+import org.apache.log4j.Priority;
+import org.apache.log4j.Category;
+import org.apache.log4j.Layout;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.spi.LoggingEvent;
+
+import javax.swing.JList;
+import javax.swing.AbstractListModel;
+import javax.swing.JFrame;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.JScrollPane;
+import javax.swing.ListCellRenderer;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import javax.swing.BoxLayout;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.Container;
+import javax.swing.ImageIcon;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.net.URL;
+import java.awt.Rectangle;
+
+/**
+ * @author Sven Reimers
+ */
+public class JTableAppender extends JTable {
+
+  static Category cat = Category.getInstance(JTableAppender.class.getName());
+
+  PatternLayout layout;
+
+  public
+  JTableAppender() {
+    layout = new PatternLayout("%r %p %c [%t] -  %m");
+    this.setDefaultRenderer(Object.class, new Renderer());
+
+  }
+
+  public
+  void add(LoggingEvent event) {
+    ((JTableAppenderModel)getModel()).add(event);
+  }
+
+  public
+  Dimension getPreferredSize() {
+    System.out.println("getPreferredSize() called");
+    return super.getPreferredSize();
+  }
+
+  static public void main(String[] args) {
+
+    JFrame frame = new JFrame("JListView test");
+    Container container = frame.getContentPane();
+
+    JTableAppender appender = new JTableAppender();
+    
+    JTableAppenderModel model = new 
+                              JTableAppenderModel(Integer.parseInt(args[0]));
+    appender.setModel(model);
+    //appender.createDefaultColumnsFromModel();    
+
+
+    JScrollPane sp = new JScrollPane(appender);
+    sp.setPreferredSize(new Dimension(250, 80));
+    
+    container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
+    //container.add(view);
+    container.add(sp);
+
+    JButton button = new JButton("ADD");
+    container.add(button);
+    
+
+    button.addActionListener(new JTableAppenderJTableAddAction(appender));
+
+    frame.setVisible(true);
+    frame.setSize(new Dimension(700,700));
+
+    long before = System.currentTimeMillis();
+
+    int RUN = 10000;
+    int i = 0;
+    while(i++ < RUN) {      
+      LoggingEvent event = new LoggingEvent("x", cat, Priority.ERROR, 
+					    "Message "+i, null);
+      event.getThreadName();
+      if(i % 10 == 0) {
+	//event.throwable = new Exception("hello "+i);
+      }
+      appender.add(event);
+    }
+
+    long after = System.currentTimeMillis();
+    System.out.println("Time taken :"+ ((after-before)*1000/RUN));
+
+  }
+
+  class Renderer extends JTextArea implements TableCellRenderer {
+
+    Object o = new Object();
+    int i = 0;
+
+    public
+    Renderer() {
+      System.out.println("Render() called ----------------------");      
+    }
+
+    public Component getTableCellRendererComponent(JTable table,
+						   Object value,
+						   boolean isSelected,
+						   boolean hasFocus,
+						   int row,
+						   int column) {
+
+      System.out.println(o + " ============== " + i++);
+      //LogLog.error("=======", new Exception());
+      //setIcon(longIcon);
+      if(value instanceof LoggingEvent) {
+	LoggingEvent event = (LoggingEvent) value;
+	String str = layout.format(event);
+	String t = event.getThrowableInformation().toString();
+	
+	if(t != null) {
+	  System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+	  setText(str + Layout.LINE_SEP + t);
+	} else {	
+	  setText(str);
+	}
+	
+      } else {
+	setText(value.toString());
+      }
+
+
+      return this;
+    }
+  }
+}
+
+
+
+class JTableAppenderModel extends AbstractTableModel {
+
+  CyclicBuffer cb;
+  
+  JTableAppenderModel(int size) {
+    cb = new CyclicBuffer(size);
+  }
+
+  public
+  void add(LoggingEvent event) {
+    //System.out.println("JListViewModel.add called");
+    cb.add(event);
+    int j = cb.length();
+
+    fireTableDataChanged();
+
+  }
+  public 
+  int getColumnCount() { 
+    return 1; 
+  }
+
+  public int getRowCount() { 
+    return cb.length();
+  }
+
+  //public
+  //Class getColumnClass(int index) {
+  //  System.out.println("getColumnClass called " + index);
+  //  return LoggingEvent.class;
+  //}
+
+  public 
+  Object getValueAt(int row, int col) {
+    return cb.get(row);
+  }
+}
+
+
+class JTableAppenderJTableAddAction implements ActionListener {
+    
+  int j;
+  JTableAppender appender;
+
+  Category cat = Category.getInstance("x");
+  
+  public
+  JTableAppenderJTableAddAction(JTableAppender appender) {
+    this.appender = appender;
+    j = 0;
+  }
+    
+  public
+  void actionPerformed(ActionEvent e) {
+    System.out.println("Action occured");
+
+    LoggingEvent event = new LoggingEvent("x", cat, Priority.DEBUG, 
+					    "Message "+j, null);
+    
+    if(j % 5 == 0) {
+      //event.throwable = new Exception("hello "+j);
+    }
+    j++;
+    appender.add(event);
+  }
+}

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/gui/JTableAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java (from r1345516, logging/log4j/branches/log4j12-bz53299/contribs/KitchingSimon/DatagramStringWriter.java)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java?p2=logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java&p1=logging/log4j/branches/log4j12-bz53299/contribs/KitchingSimon/DatagramStringWriter.java&r1=1345516&r2=1345524&rev=1345524&view=diff
==============================================================================
    (empty)

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/DatagramStringWriter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.net;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * This interface defines all methods that have to be implemented for a HTTPRequestHandler for the
+ * PluggableHTTPServer.
+ *
+ * @author <a HREF="mailto:V.Mentzner@psi-bt.de">Volker Mentzner</a>
+ */
+public interface HTTPRequestHandler {
+
+ /**
+   * Gets the title for html page
+   */
+  public String getTitle();
+
+ /**
+   * Sets the title for html page
+   */
+  public void setTitle(String title);
+
+ /**
+   * Gets the description for html page
+   */
+  public String getDescription();
+
+ /**
+   * Sets the description for html page
+   */
+  public void setDescription(String description);
+
+ /**
+   * Gets the virtual path in the HTTP server that ist handled in this HTTPRequestHandler.
+   * So the root path handler will return "/" (without brackets) because it handles the path
+   * "http://servername/" or a handler for "http://servername/somepath/" will return "/somepath/"
+   * It is important to include the trailing "/" because all HTTPRequestHandler have to serve a path!
+   */
+  public String getHandledPath();
+
+ /**
+   * Sets the virtual path in the HTTP server that ist handled in this HTTPRequestHandler.
+   * So set the path to "/" for the root path handler because it handles the path
+   * "http://servername/" or set it to "/somepath/" for a handler for "http://servername/somepath/".
+   * It is important to include the trailing "/" because all HTTPRequestHandler have to serve a path!
+   */
+  public void setHandledPath(String path);
+
+ /**
+   * Handles the given request and writes the reply to the given out-stream. Every handler has to check
+   * the request for the right path info.
+   *
+   * @param request - client browser request
+   * @param out - Out stream for sending data to client browser
+   * @return if the request was handled by this handler : true, else : false
+   */
+  public boolean handleRequest(String request, Writer out);
+}
\ No newline at end of file

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/HTTPRequestHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,601 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j.net;
+
+import java.sql.*;
+import java.util.*;
+import org.apache.log4j.*;
+import org.apache.log4j.helpers.*;
+import org.apache.log4j.spi.*;
+
+/**
+The JDBCAppender, writes messages into a database
+
+<p><b>The JDBCAppender is configurable at runtime by setting options in two alternatives : </b></p>
+<dir>
+	<p><b>1. Use a configuration-file</b></p>
+	<p>Define the options in a file (<A HREF="configfile_example.txt">example</A>) and call a <code>PropertyConfigurator.configure(filename)</code> in your code.</p>
+	<p><b>2. Use the methods of JDBCAppender to do it</b></p>
+	<p>Call <code>JDBCAppender::setOption(JDBCAppender.xxx_OPTION, String value)</code> to do it analogically without a configuration-file (<A HREF="code_example2.java">example</A>)</p>
+</dir>
+
+<p>All available options are defined as static String-constants in JDBCAppender named xxx_OPTION.</p>
+
+<p><b>Here is a description of all available options :</b></p>
+<dir>
+	<p><b>1. Database-options to connect to the database</b></p>
+	<p>- <b>URL_OPTION</b>			: a database url of the form jdbc:subprotocol:subname</p>
+	<p>- <b>USERNAME_OPTION</b>	: the database user on whose behalf the connection is being made</p>
+	<p>- <b>PASSWORD_OPTION</b>	: the user's password</p>
+
+	<p><b>2. Connector-option to specify your own JDBCConnectionHandler</b></p>
+	<p>- <b>CONNECTOR_OPTION</b>	: a classname which is implementing the JDBCConnectionHandler-interface</p>
+	<p>This interface is used to get a customized connection.</p>
+	<p>If in addition the database-options are given, these options will be used as arguments for the JDBCConnectionHandler-interface to get a connection.</p>
+	<p>Else if no database-options are given, the JDBCConnectionHandler-interface is called without them.</p>
+	<p>Else if this option is not defined, the database-options are required to open a connection by the JDBCAppender.</p>
+
+	<p><b>3. SQL-option to specify a static sql-statement which will be performed with every occuring message-event</b></p>
+	<p>- <b>SQL_OPTION</b>			: a sql-statement which will be used to write to the database</p>
+	<p>Use the variable <b>@MSG@</b> on a location in the statement, which has to be dynamically replaced by the message-text.</p>
+	<p>If you give this option, the table-option and columns-option will be ignored !</p>
+
+	<p><b>4. Table-option to specify a table contained by the database</b></p>
+	<p>- <b>TABLE_OPTION</b>		: the table in which the logging will be done</p>
+
+	<p><b>5. Columns-option to describe the important columns of the table (Not nullable columns are mandatory to describe!)</b></p>
+	<p>- <b>COLUMNS_OPTION</b>		: a formatted list of column-descriptions</p>
+	<p>Each column description consists of</p>
+	<dir>
+		<p>- the <b><i>name</i></b> of the column (required)</p>
+		<p>- a <b><i>logtype</i></b> which is a static constant of class LogType (required)</p>
+		<p>- and a <b><i>value</i></b> which depends by the LogType (optional/required, depending by logtype)</p>
+	</dir>
+	<p>Here is a description of the available logtypes of class <b>{@link LogType}</b> and how to handle the <b><i>value</i></b>:</p>
+	<dir>
+		<p>o <b>MSG</b>			= a value will be ignored, the column will get the message. (One columns need to be of this type!)</p>
+		<p>o <b>STATIC</b>		= the value will be filled into the column with every logged message. (Ensure that the type of value can be casted into the sql-type of the column!)</p>
+		<p>o <b>ID</b>			= value must be a classname, which implements the JDBCIDHandler-interface.</p>
+		<p>o <b>TIMESTAMP</b>	= a value will be ignored, the column will be filled with a actually timestamp with every logged message.</p>
+		<p>o <b>EMPTY</b>		= a value will be ignored, the column will be ignored when writing to the database (Ensure to fill not nullable columns by a database trigger!)</p>
+	</dir>
+	<p>If there are more than one column to describe, the columns must be separated by a Tabulator-delimiter (unicode0008) !</p>
+	<p>The arguments of a column-description must be separated by the delimiter '~' !</p>
+	<p><i>(Example :  name1~logtype1~value1   name2~logtype2~value2...)</i></p>
+
+	<p><b>6. Layout-options to define the layout of the messages (optional)</b></p>
+	<p>- <b>_</b> : the layout wont be set by a xxx_OPTION</p>
+	<p>See the configuration-file and code examples below...</p>
+	<p>The default is a layout of the class {@link org.apache.log4j.PatternLayout} with the pattern=%m which representate only the message.</p>
+
+	<p><b>7. Buffer-option to define the size of the message-event-buffer (optional)</b></p>
+	<p>- <b>BUFFER_OPTION</b>		: define how many messages will be buffered until they will be updated to the database.</p>
+	<p>The default is buffer=1, which will do a update with every happened message-event.</p>
+
+	<p><b>8. Commit-option to define a auto-commitment</b></p>
+	<p>- <b>COMMIT_OPTION</b>		: define whether updated messages should be committed to the database (Y) or not (N).</p>
+	<p>The default is commit=Y.</p>
+</dir>
+
+<p><b>The sequence of some options is important :</b></p>
+<dir>
+	<p><b>1. Connector-option OR/AND Database-options</b></p>
+	<p>Any database connection is required !</p>
+	<p><b>2. (Table-option AND Columns-option) OR SQL-option</b></p>
+	<p>Anything of that is required ! Whether where to write something OR what to write somewhere...;-)</p>
+	<p><b>3. All other options can be set at any time...</b></p>
+	<p>The other options are optional and have a default initialization, which can be customized.</p>
+</dir>
+
+<p><b>Here is a <b>configuration-file example</b>, which can be used as argument for the <b>PropertyConfigurator</b> : </b><A HREF="configfile_example.txt"> configfile_example.txt</A></p>
+
+<p><b>Here is a <b>code-example</b> to configure the JDBCAppender <b>with a configuration-file</b> : </b><A HREF="code_example1.java"> code_example1.java</A></p>
+
+<p><b>Here is a <b>another code-example</b> to configure the JDBCAppender <b>without a configuration-file</b> : </b><A HREF="code_example2.java"> code_example2.java</A></p>
+
+
+
+<p><b>Author : </b><A HREF="mailto:t.fenner@klopotek.de">Thomas Fenner</A></p>
+
+@since 1.0
+*/
+public class JDBCAppender extends AppenderSkeleton
+{
+	/**
+	A database-option to to set a database url of the form jdbc:subprotocol:subname.
+	*/
+	public static final String URL_OPTION			= "url";
+
+	/**
+	A database-option to set the database user on whose behalf the connection is being made.
+	*/
+	public static final String USERNAME_OPTION	= "username";
+
+	/**
+	A database-option to set the user's password.
+	*/
+	public static final String PASSWORD_OPTION	= "password";
+
+	/**
+	A table-option to specify a table contained by the database
+	*/
+	public static final String TABLE_OPTION		= "table";
+
+	/**
+	A connector-option to specify your own JDBCConnectionHandler
+	*/
+	public static final String CONNECTOR_OPTION	= "connector";
+
+	/**
+   A columns-option to describe the important columns of the table
+	*/
+	public static final String COLUMNS_OPTION		= "columns";
+
+	/**
+	A sql-option to specify a static sql-statement which will be performed with every occuring message-event
+   */
+	public static final String SQL_OPTION			= "sql";
+
+	/**
+   A buffer-option to define the size of the message-event-buffer
+	*/
+	public static final String BUFFER_OPTION		= "buffer";
+
+	/**
+   A commit-option to define a auto-commitment
+	*/
+	public static final String COMMIT_OPTION		= "commit";
+
+
+	//Variables to store the options values setted by setOption() :
+	private String url		= null;
+	private String username	= null;
+	private String password	= null;
+	private String table		= null;
+	private String connection_class = null;
+	private String sql		= null;
+	private boolean docommit = true;
+	private int buffer_size	= 1;
+   private JDBCConnectionHandler connectionHandler = null;
+
+	//This buffer stores message-events.
+   //When the buffer_size is reached, the buffer will be flushed and the messages will updated to the database.
+	private ArrayList buffer = new ArrayList();
+
+   //Database-connection
+	private Connection con = null;
+
+	//This class encapsulate the logic which is necessary to log into a table
+	private JDBCLogger jlogger = new JDBCLogger();
+
+   //Flags :
+   //A flag to indicate a established database connection
+	private boolean connected = false;
+   //A flag to indicate configuration status
+	private boolean configured = false;
+   //A flag to indicate that everything is ready to get append()-commands.
+	private boolean ready = false;
+
+	/**
+	If program terminates close the database-connection and flush the buffer
+   */
+	public void finalize()
+	{
+		close();
+      super.finalize();
+	}
+
+	/**
+	Internal method. Returns a array of strings containing the available options which can be set with method setOption()
+	*/
+	public String[] getOptionStrings()
+   {
+   	// The sequence of options in this string is important, because setOption() is called this way ...
+		return new String[]{CONNECTOR_OPTION, URL_OPTION, USERNAME_OPTION, PASSWORD_OPTION, SQL_OPTION, TABLE_OPTION, COLUMNS_OPTION, BUFFER_OPTION, COMMIT_OPTION};
+	}
+
+
+	/**
+     Sets all necessary options
+	*/
+	public void setOption(String _option, String _value)
+	{
+   	_option = _option.trim();
+      _value = _value.trim();
+
+		if(_option == null || _value == null) return;
+		if(_option.length() == 0 || _value.length() == 0) return;
+
+      _value = _value.trim();
+
+		if(_option.equals(CONNECTOR_OPTION))
+      {
+      	if(!connected) connection_class = _value;
+      }
+		else if(_option.equals(URL_OPTION))
+		{
+			if(!connected) url = _value;
+		}
+		else if(_option.equals(USERNAME_OPTION))
+		{
+			if(!connected) username = _value;
+		}
+		else if(_option.equals(PASSWORD_OPTION))
+		{
+			if(!connected) password = _value;
+		}
+		else if(_option.equals(SQL_OPTION))
+      {
+			sql = _value;
+      }
+		else if(_option.equals(TABLE_OPTION))
+      {
+      	if(sql != null) return;
+      	table = _value;
+      }
+		else if(_option.equals(COLUMNS_OPTION))
+      {
+      	if(sql != null) return;
+
+			String name = null;
+         int logtype = -1;
+         String value = null;
+         String column = null;
+         String arg = null;
+         int num_args = 0;
+         int num_columns = 0;
+			StringTokenizer st_col;
+			StringTokenizer st_arg;
+
+         //Columns are TAB-separated
+			st_col = new StringTokenizer(_value,  "	");
+
+			num_columns = st_col.countTokens();
+
+         if(num_columns < 1)
+  	      {
+     	   	errorHandler.error("JDBCAppender::setOption(), Invalid COLUMN_OPTION value : " + _value + " !");
+            return;
+        	}
+
+         for(int i=1; i<=num_columns; i++)
+         {
+				column = st_col.nextToken();
+
+            //Arguments are ~-separated
+				st_arg = new StringTokenizer(column, "~");
+
+				num_args = st_arg.countTokens();
+
+	         if(num_args < 2)
+   	      {
+      	   	errorHandler.error("JDBCAppender::setOption(), Invalid COLUMN_OPTION value : " + _value + " !");
+               return;
+         	}
+
+	         for(int j=1; j<=num_args; j++)
+   	      {
+					arg = st_arg.nextToken();
+
+					if(j == 1) name = arg;
+					else if(j == 2)
+      	      {
+         	   	try
+            	   {
+							logtype = Integer.parseInt(arg);
+	               }
+   	            catch(Exception e)
+      	         {
+         	      	logtype = LogType.parseLogType(arg);
+	               }
+
+						if(!LogType.isLogType(logtype))
+   	            {
+	   	            errorHandler.error("JDBCAppender::setOption(), Invalid COLUMN_OPTION LogType : " + arg + " !");
+                     return;
+         	      }
+            	}
+					else if(j == 3) value = arg;
+   	      }
+
+	         if(!setLogType(name, logtype, value)) return;
+         }
+      }
+		else if(_option.equals(BUFFER_OPTION))
+      {
+        	try
+         {
+				buffer_size = Integer.parseInt(_value);
+         }
+         catch(Exception e)
+         {
+	         errorHandler.error("JDBCAppender::setOption(), Invalid BUFFER_OPTION value : " + _value + " !");
+				return;
+         }
+      }
+		else if(_option.equals(COMMIT_OPTION))
+      {
+      	docommit = _value.equals("Y");
+      }
+
+      if(_option.equals(SQL_OPTION) || _option.equals(TABLE_OPTION))
+      {
+			if(!configured) configure();
+      }
+	}
+
+	/**
+	Internal method. Returns true, you may define your own layout...
+	*/
+	public boolean requiresLayout()
+	{
+		return true;
+	}
+
+
+	/**
+	Internal method. Close the database connection & flush the buffer.
+	*/
+	public void close()
+	{
+	   flush_buffer();
+      if(connection_class == null)
+      {
+			try{con.close();}catch(Exception e){errorHandler.error("JDBCAppender::close(), " + e);}
+      }
+		this.closed = true;
+	}
+
+
+	/**
+	You have to call this function for all provided columns of your log-table !
+   */
+	public boolean setLogType(String _name, int _logtype, Object _value)
+	{
+   	if(sql != null) return true;
+
+		if(!configured)
+		{
+			if(!configure()) return false;
+		}
+
+		try
+		{
+			jlogger.setLogType(_name, _logtype, _value);
+		}
+		catch(Exception e)
+		{
+			errorHandler.error("JDBCAppender::setLogType(), " + e);
+			return false;
+		}
+
+		return true;
+	}
+
+
+	/**
+	Internal method. Appends the message to the database table.
+	*/
+	public void append(LoggingEvent event)
+	{
+		if(!ready)
+      {
+      	if(!ready())
+         {
+				errorHandler.error("JDBCAppender::append(), Not ready to append !");
+         	return;
+			}
+      }
+
+		buffer.add(event);
+
+		if(buffer.size() >= buffer_size) flush_buffer();
+	}
+
+
+	/**
+	Internal method. Flushes the buffer.
+	*/
+   public void flush_buffer()
+   {
+   	try
+      {
+      	int size = buffer.size();
+
+         if(size < 1) return;
+
+        	for(int i=0; i<size; i++)
+         {
+				LoggingEvent event = (LoggingEvent)buffer.get(i);
+
+				//Insert message into database
+				jlogger.append(layout.format(event));
+         }
+
+         buffer.clear();
+
+			if(docommit) con.commit();
+      }
+		catch(Exception e)
+		{
+			errorHandler.error("JDBCAppender::flush_buffer(), " + e + " : " + jlogger.getErrorMsg());
+			try{con.rollback();} catch(Exception ex){}
+			return;
+		}
+   }
+
+
+	/**
+	Internal method. Returns true, when the JDBCAppender is ready to append messages to the database, else false.
+	*/
+	public boolean ready()
+	{
+   	if(ready) return true;
+
+		if(!configured) return false;
+
+		ready = jlogger.ready();
+
+      if(!ready){errorHandler.error(jlogger.getErrorMsg());}
+
+      return ready;
+	}
+
+
+	/**
+	Internal method. Connect to the database.
+	*/
+	protected void connect() throws Exception
+	{
+   	if(connected) return;
+
+		try
+		{
+      	if(connection_class == null)
+         {
+				if(url == null)		throw new Exception("JDBCAppender::connect(), No URL defined.");
+
+				if(username == null)	throw new Exception("JDBCAppender::connect(), No USERNAME defined.");
+
+				if(password == null)	throw new Exception("JDBCAppender::connect(), No PASSWORD defined.");
+
+				connectionHandler = new DefaultConnectionHandler();
+			}
+         else
+         {
+				connectionHandler = (JDBCConnectionHandler)(Class.forName(connection_class).newInstance());
+         }
+
+         if(url != null && username != null && password != null)
+         {
+				con = connectionHandler.getConnection(url, username, password);
+         }
+         else
+         {
+	     		con = connectionHandler.getConnection();
+         }
+
+         if(con.isClosed())
+         {
+         	throw new Exception("JDBCAppender::connect(), JDBCConnectionHandler returns no connected Connection !");
+			}
+		}
+		catch(Exception e)
+		{
+			throw new Exception("JDBCAppender::connect(), " + e);
+		}
+
+      connected = true;
+	}
+
+	/**
+	Internal method. Configures for appending...
+	*/
+	protected boolean configure()
+	{
+		if(configured) return true;
+
+		if(!connected)
+		{
+      	if((connection_class == null) && (url == null || username == null || password == null))
+			{
+				errorHandler.error("JDBCAppender::configure(), Missing database-options or connector-option !");
+				return false;
+         }
+
+         try
+         {
+				connect();
+         }
+         catch(Exception e)
+         {
+         	connection_class = null;
+            url = null;
+				errorHandler.error("JDBCAppender::configure(), " + e);
+            return false;
+         }
+		}
+
+		if(sql == null && table == null)
+		{
+			errorHandler.error("JDBCAppender::configure(), No SQL_OPTION or TABLE_OPTION given !");
+			return false;
+		}
+
+		if(!jlogger.isConfigured())
+		{
+			try
+         {
+         	jlogger.setConnection(con);
+
+         	if(sql == null)
+            {
+	         	jlogger.configureTable(table);
+            }
+            else jlogger.configureSQL(sql);
+         }
+         catch(Exception e)
+         {
+	         errorHandler.error("JDBCAppender::configure(), " + e);
+         	return false;
+         }
+		}
+
+      //Default Message-Layout
+      if(layout == null)
+      {
+      	layout = new PatternLayout("%m");
+      }
+
+      configured = true;
+
+		return true;
+	}
+}
+
+/**
+This is a default JDBCConnectionHandler used by JDBCAppender
+*/
+class DefaultConnectionHandler implements JDBCConnectionHandler
+{
+	Connection con = null;
+
+   public Connection getConnection()
+   {
+   	return con;
+   }
+
+   public Connection getConnection(String _url, String _username, String _password)
+   {
+   	try
+      {
+   		if(con != null && !con.isClosed()) con.close();
+			con = DriverManager.getConnection(_url, _username, _password);
+			con.setAutoCommit(false);
+      }
+      catch(Exception e){}
+
+   	return con;
+   }
+}
+
+
+
+
+
+

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j.net;
+
+import java.sql.*;
+
+
+/**
+This interface has to be implemented for your own database-connection-handling and its used in class JDBCLogger.
+
+<p><b>Author : </b><A HREF="mailto:t.fenner@klopotek.de">Thomas Fenner</A></p>
+
+@since 1.0
+*/
+public interface JDBCConnectionHandler
+{
+	/**Get a connection*/
+	Connection getConnection();
+	/**Get a defined connection*/
+   Connection getConnection(String _url, String _username, String _password);
+}
+
+

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCConnectionHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java?rev=1345524&view=auto
==============================================================================
--- logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java (added)
+++ logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java Sat Jun  2 15:35:46 2012
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j.net;
+
+
+/**
+This interface has to be implemented to provide ID-columns with unique IDs and its used in class JDBCLogger.
+
+<p><b>Author : </b><A HREF="mailto:t.fenner@klopotek.de">Thomas Fenner</A></p>
+
+@since 1.0
+*/
+public interface JDBCIDHandler
+{
+	/**Get a unique ID*/
+	Object getID();
+}
+
+
+

Propchange: logging/log4j/branches/log4j12-bz53299/modules/contribs/src/main/java/org/apache/log4j/net/JDBCIDHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message