1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.apache.harmony.logging.tests.java.util.logging;
19
20import java.io.ByteArrayOutputStream;
21import java.io.IOException;
22import java.io.InputStreamReader;
23import java.io.OutputStream;
24import java.io.PrintStream;
25import java.net.ServerSocket;
26import java.net.Socket;
27import java.security.Permission;
28import java.util.Properties;
29import java.util.logging.Filter;
30import java.util.logging.Formatter;
31import java.util.logging.Handler;
32import java.util.logging.Level;
33import java.util.logging.LogManager;
34import java.util.logging.LogRecord;
35import java.util.logging.LoggingPermission;
36import java.util.logging.SocketHandler;
37import java.util.logging.XMLFormatter;
38
39import junit.framework.TestCase;
40
41import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
42import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
43
44import tests.util.CallVerificationStack;
45
46/**
47 * Test class java.util.logging.ConsoleHandler
48 */
49public class SocketHandlerTest extends TestCase {
50
51    private static final LogManager LOG_MANAGER = LogManager.getLogManager();
52
53    private final static String INVALID_LEVEL = "impossible_level";
54
55    private final PrintStream err = System.err;
56
57    private OutputStream errSubstituteStream = null;
58
59    private static String className = SocketHandlerTest.class.getName();
60
61    private SocketHandler h = null;
62
63    private Properties props;
64
65    /*
66      * @see TestCase#setUp()
67      */
68    protected void setUp() throws Exception {
69        super.setUp();
70        errSubstituteStream = new NullOutputStream();
71        System.setErr(new PrintStream(errSubstituteStream));
72    }
73
74    /*
75      * @see TestCase#tearDown()
76      */
77    protected void tearDown() throws Exception {
78        initProps();
79        LOG_MANAGER.reset();
80        LOG_MANAGER.readConfiguration(EnvironmentHelper
81                .PropertiesToInputStream(props));
82        CallVerificationStack.getInstance().clear();
83        if (null != h) {
84            h.close();
85            h = null;
86        }
87        System.setErr(err);
88        super.tearDown();
89    }
90
91
92    private void initProps() throws Exception {
93        props = new Properties();
94        props.put("handlers", className + "$MockHandler " + className
95                + "$MockHandler");
96        props.put("java.util.logging.FileHandler.pattern", "%h/java%u.log");
97        props.put("java.util.logging.FileHandler.limit", "50000");
98        props.put("java.util.logging.FileHandler.count", "5");
99        props.put("java.util.logging.FileHandler.formatter",
100                "java.util.logging.XMLFormatter");
101        props.put(".level", "FINE");
102        props.put("java.util.logging.ConsoleHandler.level", "OFF");
103        props.put("java.util.logging.ConsoleHandler.formatter",
104                "java.util.logging.SimpleFormatter");
105        props.put("foo.handlers", "java.util.logging.ConsoleHandler");
106        props.put("foo.level", "WARNING");
107        props.put("com.xyz.foo.level", "SEVERE");
108    }
109
110    /*
111      * Test the constructor with no relevant log manager properties are set.
112      */
113    public void testConstructor_NoProperties() throws Exception {
114        assertNull(LOG_MANAGER.getProperty(
115                "java.util.logging.SocketHandler.level"));
116        assertNull(LOG_MANAGER.getProperty(
117                "java.util.logging.SocketHandler.filter"));
118        assertNull(LOG_MANAGER.getProperty(
119                "java.util.logging.SocketHandler.formatter"));
120        assertNull(LOG_MANAGER.getProperty(
121                "java.util.logging.SocketHandler.encoding"));
122        assertNull(LOG_MANAGER.getProperty(
123                "java.util.logging.SocketHandler.host"));
124        assertNull(LOG_MANAGER.getProperty(
125                "java.util.logging.SocketHandler.port"));
126
127        try {
128            h = new SocketHandler();
129            fail("Should throw IllegalArgumentException!");
130        } catch (IllegalArgumentException e) {
131        }
132
133        try {
134            h = new SocketHandler(null, 0);
135            fail("Should throw IllegalArgumentException!");
136        } catch (IllegalArgumentException e) {
137        }
138
139        try {
140            h = new SocketHandler("", 0);
141            fail("Should throw IllegalArgumentException!");
142        } catch (IllegalArgumentException e) {
143        }
144
145        try {
146            h = new SocketHandler("127.0.0.1", -1);
147            fail("Should throw IllegalArgumentException!");
148        } catch (IllegalArgumentException e) {
149        }
150
151        try {
152            h = new SocketHandler("127.0.0.1", Integer.MAX_VALUE);
153            fail("Should throw IllegalArgumentException!");
154        } catch (IllegalArgumentException e) {
155        }
156
157        try {
158            h = new SocketHandler("127.0.0.1", 66666);
159            fail("Should throw IllegalArgumentException!");
160        } catch (IllegalArgumentException e) {
161        }
162
163        try {
164            h = new SocketHandler("127.0.0.1", 0);
165            fail("Should throw IllegalArgumentException!");
166        } catch (IllegalArgumentException e) {
167        }
168
169        // start the server to be ready to accept log messages
170        ServerThread thread = new ServerThread();
171        thread.start();
172        Thread.sleep(2000);
173
174        h = new SocketHandler("127.0.0.1", 6666);
175        assertSame(h.getLevel(), Level.ALL);
176        assertTrue(h.getFormatter() instanceof XMLFormatter);
177        assertNull(h.getFilter());
178        assertNull(h.getEncoding());
179        h.close();
180        // ensure the thread exits and the port becomes available again
181        thread.getReadString();
182    }
183
184    /*
185      * Test the constructor with no relevant log manager properties are set
186      * except host and port.
187      */
188    public void testConstructor_NoBasicProperties() throws Exception {
189        assertNull(LOG_MANAGER.getProperty(
190                "java.util.logging.SocketHandler.level"));
191        assertNull(LOG_MANAGER.getProperty(
192                "java.util.logging.SocketHandler.filter"));
193        assertNull(LOG_MANAGER.getProperty(
194                "java.util.logging.SocketHandler.formatter"));
195        assertNull(LOG_MANAGER.getProperty(
196                "java.util.logging.SocketHandler.encoding"));
197        Properties p = new Properties();
198        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
199        p.put("java.util.logging.SocketHandler.port", "6666");
200        LOG_MANAGER.readConfiguration(
201                EnvironmentHelper.PropertiesToInputStream(p));
202
203        // start the server to be ready to accept log messages
204        ServerThread thread = new ServerThread();
205        thread.start();
206        Thread.sleep(2000);
207
208        h = new SocketHandler();
209        assertSame(h.getLevel(), Level.ALL);
210        assertTrue(h.getFormatter() instanceof XMLFormatter);
211        assertNull(h.getFilter());
212        assertNull(h.getEncoding());
213        h.close();
214        // ensure the thread exits and the port becomes available again
215        thread.getReadString();
216
217        try {
218            h = new SocketHandler("127.0.sdfcdsfsa%%&&^0.1", 6665);
219            fail("Should throw IOException!");
220        } catch (IOException e) {
221        }
222    }
223
224    /*
225      * Test the constructor with valid relevant log manager properties are set.
226      */
227    public void testConstructor_ValidProperties() throws Exception {
228        Properties p = new Properties();
229        p.put("java.util.logging.SocketHandler.level", "FINE");
230        p.put("java.util.logging.SocketHandler.filter", className
231                + "$MockFilter");
232        p.put("java.util.logging.SocketHandler.formatter", className
233                + "$MockFormatter");
234        p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
235        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
236        p.put("java.util.logging.SocketHandler.port", "6666");
237        LOG_MANAGER.readConfiguration(
238                EnvironmentHelper.PropertiesToInputStream(p));
239
240        // start the server to be ready to accept log messages
241        ServerThread thread = new ServerThread();
242        thread.start();
243        Thread.sleep(2000);
244
245        h = new SocketHandler();
246        assertSame(h.getLevel(), Level.parse("FINE"));
247        assertTrue(h.getFormatter() instanceof MockFormatter);
248        assertTrue(h.getFilter() instanceof MockFilter);
249        assertEquals(h.getEncoding(), "iso-8859-1");
250        h.close();
251        // ensure the thread exits and the port becomes available again
252        thread.getReadString();
253
254        // start the server to be ready to accept log messages
255        thread = new ServerThread();
256        thread.start();
257        Thread.sleep(2000);
258
259        h = new SocketHandler("127.0.0.1", 6666);
260        assertSame(h.getLevel(), Level.parse("FINE"));
261        assertTrue(h.getFormatter() instanceof MockFormatter);
262        assertTrue(h.getFilter() instanceof MockFilter);
263        assertEquals(h.getEncoding(), "iso-8859-1");
264        h.close();
265        // ensure the thread exits and the port becomes available again
266        thread.getReadString();
267    }
268
269    /*
270      * Test the constructor with invalid relevant log manager properties are set
271      * except host and port.
272      */
273    public void testConstructor_InvalidBasicProperties() throws Exception {
274        Properties p = new Properties();
275        p.put("java.util.logging.SocketHandler.level", INVALID_LEVEL);
276        p.put("java.util.logging.SocketHandler.filter", className + "");
277        p.put("java.util.logging.SocketHandler.formatter", className + "");
278        p.put("java.util.logging.SocketHandler.encoding", "XXXX");
279        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
280        p.put("java.util.logging.SocketHandler.port", "6666");
281        LOG_MANAGER.readConfiguration(
282                EnvironmentHelper.PropertiesToInputStream(p));
283
284        // start the server to be ready to accept log messages
285        ServerThread thread = new ServerThread();
286        thread.start();
287        Thread.sleep(2000);
288
289        h = new SocketHandler();
290        assertSame(h.getLevel(), Level.ALL);
291        assertTrue(h.getFormatter() instanceof XMLFormatter);
292        assertNull(h.getFilter());
293        assertNull(h.getEncoding());
294        h.publish(new LogRecord(Level.SEVERE, "test"));
295        assertNull(h.getEncoding());
296        h.close();
297        // ensure the thread exits and the port becomes available again
298        thread.getReadString();
299
300        // start the server to be ready to accept log messages
301        thread = new ServerThread();
302        thread.start();
303        Thread.sleep(2000);
304
305        h = new SocketHandler("127.0.0.1", 6666);
306        assertSame(h.getLevel(), Level.ALL);
307        assertTrue(h.getFormatter() instanceof XMLFormatter);
308        assertNull(h.getFilter());
309        assertNull(h.getEncoding());
310        h.publish(new LogRecord(Level.SEVERE, "test"));
311        assertNull(h.getEncoding());
312        h.close();
313        // ensure the thread exits and the port becomes available again
314        thread.getReadString();
315    }
316
317    /*
318      * Test the constructor with valid relevant log manager properties are set
319      * except port.
320      */
321    public void testConstructor_InvalidPort() throws Exception {
322        Properties p = new Properties();
323        p.put("java.util.logging.SocketHandler.level", "FINE");
324        p.put("java.util.logging.SocketHandler.filter", className
325                + "$MockFilter");
326        p.put("java.util.logging.SocketHandler.formatter", className
327                + "$MockFormatter");
328        p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
329        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
330        p.put("java.util.logging.SocketHandler.port", "6666i");
331        LOG_MANAGER.readConfiguration(
332                EnvironmentHelper.PropertiesToInputStream(p));
333
334        try {
335            h = new SocketHandler();
336            fail("Should throw IllegalArgumentException!");
337        } catch (IllegalArgumentException e) {
338
339        }
340    }
341
342    /*
343      * Test the constructor with valid relevant log manager properties are set,
344      * but the port is not open.
345      */
346    public void testConstructor_NotOpenPort() throws Exception {
347        Properties p = new Properties();
348        p.put("java.util.logging.SocketHandler.level", "FINE");
349        p.put("java.util.logging.SocketHandler.filter", className
350                + "$MockFilter");
351        p.put("java.util.logging.SocketHandler.formatter", className
352                + "$MockFormatter");
353        p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
354        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
355        p.put("java.util.logging.SocketHandler.port", "6665");
356        LOG_MANAGER.readConfiguration(
357                EnvironmentHelper.PropertiesToInputStream(p));
358
359        try {
360            h = new SocketHandler();
361            fail("Should throw IOException!");
362        } catch (IOException e) {
363
364        }
365
366        try {
367            h = new SocketHandler("127.0.0.1", 6665);
368            fail("Should throw IOException!");
369        } catch (IOException e) {
370
371        }
372    }
373
374    /*
375      * Test the constructor with valid relevant log manager properties are set
376      * except port.
377      */
378    public void testConstructor_InvalidHost() throws Exception {
379        Properties p = new Properties();
380        p.put("java.util.logging.SocketHandler.level", "FINE");
381        p.put("java.util.logging.SocketHandler.filter", className
382                + "$MockFilter");
383        p.put("java.util.logging.SocketHandler.formatter", className
384                + "$MockFormatter");
385        p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
386        p.put("java.util.logging.SocketHandler.host", " 34345 #$#%$%$");
387        p.put("java.util.logging.SocketHandler.port", "6666");
388        LOG_MANAGER.readConfiguration(
389                EnvironmentHelper.PropertiesToInputStream(p));
390
391        try {
392            h = new SocketHandler();
393            fail("Should throw IOException!");
394        } catch (IOException e) {
395
396        }
397
398        try {
399            h = new SocketHandler(" 34345 #$#%$%$", 6666);
400            fail("Should throw IOException!");
401        } catch (IOException e) {
402
403        }
404    }
405
406    /*
407      * Test close() when having sufficient privilege, and a record has been
408      * written to the output stream.
409      */
410    public void testClose_SufficientPrivilege_NormalClose() throws Exception {
411        Properties p = new Properties();
412        p.put("java.util.logging.SocketHandler.formatter", className
413                + "$MockFormatter");
414        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
415        p.put("java.util.logging.SocketHandler.port", "6666");
416        LOG_MANAGER.readConfiguration(
417                EnvironmentHelper.PropertiesToInputStream(p));
418
419        // start the server to be ready to accept log messages
420        ServerThread thread = new ServerThread();
421        thread.start();
422        Thread.sleep(2000);
423
424        h = new SocketHandler();
425        h.publish(new LogRecord(Level.SEVERE,
426                "testClose_SufficientPrivilege_NormalClose msg"));
427        h.close();
428        assertEquals("MockFormatter_Head"
429                + "testClose_SufficientPrivilege_NormalClose msg"
430                + "MockFormatter_Tail", thread.getReadString());
431        h.close();
432    }
433
434    /*
435      * Test close() when having sufficient privilege, and no record has been
436      * written to the output stream.
437      */
438    public void testClose_SufficientPrivilege_DirectClose() throws Exception {
439        Properties p = new Properties();
440        p.put("java.util.logging.SocketHandler.formatter", className
441                + "$MockFormatter");
442        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
443        p.put("java.util.logging.SocketHandler.port", "6666");
444        LOG_MANAGER.readConfiguration(
445                EnvironmentHelper.PropertiesToInputStream(p));
446
447        // start the server to be ready to accept log messages
448        ServerThread thread = new ServerThread();
449        thread.start();
450        Thread.sleep(2000);
451
452        h = new SocketHandler();
453        h.setLevel(Level.INFO);
454
455        h.close();
456        assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
457                .getReadString());
458    }
459
460    /*
461      * Test publish(), use no filter, having output stream, normal log record.
462      */
463    public void testPublish_NoFilter() throws Exception {
464        Properties p = new Properties();
465        p.put("java.util.logging.SocketHandler.formatter", className
466                + "$MockFormatter");
467        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
468        p.put("java.util.logging.SocketHandler.port", "6666");
469        LOG_MANAGER.readConfiguration(
470                EnvironmentHelper.PropertiesToInputStream(p));
471
472        // start the server to be ready to accept log messages
473        ServerThread thread = new ServerThread();
474        thread.start();
475        Thread.sleep(2000);
476
477        h = new SocketHandler();
478        h.setLevel(Level.INFO);
479
480        LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
481        h.setLevel(Level.INFO);
482        h.publish(r);
483
484        h.setLevel(Level.WARNING);
485        h.publish(r);
486
487        h.setLevel(Level.CONFIG);
488        h.publish(r);
489
490        r.setLevel(Level.OFF);
491        h.setLevel(Level.OFF);
492        h.publish(r);
493        h.close();
494        assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
495                + "testPublish_NoFilter" + "MockFormatter_Tail", thread
496                .getReadString());
497    }
498
499    /*
500      * Test publish(), use a filter, having output stream, normal log record.
501      */
502    public void testPublish_WithFilter() throws Exception {
503        Properties p = new Properties();
504        p.put("java.util.logging.SocketHandler.formatter", className
505                + "$MockFormatter");
506        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
507        p.put("java.util.logging.SocketHandler.port", "6666");
508        LOG_MANAGER.readConfiguration(
509                EnvironmentHelper.PropertiesToInputStream(p));
510
511        // start the server to be ready to accept log messages
512        ServerThread thread = new ServerThread();
513        thread.start();
514        Thread.sleep(2000);
515        h = new SocketHandler();
516        h.setLevel(Level.INFO);
517        h.setFilter(new MockFilter());
518
519        System.setErr(new PrintStream(new ByteArrayOutputStream()));
520
521        LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
522        h.setLevel(Level.INFO);
523        h.publish(r);
524        h.close();
525        assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
526                .getReadString());
527    }
528
529    /*
530      * Test publish(), null log record, having output stream
531      */
532    public void testPublish_Null() throws Exception {
533        Properties p = new Properties();
534        p.put("java.util.logging.SocketHandler.formatter", className
535                + "$MockFormatter");
536        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
537        p.put("java.util.logging.SocketHandler.port", "6666");
538        LOG_MANAGER.readConfiguration(
539                EnvironmentHelper.PropertiesToInputStream(p));
540
541        // start the server to be ready to accept log messages
542        ServerThread thread = new ServerThread();
543        thread.start();
544        Thread.sleep(2000);
545        h = new SocketHandler();
546        h.setLevel(Level.INFO);
547        try {
548            h.publish(null);
549        } finally {
550            h.close();
551            // ensure the thread exits and the port becomes available again
552            thread.getReadString();
553        }
554    }
555
556    /*
557      * Test publish(), a log record with empty msg, having output stream
558      */
559    public void testPublish_EmptyMsg() throws Exception {
560        Properties p = new Properties();
561        p.put("java.util.logging.SocketHandler.formatter", className
562                + "$MockFormatter");
563        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
564        p.put("java.util.logging.SocketHandler.port", "6666");
565        LOG_MANAGER.readConfiguration(
566                EnvironmentHelper.PropertiesToInputStream(p));
567
568        // start the server to be ready to accept log messages
569        ServerThread thread = new ServerThread();
570        thread.start();
571        Thread.sleep(2000);
572        h = new SocketHandler();
573        h.setLevel(Level.INFO);
574        LogRecord r = new LogRecord(Level.INFO, "");
575        h.publish(r);
576        h.close();
577        assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
578                .getReadString());
579    }
580
581    /*
582      * Test publish(), a log record with null msg, having output stream
583      */
584    public void testPublish_NullMsg() throws Exception {
585        Properties p = new Properties();
586        p.put("java.util.logging.SocketHandler.formatter", className
587                + "$MockFormatter");
588        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
589        p.put("java.util.logging.SocketHandler.port", "6666");
590        LOG_MANAGER.readConfiguration(
591                EnvironmentHelper.PropertiesToInputStream(p));
592
593        // start the server to be ready to accept log messages
594        ServerThread thread = new ServerThread();
595        thread.start();
596        Thread.sleep(2000);
597        h = new SocketHandler();
598        h.setLevel(Level.INFO);
599        LogRecord r = new LogRecord(Level.INFO, null);
600        h.publish(r);
601        h.close();
602        assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
603                .getReadString());
604    }
605
606    /*
607      * Test publish(), after close.
608      */
609    public void testPublish_AfterClose() throws Exception {
610        Properties p = new Properties();
611        p.put("java.util.logging.SocketHandler.formatter", className
612                + "$MockFormatter");
613        p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
614        p.put("java.util.logging.SocketHandler.port", "6666");
615        LOG_MANAGER.readConfiguration(
616                EnvironmentHelper.PropertiesToInputStream(p));
617
618        // start the server to be ready to accept log messages
619        ServerThread thread = new ServerThread();
620        thread.start();
621        Thread.sleep(2000);
622        h = new SocketHandler();
623        h.setLevel(Level.FINE);
624
625        assertSame(h.getLevel(), Level.FINE);
626        LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFormatter");
627        assertTrue(h.isLoggable(r));
628        h.close();
629        // ensure the thread exits and the port becomes available again
630        thread.getReadString();
631        // assertFalse(h.isLoggable(r));
632        h.publish(r);
633        h.flush();
634        // assertEquals("MockFormatter_Head",
635        // this.errSubstituteStream.toString());
636    }
637
638    /*
639      * A mock filter, always return false.
640      */
641    public static class MockFilter implements Filter {
642
643        public boolean isLoggable(LogRecord record) {
644            CallVerificationStack.getInstance().push(record);
645            // System.out.println("filter called...");
646            return false;
647        }
648    }
649
650    /*
651      * A mock formatter.
652      */
653    public static class MockFormatter extends Formatter {
654        public String format(LogRecord r) {
655            // System.out.println("formatter called...");
656            return super.formatMessage(r);
657        }
658
659        /*
660           * (non-Javadoc)
661           *
662           * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
663           */
664        public String getHead(Handler h) {
665            return "MockFormatter_Head";
666        }
667
668        /*
669           * (non-Javadoc)
670           *
671           * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
672           */
673        public String getTail(Handler h) {
674            return "MockFormatter_Tail";
675        }
676    }
677
678    /*
679      * A mock stream handler, expose setOutputStream.
680      */
681    public static class MockSocketHandler extends SocketHandler {
682        public MockSocketHandler() throws Exception {
683            super();
684        }
685
686        public void setOutputStream(OutputStream out) {
687            super.setOutputStream(out);
688        }
689
690        public boolean isLoggable(LogRecord r) {
691            CallVerificationStack.getInstance().push(r);
692            return super.isLoggable(r);
693        }
694    }
695
696    /*
697      * A server thread that accepts an incoming connection request and reads any
698      * incoming data into an byte array.
699      */
700    public static class ServerThread extends Thread {
701
702        private volatile StringBuffer sb = new StringBuffer();
703
704        private volatile boolean finished = false;
705
706        public boolean finished() {
707            return this.finished;
708        }
709
710        public String getReadString() throws Exception {
711            int i = 0;
712            while (!this.finished) {
713                sleep(100);
714                if (++i > 100) {
715                    // connect to port 6666 to stop the listening.
716                    try {
717                        Socket s = new Socket("127.0.0.1", 6666);
718                        OutputStream os = s.getOutputStream();
719                        os.write(1);
720                        os.close();
721                        s.close();
722                    } catch (Exception e) {
723                        // ignore
724                    }
725                }
726            }
727            return this.sb.toString();
728        }
729
730        public void run() {
731            ServerSocket ss = null;
732            Socket s = null;
733            InputStreamReader reader = null;
734            try {
735                char[] buffer = new char[32];
736                ss = new ServerSocket(6666);
737                s = ss.accept();
738                reader = new InputStreamReader(s.getInputStream());
739                while (true) {
740                    int length = reader.read(buffer);
741                    if (-1 == length) {
742                        break;
743                    }
744                    this.sb.append(buffer, 0, length);
745                }
746            } catch (Exception e) {
747                e.printStackTrace(System.err);
748            } finally {
749                try {
750                    if (null != reader) {
751                        reader.close();
752                        s.close();
753                        ss.close();
754                    }
755                } catch (Exception e) {
756                    e.printStackTrace(System.err);
757                }
758                this.finished = true;
759            }
760        }
761    }
762
763}
764