home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / VCAFE.3.0A / Main.bin / InterleavedReader.java < prev    next >
Text File  |  1998-09-08  |  5KB  |  164 lines

  1. package com.symantec.itools.io;
  2.  
  3.  
  4. import java.io.*;
  5. import java.util.*;
  6.  
  7.  
  8. /**
  9.  * @author Symantec Internet Tools Division
  10.  * @version 1.0
  11.  * @since VCafe 3.0
  12.  */
  13.  
  14. public class InterleavedReader
  15. {
  16.     public InterleavedReader()
  17.     {
  18.     }
  19.  
  20.     /**
  21.      * @param ins TODO
  22.      * @since VCafe 3.0
  23.      */
  24.     
  25.     public void addInputStream(InputStream ins) 
  26.     {
  27.         BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
  28.         ReaderThread readerThread = new ReaderThread(reader, this);
  29.         inputRecords.addElement(new InputRecord(ins, readerThread));
  30.         readerThread.start();  // and he's off.....
  31.     }
  32.  
  33.     public synchronized void removeInputStream(InputStream ins)
  34.     {
  35.         for (Enumeration e = inputRecords.elements(); e.hasMoreElements(); ) {
  36.             InputRecord record = (InputRecord) e.nextElement();
  37.             if (record.stream == ins) {
  38.                 try {
  39.                     record.stream.close();  // will hopefully cause thread to exit cleanly....
  40.                 } catch (IOException exception) {
  41.                     System.out.println("Unexpected IOException when removing input stream: " + exception);
  42.                 }
  43.                 inputRecords.removeElement(record);
  44.                 return;
  45.             }
  46.         }
  47.     }
  48.  
  49.     public synchronized String readLine()
  50.         throws IOException
  51.     {
  52.         String line;
  53.         if (inputRecords.size() == 0)
  54.             return null;
  55.         while (true) {
  56.             // Debug.println("Checking for input....");         
  57.             if (readException != null) {
  58.                 IOException e = readException;
  59.                 readException = null;
  60.                 throw e;
  61.             } else if (lastLineRead != null) {
  62.                 line = lastLineRead;
  63.                 lastLineRead = null;
  64.                 break;
  65.             } else if (inputRecords.size() == 0) {
  66.                 line = null;
  67.                 break;
  68.             }
  69.             try {
  70.                 wait(10);  // do we want a (short) timeout?
  71.             } catch (InterruptedException e) {
  72.             }
  73.         }
  74.         notify();
  75.         return line;
  76.     }
  77.  
  78.     
  79.     public synchronized InputStream lastStreamRead()
  80.     {
  81.         for(Enumeration e = inputRecords.elements(); e.hasMoreElements(); ) {
  82.             InputRecord record = (InputRecord) e.nextElement();
  83.             if (record.thread == lastThreadRead)
  84.                 return record.stream;
  85.         }
  86.         return null;
  87.     }
  88.     
  89.     protected synchronized void lineWasRead(String line, ReaderThread thread)
  90.     {
  91.         while (lastLineRead != null) {
  92.             try {
  93.                 wait(100);
  94.             } catch (InterruptedException e) {
  95.             }
  96.         }
  97.         lastThreadRead = thread;
  98.         lastLineRead = line;
  99.         notify();
  100.     }
  101.     
  102.     protected synchronized void exceptionDuringRead(IOException e)
  103.     {
  104.         readException = e;
  105.         notify();
  106.     }
  107.  
  108.     protected synchronized void inputDone(ReaderThread thd)
  109.     {
  110.         for (Enumeration e = inputRecords.elements(); e.hasMoreElements(); ) {
  111.             InputRecord record = (InputRecord) e.nextElement();
  112.             if (record.thread == thd)
  113.                 inputRecords.removeElement(record);
  114.         }
  115.         notify();
  116.     }
  117.     
  118.     protected class ReaderThread extends java.lang.Thread
  119.     {
  120.         public ReaderThread(BufferedReader rdr, InterleavedReader owner)
  121.         {
  122.             super("ReaderThread-" + (new Integer(threadCount++)).toString());
  123.             reader = rdr;
  124.             master = owner;
  125.         }
  126.         
  127.         public void run()
  128.         {
  129.             try {
  130.                 String s = reader.readLine();
  131.                 while (s != null) {
  132.                     //Debug.println("Got input: " + s);
  133.                     master.lineWasRead(s, this);
  134.                     s = reader.readLine();
  135.                 }
  136.             } catch (IOException e) {
  137.                 master.exceptionDuringRead(e);
  138.             }       
  139.             // either input has been exhausted or an exception was reported, so no more work to do
  140.             master.inputDone(this);
  141.             // Debug.println("No more input.   Exiting....");
  142.         }
  143.         
  144.         private BufferedReader reader;
  145.         private InterleavedReader master;
  146.     }
  147.     
  148.     protected class InputRecord {
  149.         public InputRecord(InputStream strm, ReaderThread th)
  150.         {
  151.             stream = strm;
  152.             thread = th;
  153.         }
  154.         
  155.         public InputStream stream;
  156.         public ReaderThread thread;
  157.     }
  158.     
  159.     protected Vector inputRecords = new Vector(4);
  160.     protected String lastLineRead;
  161.     protected ReaderThread lastThreadRead;
  162.     protected IOException readException;
  163.     static private int threadCount = 0;    
  164. }