ws-pubscribe-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lisc...@apache.org
Subject svn commit: r158387 [2/3] - in incubator/hermes/trunk/src/examples: ./ broker/ broker/WEB-INF/ pubsubclient/ pubsubclient/WEB-INF/
Date Mon, 21 Mar 2005 00:41:16 GMT
Added: incubator/hermes/trunk/src/examples/pubsubclient/PubSubClient.java
URL: http://svn.apache.org/viewcvs/incubator/hermes/trunk/src/examples/pubsubclient/PubSubClient.java?view=auto&rev=158387
==============================================================================
--- incubator/hermes/trunk/src/examples/pubsubclient/PubSubClient.java (added)
+++ incubator/hermes/trunk/src/examples/pubsubclient/PubSubClient.java Sun Mar 20 16:41:11 2005
@@ -0,0 +1,1668 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.*;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.plaf.basic.BasicButtonListener;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+
+/**
+ * TCP monitor to log http messages and responses, both SOAP and plain HTTP.
+ * If you want to choose a different Swing look and feel, set the property
+ * tcpmon.laf to the classname of the new look and feel
+ * @author Doug Davis (dug@us.ibm.com)
+ * @author Steve Loughran
+ */
+
+public class PubSubClient extends JFrame {
+    private JTabbedPane  notebook = null ;
+
+    private static final int STATE_COLUMN    = 0 ;
+    private static final int TIME_COLUMN     = 1 ;
+    private static final int INHOST_COLUMN   = 2 ;
+    private static final int OUTHOST_COLUMN  = 3 ;
+    private static final int REQ_COLUMN      = 4 ;
+
+
+    private static final String DEFAULT_HOST="127.0.0.1";
+    private static final int    DEFAULT_PORT=8080;
+
+    /**
+     * wait for incoming connections, spawn a connection thread when
+     * stuff comes in.
+     */
+    class SocketWaiter extends Thread {
+        ServerSocket  sSocket = null ;
+        Listener      listener ;
+        int           port ;
+        boolean       pleaseStop = false ;
+
+        public SocketWaiter(Listener l, int p) {
+            listener = l ;
+            port = p ;
+            start();
+        }
+
+        public void run() {
+            try {
+                listener.setLeft( new JLabel(getMessage("wait00", " Waiting for Connection...") ) );
+                listener.repaint();
+                sSocket = new ServerSocket( port );
+                for (; ; ) {
+                    Socket inSocket = sSocket.accept();
+
+                    if ( pleaseStop ) {
+                        break ;
+                    }
+                    new Connection( listener, inSocket );
+                    inSocket = null ;
+                }
+            } catch ( Exception exp ) {
+                if ( !"socket closed".equals(exp.getMessage()) ) {
+                    JLabel tmp = new JLabel( exp.toString() );
+
+                    tmp.setForeground( Color.red );
+                    listener.setLeft( tmp );
+                    listener.setRight( new JLabel("") );
+                    listener.stop();
+                }
+            }
+        }
+
+        /**
+         * force a halt by connecting to self and then closing the server socket
+         */
+        public void halt() {
+            try {
+                pleaseStop = true ;
+                new Socket( "127.0.0.1", port );
+                if ( sSocket != null ) {
+                    sSocket.close();
+                }
+            } catch ( Exception e ) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    /**
+     * class to simulate slow connections by slowing down the system
+     */
+    static class SlowLinkSimulator {
+        private int delayBytes;
+        private int delayTime;
+        private int currentBytes;
+        private int totalBytes;
+
+        /**
+         * construct
+         * @param delayBytes bytes per delay; set to 0 for no delay
+         * @param delayTime delay time per delay in milliseconds
+         */
+        public SlowLinkSimulator(int delayBytes, int delayTime) {
+            this.delayBytes = delayBytes;
+            this.delayTime = delayTime;
+        }
+
+        /**
+         * construct by copying delay bytes and time, but not current
+         * count of bytes
+         * @param that source of data
+         */
+        public SlowLinkSimulator(SlowLinkSimulator that) {
+            this.delayBytes=that.delayBytes;
+            this.delayTime=that.delayTime;
+        }
+
+        /**
+         * how many bytes have gone past?
+         * @return
+         */
+        public int getTotalBytes() {
+            return totalBytes;
+        }
+
+        /**
+         * log #of bytes pumped. Will pause when necessary. This method is not
+         * synchronized
+         * @param bytes
+         */
+        public void pump(int bytes) {
+            totalBytes+=bytes;
+            if(delayBytes==0) {
+                //when not delaying, we are just a byte counter
+                return;
+            }
+            currentBytes += bytes;
+            if(currentBytes>delayBytes) {
+                //we have overshot. lets find out how far
+                int delaysize=currentBytes/delayBytes;
+                long delay=delaysize*(long)delayTime;
+                //move byte counter down to the remainder of bytes
+                currentBytes=currentBytes%delayBytes;
+                //now wait
+                try {
+                    Thread.sleep(delay);
+                } catch (InterruptedException e) {
+                    ; //ignore the exception
+                }
+            }
+        }
+
+        /**
+         * get the current byte count
+         * @return
+         */
+        public int getCurrentBytes() {
+            return currentBytes;
+        }
+
+        /**
+         * set the current byte count
+         * @param currentBytes
+         */
+        public void setCurrentBytes(int currentBytes) {
+            this.currentBytes = currentBytes;
+        }
+
+    }
+
+    /**
+     * this class handles the pumping of data from the incoming socket to the
+     * outgoing socket
+     */
+    class SocketRR extends Thread {
+        Socket        inSocket  = null ;
+        Socket        outSocket  = null ;
+        JTextArea     textArea ;
+        InputStream   in = null ;
+        OutputStream  out = null ;
+        boolean       xmlFormat ;
+        volatile boolean       done = false ;
+        TableModel    tmodel = null ;
+        int           tableIndex = 0 ;
+        String type = null;
+        Connection    myConnection = null;
+        SlowLinkSimulator slowLink;
+
+        public SocketRR(Connection c, Socket inputSocket, InputStream inputStream,
+            Socket outputSocket, OutputStream outputStream,
+            JTextArea _textArea, boolean format,
+            TableModel tModel, int index, final String type, SlowLinkSimulator slowLink) {
+            inSocket = inputSocket ;
+            in       = inputStream ;
+            outSocket = outputSocket ;
+            out       = outputStream ;
+            textArea  = _textArea ;
+            xmlFormat = format ;
+            tmodel    = tModel ;
+            tableIndex = index ;
+            this.type = type;
+            myConnection = c;
+            this.slowLink= slowLink;
+            start();
+        }
+
+        public boolean isDone() {
+            return ( done );
+        }
+
+        public void run() {
+            try {
+                byte[]      buffer = new byte[4096];
+                byte[]      tmpbuffer = new byte[8192];
+                int         saved = 0 ;
+                int         len ;
+                int         i1, i2 ;
+                int         i ;
+                int         reqSaved = 0 ;
+                int         tabWidth = 3 ;
+                boolean     atMargin = true ;
+                int         thisIndent = -1,
+                    nextIndent = -1,
+                    previousIndent = -1;
+
+                //if ( inSocket  != null ) inSocket.setSoTimeout( 10 );
+                //if ( outSocket != null ) outSocket.setSoTimeout( 10 );
+
+                if ( tmodel != null ) {
+                    String tmpStr = (String) tmodel.getValueAt(tableIndex,
+                            REQ_COLUMN);
+
+                    if ( !"".equals(tmpStr) ) {
+                        reqSaved = tmpStr.length();
+                    }
+                }
+
+            a:
+                for ( ; ; ) {
+                    if ( done ) {
+                        break;
+                    }
+                    //try{
+                    //len = in.available();
+                    //}catch(Exception e){len=0;}
+                    len = buffer.length ;
+                    // Used to be 1, but if we block it doesn't matter
+                    // however 1 will break with some servers, including apache
+                    if ( len == 0 ) {
+                        len = buffer.length;
+                    }
+                    if ( saved + len > buffer.length) {
+                        len = buffer.length - saved ;
+                    }
+                    int len1 = 0;
+
+                    while ( len1 == 0 ) {
+                        try {
+                            len1 = in.read(buffer, saved, len);
+                        }
+                        catch ( Exception ex ) {
+                            if ( done && saved == 0  ) {
+                                break a;
+                            }
+                            len1 = -1;
+                            break;
+                        }
+                    }
+                    len = len1;
+
+                    if ( len == -1 && saved == 0 ) {
+                        break ;
+                    }
+                    if ( len == -1) {
+                        done = true;
+                    }
+
+                    // No matter how we may (or may not) format it, send it
+                    // on unformatted - we don't want to mess with how its
+                    // sent to the other side, just how its displayed
+                    if ( out != null && len > 0 ) {
+                        slowLink.pump(len);
+                        out.write( buffer, saved, len );
+                    }
+
+                    if ( tmodel != null && reqSaved < 50 ) {
+                        String old = (String) tmodel.getValueAt( tableIndex,
+                                REQ_COLUMN);
+
+                        old = old + new String(buffer, saved, len);
+                        if ( old.length() > 50 ) {
+                            old = old.substring(0, 50);
+                        }
+
+                        reqSaved = old.length();
+
+                        if ( (i = old.indexOf('\n')) > 0 ) {
+                            old = old.substring(0, i - 1);
+                            reqSaved = 50 ;
+                        }
+
+                        tmodel.setValueAt( old, tableIndex, REQ_COLUMN );
+                    }
+
+                    if ( xmlFormat ) {
+                        // Do XML Formatting
+                        boolean inXML = false ;
+                        int     bufferLen = saved ;
+
+                        if ( len != -1 ) {
+                            bufferLen += len ;
+                        }
+                        i1 = 0 ;
+                        i2 = 0 ;
+                        saved = 0 ;
+                        for ( ; i1 < bufferLen ; i1++ ) {
+                            // Except when we're at EOF, saved last char
+                            if ( len != -1 && i1 + 1 == bufferLen ) {
+                                saved = 1;
+                                break;
+                            }
+                            thisIndent = -1;
+                            if ( buffer[i1] == '<' && buffer[i1 + 1] != '/' ) {
+                                previousIndent = nextIndent++;
+                                thisIndent = nextIndent;
+                                inXML = true ;
+                            }
+                            if ( buffer[i1] == '<' && buffer[i1 + 1] == '/' ) {
+                                if (previousIndent > nextIndent) {
+                                    thisIndent = nextIndent;
+                                }
+                                previousIndent = nextIndent--;
+                                inXML = true ;
+                            }
+                            if ( buffer[i1] == '/' && buffer[i1 + 1] == '>' ) {
+                                previousIndent = nextIndent--;
+                                inXML = true ;
+                            }
+                            if ( thisIndent != -1 ) {
+                                if ( thisIndent > 0 ) {
+                                    tmpbuffer[i2++] = (byte) '\n';
+                                }
+                                for ( i = tabWidth * thisIndent; i > 0; i-- ) {
+                                    tmpbuffer[i2++] = (byte) ' ';
+                                }
+                            }
+                            atMargin = ( buffer[i1] == '\n' || buffer[i1] == '\r');
+
+                            if ( !inXML || !atMargin ) {
+                                tmpbuffer[i2++] = buffer[i1];
+                            }
+                        }
+
+                        textArea.append( new String( tmpbuffer, 0, i2 ) );
+
+                        // Shift saved bytes to the beginning
+                        for ( i = 0 ; i < saved ; i++ ) {
+                            buffer[i] = buffer[bufferLen - saved + i];
+                        }
+                    }
+                    else {
+                        textArea.append( new String( buffer, 0, len ) );
+                    }
+                // this.sleep(3);  // Let other threads have a chance to run
+                }
+            // this.sleep(3);  // Let other threads have a chance to run
+            // halt();
+            // Only set the 'done' flag if we were reading from a
+            // Socket - if we were reading from an input stream then
+            // we'll let the other side control when we're done
+            //      if ( inSocket != null ) done = true ;
+            }
+            catch ( Exception e ) {
+                e.printStackTrace();
+            }
+            finally {
+                done = true ;
+                try {
+                    if (out != null) {
+                        out.flush();
+                        if (null != outSocket) {
+                            outSocket.shutdownOutput();
+                        } else {
+                            out.close();
+                        }
+                        out = null;
+                    }
+                }
+                catch (Exception e) {
+                    ;
+                }
+                try {
+                    if (in != null) {
+                        if (inSocket != null) {
+                            inSocket.shutdownInput();
+                        } else {
+                            in.close();
+                        }
+                        in = null;
+                    }
+                }
+                catch (Exception e) {
+                    ;
+                }
+                myConnection.wakeUp();
+            }
+        }
+
+        public  void halt() {
+            try {
+                if ( inSocket != null ) {
+                    inSocket.close();
+                }
+                if ( outSocket != null ) {
+                    outSocket.close();
+                }
+                inSocket  = null ;
+                outSocket = null ;
+                if ( in != null ) {
+                    in.close();
+                }
+                if ( out != null ) {
+                    out.close();
+                }
+                in = null ;
+                out = null ;
+                done = true;
+            }
+            catch ( Exception e ) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    /**
+     * a connection listens to a single current connection
+     */
+    class Connection extends Thread {
+        Listener     listener ;
+        boolean      active ;
+        String       fromHost ;
+        String       time ;
+        JTextArea    inputText    = null ;
+        JScrollPane  inputScroll  = null ;
+        JTextArea    outputText   = null ;
+        JScrollPane  outputScroll = null ;
+        Socket       inSocket     = null ;
+        Socket       outSocket    = null ;
+        Thread       clientThread = null ;
+        Thread       serverThread = null ;
+        SocketRR     rr1          = null ;
+        SocketRR     rr2          = null ;
+        InputStream  inputStream  = null ;
+
+        String       HTTPProxyHost = null ;
+        int          HTTPProxyPort = 80 ;
+        private SlowLinkSimulator slowLink;
+
+        public Connection(Listener l) {
+            listener = l ;
+            HTTPProxyHost = l.HTTPProxyHost ;
+            HTTPProxyPort = l.HTTPProxyPort ;
+            slowLink =l.slowLink;
+        }
+
+        public Connection(Listener l, Socket s ) {
+            this (l);
+            inSocket = s ;
+            start();
+        }
+
+        public Connection(Listener l, InputStream in ) {
+            this (l);
+            inputStream = in ;
+            start();
+        }
+
+        public void run() {
+            try {
+                active        = true ;
+
+                HTTPProxyHost = System.getProperty( "http.proxyHost" );
+                if ( HTTPProxyHost != null && HTTPProxyHost.equals("") ) {
+                    HTTPProxyHost = null ;
+                }
+
+                if ( HTTPProxyHost != null ) {
+                    String tmp = System.getProperty( "http.proxyPort" );
+
+                    if ( tmp != null && tmp.equals("") ) {
+                        tmp = null ;
+                    }
+                    if ( tmp == null ) {
+                        HTTPProxyPort = 80 ;
+                    } else {
+                        HTTPProxyPort = Integer.parseInt( tmp );
+                    }
+                }
+
+                if ( inSocket != null ) {
+                    fromHost = (inSocket.getInetAddress()).getHostName();
+                } else {
+                    fromHost = "resend" ;
+                }
+
+
+                String dateformat=getMessage("dateformat00", "yyyy-MM-dd HH:mm:ss");
+                DateFormat   df = new SimpleDateFormat(dateformat);
+
+                time = df.format( new Date() );
+
+                int count = listener.connections.size();
+
+                listener.tableModel.insertRow(count + 1, new Object[] {
+                        getMessage("active00", "Active"),
+                        time,
+                        fromHost,
+                        listener.hostField.getText(), ""
+                    }
+                );
+                listener.connections.add( this );
+                inputText  = new JTextArea( null, null, 20, 80 );
+                inputScroll = new JScrollPane( inputText );
+                outputText = new JTextArea( null, null, 20, 80 );
+                outputScroll = new JScrollPane( outputText );
+
+                ListSelectionModel lsm = listener.connectionTable.getSelectionModel();
+
+                if ( count == 0 || lsm.getLeadSelectionIndex() == 0 ) {
+                    listener.outPane.setVisible( false );
+                    int divLoc = listener.outPane.getDividerLocation();
+
+                    listener.setLeft( inputScroll );
+                    listener.setRight( outputScroll );
+
+                    listener.removeButton.setEnabled(false);
+                    listener.removeAllButton.setEnabled(true);
+                    listener.saveButton.setEnabled(true);
+                    listener.resendButton.setEnabled(true);
+                    listener.outPane.setDividerLocation(divLoc);
+                    listener.outPane.setVisible( true );
+                }
+
+                String targetHost = listener.hostField.getText();
+                int    targetPort = Integer.parseInt(listener.tPortField.getText());
+                int    listenPort = Integer.parseInt(listener.portField.getText());
+
+                InputStream  tmpIn1  = inputStream ;
+                OutputStream tmpOut1 = null ;
+
+                InputStream  tmpIn2  = null ;
+                OutputStream tmpOut2 = null ;
+
+                if ( tmpIn1 == null ) {
+                    tmpIn1  = inSocket.getInputStream();
+                }
+
+                if ( inSocket != null ) {
+                    tmpOut1 = inSocket.getOutputStream();
+                }
+
+                String         bufferedData = null ;
+                StringBuffer   buf = null ;
+
+                int index = listener.connections.indexOf( this );
+
+                if (listener.isProxyBox.isSelected() || HTTPProxyHost != null) {
+                    // Check if we're a proxy
+                    byte[]       b = new byte[1];
+
+                    buf = new StringBuffer();
+                    String       s ;
+
+                    for ( ; ; ) {
+                        int len ;
+
+                        len = tmpIn1.read(b, 0, 1);
+                        if ( len == -1 ) {
+                            break ;
+                        }
+                        s = new String( b );
+                        buf.append( s );
+                        if ( b[0] != '\n' ) {
+                            continue ;
+                        }
+                        break ;
+                    }
+
+                    bufferedData = buf.toString();
+                    inputText.append( bufferedData );
+
+                    if ( bufferedData.startsWith( "GET " ) ||
+                        bufferedData.startsWith( "POST " ) ||
+                        bufferedData.startsWith( "PUT " ) ||
+                        bufferedData.startsWith( "DELETE " ) ) {
+                        int  start, end ;
+                        URL  url ;
+
+                        start = bufferedData.indexOf( ' ' ) + 1;
+                        while ( bufferedData.charAt(start) == ' ' ) {
+                            start++ ;
+                        }
+                        end   = bufferedData.indexOf( ' ', start );
+                        String urlString = bufferedData.substring( start, end );
+
+                        if ( urlString.charAt(0) == '/' ) {
+                            urlString = urlString.substring(1);
+                        }
+                        if ( listener.isProxyBox.isSelected() ) {
+                            url = new URL( urlString );
+                            targetHost = url.getHost();
+                            targetPort = url.getPort();
+                            if ( targetPort == -1 ) {
+                                targetPort = 80 ;
+                            }
+
+                            listener.tableModel.setValueAt( targetHost, index + 1,
+                                OUTHOST_COLUMN );
+                            bufferedData = bufferedData.substring( 0, start) +
+                            url.getFile() +
+                            bufferedData.substring( end );
+                        }
+                        else {
+                            url = new URL( "http://" + targetHost + ":" +
+                                targetPort + "/" + urlString );
+
+                            listener.tableModel.setValueAt( targetHost, index + 1,
+                                OUTHOST_COLUMN );
+                            bufferedData = bufferedData.substring( 0, start) +
+                                url.toExternalForm() +
+                                bufferedData.substring( end );
+
+                            targetHost = HTTPProxyHost ;
+                            targetPort = HTTPProxyPort ;
+                        }
+
+                    }
+                }
+                else {
+                    //
+                    // Change Host: header to point to correct host
+                    //
+                    byte[] b1 = new byte[1];
+
+                    buf = new StringBuffer();
+                    String s1;
+                    String lastLine = null ;
+
+                    for ( ; ; ) {
+                        int len ;
+
+                        len = tmpIn1.read(b1, 0, 1);
+                        if ( len == -1 ) {
+                            break ;
+                        }
+                        s1 = new String( b1 );
+                        buf.append( s1 );
+                        if ( b1[0] != '\n' ) {
+                            continue ;
+                        }
+                        // we have a complete line
+                        String line = buf.toString();
+
+                        buf.setLength(0);
+                        // check to see if we have found Host: header
+                        if (line.startsWith("Host: ")) {
+                            // we need to update the hostname to target host
+                            String newHost = "Host: " + targetHost + ":" + listenPort + "\r\n";
+
+                            bufferedData = bufferedData.concat(newHost);
+                            break ;
+                        }
+                        // add it to our headers so far
+                        if (bufferedData == null) {
+                            bufferedData = line;
+                        } else {
+                            bufferedData = bufferedData.concat(line);
+                        }
+
+                        // failsafe
+                        if (line.equals("\r\n")) {
+                            break;
+                        }
+                        if ("\n".equals(lastLine) && line.equals("\n")) {
+                            break ;
+                        }
+                        lastLine = line ;
+                    }
+                    if ( bufferedData != null ) {
+                        inputText.append( bufferedData );
+                        int idx = bufferedData.length() < 50 ? bufferedData.length() : 50;
+                        s1 = bufferedData.substring( 0, idx );
+                        int i = s1.indexOf('\n');
+
+                        if ( i > 0 ) {
+                            s1 = s1.substring(0, i - 1);
+                        }
+                        s1 = s1 + "                           " +
+                                  "                       ";
+                        s1 = s1.substring(0, 51);
+                        listener.tableModel.setValueAt( s1, index + 1,
+                            REQ_COLUMN );
+                    }
+                }
+
+                if ( targetPort == -1 ) {
+                    targetPort = 80 ;
+                }
+                outSocket = new Socket(targetHost, targetPort );
+
+                tmpIn2  = outSocket.getInputStream();
+                tmpOut2 = outSocket.getOutputStream();
+
+                if ( bufferedData != null ) {
+                    byte[] b = bufferedData.getBytes();
+                    tmpOut2.write( b );
+                    slowLink.pump(b.length);
+                }
+
+                boolean format = listener.xmlFormatBox.isSelected();
+
+
+                //this is the channel to the endpoint
+                rr1 = new SocketRR(this, inSocket, tmpIn1, outSocket,
+                    tmpOut2, inputText, format,
+                    listener.tableModel, index + 1, "request:", slowLink);
+                //create the response slow link from the inbound slow link
+                SlowLinkSimulator responseLink = new SlowLinkSimulator(slowLink);
+                //this is the channel from the endpoint
+                rr2 = new SocketRR( this, outSocket, tmpIn2, inSocket,
+                    tmpOut1, outputText, format,
+                    null, 0, "response:", responseLink);
+
+                while ( rr1 != null || rr2 != null ) {
+                    // Only loop as long as the connection to the target
+                    // machine is available - once that's gone we can stop.
+                    // The old way, loop until both are closed, left us
+                    // looping forever since no one closed the 1st one.
+                    // while( !rr2.isDone() )
+                    if (null != rr1 && rr1.isDone()) {
+                        if ( index >= 0  && rr2 != null) {
+                            listener.tableModel.setValueAt(getMessage("resp00", "Resp"),
+                                1 + index, STATE_COLUMN );
+                        }
+                       rr1 = null;
+                    }
+                    if (null != rr2 && rr2.isDone()) {
+                        if ( index >= 0 && rr1 != null ) {
+                            listener.tableModel.setValueAt(getMessage("req00", "Req"),
+                                1 + index, STATE_COLUMN );
+                        }
+                        rr2 = null;
+                    }
+
+                    //  Thread.sleep( 10 );
+                    synchronized ( this) {
+                        this.wait(1000); //Safety just incase we're not told to wake up.
+                    }
+                }
+
+                //  System.out.println("Done ");
+                // rr1.halt();
+                // rr2.halt();
+
+
+                active = false ;
+
+                /*
+                 if ( inSocket != null ) {
+                 inSocket.close();
+                 inSocket = null ;
+                 }
+                 outSocket.close();
+                 outSocket = null ;
+                 */
+
+                if ( index >= 0 ) {
+                    listener.tableModel.setValueAt(getMessage("done00", "Done"),
+                        1 + index, STATE_COLUMN );
+
+                }
+            }
+            catch ( Exception e ) {
+                StringWriter st = new StringWriter();
+                PrintWriter  wr = new PrintWriter(st);
+                int index = listener.connections.indexOf( this );
+
+                if ( index >= 0 ) {
+                    listener.tableModel.setValueAt( getMessage("error00", "Error"), 1 + index, STATE_COLUMN );
+                }
+                e.printStackTrace(wr);
+                wr.close();
+                if(outputText!=null) {
+                    outputText.append( st.toString() );
+                } else {
+                    //something went wrong before we had the output area
+                    System.out.println(st.toString());
+                }
+                halt();
+            }
+        }
+
+        synchronized void wakeUp() {
+            this.notifyAll();
+        }
+
+        public void halt() {
+            try {
+                if ( rr1 != null ) {
+                    rr1.halt();
+                }
+                if ( rr2 != null ) {
+                    rr2.halt();
+                }
+                if ( inSocket  != null ) {
+                    inSocket.close();
+                }
+                inSocket = null ;
+                if ( outSocket != null ) {
+                    outSocket.close();
+                }
+                outSocket = null ;
+            }
+            catch ( Exception e ) {
+                e.printStackTrace();
+            }
+        }
+
+        public void remove() {
+            int index = -1;
+
+            try {
+                halt();
+                index = listener.connections.indexOf( this );
+                listener.tableModel.removeRow( index + 1 );
+                listener.connections.remove( index );
+            }
+            catch ( Exception e ) {
+                System.err.println("index:=" + index + this );
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    /**
+     * this is one of the tabbed panels that acts as the actual proxy
+     */
+    class Listener extends JPanel {
+        public  Socket      inputSocket     = null ;
+        public  Socket      outputSocket    = null ;
+        public  JTextField  portField       = null ;
+        public  JTextField  hostField       = null ;
+        public  JTextField  tPortField      = null ;
+        public  JCheckBox   isProxyBox      = null ;
+        public  JButton     stopButton      = null ;
+        public  JButton     removeButton    = null ;
+        public  JButton     removeAllButton = null ;
+        public  JCheckBox   xmlFormatBox    = null ;
+        public  JButton     saveButton      = null ;
+        public  JButton     resendButton    = null ;
+        public  JButton     switchButton    = null ;
+        public  JButton     closeButton     = null ;
+        public  JTable      connectionTable = null ;
+        public  DefaultTableModel  tableModel      = null ;
+        public  JSplitPane  outPane         = null ;
+        public  ServerSocket sSocket        = null ;
+        public  SocketWaiter sw = null ;
+        public  JPanel      leftPanel       = null ;
+        public  JPanel      rightPanel      = null ;
+        public  JTabbedPane notebook        = null ;
+        public  String      HTTPProxyHost   = null ;
+        public  int         HTTPProxyPort   = 80 ;
+        public  int         delayBytes      = 0;
+        public  int         delayTime       = 0;
+        public SlowLinkSimulator slowLink;
+
+        public final Vector connections = new Vector();
+
+        /**
+         * create a listener
+         * @param _notebook
+         * @param name
+         * @param listenPort
+         * @param host
+         * @param targetPort
+         * @param isProxy
+         * @param slowLink optional reference to a slow connection
+         */
+        public Listener(JTabbedPane _notebook, String name,
+            int listenPort, String host, int targetPort,
+            boolean isProxy, SlowLinkSimulator slowLink) {
+            notebook = _notebook ;
+
+            //set the slow link to the passed down link
+            if(slowLink!=null) {
+                this.slowLink=slowLink;
+            } else {
+                //or make up a no-op one.
+                this.slowLink=new SlowLinkSimulator(0,0);
+            }
+            this.setLayout( new BorderLayout() );
+
+            // 1st component is just a row of labels and 1-line entry fields
+            /////////////////////////////////////////////////////////////////////
+            JPanel top = new JPanel();
+
+            top.setLayout( new BoxLayout(top, BoxLayout.X_AXIS) );
+            top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+            final String start = getMessage("start00", "Start");
+
+            top.add( stopButton = new JButton( start ) );
+            top.add( Box.createRigidArea(new Dimension(5, 0)) );
+            top.add( new JLabel( "  " + getMessage("listenPort01", "Listen Port:") + " ", SwingConstants.RIGHT ) );
+            top.add( portField = new JTextField( "" + listenPort, 4 ) );
+            top.add( new JLabel( "  " + getMessage("host00", "Host:"), SwingConstants.RIGHT ) );
+            top.add( hostField = new JTextField( host, 30 ) );
+            top.add( new JLabel( "  " + getMessage("port02", "Port:") + " ", SwingConstants.RIGHT ) );
+            top.add( tPortField = new JTextField( "" + targetPort, 4 ) );
+            top.add( Box.createRigidArea(new Dimension(5, 0)) );
+            top.add( isProxyBox = new JCheckBox(getMessage("proxy00", "Proxy")) );
+
+            isProxyBox.addChangeListener( new BasicButtonListener(isProxyBox) {
+                    public void stateChanged(ChangeEvent event) {
+                        JCheckBox box = (JCheckBox) event.getSource();
+                        boolean state = box.isSelected();
+
+                        tPortField.setEnabled( !state );
+                        hostField.setEnabled( !state );
+                    }
+                }
+            );
+
+            isProxyBox.setSelected(isProxy);
+
+            portField.setEditable(false);
+            portField.setMaximumSize(new Dimension(50, Short.MAX_VALUE) );
+            hostField.setEditable(false);
+            hostField.setMaximumSize(new Dimension(85, Short.MAX_VALUE) );
+            tPortField.setEditable(false);
+            tPortField.setMaximumSize(new Dimension(50, Short.MAX_VALUE) );
+
+            stopButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if ( getMessage("stop00", "Stop").equals(event.getActionCommand()) ) {
+                            stop();
+                        }
+                        if ( start.equals(event.getActionCommand()) ) {
+                            //start();
+                        }
+                    }
+                }
+            );
+
+            this.add( top, BorderLayout.NORTH );
+
+            // 2nd component is a split pane with a table on the top
+            // and the request/response text areas on the bottom
+            /////////////////////////////////////////////////////////////////////
+
+            tableModel = new DefaultTableModel(new String[] {
+                    getMessage("state00", "State"),
+                    getMessage("time00", "Time"),
+                    getMessage("requestHost00", "Request Host"),
+                    getMessage("targetHost", "Target Host"),
+                    getMessage("request00", "Request...")
+                } , 0 );
+
+            tableModel.addRow( new Object[] {
+                    "---", getMessage("mostRecent00", "Most Recent"), "---", "---", "---"
+                }
+            );
+
+            connectionTable = new JTable(1, 2);
+            connectionTable.setModel( tableModel );
+            connectionTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+            // Reduce the STATE column and increase the REQ column
+            TableColumn col ;
+
+            col = connectionTable.getColumnModel().getColumn(STATE_COLUMN);
+            col.setMaxWidth( col.getPreferredWidth() / 2 );
+            col = connectionTable.getColumnModel().getColumn(REQ_COLUMN);
+            col.setPreferredWidth( col.getPreferredWidth() * 2 );
+
+
+            ListSelectionModel sel = connectionTable.getSelectionModel();
+
+            sel.addListSelectionListener( new ListSelectionListener() {
+                    public void valueChanged(ListSelectionEvent event) {
+                        if (event.getValueIsAdjusting()) {
+                            return ;
+                        }
+                        ListSelectionModel m = (ListSelectionModel) event.getSource();
+                        int divLoc = outPane.getDividerLocation();
+
+                        if (m.isSelectionEmpty()) {
+                            setLeft( new JLabel(" " + getMessage("wait00", "Waiting for Connection...") ) );
+                            setRight( new JLabel("") );
+                            removeButton.setEnabled(false);
+                            removeAllButton.setEnabled(false);
+                            saveButton.setEnabled(false);
+                            resendButton.setEnabled(false);
+                        }
+                        else {
+                            int row = m.getLeadSelectionIndex();
+
+                            if ( row == 0 ) {
+                                if ( connections.size() == 0 ) {
+                                    setLeft(new JLabel(" " + getMessage("wait00", "Waiting for connection...")));
+                                    setRight(new JLabel(""));
+                                    removeButton.setEnabled(false);
+                                    removeAllButton.setEnabled(false);
+                                    saveButton.setEnabled(false);
+                                    resendButton.setEnabled(false);
+                                }
+                                else {
+                                    Connection conn = (Connection) connections.lastElement();
+
+                                    setLeft( conn.inputScroll );
+                                    setRight( conn.outputScroll );
+                                    removeButton.setEnabled(false);
+                                    removeAllButton.setEnabled(true);
+                                    saveButton.setEnabled(true);
+                                    resendButton.setEnabled(true);
+                                }
+                            }
+                            else {
+                                Connection conn = (Connection) connections.get(row - 1);
+
+                                setLeft( conn.inputScroll );
+                                setRight( conn.outputScroll );
+                                removeButton.setEnabled(true);
+                                removeAllButton.setEnabled(true);
+                                saveButton.setEnabled(true);
+                                resendButton.setEnabled(true);
+                            }
+                        }
+                        outPane.setDividerLocation(divLoc);
+                    }
+                }
+            );
+
+            JPanel  tablePane = new JPanel();
+
+            tablePane.setLayout( new BorderLayout() );
+
+            JScrollPane tableScrollPane = new JScrollPane( connectionTable );
+
+            tablePane.add( tableScrollPane, BorderLayout.CENTER );
+            JPanel buttons = new JPanel();
+
+            buttons.setLayout( new BoxLayout(buttons, BoxLayout.X_AXIS) );
+            buttons.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) );
+            final String removeSelected = getMessage("removeSelected00", "Remove Selected");
+
+            buttons.add( removeButton = new JButton(removeSelected) );
+            buttons.add( Box.createRigidArea(new Dimension(5, 0)) );
+            final String removeAll = getMessage("removeAll00", "Remove All");
+
+            buttons.add( removeAllButton = new JButton(removeAll) );
+            tablePane.add( buttons, BorderLayout.SOUTH );
+
+            removeButton.setEnabled( false );
+            removeButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if ( removeSelected.equals(event.getActionCommand()) ) {
+                            remove();
+                        }
+                    }
+                }
+            );
+
+            removeAllButton.setEnabled( false );
+            removeAllButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if ( removeAll.equals(event.getActionCommand()) ) {
+                            removeAll();
+                        }
+                    }
+                }
+            );
+
+            // Add Response Section
+            /////////////////////////////////////////////////////////////////////
+            JPanel     pane2     = new JPanel();
+
+            pane2.setLayout( new BorderLayout() );
+
+            leftPanel = new JPanel();
+            leftPanel.setAlignmentX( Component.LEFT_ALIGNMENT );
+            leftPanel.setLayout( new BoxLayout(leftPanel, BoxLayout.Y_AXIS) );
+            leftPanel.add( new JLabel("  " + getMessage("request01", "Request")) );
+            leftPanel.add( new JLabel(" " + getMessage("wait01", "Waiting for connection") ));
+
+            rightPanel = new JPanel();
+            rightPanel.setLayout( new BoxLayout(rightPanel, BoxLayout.Y_AXIS) );
+            rightPanel.add( new JLabel("  " + getMessage("response00", "Response")) );
+            rightPanel.add( new JLabel("") );
+
+            outPane = new JSplitPane(0, leftPanel, rightPanel );
+            outPane.setDividerSize(4);
+            pane2.add( outPane, BorderLayout.CENTER );
+
+            JPanel bottomButtons = new JPanel();
+
+            bottomButtons.setLayout( new BoxLayout(bottomButtons, BoxLayout.X_AXIS));
+            bottomButtons.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+            bottomButtons.add( xmlFormatBox = new JCheckBox( getMessage("xmlFormat00", "XML Format") ) );
+            bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
+            final String save = getMessage("save00", "Save");
+
+            bottomButtons.add( saveButton = new JButton( save ) );
+            bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
+            final String resend = getMessage("resend00", "Resend");
+
+            bottomButtons.add( resendButton = new JButton( resend ) );
+            bottomButtons.add( Box.createRigidArea(new Dimension(5, 0)) );
+            final String switchStr = getMessage("switch00", "Switch Layout");
+
+            bottomButtons.add( switchButton = new JButton( switchStr ) );
+            bottomButtons.add( Box.createHorizontalGlue() );
+            final String close = getMessage("close00", "Close");
+
+            bottomButtons.add( closeButton = new JButton( close ) );
+            pane2.add( bottomButtons, BorderLayout.SOUTH );
+
+            saveButton.setEnabled( false );
+            saveButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if ( save.equals(event.getActionCommand()) ) {
+                            save();
+                        }
+                    }
+                }
+            );
+
+            resendButton.setEnabled( false );
+            resendButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if ( resend.equals(event.getActionCommand()) ) {
+                            resend();
+                        }
+                    }
+                }
+            );
+
+            switchButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if (switchStr.equals(event.getActionCommand()) ) {
+                            int v = outPane.getOrientation();
+
+                            if ( v == 0 ) {
+                                // top/bottom
+                                outPane.setOrientation(1);
+                            }
+                            else  {
+                                // left/right
+                                outPane.setOrientation(0);
+                            }
+                            outPane.setDividerLocation(0.5);
+                        }
+                    }
+                }
+            );
+
+            closeButton.addActionListener( new ActionListener() {
+                    public void actionPerformed(ActionEvent event) {
+                        if (close.equals(event.getActionCommand()) ) {
+                            close();
+                        }
+                    }
+                }
+            );
+
+            JSplitPane  pane1 = new JSplitPane( 0 );
+
+            pane1.setDividerSize(4);
+            pane1.setTopComponent( tablePane );
+            pane1.setBottomComponent( pane2 );
+            pane1.setDividerLocation( 150 );
+            this.add( pane1, BorderLayout.CENTER );
+
+            //
+            ////////////////////////////////////////////////////////////////////
+            sel.setSelectionInterval(0, 0);
+            outPane.setDividerLocation( 150 );
+            notebook.addTab( name, this );
+            start(name);
+        }
+
+        public void setLeft(Component left) {
+            leftPanel.removeAll();
+            leftPanel.add(left);
+        }
+
+        public void setRight(Component right) {
+            rightPanel.removeAll();
+            rightPanel.add(right);
+        }
+
+        public void start(String name) {
+            int  port = Integer.parseInt( portField.getText() );
+
+            portField.setText( "" + port );
+            int i = notebook.indexOfComponent( this );
+
+            notebook.setTitleAt( i, name);
+
+            int  tmp = Integer.parseInt( tPortField.getText() );
+
+            tPortField.setText( "" + tmp );
+
+            sw = new SocketWaiter( this, port );
+            stopButton.setText( getMessage("stop00", "Stop") );
+
+            portField.setEditable(false);
+            hostField.setEditable(false);
+            tPortField.setEditable(false);
+            isProxyBox.setEnabled(false);
+        }
+
+        public void close() {
+            stop();
+            notebook.remove( this );
+        }
+
+        public void stop() {
+            try {
+                for ( int i = 0 ; i < connections.size() ; i++ ) {
+                    Connection conn = (Connection) connections.get( i );
+
+                    conn.halt();
+                }
+                sw.halt();
+                stopButton.setText( getMessage("start00", "Start") );
+                portField.setEditable(true);
+                hostField.setEditable(true);
+                tPortField.setEditable(true);
+                isProxyBox.setEnabled(true);
+            }
+            catch ( Exception e ) {
+                e.printStackTrace();
+            }
+        }
+
+        public void remove() {
+            ListSelectionModel lsm = connectionTable.getSelectionModel();
+            int bot = lsm.getMinSelectionIndex();
+            int top = lsm.getMaxSelectionIndex();
+
+            for ( int i = top ; i >= bot ; i-- ) {
+                ((Connection) connections.get(i - 1)).remove();
+            }
+            if ( bot > connections.size() ) {
+                bot = connections.size();
+            }
+            lsm.setSelectionInterval(bot, bot);
+        }
+
+        public void removeAll() {
+            ListSelectionModel lsm = connectionTable.getSelectionModel();
+            lsm.clearSelection();
+            while ( connections.size() > 0 ) {
+                ((Connection) connections.get(0)).remove();
+            }
+
+            lsm.setSelectionInterval(0, 0);
+        }
+
+        public void save() {
+            JFileChooser  dialog = new JFileChooser( "." );
+            int rc = dialog.showSaveDialog( this );
+
+            if ( rc == JFileChooser.APPROVE_OPTION ) {
+                try {
+                    File             file = dialog.getSelectedFile();
+                    FileOutputStream out  = new FileOutputStream( file );
+
+                    ListSelectionModel lsm = connectionTable.getSelectionModel();
+
+                    rc = lsm.getLeadSelectionIndex();
+
+                    int n = 0;
+                    for (Iterator i = connections.iterator();i.hasNext();n++) {
+                      Connection conn = (Connection)i.next();
+                      if (lsm.isSelectedIndex(n + 1) ||
+                                   (!(i.hasNext()) && lsm.getLeadSelectionIndex() == 0)) {
+                        rc = Integer.parseInt( portField.getText() );
+                        out.write("\n==============\n".getBytes());
+                        out.write( ((getMessage("listenPort01", "Listen Port:") + " " + rc + "\n" )).getBytes() );
+                        out.write( (getMessage("targetHost01", "Target Host:") + " " + hostField.getText() +
+                                    "\n" ).getBytes() );
+                        rc = Integer.parseInt( tPortField.getText() );
+                        out.write( ((getMessage("targetPort01", "Target Port:") + " " + rc + "\n" )).getBytes() );
+
+                        out.write( (("==== " + getMessage("request01", "Request") + " ====\n" )).getBytes() );
+                        out.write( conn.inputText.getText().getBytes() );
+
+                        out.write( (("==== " + getMessage("response00", "Response") + " ====\n" )).getBytes() );
+                        out.write( conn.outputText.getText().getBytes() );
+                        out.write("\n==============\n".getBytes());
+                      }
+                    }
+
+                    out.close();
+                }
+                catch ( Exception e ) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        public void resend() {
+            int rc ;
+
+            try {
+                ListSelectionModel lsm = connectionTable.getSelectionModel();
+
+                rc = lsm.getLeadSelectionIndex();
+                if ( rc == 0 ) {
+                    rc = connections.size();
+                }
+                Connection conn = (Connection) connections.get( rc - 1 );
+
+                if ( rc > 0 ) {
+                    lsm.clearSelection();
+                    lsm.setSelectionInterval(0, 0);
+                }
+
+                InputStream in = null ;
+                String      text = conn.inputText.getText();
+
+                // Fix Content-Length HTTP headers
+                if ( text.startsWith("POST ") || text.startsWith("GET ") ) {
+                    // System.err.println("IN CL" );
+                    int         pos1, pos2, pos3 ;
+                    String      body, headers, headers1, header2 ;
+
+                    pos3 = text.indexOf( "\n\n" );
+                    if ( pos3 == -1 ) {
+                        pos3 = text.indexOf( "\r\n\r\n" );
+                        if ( pos3 != -1 ) {
+                            pos3 = pos3 + 4 ;
+                        }
+                    }
+                    else {
+                        pos3 += 2 ;
+                    }
+
+                    headers = text.substring( 0, pos3 );
+
+                    pos1 = headers.indexOf( "Content-Length:" );
+                    // System.err.println("pos1: " + pos1 );
+                    // System.err.println("pos3: " + pos3 );
+                    if ( pos1 != -1 ) {
+                        int  newLen = text.length() - pos3 ;
+
+                        pos2 = headers.indexOf( "\n", pos1 );
+
+                        System.err.println("CL: " + newLen );
+                        System.err.println("Hdrs: '" + headers + "'" );
+                        System.err.println("subTEXT: '" +
+                            text.substring(pos3, pos3 + newLen) + "'");
+                        text = headers.substring(0, pos1) +
+                        "Content-Length: " + newLen + "\n" +
+                        headers.substring(pos2 + 1) +
+                        text.substring(pos3) ;
+                        System.err.println("\nTEXT: '" + text + "'" );
+                    }
+                }
+
+                in = new ByteArrayInputStream( text.getBytes() );
+                new Connection( this, in );
+            }
+            catch ( Exception e ) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    public PubSubClient(String hermes_home) throws Exception{
+        super ( "Apache Hermes Client" );
+
+        notebook = new JTabbedPane();
+        this.getContentPane().add( notebook );
+
+        PubSubWSmanager pman = new PubSubWSmanager(hermes_home);
+
+        SubscribePanel app = new SubscribePanel(notebook,pman); 
+        PublisherPanel app2 = new PublisherPanel(notebook,pman); 
+        
+        Listener outgoing=  new Listener( notebook, "Producer", pman.outport, "localhost", 8080, false,null);
+        Listener subman =  new Listener( notebook, "SubscriptionManger", 12345, "localhost", 8080, false,null);
+        Listener incoming=  new Listener( notebook, "Incoming", pman.inportL, "localhost", pman.inportS, false,null);
+        
+        this.pack();
+        this.setSize( 600, 600 );
+        this.setVisible( true );
+    }
+
+    /**
+     * set up the L&F
+     */
+    private static void setupLookAndFeel(boolean nativeLookAndFeel) throws Exception {
+        String classname= UIManager.getCrossPlatformLookAndFeelClassName();
+        if(nativeLookAndFeel) {
+            classname= UIManager.getSystemLookAndFeelClassName();
+        }
+        String lafProperty= System.getProperty("tcpmon.laf", "");
+        if(lafProperty.length()>0) {
+            classname=lafProperty;
+        }
+        try {
+            UIManager.setLookAndFeel(classname);
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (UnsupportedLookAndFeelException e) {
+            e.printStackTrace();
+        }
+    }
+    /**
+     * this is our main method
+     * @param args
+     */
+    public static void main(String[] args) {
+        try {
+            setupLookAndFeel(true);
+            new PubSubClient(args[0]);
+        }catch ( Throwable exp ) {
+            exp.printStackTrace();
+        }
+    }
+
+    // Message resource bundle.
+    private static ResourceBundle messages = null;
+
+    /**
+     * Get the message with the given key.  There are no arguments for this message.
+     */
+    public static String getMessage(String key, String defaultMsg) {
+        try {
+            if (messages == null) {
+                initializeMessages();
+            }
+            return messages.getString(key);
+        } catch (Throwable t) {
+            // If there is any problem whatsoever getting the internationalized
+            // message, return the default.
+            return defaultMsg;
+        }
+    } // getMessage
+
+    /**
+     * Load the resource bundle messages from the properties file.  This is ONLY done when it is
+     * needed.  If no messages are printed (for example, only Wsdl2java is being run in non-
+     * verbose mode) then there is no need to read the properties file.
+     */
+    private static void initializeMessages() {
+        messages = ResourceBundle.getBundle("org.apache.axis.utils.tcpmon");
+    } // initializeMessages
+
+    /**
+     * a text field with a restricted set of characters
+     */
+    static class RestrictedTextField extends JTextField {
+        protected String validText;
+
+        public RestrictedTextField(String validText) {
+            setValidText(validText);
+        }
+
+        public RestrictedTextField(int columns, String validText) {
+            super(columns);
+            setValidText(validText);
+        }
+
+        public RestrictedTextField(String text, String validText) {
+            super(text);
+            setValidText(validText);
+        }
+
+        public RestrictedTextField(String text, int columns, String validText) {
+            super(text, columns);
+            setValidText(validText);
+        }
+
+        private void setValidText(String validText) {
+            this.validText = validText;
+        }
+
+        /**
+         * fascinatingly, this method is called in the super() constructor,
+         * meaning before we are fully initialized. C++ doesnt actually permit
+         * such a situation, but java clearly does...
+         * @return a new document
+         */
+        public Document createDefaultModel() {
+            return new RestrictedDocument();
+        }
+
+        /**
+         * this class strips out invaid chars
+         */
+        class RestrictedDocument extends PlainDocument {
+
+
+            /**
+             * Constructs a plain text document.  A default model using
+             * <code>GapContent</code> is constructed and set.
+             */
+            public RestrictedDocument() {
+
+            }
+
+            /**
+             * add a string; only those chars in the valid text list are allowed
+             * @param offset
+             * @param string
+             * @param attributes
+             * @throws BadLocationException
+             */
+            public void insertString(int offset, String string, AttributeSet attributes)
+                    throws BadLocationException {
+
+                if (string == null) {
+                    return;
+                }
+                int len = string.length();
+                StringBuffer buffer = new StringBuffer(string.length());
+                for (int i = 0; i < len; i++) {
+                    char ch = string.charAt(i);
+                    if (validText.indexOf(ch) >= 0) {
+                        buffer.append(ch);
+                    }
+                }
+                super.insertString(offset, new String(buffer), attributes);
+            }
+        } //end class NumericDocument
+    }
+
+    /**
+     * because we cant use Java1.4's JFormattedTextField, here is
+     * a class that accepts numbers only
+     */
+    static class NumberField extends RestrictedTextField {
+
+        private static final String VALID_TEXT = "0123456789";
+
+        /**
+         * Constructs a new <code>TextField</code>.  A default model is created,
+         * the initial string is <code>null</code>,
+         * and the number of columns is set to 0.
+         */
+        public NumberField() {
+            super(VALID_TEXT);
+        }
+
+        /**
+         * Constructs a new empty <code>TextField</code> with the specified
+         * number of columns.
+         * A default model is created and the initial string is set to
+         * <code>null</code>.
+         *
+         * @param columns  the number of columns to use to calculate
+         *   the preferred width; if columns is set to zero, the
+         *   preferred width will be whatever naturally results from
+         *   the component implementation
+         */
+        public NumberField(int columns) {
+            super(columns, VALID_TEXT);
+        }
+
+
+        /**
+         * get the int value of a field, any invalid (non int) field returns
+         * the default
+         * @param def default value
+         * @return the field contents
+         */
+        public int getValue(int def) {
+            int result = def;
+            String text = getText();
+            if (text != null && text.length() != 0) {
+                try {
+                    result = Integer.parseInt(text);
+                } catch (NumberFormatException e) {
+
+                }
+            }
+            return result;
+        }
+
+        /**
+         * set the text to a numeric value
+         * @param value number to assign
+         */
+        public void setValue(int value) {
+            setText(Integer.toString(value));
+        }
+
+    } //end class NumericTextField
+
+    /**
+     * hostname fields
+     */
+    static class HostnameField extends RestrictedTextField {
+        //list of valid chars in a hostname
+        private static final String VALID_TEXT =
+                "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ-.";
+
+        public HostnameField(int columns) {
+            super(columns, VALID_TEXT);
+        }
+
+        public HostnameField() {
+            super(VALID_TEXT);
+        }
+    }
+
+}

Added: incubator/hermes/trunk/src/examples/pubsubclient/PubSubWSmanager.java
URL: http://svn.apache.org/viewcvs/incubator/hermes/trunk/src/examples/pubsubclient/PubSubWSmanager.java?view=auto&rev=158387
==============================================================================
--- incubator/hermes/trunk/src/examples/pubsubclient/PubSubWSmanager.java (added)
+++ incubator/hermes/trunk/src/examples/pubsubclient/PubSubWSmanager.java Sun Mar 20 16:41:11 2005
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.ws.pubsub.*;
+import org.apache.ws.notification.topics.Topic;
+import java.util.Calendar;
+
+public class PubSubWSmanager {
+    public NotificationProducer nprod;
+    public int outport;
+    public int inportL;
+    public int inportS;
+    public org.apache.ws.notification.topics.TopicSpace topicSpace;
+    /** Creates a new instance of PubSubWSmanager */
+    public PubSubWSmanager(String hermes_home) throws Exception{
+        java.util.Random r = new java.util.Random(System.currentTimeMillis());
+	outport= r.nextInt(60000)+1024;
+        inportL =r.nextInt(60000)+1024;
+        inportS =r.nextInt(60000)+1024;
+        
+        JettyAxisServer jas = new JettyAxisServer();
+        jas.setPort(inportS);
+        jas.setResourceBase(hermes_home);
+        jas.start();       
+        
+        NotificationProducerFactory nprodF = NotificationProducerFactory.getInstance();
+        //TODO
+        nprod= nprodF.createNotificationProducer("http://localhost:"+outport+"/axis/services/NotificationProducer","jndi-config_wsn.xml");
+       // nprod= nprodF.createNotificationProducer("http://localhost:"+outport+"/axis/services/NotificationProducer","jndi-config_wse.xml");
+
+        topicSpace = org.apache.ws.notification.topics.util.TopicSpaceParser.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("topicspace.xml"));   
+        System.out.println("topicSpace : "+topicSpace);
+        
+    }
+    
+    public Subscription subscribe(SubListModel sl, NotListModel nl, String xpath, Topic t, java.util.Date termtime, boolean  subend){
+        try{
+            TopicFilter tf = null;
+            XPathFilter xf = null;
+            if(xpath!=null)
+                xf= new XPathFilter(xpath);
+            if(t!=null)
+                tf= new TopicFilter(t);
+                
+            NotificationConsumer c = new GUIConsumer("http://localhost:"+inportL+"/axis/services/NotificationPort",sl);
+            SubscriptionEndConsumer ec = new GUIEndConsumer("http://localhost:"+inportL+"/axis/services/SubscriptionEndPort",nl);
+            Calendar termTime= Calendar.getInstance();
+            org.apache.ws.pubsub.Subscription s =  nprod.subscribe(c,ec,tf,xf,termTime,true);
+            return s;
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+ 
+        return null;
+    }
+    public void publish(String text, Topic t){
+        Publisher p = PublisherFactory.getInstance().createPublisher("http://localhost:"+outport+"/axis/services/NotificationPort");
+        p.publish(text,t);
+    }
+    
+}

Added: incubator/hermes/trunk/src/examples/pubsubclient/PublisherPanel.java
URL: http://svn.apache.org/viewcvs/incubator/hermes/trunk/src/examples/pubsubclient/PublisherPanel.java?view=auto&rev=158387
==============================================================================
--- incubator/hermes/trunk/src/examples/pubsubclient/PublisherPanel.java (added)
+++ incubator/hermes/trunk/src/examples/pubsubclient/PublisherPanel.java Sun Mar 20 16:41:11 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import javax.swing.tree.*;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.text.DateFormat;
+
+import org.apache.ws.pubsub.*;
+import org.apache.ws.notification.topics.Topic;
+public class PublisherPanel extends JPanel{
+    public  JTabbedPane notebook        = null ;
+    
+    public JButton publishButton= null;
+    public JTextArea pubtext=null;
+    public JTree tree=null;
+    
+    public JCheckBox cXfilter=null;
+    public JCheckBox cTfilter=null;
+    public JCheckBox cSubend=null;
+    public JCheckBox cTermtime=null;
+    
+    private PubSubWSmanager pman;
+    private Calendar time;
+    
+    public PublisherPanel(JTabbedPane _notebook, PubSubWSmanager _pman) {
+        try{
+            this.pman=_pman;
+            notebook = _notebook ;
+            
+            
+            this.setLayout( new BoxLayout(this, BoxLayout.Y_AXIS) );
+            
+            // 1st component is just a row of labels and 1-line entry fields
+            /////////////////////////////////////////////////////////////////////
+            JPanel top = new JPanel();
+            
+            top.setLayout( new FlowLayout() );
+            top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+            
+            JPanel top2 = new JPanel();
+            //topictree
+            top2.add( cTfilter = new JCheckBox("Topic"));
+            DefaultTreeCellRenderer renderer2 = new DefaultTreeCellRenderer();
+            renderer2.setOpenIcon(null);
+            renderer2.setClosedIcon(null);
+            renderer2.setLeafIcon(null);
+            tree = new TopicSpaceTree(pman).getTree();
+            tree.setCellRenderer(renderer2);
+            top2.add(tree);
+            this.add(top2 );
+            
+            JPanel top3 = new JPanel();
+            top3.add(pubtext = new JTextArea("<?xml version=\"1.0\" ?>\n<a><b/></a>",10,30) );
+            this.add(top3);
+            
+            JPanel top4 = new JPanel();
+            
+            //publish button
+            top4.add(publishButton = new JButton("Publish"));
+            this.add(top4);
+            
+            publishButton.addActionListener( new ActionListener() {
+                public void actionPerformed(ActionEvent event) {
+                    Topic t=null;
+                    if(cTfilter.getSelectedObjects()!=null){
+                        TreePath[] ts =tree.getSelectionModel().getSelectionPaths();
+                        if(ts!=null)
+                            t = (org.apache.ws.notification.topics.Topic)((DefaultMutableTreeNode) ts[ts.length-1].getLastPathComponent()).getUserObject();
+                    }
+                    pman.publish(pubtext.getText(),t);
+                }
+            }
+            );         
+
+            
+            notebook.addTab( "Publisher", this );
+            // start();
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+    }
+    
+    private void updateTime(){
+        time=Calendar.getInstance();
+        time.add(Calendar.MINUTE,1);
+    }
+}
+
+
+

Added: incubator/hermes/trunk/src/examples/pubsubclient/SubListModel.java
URL: http://svn.apache.org/viewcvs/incubator/hermes/trunk/src/examples/pubsubclient/SubListModel.java?view=auto&rev=158387
==============================================================================
--- incubator/hermes/trunk/src/examples/pubsubclient/SubListModel.java (added)
+++ incubator/hermes/trunk/src/examples/pubsubclient/SubListModel.java Sun Mar 20 16:41:11 2005
@@ -0,0 +1,37 @@
+import javax.swing.AbstractListModel;
+
+class SubListModel extends AbstractListModel {
+    private java.util.Vector myData;
+    
+    public SubListModel() {
+        myData=new java.util.Vector();
+    }
+    
+    public int  getSize() { return myData.size();}
+    public Object getElementAt(int i) { return myData.elementAt(i);}
+    
+    public void addData(Object obj) {
+        myData.add(obj);    //Add data to the vector.
+        fireContentsChanged(this,0,myData.size()-1);    //fire event so that List updates itself.
+    }
+    
+    public void removeData(Object obj) {
+        myData.remove(obj);    //Add data to the vector.
+        fireContentsChanged(this,0,myData.size()-1);    //fire event so that List updates itself.
+    }
+    /*
+    public class notentry{
+        public String id;
+        public String content;
+        public notentry(String id, Object message)throws Exception{
+            this.id=id;
+            this.content=((org.apache.axis.message.SOAPEnvelope)message).getBody().toString();
+        }
+        
+        public String toString(){
+            return id;//+" "+content;
+        }
+        
+    }
+    */
+}

Added: incubator/hermes/trunk/src/examples/pubsubclient/SubscribePanel.java
URL: http://svn.apache.org/viewcvs/incubator/hermes/trunk/src/examples/pubsubclient/SubscribePanel.java?view=auto&rev=158387
==============================================================================
--- incubator/hermes/trunk/src/examples/pubsubclient/SubscribePanel.java (added)
+++ incubator/hermes/trunk/src/examples/pubsubclient/SubscribePanel.java Sun Mar 20 16:41:11 2005
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import javax.swing.tree.*;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.text.DateFormat;
+
+import org.apache.ws.pubsub.*;
+import org.apache.ws.notification.topics.Topic;
+public class SubscribePanel extends JPanel{
+    public  JTabbedPane notebook        = null ;
+    public JTextField filterstr =null;
+    public JTextField termtime =null;
+    public JButton subscribeButton= null;
+    public JButton unsubscribeButton= null;
+    public JButton renewButton= null;
+    public JButton publishButton= null;
+    public JTextArea pubtext=null;
+    public JList subs=null;
+    public JTree tree=null;    
+    
+    public JCheckBox cXfilter=null;
+    public JCheckBox cTfilter=null;
+    public JCheckBox cSubend=null;
+    public JCheckBox cTermtime=null;
+    
+    public SubListModel sublistmodel=    new SubListModel();
+    
+    public JList nots=null;
+    public NotListModel notlistmodel=    new NotListModel();
+    
+    private PubSubWSmanager pman;
+    private Calendar time;
+    
+    public SubscribePanel(JTabbedPane _notebook, PubSubWSmanager _pman) {
+        try{
+            this.pman=_pman;
+            notebook = _notebook ;
+            
+            
+            this.setLayout( new BoxLayout(this, BoxLayout.Y_AXIS) );
+            
+            // 1st component is just a row of labels and 1-line entry fields
+            /////////////////////////////////////////////////////////////////////
+            JPanel top = new JPanel();
+            
+            top.setLayout( new FlowLayout() );
+            top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+            
+            //xpath filter
+            top.add( cXfilter = new JCheckBox("XPath Filter"));
+            top.add( filterstr = new JTextField("//a/b", 10));
+            top.add( Box.createRigidArea(new Dimension(5, 0)) );
+            this.add(top );
+
+            JPanel top0 = new JPanel();
+
+            //termination time
+            updateTime();
+            top0.add( cTermtime = new JCheckBox("Expiration"));
+            top0.add( termtime = new JTextField(time.getTime().toString(), 20)); 
+            top0.add( Box.createRigidArea(new Dimension(5, 0)) );
+            this.add(top0);
+
+            JPanel top2 = new JPanel();
+
+            //topictree
+            top2.add( cTfilter = new JCheckBox("Topic Filter"));
+            DefaultTreeCellRenderer renderer2 = new DefaultTreeCellRenderer();
+            renderer2.setOpenIcon(null);
+            renderer2.setClosedIcon(null);
+            renderer2.setLeafIcon(null);
+            tree = new TopicSpaceTree(pman).getTree();
+            tree.setCellRenderer(renderer2);
+            top2.add(tree);
+            this.add(top2 );
+            
+            JPanel top3 = new JPanel();
+            
+            //subendnotif
+            top3.add( cSubend = new JCheckBox("Subscription End Notification"));
+            this.add(top3 );
+            
+            JPanel top4 = new JPanel();
+            
+            //subscribe button
+            top4.add(subscribeButton = new JButton("Subscribe"));
+            this.add(top4);
+
+            subscribeButton.addActionListener( new ActionListener() {
+                public void actionPerformed(ActionEvent event) {
+                    Topic t=null;
+                    String xpath=null;
+                    Date expire=null;
+                    boolean subend = (cSubend.getSelectedObjects()!=null);
+                    if(cTfilter.getSelectedObjects()!=null){
+                        TreePath[] ts =tree.getSelectionModel().getSelectionPaths();
+                        if(ts!=null)
+                            t = (org.apache.ws.notification.topics.Topic)((DefaultMutableTreeNode) ts[ts.length-1].getLastPathComponent()).getUserObject();
+                    }
+                    if(cXfilter.getSelectedObjects()!=null){
+                        xpath= filterstr.getText();
+                    }
+                    if(cTermtime.getSelectedObjects()!=null){
+                        try{
+                            expire = java.text.DateFormat.getDateInstance().parse(termtime.getText());
+                        }catch(java.text.ParseException pe){
+                            pe.printStackTrace();                            
+                        }
+                    }
+                    Subscription s = pman.subscribe(sublistmodel,notlistmodel,xpath,t, expire,subend);   
+                    sublistmodel.addData(s);
+                }
+            }
+            );
+            /*
+            this.add( Box.createRigidArea(new Dimension(0, 10)) );
+            JPanel top2 = new JPanel();
+            top2.add( new JLabel("Message", SwingConstants.RIGHT ) );
+            top2.add(pubtext = new JTextArea("<?xml version=\"1.0\" ?>\n<a><b/></a>",10,30));
+            top2.add(publishButton = new JButton("Publish"));
+            
+            publishButton.addActionListener( new ActionListener() {
+                public void actionPerformed(ActionEvent event) {
+                    //if ( removeSelected.equals(event.getActionCommand()) ) {
+                    //   remove();
+                    //}
+                    try{
+                        Publisher.publish("http://localhost:"+pman.outport+"/axis/services/NotificationPort", pubtext.getText());
+                    }catch(Exception e){
+                        e.printStackTrace();
+                    }
+                }
+            }
+            );
+            
+            this.add( top2);
+            this.add( Box.createRigidArea(new Dimension(0, 10)) );
+            */
+            JPanel ls = new JPanel();
+            ls.setLayout( new FlowLayout() );
+            
+            subs = new JList();
+            subs.setModel(sublistmodel);
+            JScrollPane scrollPane = new JScrollPane(subs);
+            ls.add(scrollPane);
+            
+            ls.add( Box.createRigidArea(new Dimension(0, 10)) );
+            
+            nots = new JList();
+            nots.setModel(notlistmodel);
+            JScrollPane scrollPane2 = new JScrollPane(nots);
+            MouseListener mouseListener = new MouseAdapter() {
+                public void mouseClicked(MouseEvent e) {
+                    if (e.getClickCount() == 2) {
+                        int index = nots.locationToIndex(e.getPoint());
+                        JOptionPane.showMessageDialog(notebook,((notentry)notlistmodel.getElementAt(index)).content,"Notification detail",JOptionPane.INFORMATION_MESSAGE);
+                    }
+                }
+            };
+            nots.addMouseListener(mouseListener);
+            ls.add(scrollPane2);
+            this.add(ls);
+        /*
+        this.add(unsubscribeButton = new JButton("Unsubscribe"));
+        unsubscribeButton.addActionListener( new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                if(subs.getSelectedIndex()!=-1){
+                    org.apache.ws.pubsub.Subscription s = (org.apache.ws.pubsub.Subscription)sublistmodel.getElementAt(subs.getSelectedIndex());
+                    s.unsubscribe();
+                }
+            }
+        }*/
+            this.add(renewButton = new JButton("Renew"));
+            renewButton.addActionListener( new ActionListener() {
+                public void actionPerformed(ActionEvent event) {
+                    if(subs.getSelectedIndex()!=-1){
+                        org.apache.ws.pubsub.Subscription s = (org.apache.ws.pubsub.Subscription)sublistmodel.getElementAt(subs.getSelectedIndex());
+                        Calendar c = Calendar.getInstance();
+                        c.add(Calendar.HOUR, 1);
+                        s.setTerminationTime(c);
+                    }
+                }
+            }
+            );
+            
+            notebook.addTab( "Subscriptions", this );
+            // start();
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+    }
+    
+    private void updateTime(){
+        time=Calendar.getInstance();
+        time.add(Calendar.MINUTE,1);
+    }
+}
+
+
+

Added: incubator/hermes/trunk/src/examples/pubsubclient/TopicSpaceTree.java
URL: http://svn.apache.org/viewcvs/incubator/hermes/trunk/src/examples/pubsubclient/TopicSpaceTree.java?view=auto&rev=158387
==============================================================================
--- incubator/hermes/trunk/src/examples/pubsubclient/TopicSpaceTree.java (added)
+++ incubator/hermes/trunk/src/examples/pubsubclient/TopicSpaceTree.java Sun Mar 20 16:41:11 2005
@@ -0,0 +1,44 @@
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import org.apache.ws.notification.topics.Topic;
+import java.util.Iterator;
+/**
+ *
+ * @author  Stefan Lischke
+ */
+public class TopicSpaceTree {
+    private JTree tree;
+    /** Creates a new instance of TopicSpaceTree */
+    public TopicSpaceTree(PubSubWSmanager pman) {  
+        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
+
+        Iterator rootit =pman.topicSpace.topicIterator();
+        while(rootit.hasNext()){
+            Topic t = (Topic)rootit.next();
+            root.add(recurse(t));
+        }
+        tree = new JTree(root);
+//        tree.setRootVisible(true);        
+    }
+        
+    private DefaultMutableTreeNode recurse(Topic t){
+        DefaultMutableTreeNode tn = new DefaultMutableTreeNode(t);
+        Iterator it = t.topicIterator();
+       // System.out.println("topic "+t.getName());
+        while(it.hasNext()){
+            Topic tc = (Topic)it.next(); 
+            tn.add(recurse(tc));
+        }
+        return tn;
+    }
+    
+    public JTree getTree(){
+        return tree;
+    }
+    /*
+    public class TopicTreeNode extends DefaultMutableTreeNode{
+        public TopicTreeNode(Topic t){
+            super.()
+        }
+    }*/
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: hermes-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: hermes-dev-help@ws.apache.org


Mime
View raw message