KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > utils > tcpmon


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.axis.utils ;
17
18
19 import java.awt.BorderLayout JavaDoc;
20 import java.awt.Color JavaDoc;
21 import java.awt.Component JavaDoc;
22 import java.awt.Dimension JavaDoc;
23 import java.awt.GridBagConstraints JavaDoc;
24 import java.awt.GridBagLayout JavaDoc;
25 import java.awt.event.ActionEvent JavaDoc;
26 import java.awt.event.ActionListener JavaDoc;
27 import java.io.ByteArrayInputStream JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.InputStream JavaDoc;
31 import java.io.OutputStream JavaDoc;
32 import java.io.PrintWriter JavaDoc;
33 import java.io.StringWriter JavaDoc;
34 import java.net.ServerSocket JavaDoc;
35 import java.net.Socket JavaDoc;
36 import java.net.URL JavaDoc;
37 import java.text.DateFormat JavaDoc;
38 import java.text.SimpleDateFormat JavaDoc;
39 import java.util.Date JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.ResourceBundle JavaDoc;
42 import java.util.Vector JavaDoc;
43
44 import javax.swing.BorderFactory JavaDoc;
45 import javax.swing.Box JavaDoc;
46 import javax.swing.BoxLayout JavaDoc;
47 import javax.swing.ButtonGroup JavaDoc;
48 import javax.swing.JButton JavaDoc;
49 import javax.swing.JCheckBox JavaDoc;
50 import javax.swing.JFileChooser JavaDoc;
51 import javax.swing.JFrame JavaDoc;
52 import javax.swing.JLabel JavaDoc;
53 import javax.swing.JPanel JavaDoc;
54 import javax.swing.JRadioButton JavaDoc;
55 import javax.swing.JScrollPane JavaDoc;
56 import javax.swing.JSplitPane JavaDoc;
57 import javax.swing.JTabbedPane JavaDoc;
58 import javax.swing.JTable JavaDoc;
59 import javax.swing.JTextArea JavaDoc;
60 import javax.swing.JTextField JavaDoc;
61 import javax.swing.ListSelectionModel JavaDoc;
62 import javax.swing.SwingConstants JavaDoc;
63 import javax.swing.UIManager JavaDoc;
64 import javax.swing.UnsupportedLookAndFeelException JavaDoc;
65 import javax.swing.border.TitledBorder JavaDoc;
66 import javax.swing.event.ChangeEvent JavaDoc;
67 import javax.swing.event.ListSelectionEvent JavaDoc;
68 import javax.swing.event.ListSelectionListener JavaDoc;
69 import javax.swing.plaf.basic.BasicButtonListener JavaDoc;
70 import javax.swing.table.DefaultTableModel JavaDoc;
71 import javax.swing.table.TableColumn JavaDoc;
72 import javax.swing.table.TableModel JavaDoc;
73 import javax.swing.text.AttributeSet JavaDoc;
74 import javax.swing.text.BadLocationException JavaDoc;
75 import javax.swing.text.Document JavaDoc;
76 import javax.swing.text.PlainDocument JavaDoc;
77
78
79 /**
80  * TCP monitor to log http messages and responses, both SOAP and plain HTTP.
81  * If you want to choose a different Swing look and feel, set the property
82  * tcpmon.laf to the classname of the new look and feel
83  * @author Doug Davis (dug@us.ibm.com)
84  * @author Steve Loughran
85  */

86
87 public class tcpmon extends JFrame JavaDoc {
88     private JTabbedPane JavaDoc notebook = null ;
89
90     private static final int STATE_COLUMN = 0 ;
91     private static final int TIME_COLUMN = 1 ;
92     private static final int INHOST_COLUMN = 2 ;
93     private static final int OUTHOST_COLUMN = 3 ;
94     private static final int REQ_COLUMN = 4 ;
95
96
97     private static final String JavaDoc DEFAULT_HOST="127.0.0.1";
98     private static final int DEFAULT_PORT=8080;
99
100     /**
101      * this is the admin page
102      */

103     class AdminPage extends JPanel JavaDoc {
104         public JRadioButton JavaDoc listenerButton, proxyButton ;
105         public JLabel JavaDoc hostLabel, tportLabel;
106         public NumberField port;
107         public HostnameField host;
108         public NumberField tport ;
109         public JTabbedPane JavaDoc noteb ;
110         public JCheckBox JavaDoc HTTPProxyBox ;
111         public HostnameField HTTPProxyHost;
112         public NumberField HTTPProxyPort ;
113         public JLabel JavaDoc HTTPProxyHostLabel, HTTPProxyPortLabel ;
114         public JLabel JavaDoc delayTimeLabel, delayBytesLabel;
115         public NumberField delayTime, delayBytes;
116         public JCheckBox JavaDoc delayBox;
117
118         public AdminPage( JTabbedPane JavaDoc notebook, String JavaDoc name ) {
119             JPanel JavaDoc mainPane = null ;
120             JButton JavaDoc addButton = null ;
121
122             this.setLayout( new BorderLayout JavaDoc() );
123             noteb = notebook ;
124
125             GridBagLayout JavaDoc layout = new GridBagLayout JavaDoc();
126             GridBagConstraints JavaDoc c = new GridBagConstraints JavaDoc();
127
128             mainPane = new JPanel JavaDoc(layout);
129
130             c.anchor = GridBagConstraints.WEST ;
131             c.gridwidth = GridBagConstraints.REMAINDER;
132             mainPane.add( new JLabel JavaDoc(getMessage("newTCP00", "Create a new TCP/IP Monitor...") + " "), c );
133
134             // Add some blank space
135
mainPane.add( Box.createRigidArea(new Dimension JavaDoc(1, 5)), c );
136
137             // The listener info
138
///////////////////////////////////////////////////////////////////
139
JPanel JavaDoc tmpPanel = new JPanel JavaDoc(new GridBagLayout JavaDoc());
140
141             c.anchor = GridBagConstraints.WEST ;
142             c.gridwidth = 1 ;
143             tmpPanel.add( new JLabel JavaDoc(getMessage("listenPort00", "Listen Port #") + " "), c );
144
145             c.anchor = GridBagConstraints.WEST ;
146             c.gridwidth = GridBagConstraints.REMAINDER ;
147             tmpPanel.add( port = new NumberField(4), c );
148
149             mainPane.add( tmpPanel, c );
150
151             mainPane.add( Box.createRigidArea(new Dimension JavaDoc(1, 5)), c );
152
153             // Group for the radio buttons
154
ButtonGroup JavaDoc btns = new ButtonGroup JavaDoc();
155
156             c.anchor = GridBagConstraints.WEST ;
157             c.gridwidth = GridBagConstraints.REMAINDER ;
158             mainPane.add( new JLabel JavaDoc(getMessage("actAs00", "Act as a...") ), c );
159
160             // Target Host/Port section
161
///////////////////////////////////////////////////////////////////
162
c.anchor = GridBagConstraints.WEST ;
163             c.gridwidth = GridBagConstraints.REMAINDER ;
164
165             final String JavaDoc listener = getMessage("listener00", "Listener");
166
167             mainPane.add( listenerButton = new JRadioButton JavaDoc( listener ), c );
168             btns.add( listenerButton );
169             listenerButton.setSelected( true );
170
171             listenerButton.addActionListener( new ActionListener JavaDoc() {
172                     public void actionPerformed(ActionEvent JavaDoc event) {
173                         if (listener.equals(event.getActionCommand())) {
174                             boolean state = listenerButton.isSelected();
175
176                             tport.setEnabled( state );
177                             host.setEnabled( state );
178                             hostLabel.setForeground(state ? Color.black : Color.gray);
179                             tportLabel.setForeground(state ? Color.black : Color.gray);
180                         }
181                     }
182                 }
183             );
184
185             c.anchor = GridBagConstraints.WEST ;
186             c.gridwidth = 1 ;
187             mainPane.add( Box.createRigidArea(new Dimension JavaDoc(25, 0)) );
188             mainPane.add( hostLabel = new JLabel JavaDoc(getMessage("targetHostname00", "Target Hostname") + " "), c );
189
190             c.anchor = GridBagConstraints.WEST ;
191             c.gridwidth = GridBagConstraints.REMAINDER ;
192             host = new HostnameField(30);
193             mainPane.add( host, c );
194             host.setText(DEFAULT_HOST);
195
196             c.anchor = GridBagConstraints.WEST ;
197             c.gridwidth = 1 ;
198             mainPane.add( Box.createRigidArea(new Dimension JavaDoc(25, 0)) );
199             mainPane.add( tportLabel = new JLabel JavaDoc(getMessage("targetPort00", "Target Port #") + " "), c );
200
201             c.anchor = GridBagConstraints.WEST ;
202             c.gridwidth = GridBagConstraints.REMAINDER ;
203             tport = new NumberField(4);
204             mainPane.add( tport, c );
205             tport.setValue(DEFAULT_PORT);
206
207             // Act as proxy section
208
///////////////////////////////////////////////////////////////////
209
c.anchor = GridBagConstraints.WEST ;
210             c.gridwidth = GridBagConstraints.REMAINDER ;
211             final String JavaDoc proxy = getMessage("proxy00", "Proxy");
212
213             mainPane.add( proxyButton = new JRadioButton JavaDoc( proxy ), c);
214             btns.add( proxyButton );
215
216             proxyButton.addActionListener( new ActionListener JavaDoc() {
217                     public void actionPerformed(ActionEvent JavaDoc event) {
218                         if (proxy.equals(event.getActionCommand())) {
219                             boolean state = proxyButton.isSelected();
220
221                             tport.setEnabled( !state );
222                             host.setEnabled( !state );
223                             hostLabel.setForeground(state ? Color.gray : Color.black);
224                             tportLabel.setForeground(state ? Color.gray : Color.black);
225                         }
226                     }
227                 }
228             );
229
230             // Spacer
231
/////////////////////////////////////////////////////////////////
232
c.anchor = GridBagConstraints.WEST ;
233             c.gridwidth = GridBagConstraints.REMAINDER ;
234             mainPane.add( Box.createRigidArea(new Dimension JavaDoc(1, 10)), c );
235
236             // Options section
237
///////////////////////////////////////////////////////////////////
238
JPanel JavaDoc opts = new JPanel JavaDoc(new GridBagLayout JavaDoc());
239
240             opts.setBorder( new TitledBorder JavaDoc(getMessage("options00", "Options")) );
241             c.anchor = GridBagConstraints.WEST ;
242             c.gridwidth = GridBagConstraints.REMAINDER ;
243             mainPane.add( opts, c );
244
245             // HTTP Proxy Support section
246
///////////////////////////////////////////////////////////////////
247
c.anchor = GridBagConstraints.WEST ;
248             c.gridwidth = GridBagConstraints.REMAINDER ;
249             final String JavaDoc proxySupport = getMessage("proxySupport00", "HTTP Proxy Support");
250
251             opts.add(HTTPProxyBox = new JCheckBox JavaDoc(proxySupport), c);
252
253             c.anchor = GridBagConstraints.WEST ;
254             c.gridwidth = 1 ;
255             opts.add( HTTPProxyHostLabel = new JLabel JavaDoc(getMessage("hostname00", "Hostname") + " "), c );
256             HTTPProxyHostLabel.setForeground( Color.gray );
257
258             c.anchor = GridBagConstraints.WEST ;
259             c.gridwidth = GridBagConstraints.REMAINDER ;
260             opts.add( HTTPProxyHost = new HostnameField(30), c );
261             HTTPProxyHost.setEnabled( false );
262
263             c.anchor = GridBagConstraints.WEST ;
264             c.gridwidth = 1 ;
265             opts.add( HTTPProxyPortLabel = new JLabel JavaDoc(getMessage("port00", "Port #") + " "), c );
266             HTTPProxyPortLabel.setForeground( Color.gray );
267
268             c.anchor = GridBagConstraints.WEST ;
269             c.gridwidth = GridBagConstraints.REMAINDER ;
270             opts.add( HTTPProxyPort = new NumberField(4), c );
271             HTTPProxyPort.setEnabled( false );
272
273             HTTPProxyBox.addActionListener( new ActionListener JavaDoc() {
274                     public void actionPerformed(ActionEvent JavaDoc event) {
275                         if (proxySupport.equals(event.getActionCommand())) {
276                             boolean b = HTTPProxyBox.isSelected();
277                             Color JavaDoc color = b ? Color.black : Color.gray ;
278
279                             HTTPProxyHost.setEnabled( b );
280                             HTTPProxyPort.setEnabled( b );
281                             HTTPProxyHostLabel.setForeground( color );
282                             HTTPProxyPortLabel.setForeground( color );
283                         }
284                     }
285                 }
286             );
287
288             // Set default proxy values...
289
String JavaDoc tmp = System.getProperty( "http.proxyHost" );
290
291             if ( tmp != null && tmp.equals("") ) {
292                 tmp = null ;
293             }
294
295             HTTPProxyBox.setSelected( tmp != null );
296             HTTPProxyHost.setEnabled( tmp != null );
297             HTTPProxyPort.setEnabled( tmp != null );
298             HTTPProxyHostLabel.setForeground( tmp != null ? Color.black : Color.gray);
299             HTTPProxyPortLabel.setForeground( tmp != null ? Color.black : Color.gray);
300
301             if ( tmp != null ) {
302                 HTTPProxyBox.setSelected( true );
303                 HTTPProxyHost.setText( tmp );
304                 tmp = System.getProperty( "http.proxyPort" );
305                 if ( tmp != null && tmp.equals("") ) {
306                     tmp = null ;
307                 }
308                 if ( tmp == null ) {
309                     tmp = "80" ;
310                 }
311                 HTTPProxyPort.setText( tmp );
312             }
313
314             //add byte delay fields
315
opts.add(Box.createRigidArea(new Dimension JavaDoc(1, 10)), c);
316             c.anchor = GridBagConstraints.WEST;
317             c.gridwidth = GridBagConstraints.REMAINDER;
318             final String JavaDoc delaySupport = getMessage("delay00", "Simulate Slow Connection");
319             opts.add(delayBox = new JCheckBox JavaDoc(delaySupport), c);
320
321             //bytes per pause
322
c.anchor = GridBagConstraints.WEST;
323             c.gridwidth = 1;
324             delayBytesLabel=new JLabel JavaDoc(getMessage("delay01", "Bytes per Pause"));
325             opts.add(delayBytesLabel, c);
326             delayBytesLabel.setForeground(Color.gray);
327             c.anchor = GridBagConstraints.WEST;
328             c.gridwidth = GridBagConstraints.REMAINDER;
329             opts.add(delayBytes = new NumberField(6), c);
330             delayBytes.setEnabled(false);
331
332             //delay interval
333
c.anchor = GridBagConstraints.WEST;
334             c.gridwidth = 1;
335             delayTimeLabel = new JLabel JavaDoc(getMessage("delay02", "Delay in Milliseconds"));
336             opts.add(delayTimeLabel, c);
337             delayTimeLabel.setForeground(Color.gray);
338             c.anchor = GridBagConstraints.WEST;
339             c.gridwidth = GridBagConstraints.REMAINDER;
340             opts.add(delayTime = new NumberField(6), c);
341             delayTime.setEnabled(false);
342
343             //enabler callback
344
delayBox.addActionListener(new ActionListener JavaDoc() {
345                 public void actionPerformed(ActionEvent JavaDoc event) {
346                     if (delaySupport.equals(event.getActionCommand())) {
347                         boolean b = delayBox.isSelected();
348                         Color JavaDoc color = b ? Color.black : Color.gray;
349
350                         delayBytes.setEnabled(b);
351                         delayTime.setEnabled(b);
352                         delayBytesLabel.setForeground(color);
353                         delayTimeLabel.setForeground(color);
354                     }
355                 }
356             }
357             );
358
359             // Spacer
360
//////////////////////////////////////////////////////////////////
361
mainPane.add( Box.createRigidArea(new Dimension JavaDoc(1, 10)), c );
362
363             // ADD Button
364
///////////////////////////////////////////////////////////////////
365
c.anchor = GridBagConstraints.WEST ;
366             c.gridwidth = GridBagConstraints.REMAINDER ;
367             final String JavaDoc add = getMessage("add00", "Add");
368
369             mainPane.add( addButton = new JButton JavaDoc( add ), c );
370
371
372             this.add( new JScrollPane JavaDoc( mainPane ), BorderLayout.CENTER );
373
374             // addButton.setEnabled( false );
375
addButton.addActionListener( new ActionListener JavaDoc() {
376                     public void actionPerformed(ActionEvent JavaDoc event) {
377                         if ( add.equals(event.getActionCommand()) ) {
378                             String JavaDoc text ;
379                             Listener JavaDoc l = null ;
380                             int lPort;
381                             lPort=port.getValue(0);
382                             if(lPort==0) {
383                                 //no port, button does nothing
384
return;
385                             }
386                             String JavaDoc tHost = host.getText();
387                             int tPort = 0 ;
388                             tPort=tport.getValue(0);
389                             SlowLinkSimulator slowLink=null;
390                             if(delayBox.isSelected()) {
391                                 int bytes= delayBytes.getValue(0);
392                                 int time = delayTime.getValue(0);
393                                 slowLink=new SlowLinkSimulator(bytes,time);
394                             }
395                             try {
396                             l = new Listener JavaDoc( noteb, null, lPort, tHost, tPort,
397                                            proxyButton.isSelected(), slowLink);
398                             } catch (Exception JavaDoc e){
399                                 e.printStackTrace();
400                             }
401                             // Pick-up the HTTP Proxy settings
402
///////////////////////////////////////////////////
403
text = HTTPProxyHost.getText();
404                             if ( "".equals(text) ) {
405                                 text = null ;
406                             }
407                             l.HTTPProxyHost = text ;
408                             text = HTTPProxyPort.getText();
409                             int proxyPort=HTTPProxyPort.getValue(-1);
410                             if(proxyPort!=-1) {
411                                 l.HTTPProxyPort = Integer.parseInt(text);
412                             }
413                             //reset the port
414
port.setText(null);
415
416                             /* but not, any more, the target port and host
417                                values
418                             host.setText(null);
419                             tport.setText(null);
420                             */

421                         }
422                     }
423                 }
424             );
425
426             notebook.addTab( name, this );
427             notebook.repaint();
428             notebook.setSelectedIndex( notebook.getTabCount() - 1 );
429         }
430
431
432     }
433
434     /**
435      * wait for incoming connections, spawn a connection thread when
436      * stuff comes in.
437      */

438     class SocketWaiter extends Thread JavaDoc {
439         ServerSocket JavaDoc sSocket = null ;
440         Listener JavaDoc listener ;
441         int port ;
442         boolean pleaseStop = false ;
443
444         public SocketWaiter(Listener JavaDoc l, int p) {
445             listener = l ;
446             port = p ;
447             start();
448         }
449
450         public void run() {
451             try {
452                 listener.setLeft( new JLabel JavaDoc(getMessage("wait00", " Waiting for Connection...") ) );
453                 listener.repaint();
454                 sSocket = new ServerSocket JavaDoc( port );
455                 for (; ; ) {
456                     Socket JavaDoc inSocket = sSocket.accept();
457
458                     if ( pleaseStop ) {
459                         break ;
460                     }
461                     new Connection( listener, inSocket );
462                     inSocket = null ;
463                 }
464             } catch ( Exception JavaDoc exp ) {
465                 if ( !"socket closed".equals(exp.getMessage()) ) {
466                     JLabel JavaDoc tmp = new JLabel JavaDoc( exp.toString() );
467
468                     tmp.setForeground( Color.red );
469                     listener.setLeft( tmp );
470                     listener.setRight( new JLabel JavaDoc("") );
471                     listener.stop();
472                 }
473             }
474         }
475
476         /**
477          * force a halt by connecting to self and then closing the server socket
478          */

479         public void halt() {
480             try {
481                 pleaseStop = true ;
482                 new Socket JavaDoc( "127.0.0.1", port );
483                 if ( sSocket != null ) {
484                     sSocket.close();
485                 }
486             } catch ( Exception JavaDoc e ) {
487                 e.printStackTrace();
488             }
489         }
490     }
491
492
493     /**
494      * class to simulate slow connections by slowing down the system
495      */

496     static class SlowLinkSimulator {
497         private int delayBytes;
498         private int delayTime;
499         private int currentBytes;
500         private int totalBytes;
501
502         /**
503          * construct
504          * @param delayBytes bytes per delay; set to 0 for no delay
505          * @param delayTime delay time per delay in milliseconds
506          */

507         public SlowLinkSimulator(int delayBytes, int delayTime) {
508             this.delayBytes = delayBytes;
509             this.delayTime = delayTime;
510         }
511
512         /**
513          * construct by copying delay bytes and time, but not current
514          * count of bytes
515          * @param that source of data
516          */

517         public SlowLinkSimulator(SlowLinkSimulator that) {
518             this.delayBytes=that.delayBytes;
519             this.delayTime=that.delayTime;
520         }
521
522         /**
523          * how many bytes have gone past?
524          * @return
525          */

526         public int getTotalBytes() {
527             return totalBytes;
528         }
529
530         /**
531          * log #of bytes pumped. Will pause when necessary. This method is not
532          * synchronized
533          * @param bytes
534          */

535         public void pump(int bytes) {
536             totalBytes+=bytes;
537             if(delayBytes==0) {
538                 //when not delaying, we are just a byte counter
539
return;
540             }
541             currentBytes += bytes;
542             if(currentBytes>delayBytes) {
543                 //we have overshot. lets find out how far
544
int delaysize=currentBytes/delayBytes;
545                 long delay=delaysize*(long)delayTime;
546                 //move byte counter down to the remainder of bytes
547
currentBytes=currentBytes%delayBytes;
548                 //now wait
549
try {
550                     Thread.sleep(delay);
551                 } catch (InterruptedException JavaDoc e) {
552                     ; //ignore the exception
553
}
554             }
555         }
556
557         /**
558          * get the current byte count
559          * @return
560          */

561         public int getCurrentBytes() {
562             return currentBytes;
563         }
564
565         /**
566          * set the current byte count
567          * @param currentBytes
568          */

569         public void setCurrentBytes(int currentBytes) {
570             this.currentBytes = currentBytes;
571         }
572
573     }
574
575     /**
576      * this class handles the pumping of data from the incoming socket to the
577      * outgoing socket
578      */

579     class SocketRR extends Thread JavaDoc {
580         Socket JavaDoc inSocket = null ;
581         Socket JavaDoc outSocket = null ;
582         JTextArea JavaDoc textArea ;
583         InputStream JavaDoc in = null ;
584         OutputStream JavaDoc out = null ;
585         boolean xmlFormat ;
586         boolean numericEnc ;
587         volatile boolean done = false ;
588         TableModel JavaDoc tmodel = null ;
589         int tableIndex = 0 ;
590         String JavaDoc type = null;
591         Connection myConnection = null;
592         SlowLinkSimulator slowLink;
593
594         public SocketRR(Connection c, Socket JavaDoc inputSocket, InputStream JavaDoc inputStream,
595             Socket JavaDoc outputSocket, OutputStream JavaDoc outputStream,
596             JTextArea JavaDoc _textArea, boolean format, boolean numeric,
597             TableModel JavaDoc tModel, int index, final String JavaDoc type, SlowLinkSimulator slowLink) {
598             inSocket = inputSocket ;
599             in = inputStream ;
600             outSocket = outputSocket ;
601             out = outputStream ;
602             textArea = _textArea ;
603             xmlFormat = format ;
604             numericEnc= numeric ;
605             tmodel = tModel ;
606             tableIndex = index ;
607             this.type = type;
608             myConnection = c;
609             this.slowLink= slowLink;
610             start();
611         }
612
613         public boolean isDone() {
614             return ( done );
615         }
616
617         public void run() {
618             try {
619                 byte[] buffer = new byte[4096];
620                 byte[] tmpbuffer = new byte[8192];
621                 String JavaDoc message = null;
622                 int saved = 0 ;
623                 int len ;
624                 int i1, i2 ;
625                 int i ;
626                 int reqSaved = 0 ;
627                 int tabWidth = 3 ;
628                 boolean atMargin = true ;
629                 int thisIndent = -1,
630                     nextIndent = -1,
631                     previousIndent = -1;
632
633                 //if ( inSocket != null ) inSocket.setSoTimeout( 10 );
634
//if ( outSocket != null ) outSocket.setSoTimeout( 10 );
635

636                 if ( tmodel != null ) {
637                     String JavaDoc tmpStr = (String JavaDoc) tmodel.getValueAt(tableIndex,
638                             REQ_COLUMN);
639
640                     if ( !"".equals(tmpStr) ) {
641                         reqSaved = tmpStr.length();
642                     }
643                 }
644
645             a:
646                 for ( ; ; ) {
647                     if ( done ) {
648                         break;
649                     }
650                     //try{
651
//len = in.available();
652
//}catch(Exception e){len=0;}
653
len = buffer.length ;
654                     // Used to be 1, but if we block it doesn't matter
655
// however 1 will break with some servers, including apache
656
if ( len == 0 ) {
657                         len = buffer.length;
658                     }
659                     if ( saved + len > buffer.length) {
660                         len = buffer.length - saved ;
661                     }
662                     int len1 = 0;
663
664                     while ( len1 == 0 ) {
665                         try {
666                             len1 = in.read(buffer, saved, len);
667                         }
668                         catch ( Exception JavaDoc ex ) {
669                             if ( done && saved == 0 ) {
670                                 break a;
671                             }
672                             len1 = -1;
673                             break;
674                         }
675                     }
676                     len = len1;
677
678                     if ( len == -1 && saved == 0 ) {
679                         break ;
680                     }
681                     if ( len == -1) {
682                         done = true;
683                     }
684
685                     // No matter how we may (or may not) format it, send it
686
// on unformatted - we don't want to mess with how its
687
// sent to the other side, just how its displayed
688
if ( out != null && len > 0 ) {
689                         slowLink.pump(len);
690                         out.write( buffer, saved, len );
691                     }
692
693                     if ( tmodel != null && reqSaved < 50 ) {
694                         String JavaDoc old = (String JavaDoc) tmodel.getValueAt( tableIndex,
695                                 REQ_COLUMN);
696
697                         old = old + new String JavaDoc(buffer, saved, len);
698                         if ( old.length() > 50 ) {
699                             old = old.substring(0, 50);
700                         }
701
702                         reqSaved = old.length();
703
704                         if ( (i = old.indexOf('\n')) > 0 ) {
705                             old = old.substring(0, i - 1);
706                             reqSaved = 50 ;
707                         }
708
709                         tmodel.setValueAt( old, tableIndex, REQ_COLUMN );
710                     }
711
712                     if ( xmlFormat ) {
713                         // Do XML Formatting
714
boolean inXML = false ;
715                         int bufferLen = saved ;
716
717                         if ( len != -1 ) {
718                             bufferLen += len ;
719                         }
720                         i1 = 0 ;
721                         i2 = 0 ;
722                         saved = 0 ;
723                         for ( ; i1 < bufferLen ; i1++ ) {
724                             // Except when we're at EOF, saved last char
725
if ( len != -1 && i1 + 1 == bufferLen ) {
726                                 saved = 1;
727                                 break;
728                             }
729                             thisIndent = -1;
730                             if ( buffer[i1] == '<' && buffer[i1 + 1] != '/' ) {
731                                 previousIndent = nextIndent++;
732                                 thisIndent = nextIndent;
733                                 inXML = true ;
734                             }
735                             if ( buffer[i1] == '<' && buffer[i1 + 1] == '/' ) {
736                                 if (previousIndent > nextIndent) {
737                                     thisIndent = nextIndent;
738                                 }
739                                 previousIndent = nextIndent--;
740                                 inXML = true ;
741                             }
742                             if ( buffer[i1] == '/' && buffer[i1 + 1] == '>' ) {
743                                 previousIndent = nextIndent--;
744                                 inXML = true ;
745                             }
746                             if ( thisIndent != -1 ) {
747                                 if ( thisIndent > 0 ) {
748                                     tmpbuffer[i2++] = (byte) '\n';
749                                 }
750                                 for ( i = tabWidth * thisIndent; i > 0; i-- ) {
751                                     tmpbuffer[i2++] = (byte) ' ';
752                                 }
753                             }
754                             atMargin = ( buffer[i1] == '\n' || buffer[i1] == '\r');
755
756                             if ( !inXML || !atMargin ) {
757                                 tmpbuffer[i2++] = buffer[i1];
758                             }
759                         }
760                         message = new String JavaDoc( tmpbuffer, 0, i2, getEncoding() );
761                         if (numericEnc) {
762                             textArea.append( StringUtils.escapeNumericChar(message) );
763                         } else {
764                             textArea.append( StringUtils.unescapeNumericChar(message) );
765                         }
766
767                         // Shift saved bytes to the beginning
768
for ( i = 0 ; i < saved ; i++ ) {
769                             buffer[i] = buffer[bufferLen - saved + i];
770                         }
771                     }
772                     else {
773                         message = new String JavaDoc( buffer, 0, len, getEncoding() );
774                         if (numericEnc) {
775                             textArea.append( StringUtils.escapeNumericChar(message) );
776                         } else {
777                             textArea.append( StringUtils.unescapeNumericChar(message) );
778                         }
779                     }
780                 // this.sleep(3); // Let other threads have a chance to run
781
}
782             // this.sleep(3); // Let other threads have a chance to run
783
// halt();
784
// Only set the 'done' flag if we were reading from a
785
// Socket - if we were reading from an input stream then
786
// we'll let the other side control when we're done
787
// if ( inSocket != null ) done = true ;
788
}
789             catch ( Throwable JavaDoc t ) {
790                 t.printStackTrace();
791             }
792             finally {
793                 done = true ;
794                 try {
795                     if (out != null) {
796                         out.flush();
797                         if (null != outSocket) {
798                             outSocket.shutdownOutput();
799                         } else {
800                             out.close();
801                         }
802                         out = null;
803                     }
804                 }
805                 catch (Exception JavaDoc e) {
806                     ;
807                 }
808                 try {
809                     if (in != null) {
810                         if (inSocket != null) {
811                             inSocket.shutdownInput();
812                         } else {
813                             in.close();
814                         }
815                         in = null;
816                     }
817                 }
818                 catch (Exception JavaDoc e) {
819                     ;
820                 }
821                 myConnection.wakeUp();
822             }
823         }
824
825         private String JavaDoc getEncoding() {
826             try {
827             return XMLUtils.getEncoding();
828
829             } catch (Throwable JavaDoc t){
830                 return "UTF-8";
831             }
832         }
833         
834         public void halt() {
835             try {
836                 if ( inSocket != null ) {
837                     inSocket.close();
838                 }
839                 if ( outSocket != null ) {
840                     outSocket.close();
841                 }
842                 inSocket = null ;
843                 outSocket = null ;
844                 if ( in != null ) {
845                     in.close();
846                 }
847                 if ( out != null ) {
848                     out.close();
849                 }
850                 in = null ;
851                 out = null ;
852                 done = true;
853             }
854             catch ( Exception JavaDoc e ) {
855                 e.printStackTrace();
856             }
857         }
858     }
859
860
861     /**
862      * a connection listens to a single current connection
863      */

864     class Connection extends Thread JavaDoc {
865         Listener JavaDoc listener ;
866         boolean active ;
867         String JavaDoc fromHost ;
868         String JavaDoc time ;
869         JTextArea JavaDoc inputText = null ;
870         JScrollPane JavaDoc inputScroll = null ;
871         JTextArea JavaDoc outputText = null ;
872         JScrollPane JavaDoc outputScroll = null ;
873         Socket JavaDoc inSocket = null ;
874         Socket JavaDoc outSocket = null ;
875         Thread JavaDoc clientThread = null ;
876         Thread JavaDoc serverThread = null ;
877         SocketRR rr1 = null ;
878         SocketRR rr2 = null ;
879         InputStream JavaDoc inputStream = null ;
880
881         String JavaDoc HTTPProxyHost = null ;
882         int HTTPProxyPort = 80 ;
883         private SlowLinkSimulator slowLink;
884
885         public Connection(Listener JavaDoc l) {
886             listener = l ;
887             HTTPProxyHost = l.HTTPProxyHost ;
888             HTTPProxyPort = l.HTTPProxyPort ;
889             slowLink =l.slowLink;
890         }
891
892         public Connection(Listener JavaDoc l, Socket JavaDoc s ) {
893             this (l);
894             inSocket = s ;
895             start();
896         }
897
898         public Connection(Listener JavaDoc l, InputStream JavaDoc in ) {
899             this (l);
900             inputStream = in ;
901             start();
902         }
903
904         public void run() {
905             try {
906                 active = true ;
907
908                 HTTPProxyHost = System.getProperty( "http.proxyHost" );
909                 if ( HTTPProxyHost != null && HTTPProxyHost.equals("") ) {
910                     HTTPProxyHost = null ;
911                 }
912
913                 if ( HTTPProxyHost != null ) {
914                     String JavaDoc tmp = System.getProperty( "http.proxyPort" );
915
916                     if ( tmp != null && tmp.equals("") ) {
917                         tmp = null ;
918                     }
919                     if ( tmp == null ) {
920                         HTTPProxyPort = 80 ;
921                     } else {
922                         HTTPProxyPort = Integer.parseInt( tmp );
923                     }
924                 }
925
926                 if ( inSocket != null ) {
927                     fromHost = (inSocket.getInetAddress()).getHostName();
928                 } else {
929                     fromHost = "resend" ;
930                 }
931
932
933                 String JavaDoc dateformat=getMessage("dateformat00", "yyyy-MM-dd HH:mm:ss");
934                 DateFormat JavaDoc df = new SimpleDateFormat JavaDoc(dateformat);
935
936                 time = df.format( new Date JavaDoc() );
937
938                 int count = listener.connections.size();
939
940                 listener.tableModel.insertRow(count + 1, new Object JavaDoc[] {
941                         getMessage("active00", "Active"),
942                         time,
943                         fromHost,
944                         listener.hostField.getText(), ""
945                     }
946                 );
947                 listener.connections.add( this );
948                 inputText = new JTextArea JavaDoc( null, null, 20, 80 );
949                 inputScroll = new JScrollPane JavaDoc( inputText );
950                 outputText = new JTextArea JavaDoc( null, null, 20, 80 );
951                 outputScroll = new JScrollPane JavaDoc( outputText );
952
953                 ListSelectionModel JavaDoc lsm = listener.connectionTable.getSelectionModel();
954
955                 if ( count == 0 || lsm.getLeadSelectionIndex() == 0 ) {
956                     listener.outPane.setVisible( false );
957                     int divLoc = listener.outPane.getDividerLocation();
958
959                     listener.setLeft( inputScroll );
960                     listener.setRight( outputScroll );
961
962                     listener.removeButton.setEnabled(false);
963                     listener.removeAllButton.setEnabled(true);
964                     listener.saveButton.setEnabled(true);
965                     listener.resendButton.setEnabled(true);
966                     listener.outPane.setDividerLocation(divLoc);
967                     listener.outPane.setVisible( true );
968                 }
969
970                 String JavaDoc targetHost = listener.hostField.getText();
971                 int targetPort = Integer.parseInt(listener.tPortField.getText());
972                 int listenPort = Integer.parseInt(listener.portField.getText());
973
974                 InputStream JavaDoc tmpIn1 = inputStream ;
975                 OutputStream JavaDoc tmpOut1 = null ;
976
977                 InputStream JavaDoc tmpIn2 = null ;
978                 OutputStream JavaDoc tmpOut2 = null ;
979
980                 if ( tmpIn1 == null ) {
981                     tmpIn1 = inSocket.getInputStream();
982                 }
983
984                 if ( inSocket != null ) {
985                     tmpOut1 = inSocket.getOutputStream();
986                 }
987
988                 String JavaDoc bufferedData = null ;
989                 StringBuffer JavaDoc buf = null ;
990
991                 int index = listener.connections.indexOf( this );
992
993                 if (listener.isProxyBox.isSelected() || HTTPProxyHost != null) {
994                     // Check if we're a proxy
995
byte[] b = new byte[1];
996
997                     buf = new StringBuffer JavaDoc();
998                     String JavaDoc s ;
999
1000                    for ( ; ; ) {
1001                        int len ;
1002
1003                        len = tmpIn1.read(b, 0, 1);
1004                        if ( len == -1 ) {
1005                            break ;
1006                        }
1007                        s = new String JavaDoc( b );
1008                        buf.append( s );
1009                        if ( b[0] != '\n' ) {
1010                            continue ;
1011                        }
1012                        break ;
1013                    }
1014
1015                    bufferedData = buf.toString();
1016                    inputText.append( bufferedData );
1017
1018                    if ( bufferedData.startsWith( "GET " ) ||
1019                        bufferedData.startsWith( "POST " ) ||
1020                        bufferedData.startsWith( "PUT " ) ||
1021                        bufferedData.startsWith( "DELETE " ) ) {
1022                        int start, end ;
1023                        URL JavaDoc url ;
1024
1025                        start = bufferedData.indexOf( ' ' ) + 1;
1026                        while ( bufferedData.charAt(start) == ' ' ) {
1027                            start++ ;
1028                        }
1029                        end = bufferedData.indexOf( ' ', start );
1030                        String JavaDoc urlString = bufferedData.substring( start, end );
1031
1032                        if ( urlString.charAt(0) == '/' ) {
1033                            urlString = urlString.substring(1);
1034                        }
1035                        if ( listener.isProxyBox.isSelected() ) {
1036                            url = new URL JavaDoc( urlString );
1037                            targetHost = url.getHost();
1038                            targetPort = url.getPort();
1039                            if ( targetPort == -1 ) {
1040                                targetPort = 80 ;
1041                            }
1042
1043                            listener.tableModel.setValueAt( targetHost, index + 1,
1044                                OUTHOST_COLUMN );
1045                            bufferedData = bufferedData.substring( 0, start) +
1046                            url.getFile() +
1047                            bufferedData.substring( end );
1048                        }
1049                        else {
1050                            url = new URL JavaDoc( "http://" + targetHost + ":" +
1051                                targetPort + "/" + urlString );
1052
1053                            listener.tableModel.setValueAt( targetHost, index + 1,
1054                                OUTHOST_COLUMN );
1055                            bufferedData = bufferedData.substring( 0, start) +
1056                                url.toExternalForm() +
1057                                bufferedData.substring( end );
1058
1059                            targetHost = HTTPProxyHost ;
1060                            targetPort = HTTPProxyPort ;
1061                        }
1062
1063                    }
1064                }
1065                else {
1066                    //
1067
// Change Host: header to point to correct host
1068
//
1069
byte[] b1 = new byte[1];
1070
1071                    buf = new StringBuffer JavaDoc();
1072                    String JavaDoc s1;
1073                    String JavaDoc lastLine = null ;
1074
1075                    for ( ; ; ) {
1076                        int len ;
1077
1078                        len = tmpIn1.read(b1, 0, 1);
1079                        if ( len == -1 ) {
1080                            break ;
1081                        }
1082                        s1 = new String JavaDoc( b1 );
1083                        buf.append( s1 );
1084                        if ( b1[0] != '\n' ) {
1085                            continue ;
1086                        }
1087                        // we have a complete line
1088
String JavaDoc line = buf.toString();
1089
1090                        buf.setLength(0);
1091                        // check to see if we have found Host: header
1092
if (line.startsWith("Host: ")) {
1093                            // we need to update the hostname to target host
1094
String JavaDoc newHost = "Host: " + targetHost + ":" + listenPort + "\r\n";
1095
1096                            bufferedData = bufferedData.concat(newHost);
1097                            break ;
1098                        }
1099                        // add it to our headers so far
1100
if (bufferedData == null) {
1101                            bufferedData = line;
1102                        } else {
1103                            bufferedData = bufferedData.concat(line);
1104                        }
1105
1106                        // failsafe
1107
if (line.equals("\r\n")) {
1108                            break;
1109                        }
1110                        if ("\n".equals(lastLine) && line.equals("\n")) {
1111                            break ;
1112                        }
1113                        lastLine = line ;
1114                    }
1115                    if ( bufferedData != null ) {
1116                        inputText.append( bufferedData );
1117                        int idx = bufferedData.length() < 50 ? bufferedData.length() : 50;
1118                        s1 = bufferedData.substring( 0, idx );
1119                        int i = s1.indexOf('\n');
1120
1121                        if ( i > 0 ) {
1122                            s1 = s1.substring(0, i - 1);
1123                        }
1124                        s1 = s1 + " " +
1125                                  " ";
1126                        s1 = s1.substring(0, 51);
1127                        listener.tableModel.setValueAt( s1, index + 1,
1128                            REQ_COLUMN );
1129                    }
1130                }
1131
1132                if ( targetPort == -1 ) {
1133                    targetPort = 80 ;
1134                }
1135                outSocket = new Socket JavaDoc(targetHost, targetPort );
1136
1137                tmpIn2 = outSocket.getInputStream();
1138                tmpOut2 = outSocket.getOutputStream();
1139
1140                if ( bufferedData != null ) {
1141                    byte[] b = bufferedData.getBytes();
1142                    tmpOut2.write( b );
1143                    slowLink.pump(b.length);
1144                }
1145
1146                boolean format = listener.xmlFormatBox.isSelected();
1147                boolean numeric = listener.numericBox.isSelected();
1148
1149
1150                //this is the channel to the endpoint
1151
rr1 = new SocketRR(this, inSocket, tmpIn1, outSocket,
1152                    tmpOut2, inputText, format, numeric,
1153                    listener.tableModel, index + 1, "request:", slowLink);
1154                //create the response slow link from the inbound slow link
1155
SlowLinkSimulator responseLink = new SlowLinkSimulator(slowLink);
1156                //this is the channel from the endpoint
1157
rr2 = new SocketRR( this, outSocket, tmpIn2, inSocket,
1158                    tmpOut1, outputText, format, numeric,
1159                    null, 0, "response:", responseLink);
1160
1161                while ( rr1 != null || rr2 != null ) {
1162                    // Only loop as long as the connection to the target
1163
// machine is available - once that's gone we can stop.
1164
// The old way, loop until both are closed, left us
1165
// looping forever since no one closed the 1st one.
1166
// while( !rr2.isDone() )
1167
if (null != rr1 && rr1.isDone()) {
1168                        if ( index >= 0 && rr2 != null) {
1169                            listener.tableModel.setValueAt(getMessage("resp00", "Resp"),
1170                                1 + index, STATE_COLUMN );
1171                        }
1172                       rr1 = null;
1173                    }
1174                    if (null != rr2 && rr2.isDone()) {
1175                        if ( index >= 0 && rr1 != null ) {
1176                            listener.tableModel.setValueAt(getMessage("req00", "Req"),
1177                                1 + index, STATE_COLUMN );
1178                        }
1179                        rr2 = null;
1180                    }
1181
1182                    // Thread.sleep( 10 );
1183
synchronized ( this) {
1184                        this.wait(1000); //Safety just incase we're not told to wake up.
1185
}
1186                }
1187
1188                // System.out.println("Done ");
1189
// rr1.halt();
1190
// rr2.halt();
1191

1192
1193                active = false ;
1194
1195                /*
1196                 if ( inSocket != null ) {
1197                 inSocket.close();
1198                 inSocket = null ;
1199                 }
1200                 outSocket.close();
1201                 outSocket = null ;
1202                 */

1203
1204                if ( index >= 0 ) {
1205                    listener.tableModel.setValueAt(getMessage("done00", "Done"),
1206                        1 + index, STATE_COLUMN );
1207
1208                }
1209            }
1210            catch ( Exception JavaDoc e ) {
1211                StringWriter JavaDoc st = new StringWriter JavaDoc();
1212                PrintWriter JavaDoc wr = new PrintWriter JavaDoc(st);
1213                int index = listener.connections.indexOf( this );
1214
1215                if ( index >= 0 ) {
1216                    listener.tableModel.setValueAt( getMessage("error00", "Error"), 1 + index, STATE_COLUMN );
1217                }
1218                e.printStackTrace(wr);
1219                wr.close();
1220                if(outputText!=null) {
1221                    outputText.append( st.toString() );
1222                } else {
1223                    //something went wrong before we had the output area
1224
System.out.println(st.toString());
1225                }
1226                halt();
1227            }
1228        }
1229
1230        synchronized void wakeUp() {
1231            this.notifyAll();
1232        }
1233
1234        public void halt() {
1235            try {
1236                if ( rr1 != null ) {
1237                    rr1.halt();
1238                }
1239                if ( rr2 != null ) {
1240                    rr2.halt();
1241                }
1242                if ( inSocket != null ) {
1243                    inSocket.close();
1244                }
1245                inSocket = null ;
1246                if ( outSocket != null ) {
1247                    outSocket.close();
1248                }
1249                outSocket = null ;
1250            }
1251            catch ( Exception JavaDoc e ) {
1252                e.printStackTrace();
1253            }
1254        }
1255
1256        public void remove() {
1257            int index = -1;
1258
1259            try {
1260                halt();
1261                index = listener.connections.indexOf( this );
1262                listener.tableModel.removeRow( index + 1 );
1263                listener.connections.remove( index );
1264            }
1265            catch ( Exception JavaDoc e ) {
1266                System.err.println("index:=" + index + this );
1267                e.printStackTrace();
1268            }
1269        }
1270    }
1271
1272
1273    /**
1274     * this is one of the tabbed panels that acts as the actual proxy
1275     */

1276    class Listener extends JPanel JavaDoc {
1277        public Socket JavaDoc inputSocket = null ;
1278        public Socket JavaDoc outputSocket = null ;
1279        public JTextField JavaDoc portField = null ;
1280        public JTextField JavaDoc hostField = null ;
1281        public JTextField JavaDoc tPortField = null ;
1282        public JCheckBox JavaDoc isProxyBox = null ;
1283        public JButton JavaDoc stopButton = null ;
1284        public JButton JavaDoc removeButton = null ;
1285        public JButton JavaDoc removeAllButton = null ;
1286        public JCheckBox JavaDoc xmlFormatBox = null ;
1287        public JCheckBox JavaDoc numericBox = null ;
1288        public JButton JavaDoc saveButton = null ;
1289        public JButton JavaDoc resendButton = null ;
1290        public JButton JavaDoc switchButton = null ;
1291        public JButton JavaDoc closeButton = null ;
1292        public JTable JavaDoc connectionTable = null ;
1293        public DefaultTableModel JavaDoc tableModel = null ;
1294        public JSplitPane JavaDoc outPane = null ;
1295        public ServerSocket JavaDoc sSocket = null ;
1296        public SocketWaiter sw = null ;
1297        public JPanel JavaDoc leftPanel = null ;
1298        public JPanel JavaDoc rightPanel = null ;
1299        public JTabbedPane JavaDoc notebook = null ;
1300        public String JavaDoc HTTPProxyHost = null ;
1301        public int HTTPProxyPort = 80 ;
1302        public int delayBytes = 0;
1303        public int delayTime = 0;
1304        public SlowLinkSimulator slowLink;
1305
1306        public final Vector JavaDoc connections = new Vector JavaDoc();
1307
1308        /**
1309         * create a listener
1310         * @param _notebook
1311         * @param name
1312         * @param listenPort
1313         * @param host
1314         * @param targetPort
1315         * @param isProxy
1316         * @param slowLink optional reference to a slow connection
1317         */

1318        public Listener(JTabbedPane JavaDoc _notebook, String JavaDoc name,
1319            int listenPort, String JavaDoc host, int targetPort,
1320            boolean isProxy, SlowLinkSimulator slowLink) {
1321            notebook = _notebook ;
1322            if ( name == null ) {
1323                name = getMessage("port01", "Port") + " " + listenPort ;
1324            }
1325            //set the slow link to the passed down link
1326
if(slowLink!=null) {
1327                this.slowLink=slowLink;
1328            } else {
1329                //or make up a no-op one.
1330
this.slowLink=new SlowLinkSimulator(0,0);
1331            }
1332            this.setLayout( new BorderLayout JavaDoc() );
1333
1334            // 1st component is just a row of labels and 1-line entry fields
1335
/////////////////////////////////////////////////////////////////////
1336
JPanel JavaDoc top = new JPanel JavaDoc();
1337
1338            top.setLayout( new BoxLayout JavaDoc(top, BoxLayout.X_AXIS) );
1339            top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
1340            final String JavaDoc start = getMessage("start00", "Start");
1341
1342            top.add( stopButton = new JButton JavaDoc( start ) );
1343            top.add( Box.createRigidArea(new Dimension JavaDoc(5, 0)) );
1344            top.add( new JLabel JavaDoc( " " + getMessage("listenPort01", "Listen Port:") + " ", SwingConstants.RIGHT ) );
1345            top.add( portField = new JTextField JavaDoc( "" + listenPort, 4 ) );
1346            top.add( new JLabel JavaDoc( " " + getMessage("host00", "Host:"), SwingConstants.RIGHT ) );
1347            top.add( hostField = new JTextField JavaDoc( host, 30 ) );
1348            top.add( new JLabel JavaDoc( " " + getMessage("port02", "Port:") + " ", SwingConstants.RIGHT ) );
1349            top.add( tPortField = new JTextField JavaDoc( "" + targetPort, 4 ) );
1350            top.add( Box.createRigidArea(new Dimension JavaDoc(5, 0)) );
1351            top.add( isProxyBox = new JCheckBox JavaDoc(getMessage("proxy00", "Proxy")) );
1352
1353            isProxyBox.addChangeListener( new BasicButtonListener JavaDoc(isProxyBox) {
1354                    public void stateChanged(ChangeEvent JavaDoc event) {
1355                        JCheckBox JavaDoc box = (JCheckBox JavaDoc) event.getSource();
1356                        boolean state = box.isSelected();
1357
1358                        tPortField.setEnabled( !state );
1359                        hostField.setEnabled( !state );
1360                    }
1361                }
1362            );
1363
1364            isProxyBox.setSelected(isProxy);
1365
1366            portField.setEditable(false);
1367            portField.setMaximumSize(new Dimension JavaDoc(50, Short.MAX_VALUE) );
1368            hostField.setEditable(false);
1369            hostField.setMaximumSize(new Dimension JavaDoc(85, Short.MAX_VALUE) );
1370            tPortField.setEditable(false);
1371            tPortField.setMaximumSize(new Dimension JavaDoc(50, Short.MAX_VALUE) );
1372
1373            stopButton.addActionListener( new ActionListener JavaDoc() {
1374                    public void actionPerformed(ActionEvent JavaDoc event) {
1375                        if ( getMessage("stop00", "Stop").equals(event.getActionCommand()) ) {
1376                            stop();
1377                        }
1378                        if ( start.equals(event.getActionCommand()) ) {
1379                            start();
1380                        }
1381                    }
1382                }
1383            );
1384
1385            this.add( top, BorderLayout.NORTH );
1386
1387            // 2nd component is a split pane with a table on the top
1388
// and the request/response text areas on the bottom
1389
/////////////////////////////////////////////////////////////////////
1390

1391            tableModel = new DefaultTableModel JavaDoc(new String JavaDoc[] {
1392                    getMessage("state00", "State"),
1393                    getMessage("time00", "Time"),
1394                    getMessage("requestHost00", "Request Host"),
1395                    getMessage("targetHost", "Target Host"),
1396                    getMessage("request00", "Request...")
1397                } , 0 );
1398
1399            tableModel.addRow( new Object JavaDoc[] {
1400                    "---", getMessage("mostRecent00", "Most Recent"), "---", "---", "---"
1401                }
1402            );
1403
1404            connectionTable = new JTable JavaDoc(1, 2);
1405            connectionTable.setModel( tableModel );
1406            connectionTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1407            // Reduce the STATE column and increase the REQ column
1408
TableColumn JavaDoc col ;
1409
1410            col = connectionTable.getColumnModel().getColumn(STATE_COLUMN);
1411            col.setMaxWidth( col.getPreferredWidth() / 2 );
1412            col = connectionTable.getColumnModel().getColumn(REQ_COLUMN);
1413            col.setPreferredWidth( col.getPreferredWidth() * 2 );
1414
1415
1416            ListSelectionModel JavaDoc sel = connectionTable.getSelectionModel();
1417
1418            sel.addListSelectionListener( new ListSelectionListener JavaDoc() {
1419                    public void valueChanged(ListSelectionEvent JavaDoc event) {
1420                        if (event.getValueIsAdjusting()) {
1421                            return ;
1422                        }
1423                        ListSelectionModel JavaDoc m = (ListSelectionModel JavaDoc) event.getSource();
1424                        int divLoc = outPane.getDividerLocation();
1425
1426                        if (m.isSelectionEmpty()) {
1427                            setLeft( new JLabel JavaDoc(" " + getMessage("wait00", "Waiting for Connection...") ) );
1428                            setRight( new JLabel JavaDoc("") );
1429                            removeButton.setEnabled(false);
1430                            removeAllButton.setEnabled(false);
1431                            saveButton.setEnabled(false);
1432                            resendButton.setEnabled(false);
1433                        }
1434                        else {
1435                            int row = m.getLeadSelectionIndex();
1436
1437                            if ( row == 0 ) {
1438                                if ( connections.size() == 0 ) {
1439                                    setLeft(new JLabel JavaDoc(" " + getMessage("wait00", "Waiting for connection...")));
1440                                    setRight(new JLabel JavaDoc(""));
1441                                    removeButton.setEnabled(false);
1442                                    removeAllButton.setEnabled(false);
1443                                    saveButton.setEnabled(false);
1444                                    resendButton.setEnabled(false);
1445                                }
1446                                else {
1447                                    Connection conn = (Connection) connections.lastElement();
1448
1449                                    setLeft( conn.inputScroll );
1450                                    setRight( conn.outputScroll );
1451                                    removeButton.setEnabled(false);
1452                                    removeAllButton.setEnabled(true);
1453                                    saveButton.setEnabled(true);
1454                                    resendButton.setEnabled(true);
1455                                }
1456                            }
1457                            else {
1458                                Connection conn = (Connection) connections.get(row - 1);
1459
1460                                setLeft( conn.inputScroll );
1461                                setRight( conn.outputScroll );
1462                                removeButton.setEnabled(true);
1463                                removeAllButton.setEnabled(true);
1464                                saveButton.setEnabled(true);
1465                                resendButton.setEnabled(true);
1466                            }
1467                        }
1468                        outPane.setDividerLocation(divLoc);
1469                    }
1470                }
1471            );
1472
1473            JPanel JavaDoc tablePane = new JPanel JavaDoc();
1474
1475            tablePane.setLayout( new BorderLayout JavaDoc() );
1476
1477            JScrollPane JavaDoc tableScrollPane = new JScrollPane JavaDoc( connectionTable );
1478
1479            tablePane.add( tableScrollPane, BorderLayout.CENTER );
1480            JPanel JavaDoc buttons = new JPanel JavaDoc();
1481
1482            buttons.setLayout( new BoxLayout JavaDoc(buttons, BoxLayout.X_AXIS) );
1483            buttons.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) );
1484            final String JavaDoc removeSelected = getMessage("removeSelected00", "Remove Selected");
1485
1486            buttons.add( removeButton = new JButton JavaDoc(removeSelected) );
1487            buttons.add( Box.createRigidArea(new Dimension JavaDoc(5, 0)) );
1488            final String JavaDoc removeAll = getMessage("removeAll00", "Remove All");
1489
1490            buttons.add( removeAllButton = new JButton JavaDoc(removeAll) );
1491            tablePane.add( buttons, BorderLayout.SOUTH );
1492
1493            removeButton.setEnabled( false );
1494            removeButton.addActionListener( new ActionListener JavaDoc() {
1495                    public void actionPerformed(ActionEvent JavaDoc event) {
1496                        if ( removeSelected.equals(event.getActionCommand()) ) {
1497                            remove();
1498                        }
1499                    }
1500                }
1501            );
1502
1503            removeAllButton.setEnabled( false );
1504            removeAllButton.addActionListener( new ActionListener JavaDoc() {
1505                    public void actionPerformed(ActionEvent JavaDoc event) {
1506                        if ( removeAll.equals(event.getActionCommand()) ) {
1507                            removeAll();
1508                        }
1509                    }
1510                }
1511            );
1512
1513            // Add Response Section
1514
/////////////////////////////////////////////////////////////////////
1515
JPanel JavaDoc pane2 = new JPanel JavaDoc();
1516
1517            pane2.setLayout( new BorderLayout JavaDoc() );
1518
1519            leftPanel = new JPanel JavaDoc();
1520            leftPanel.setAlignmentX( Component.LEFT_ALIGNMENT );
1521            leftPanel.setLayout( new BoxLayout JavaDoc(leftPanel, BoxLayout.Y_AXIS) );
1522            leftPanel.add( new JLabel JavaDoc(" " + getMessage("request01", "Request")) );
1523            leftPanel.add( new JLabel JavaDoc(" " + getMessage("wait01", "Waiting for connection") ));
1524
1525            rightPanel = new JPanel JavaDoc();
1526            rightPanel.setLayout( new BoxLayout JavaDoc(rightPanel, BoxLayout.Y_AXIS) );
1527            rightPanel.add( new JLabel JavaDoc(" " + getMessage("response00", "Response")) );
1528            rightPanel.add( new JLabel JavaDoc("") );
1529
1530            outPane = new JSplitPane JavaDoc(0, leftPanel, rightPanel );
1531            outPane.setDividerSize(4);
1532            pane2.add( outPane, BorderLayout.CENTER );
1533
1534            JPanel JavaDoc bottomButtons = new JPanel JavaDoc();
1535
1536            bottomButtons.setLayout( new BoxLayout JavaDoc(bottomButtons, BoxLayout.X_AXIS));
1537            bottomButtons.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
1538            bottomButtons.add( xmlFormatBox = new JCheckBox JavaDoc( getMessage("xmlFormat00", "XML Format") ) );
1539            bottomButtons.add( numericBox = new JCheckBox JavaDoc( getMessage("numericEnc00", "Numeric" ) ) );
1540            bottomButtons.add( Box.createRigidArea(new Dimension JavaDoc(5, 0)) );
1541            final String JavaDoc save = getMessage("save00", "Save");
1542
1543            bottomButtons.add( saveButton = new JButton JavaDoc( save ) );
1544            bottomButtons.add( Box.createRigidArea(new Dimension JavaDoc(5, 0)) );
1545            final String JavaDoc resend = getMessage("resend00", "Resend");
1546
1547            bottomButtons.add( resendButton = new JButton JavaDoc( resend ) );
1548            bottomButtons.add( Box.createRigidArea(new Dimension JavaDoc(5, 0)) );
1549            final String JavaDoc switchStr = getMessage("switch00", "Switch Layout");
1550
1551            bottomButtons.add( switchButton = new JButton JavaDoc( switchStr ) );
1552            bottomButtons.add( Box.createHorizontalGlue() );
1553            final String JavaDoc close = getMessage("close00", "Close");
1554
1555            bottomButtons.add( closeButton = new JButton JavaDoc( close ) );
1556            pane2.add( bottomButtons, BorderLayout.SOUTH );
1557
1558            saveButton.setEnabled( false );
1559            saveButton.addActionListener( new ActionListener JavaDoc() {
1560                    public void actionPerformed(ActionEvent JavaDoc event) {
1561                        if ( save.equals(event.getActionCommand()) ) {
1562                            save();
1563                        }
1564                    }
1565                }
1566            );
1567
1568            resendButton.setEnabled( false );
1569            resendButton.addActionListener( new ActionListener JavaDoc() {
1570                    public void actionPerformed(ActionEvent JavaDoc event) {
1571                        if ( resend.equals(event.getActionCommand()) ) {
1572                            resend();
1573                        }
1574                    }
1575                }
1576            );
1577
1578            switchButton.addActionListener( new ActionListener JavaDoc() {
1579                    public void actionPerformed(ActionEvent JavaDoc event) {
1580                        if (switchStr.equals(event.getActionCommand()) ) {
1581                            int v = outPane.getOrientation();
1582
1583                            if ( v == 0 ) {
1584                                // top/bottom
1585
outPane.setOrientation(1);
1586                            }
1587                            else {
1588                                // left/right
1589
outPane.setOrientation(0);
1590                            }
1591                            outPane.setDividerLocation(0.5);
1592                        }
1593                    }
1594                }
1595            );
1596
1597            closeButton.addActionListener( new ActionListener JavaDoc() {
1598                    public void actionPerformed(ActionEvent JavaDoc event) {
1599                        if (close.equals(event.getActionCommand()) ) {
1600                            close();
1601                        }
1602                    }
1603                }
1604            );
1605
1606            JSplitPane JavaDoc pane1 = new JSplitPane JavaDoc( 0 );
1607
1608            pane1.setDividerSize(4);
1609            pane1.setTopComponent( tablePane );
1610            pane1.setBottomComponent( pane2 );
1611            pane1.setDividerLocation( 150 );
1612            this.add( pane1, BorderLayout.CENTER );
1613
1614            //
1615
////////////////////////////////////////////////////////////////////
1616
sel.setSelectionInterval(0, 0);
1617            outPane.setDividerLocation( 150 );
1618            notebook.addTab( name, this );
1619            start();
1620        }
1621
1622        public void setLeft(Component JavaDoc left) {
1623            leftPanel.removeAll();
1624            leftPanel.add(left);
1625        }
1626
1627        public void setRight(Component JavaDoc right) {
1628            rightPanel.removeAll();
1629            rightPanel.add(right);
1630        }
1631
1632        public void start() {
1633            int port = Integer.parseInt( portField.getText() );
1634
1635            portField.setText( "" + port );
1636            int i = notebook.indexOfComponent( this );
1637
1638            notebook.setTitleAt( i, getMessage("port01", "Port") + " " + port );
1639
1640            int tmp = Integer.parseInt( tPortField.getText() );
1641
1642            tPortField.setText( "" + tmp );
1643
1644            sw = new SocketWaiter( this, port );
1645            stopButton.setText( getMessage("stop00", "Stop") );
1646
1647            portField.setEditable(false);
1648            hostField.setEditable(false);
1649            tPortField.setEditable(false);
1650            isProxyBox.setEnabled(false);
1651        }
1652
1653        public void close() {
1654            stop();
1655            notebook.remove( this );
1656        }
1657
1658        public void stop() {
1659            try {
1660                for ( int i = 0 ; i < connections.size() ; i++ ) {
1661                    Connection conn = (Connection) connections.get( i );
1662
1663                    conn.halt();
1664                }
1665                sw.halt();
1666                stopButton.setText( getMessage("start00", "Start") );
1667                portField.setEditable(true);
1668                hostField.setEditable(true);
1669                tPortField.setEditable(true);
1670                isProxyBox.setEnabled(true);
1671            }
1672            catch ( Exception JavaDoc e ) {
1673                e.printStackTrace();
1674            }
1675        }
1676
1677        public void remove() {
1678            ListSelectionModel JavaDoc lsm = connectionTable.getSelectionModel();
1679            int bot = lsm.getMinSelectionIndex();
1680            int top = lsm.getMaxSelectionIndex();
1681
1682            for ( int i = top ; i >= bot ; i-- ) {
1683                ((Connection) connections.get(i - 1)).remove();
1684            }
1685            if ( bot > connections.size() ) {
1686                bot = connections.size();
1687            }
1688            lsm.setSelectionInterval(bot, bot);
1689        }
1690
1691        public void removeAll() {
1692            ListSelectionModel JavaDoc lsm = connectionTable.getSelectionModel();
1693            lsm.clearSelection();
1694            while ( connections.size() > 0 ) {
1695                ((Connection) connections.get(0)).remove();
1696            }
1697
1698            lsm.setSelectionInterval(0, 0);
1699        }
1700
1701        public void save() {
1702            JFileChooser JavaDoc dialog = new JFileChooser JavaDoc( "." );
1703            int rc = dialog.showSaveDialog( this );
1704
1705            if ( rc == JFileChooser.APPROVE_OPTION ) {
1706                try {
1707                    File JavaDoc file = dialog.getSelectedFile();
1708                    FileOutputStream JavaDoc out = new FileOutputStream JavaDoc( file );
1709
1710                    ListSelectionModel JavaDoc lsm = connectionTable.getSelectionModel();
1711
1712                    rc = lsm.getLeadSelectionIndex();
1713
1714                    int n = 0;
1715                    for (Iterator JavaDoc i = connections.iterator();i.hasNext();n++) {
1716                      Connection conn = (Connection)i.next();
1717                      if (lsm.isSelectedIndex(n + 1) ||
1718                                   (!(i.hasNext()) && lsm.getLeadSelectionIndex() == 0)) {
1719                        rc = Integer.parseInt( portField.getText() );
1720                        out.write("\n==============\n".getBytes());
1721                        out.write( ((getMessage("listenPort01", "Listen Port:") + " " + rc + "\n" )).getBytes() );
1722                        out.write( (getMessage("targetHost01", "Target Host:") + " " + hostField.getText() +
1723                                    "\n" ).getBytes() );
1724                        rc = Integer.parseInt( tPortField.getText() );
1725                        out.write( ((getMessage("targetPort01", "Target Port:") + " " + rc + "\n" )).getBytes() );
1726
1727                        out.write( (("==== " + getMessage("request01", "Request") + " ====\n" )).getBytes() );
1728                        out.write( conn.inputText.getText().getBytes() );
1729
1730                        out.write( (("==== " + getMessage("response00", "Response") + " ====\n" )).getBytes() );
1731                        out.write( conn.outputText.getText().getBytes() );
1732                        out.write("\n==============\n".getBytes());
1733                      }
1734                    }
1735
1736                    out.close();
1737                }
1738                catch ( Exception JavaDoc e ) {
1739                    e.printStackTrace();
1740                }
1741            }
1742        }
1743
1744        public void resend() {
1745            int rc ;
1746
1747            try {
1748                ListSelectionModel JavaDoc lsm = connectionTable.getSelectionModel();
1749
1750                rc = lsm.getLeadSelectionIndex();
1751                if ( rc == 0 ) {
1752                    rc = connections.size();
1753                }
1754                Connection conn = (Connection) connections.get( rc - 1 );
1755
1756                if ( rc > 0 ) {
1757                    lsm.clearSelection();
1758                    lsm.setSelectionInterval(0, 0);
1759                }
1760
1761                InputStream JavaDoc in = null ;
1762                String JavaDoc text = conn.inputText.getText();
1763
1764                // Fix Content-Length HTTP headers
1765
if ( text.startsWith("POST ") || text.startsWith("GET ") ) {
1766                    // System.err.println("IN CL" );
1767
int pos1, pos2, pos3 ;
1768                    String JavaDoc body, headers, headers1, header2 ;
1769
1770                    pos3 = text.indexOf( "\n\n" );
1771                    if ( pos3 == -1 ) {
1772                        pos3 = text.indexOf( "\r\n\r\n" );
1773                        if ( pos3 != -1 ) {
1774                            pos3 = pos3 + 4 ;
1775                        }
1776                    }
1777                    else {
1778                        pos3 += 2 ;
1779                    }
1780
1781                    headers = text.substring( 0, pos3 );
1782
1783                    pos1 = headers.indexOf( "Content-Length:" );
1784                    // System.err.println("pos1: " + pos1 );
1785
// System.err.println("pos3: " + pos3 );
1786
if ( pos1 != -1 ) {
1787                        int newLen = text.length() - pos3 ;
1788
1789                        pos2 = headers.indexOf( "\n", pos1 );
1790
1791                        System.err.println("CL: " + newLen );
1792                        System.err.println("Hdrs: '" + headers + "'" );
1793                        System.err.println("subTEXT: '" +
1794                            text.substring(pos3, pos3 + newLen) + "'");
1795                        text = headers.substring(0, pos1) +
1796                        "Content-Length: " + newLen + "\n" +
1797                        headers.substring(pos2 + 1) +
1798                        text.substring(pos3) ;
1799                        System.err.println("\nTEXT: '" + text + "'" );
1800                    }
1801                }
1802
1803                in = new ByteArrayInputStream JavaDoc( text.getBytes() );
1804                new Connection( this, in );
1805            }
1806            catch ( Exception JavaDoc e ) {
1807                e.printStackTrace();
1808            }
1809        }
1810    }
1811
1812
1813    public tcpmon(int listenPort, String JavaDoc targetHost, int targetPort, boolean embedded) {
1814        super ( getMessage("tcpmon00", "TCPMonitor") );
1815
1816        notebook = new JTabbedPane JavaDoc();
1817        this.getContentPane().add( notebook );
1818
1819        new AdminPage( notebook, getMessage("admin00", "Admin") );
1820
1821        if ( listenPort != 0 ) {
1822            Listener JavaDoc l = null ;
1823
1824            if ( targetHost == null ) {
1825                l = new Listener JavaDoc( notebook, null, listenPort,
1826                    targetHost, targetPort, true, null);
1827            } else {
1828                l = new Listener JavaDoc( notebook, null, listenPort,
1829                    targetHost, targetPort, false, null);
1830            }
1831            notebook.setSelectedIndex( 1 );
1832
1833            l.HTTPProxyHost = System.getProperty( "http.proxyHost" );
1834            if ( l.HTTPProxyHost != null && l.HTTPProxyHost.equals("") ) {
1835                l.HTTPProxyHost = null ;
1836            }
1837
1838            if ( l.HTTPProxyHost != null ) {
1839                String JavaDoc tmp = System.getProperty( "http.proxyPort" );
1840
1841                if ( tmp != null && tmp.equals("") ) {
1842                    tmp = null ;
1843                }
1844                if ( tmp == null ) {
1845                    l.HTTPProxyPort = 80 ;
1846                } else {
1847                    l.HTTPProxyPort = Integer.parseInt( tmp );
1848                }
1849            }
1850        }
1851        
1852        if(!embedded) {
1853            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
1854        }
1855        this.pack();
1856        this.setSize( 600, 600 );
1857        this.setVisible( true );
1858    }
1859    
1860    public tcpmon(int listenPort, String JavaDoc targetHost, int targetPort) {
1861        this(listenPort, targetHost, targetPort, false);
1862    }
1863
1864    /**
1865     * set up the L&F
1866     */

1867    private static void setupLookAndFeel(boolean nativeLookAndFeel) throws Exception JavaDoc {
1868        String JavaDoc classname= UIManager.getCrossPlatformLookAndFeelClassName();
1869        if(nativeLookAndFeel) {
1870            classname= UIManager.getSystemLookAndFeelClassName();
1871        }
1872        String JavaDoc lafProperty= System.getProperty("tcpmon.laf", "");
1873        if(lafProperty.length()>0) {
1874            classname=lafProperty;
1875        }
1876        try {
1877            UIManager.setLookAndFeel(classname);
1878        } catch (ClassNotFoundException JavaDoc e) {
1879            e.printStackTrace();
1880        } catch (InstantiationException JavaDoc e) {
1881            e.printStackTrace();
1882        } catch (IllegalAccessException JavaDoc e) {
1883            e.printStackTrace();
1884        } catch (UnsupportedLookAndFeelException JavaDoc e) {
1885            e.printStackTrace();
1886        }
1887    }
1888    /**
1889     * this is our main method
1890     * @param args
1891     */

1892    public static void main(String JavaDoc[] args) {
1893        try {
1894            //switch between swing L&F here
1895
setupLookAndFeel(true);
1896            if ( args.length == 3 ) {
1897                int p1 = Integer.parseInt( args[0] );
1898                int p2 = Integer.parseInt( args[2] );
1899
1900                new tcpmon( p1, args[1], p2 );
1901            }
1902            else if ( args.length == 1 ) {
1903                int p1 = Integer.parseInt( args[0] );
1904
1905                new tcpmon( p1, null, 0 );
1906            }
1907            else if ( args.length != 0 ) {
1908                System.err.println( getMessage("usage00", "Usage:")
1909                        + " tcpmon [listenPort targetHost targetPort]\n");
1910            }
1911            else {
1912                new tcpmon(0, null, 0);
1913            }
1914        }
1915        catch ( Throwable JavaDoc exp ) {
1916            exp.printStackTrace();
1917        }
1918    }
1919
1920    // Message resource bundle.
1921
private static ResourceBundle JavaDoc messages = null;
1922
1923    /**
1924     * Get the message with the given key. There are no arguments for this message.
1925     */

1926    public static String JavaDoc getMessage(String JavaDoc key, String JavaDoc defaultMsg) {
1927        try {
1928            if (messages == null) {
1929                initializeMessages();
1930            }
1931            return messages.getString(key);
1932        } catch (Throwable JavaDoc t) {
1933            // If there is any problem whatsoever getting the internationalized
1934
// message, return the default.
1935
return defaultMsg;
1936        }
1937    } // getMessage
1938

1939    /**
1940     * Load the resource bundle messages from the properties file. This is ONLY done when it is
1941     * needed. If no messages are printed (for example, only Wsdl2java is being run in non-
1942     * verbose mode) then there is no need to read the properties file.
1943     */

1944    private static void initializeMessages() {
1945        messages = ResourceBundle.getBundle("org.apache.axis.utils.tcpmon");
1946    } // initializeMessages
1947

1948    /**
1949     * a text field with a restricted set of characters
1950     */

1951    static class RestrictedTextField extends JTextField JavaDoc {
1952        protected String JavaDoc validText;
1953
1954        public RestrictedTextField(String JavaDoc validText) {
1955            setValidText(validText);
1956        }
1957
1958        public RestrictedTextField(int columns, String JavaDoc validText) {
1959            super(columns);
1960            setValidText(validText);
1961        }
1962
1963        public RestrictedTextField(String JavaDoc text, String JavaDoc validText) {
1964            super(text);
1965            setValidText(validText);
1966        }
1967
1968        public RestrictedTextField(String JavaDoc text, int columns, String JavaDoc validText) {
1969            super(text, columns);
1970            setValidText(validText);
1971        }
1972
1973        private void setValidText(String JavaDoc validText) {
1974            this.validText = validText;
1975        }
1976
1977        /**
1978         * fascinatingly, this method is called in the super() constructor,
1979         * meaning before we are fully initialized. C++ doesnt actually permit
1980         * such a situation, but java clearly does...
1981         * @return a new document
1982         */

1983        public Document JavaDoc createDefaultModel() {
1984            return new RestrictedDocument();
1985        }
1986
1987        /**
1988         * this class strips out invaid chars
1989         */

1990        class RestrictedDocument extends PlainDocument JavaDoc {
1991
1992
1993            /**
1994             * Constructs a plain text document. A default model using
1995             * <code>GapContent</code> is constructed and set.
1996             */

1997            public RestrictedDocument() {
1998
1999            }
2000
2001            /**
2002             * add a string; only those chars in the valid text list are allowed
2003             * @param offset
2004             * @param string
2005             * @param attributes
2006             * @throws BadLocationException
2007             */

2008            public void insertString(int offset, String JavaDoc string, AttributeSet JavaDoc attributes)
2009                    throws BadLocationException JavaDoc {
2010
2011                if (string == null) {
2012                    return;
2013                }
2014                int len = string.length();
2015                StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(string.length());
2016                for (int i = 0; i < len; i++) {
2017                    char ch = string.charAt(i);
2018                    if (validText.indexOf(ch) >= 0) {
2019                        buffer.append(ch);
2020                    }
2021                }
2022                super.insertString(offset, new String JavaDoc(buffer), attributes);
2023            }
2024        } //end class NumericDocument
2025
}
2026
2027    /**
2028     * because we cant use Java1.4's JFormattedTextField, here is
2029     * a class that accepts numbers only
2030     */

2031    static class NumberField extends RestrictedTextField {
2032
2033        private static final String JavaDoc VALID_TEXT = "0123456789";
2034
2035        /**
2036         * Constructs a new <code>TextField</code>. A default model is created,
2037         * the initial string is <code>null</code>,
2038         * and the number of columns is set to 0.
2039         */

2040        public NumberField() {
2041            super(VALID_TEXT);
2042        }
2043
2044        /**
2045         * Constructs a new empty <code>TextField</code> with the specified
2046         * number of columns.
2047         * A default model is created and the initial string is set to
2048         * <code>null</code>.
2049         *
2050         * @param columns the number of columns to use to calculate
2051         * the preferred width; if columns is set to zero, the
2052         * preferred width will be whatever naturally results from
2053         * the component implementation
2054         */

2055        public NumberField(int columns) {
2056            super(columns, VALID_TEXT);
2057        }
2058
2059
2060        /**
2061         * get the int value of a field, any invalid (non int) field returns
2062         * the default
2063         * @param def default value
2064         * @return the field contents
2065         */

2066        public int getValue(int def) {
2067            int result = def;
2068            String JavaDoc text = getText();
2069            if (text != null && text.length() != 0) {
2070                try {
2071                    result = Integer.parseInt(text);
2072                } catch (NumberFormatException JavaDoc e) {
2073
2074                }
2075            }
2076            return result;
2077        }
2078
2079        /**
2080         * set the text to a numeric value
2081         * @param value number to assign
2082         */

2083        public void setValue(int value) {
2084            setText(Integer.toString(value));
2085        }
2086
2087    } //end class NumericTextField
2088

2089    /**
2090     * hostname fields
2091     */

2092    static class HostnameField extends RestrictedTextField {
2093        //list of valid chars in a hostname
2094
private static final String JavaDoc VALID_TEXT =
2095                "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ-.";
2096
2097        public HostnameField(int columns) {
2098            super(columns, VALID_TEXT);
2099        }
2100
2101        public HostnameField() {
2102            super(VALID_TEXT);
2103        }
2104    }
2105
2106}
2107
Popular Tags