psmith 2003/06/17 21:02:20 Modified: src/java/org/apache/log4j/net UDPAppender.java SocketNodeEventListener.java SocketReceiver.java SocketNode.java MulticastAppender.java SocketAppender.java Log: A few changes here: * There was a compile error due to some missing methods in one or two Appenders/Receivers. (isActive() method was not implemented. * Tweaked listeners implementation to be more JavaBean style, using an EventListenerList. This allows more than one listener to be added. Kept support for older style usage, but would prefer to get rid of this ASAP if it's not in use already. * If SocketReceiver is not active, logging events are not received. Revision Changes Path 1.8 +8 -0 jakarta-log4j-sandbox/src/java/org/apache/log4j/net/UDPAppender.java Index: UDPAppender.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/net/UDPAppender.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- UDPAppender.java 17 Jun 2003 20:06:51 -0000 1.7 +++ UDPAppender.java 18 Jun 2003 04:02:20 -0000 1.8 @@ -408,4 +408,12 @@ //LogLog.debug("Exiting Connector.run() method."); } } + + /* (non-Javadoc) + * @see org.apache.log4j.net.NetworkBased#isActive() + */ + public boolean isActive() { + // TODO handle active/inactive + return true; + } } 1.3 +3 -1 jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketNodeEventListener.java Index: SocketNodeEventListener.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketNodeEventListener.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SocketNodeEventListener.java 17 Jun 2003 23:25:02 -0000 1.2 +++ SocketNodeEventListener.java 18 Jun 2003 04:02:20 -0000 1.3 @@ -49,6 +49,8 @@ package org.apache.log4j.net; +import java.util.EventListener; + /** Interface used to listen for [EMAIL PROTECTED] SocketNode} related events. Clients register an instance of the interface and the @@ -58,7 +60,7 @@ @author Paul Smith <[EMAIL PROTECTED]> @since 1.3 */ -public interface SocketNodeEventListener { +public interface SocketNodeEventListener extends EventListener{ /** * Called when the SocketNode is created and begins awaiting data. 1.8 +70 -34 jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketReceiver.java Index: SocketReceiver.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketReceiver.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- SocketReceiver.java 17 Jun 2003 23:25:41 -0000 1.7 +++ SocketReceiver.java 18 Jun 2003 04:02:20 -0000 1.8 @@ -57,9 +57,10 @@ import java.net.Socket; import java.util.Enumeration; -import java.util.Iterator; import java.util.Vector; +import javax.swing.event.EventListenerList; + /** SocketReceiver receives a remote logging event on a configured @@ -81,7 +82,8 @@ private ServerSocket serverSocket; private Vector socketList = new Vector(); private SocketNodeEventListener listener = null; - + private EventListenerList listenerList = new EventListenerList(); + public SocketReceiver() { } @@ -133,7 +135,7 @@ /** Sets the flag to indicate if receiver is active or not. */ - protected synchronized void setActive(boolean _active) { + public synchronized void setActive(boolean _active) { active = _active; } @@ -205,7 +207,11 @@ socketList.add(socket); SocketNode node = new SocketNode(socket, this); - node.setListener(getListener()); + SocketNodeEventListener[] listeners = (SocketNodeEventListener[])listenerList.getListeners(SocketNodeEventListener.class); + for (int i = 0; i < listeners.length; i++) { + node.addSocketNodeEventListener(listeners[i]); + } + new Thread(node).start(); socket = null; } @@ -230,7 +236,7 @@ setActive(false); } - + /** * Returns a Vector of SocketDetail representing the IP/Domain name * of the currently connected sockets that this receiver has @@ -239,23 +245,72 @@ */ public Vector getConnectedSocketDetails() { Vector details = new Vector(socketList.size()); - for(Enumeration enum = socketList.elements(); enum.hasMoreElements();) { - Socket socket = (Socket)enum.nextElement(); + + for (Enumeration enum = socketList.elements(); enum.hasMoreElements();) { + Socket socket = (Socket) enum.nextElement(); details.add(new SocketDetail(socket)); } - return details; + + return details; } - - public static class SocketDetail implements AddressBased, PortBased { + /** + * Returns the currently configured SocketNodeEventListener that + * will be automatically set for each SocketNode created + * @return SocketNodeEventListener currently configured + * + * @deprecated This receiver now supports multiple listeners + */ + public SocketNodeEventListener getListener() { + return listener; + } + + /** + * Adds the listener to the list of listeners to be notified of the + * respective event + * @param listener the listener to add to the list + */ + public void addSocketNodeEventListener(SocketNodeEventListener listener) { + listenerList.add(SocketNodeEventListener.class, listener); + } + + /** + * Removes the registered Listener from this instances list of + * listeners. If the listener has not been registered, then invoking + * this method has no effect. + * + * @param listener the SocketNodeEventListener to remove + */ + public void removeSocketNodeEventListener(SocketNodeEventListener listener) { + listenerList.remove(SocketNodeEventListener.class, listener); + } + + /** + * Sets the SocketNodeEventListener that will be used for each + * created SocketNode + * @param listener the listener to set on each creation of a SocketNode + * @deprecated This receiver now supports multiple listeners and + * so this method simply removes the listener (if there already) + * and readds it to the list. + * + * The passed listener will also be returned via the getListener() + * method still, but this is also deprecated + */ + public void setListener(SocketNodeEventListener listener) { + removeSocketNodeEventListener(listener); + addSocketNodeEventListener(listener); + this.listener = listener; + } + + public static class SocketDetail implements AddressBased, PortBased { private String address; private int port; - + private SocketDetail(Socket socket) { this.address = socket.getInetAddress().getHostName(); this.port = socket.getPort(); } - + public String getAddress() { return address; } @@ -263,33 +318,14 @@ public int getPort() { return port; } + public String getName() { return "Socket"; } - + public boolean isActive() { -// TODO allow a Socket to be active/inactive/paused etc. + // TODO allow a Socket to be active/inactive/paused etc. return true; } - - } - - /** - * Returns the currently configured SocketNodeEventListener that - * will be automatically set for each SocketNode created - * @return SocketNodeEventListener currently configured - */ - public SocketNodeEventListener getListener() { - return listener; } - - /** - * Sets the SocketNodeEventListener that will be used for each - * created SocketNode - * @param listener the listener to set on each creation of a SocketNode - */ - public void setListener(SocketNodeEventListener listener) { - this.listener = listener; - } - } 1.3 +159 -44 jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketNode.java Index: SocketNode.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketNode.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SocketNode.java 17 Jun 2003 23:26:04 -0000 1.2 +++ SocketNode.java 18 Jun 2003 04:02:20 -0000 1.3 @@ -1,22 +1,69 @@ /* - * Copyright (C) The Apache Software Foundation. All rights reserved. + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "log4j" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * [EMAIL PROTECTED] + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation. For more information on the + * Apache Software Foundation, please see <http://www.apache.org/>. * - * This software is published under the terms of the Apache Software License - * version 1.1, a copy of which has been included with this distribution in - * the LICENSE.txt file. */ package org.apache.log4j.net; +import org.apache.log4j.Logger; +import org.apache.log4j.plugins.Receiver; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.LoggingEvent; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.ObjectInputStream; + import java.net.Socket; -import org.apache.log4j.Logger; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; +import java.util.EventListener; + +import javax.swing.event.EventListenerList; + // Contributors: Moses Hohman <[EMAIL PROTECTED]> @@ -34,13 +81,12 @@ @since 0.8.4 */ public class SocketNode implements Runnable { - - Socket socket; - LoggerRepository hierarchy; - Receiver receiver; - SocketNodeEventListener listener; - static Logger logger = Logger.getLogger(SocketNode.class); + private Socket socket; + private LoggerRepository hierarchy; + private Receiver receiver; + private SocketNodeEventListener listener; + private EventListenerList listenerList = new EventListenerList(); /** Constructor for socket and logger repository. */ @@ -48,7 +94,7 @@ this.socket = socket; this.hierarchy = hierarchy; } - + /** Constructor for socket and reciever. */ public SocketNode(Socket socket, Receiver receiver) { @@ -57,22 +103,47 @@ } /** - Set the event listener on this node. */ + * Set the event listener on this node. + * + * @deprecated Now supports mutliple listeners, this method + * simply invokes the removeSocketNodeEventListener() to remove + * the listener, and then readds it. + */ public void setListener(SocketNodeEventListener _listener) { - listener = _listener; + removeSocketNodeEventListener(_listener); + addSocketNodeEventListener(_listener); } - + + /** + * Adds the listener to the list of listeners to be notified of the + * respective event + * @param listener the listener to add to the list + */ + public void addSocketNodeEventListener(SocketNodeEventListener listener) { + listenerList.add(SocketNodeEventListener.class, listener); + } + + /** + * Removes the registered Listener from this instances list of + * listeners. If the listener has not been registered, then invoking + * this method has no effect. + * + * @param listener the SocketNodeEventListener to remove + */ + public void removeSocketNodeEventListener(SocketNodeEventListener listener) { + listenerList.remove(SocketNodeEventListener.class, listener); + } + public void run() { - - LoggingEvent event; Logger remoteLogger; Exception listenerException = null; ObjectInputStream ois = null; - + try { - ois = new ObjectInputStream( - new BufferedInputStream(socket.getInputStream())); + ois = + new ObjectInputStream( + new BufferedInputStream(socket.getInputStream())); } catch (Exception e) { ois = null; listenerException = e; @@ -80,47 +151,57 @@ } if (ois != null) { - String remoteInfo = socket.getInetAddress().getHostName() + ":" + socket.getPort(); + String remoteInfo = + socket.getInetAddress().getHostName() + ":" + socket.getPort(); + /** * notify the listener that the socket has been * opened and this SocketNode is ready and waiting */ - listener.socketOpened(remoteInfo); + fireSocketOpened(remoteInfo); + try { - while(true) { + while (true) { // read an event from the wire - event = (LoggingEvent) ois.readObject(); - - // store the known remote info in an event property - event.setProperty("log4j.remoteSourceInfo", remoteInfo); - - // if configured with a receiver, tell it to post the event - if (receiver != null) { - receiver.doPost(event); - // else post it via the hierarchy + event = (LoggingEvent) ois.readObject(); + + // store the known remote info in an event property + event.setProperty("log4j.remoteSourceInfo", remoteInfo); + + // if configured with a receiver, tell it to post the event + if ((receiver != null)) { + + if (receiver.isActive()) { + receiver.doPost(event); + } + + // else post it via the hierarchy } else { // get a logger from the hierarchy. The name of the logger // is taken to be the name contained in the event. remoteLogger = hierarchy.getLogger(event.getLoggerName()); + //event.logger = remoteLogger; // apply the logger-level filter - if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) { + if ( + event.getLevel().isGreaterOrEqual( + remoteLogger.getEffectiveLevel())) { // finally log the event as if was generated locally remoteLogger.callAppenders(event); } } } - } catch(java.io.EOFException e) { + } catch (java.io.EOFException e) { logger.info("Caught java.io.EOFException closing conneciton."); listenerException = e; - } catch(java.net.SocketException e) { + } catch (java.net.SocketException e) { logger.info("Caught java.net.SocketException closing conneciton."); listenerException = e; - } catch(IOException e) { - logger.info("Caught java.io.IOException: "+e); + } catch (IOException e) { + logger.info("Caught java.io.IOException: " + e); logger.info("Closing connection."); listenerException = e; - } catch(Exception e) { + } catch (Exception e) { logger.error("Unexpected exception. Closing connecition.", e); listenerException = e; } @@ -131,13 +212,47 @@ if (ois != null) { ois.close(); } - } catch(Exception e) { + } catch (Exception e) { //logger.info("Could not close connection.", e); } - + // send event to listener, if configured if (listener != null) { - listener.socketClosedEvent(listenerException); + fireSocketClosedEvent(listenerException); + } + } + + /** + * Notifies all registered listeners regarding the closing of the Socket + * @param listenerException + */ + private void fireSocketClosedEvent(Exception listenerException) { + EventListener[] listeners = + listenerList.getListeners(SocketNodeEventListener.class); + + for (int i = 0; i < listeners.length; i++) { + SocketNodeEventListener snel = (SocketNodeEventListener) listeners[i]; + + if (snel != null) { + snel.socketClosedEvent(listenerException); + } + } + } + + /** + * Notifies all registered listeners regarding the opening of a Socket + * @param remoteInfo + */ + private void fireSocketOpened(String remoteInfo) { + EventListener[] listeners = + listenerList.getListeners(SocketNodeEventListener.class); + + for (int i = 0; i < listeners.length; i++) { + SocketNodeEventListener snel = (SocketNodeEventListener) listeners[i]; + + if (snel != null) { + snel.socketOpened(remoteInfo); + } } } } 1.7 +8 -0 jakarta-log4j-sandbox/src/java/org/apache/log4j/net/MulticastAppender.java Index: MulticastAppender.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/net/MulticastAppender.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- MulticastAppender.java 17 Jun 2003 20:06:51 -0000 1.6 +++ MulticastAppender.java 18 Jun 2003 04:02:20 -0000 1.7 @@ -356,4 +356,12 @@ public int getReconnectionDelay() { return reconnectionDelay; } + + /* (non-Javadoc) + * @see org.apache.log4j.net.NetworkBased#isActive() + */ + public boolean isActive() { + // TODO handle active/inactive + return true; + } } 1.3 +8 -0 jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketAppender.java Index: SocketAppender.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/net/SocketAppender.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SocketAppender.java 17 Jun 2003 07:19:59 -0000 1.2 +++ SocketAppender.java 18 Jun 2003 04:02:20 -0000 1.3 @@ -507,4 +507,12 @@ } */ } + + /* (non-Javadoc) + * @see org.apache.log4j.net.NetworkBased#isActive() + */ + public boolean isActive() { + // TODO handle active/inactive + return true; + } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]