package org.jacorb.test.harness; /* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Date; import java.util.regex.Pattern; /** * A <code>StreamListener</code> listens to a given <code>InputStream</code> * in its own thread of control. It copies anything that it reads from the * stream to its own standard output stream. There is a special function * that allows you to capture an IOR from the <code>InputStream</code>. * * @author Andre Spiegel <spiegel@gnu.org> */ public class StreamListener extends Thread { private final BufferedReader in; private final String id; private String ior = null; private String exception = null; private volatile boolean active = true; private final StringBuffer buffer = new StringBuffer(); public StreamListener(InputStream stream, String id) { this.in = new BufferedReader(new InputStreamReader(stream)); this.id = id; setDaemon (true); setName(id + "-StreamListener"); } /** * This method blocks until a line of the form "SERVER IOR: <IOR>" * is received from the InputStream. */ public String getIOR(long timeout) { final long waitUntil; if (timeout == 0) { waitUntil = Long.MAX_VALUE; } else { waitUntil = System.currentTimeMillis() + timeout; } synchronized (this) { while (ior == null && System.currentTimeMillis() < waitUntil) { try { this.wait(1000); } catch (InterruptedException ex) { // ignore } } return ior; } } public String getException(long timeout) { final long waitUntil = System.currentTimeMillis() + timeout; synchronized(this) { while(exception == null && System.currentTimeMillis() < waitUntil) { try { this.wait(1000); } catch (InterruptedException ex) { // ignore } } return exception; } } /** * <code>setDestroyed</code> is called by ClientServerSetup when it is destroying * a subprocess. This is useful to signify to the streams that the process they * are listening to is about to 'go'. */ public void setDestroyed() { active = false; interrupt(); } public String getBuffer() { return buffer.toString(); } public void run() { buffer.append("Starttime: " + new Date()); buffer.append('\n'); Pattern pattern = Pattern.compile("^(\\w+\\.)+\\w+: .*"); while (active) { try { String line = in.readLine(); buffer.append(line); buffer.append('\n'); if (line == null) { break; } else if (line.startsWith("SERVER IOR: ")) { buffer.append("Detected IOR: " + new Date()); buffer.append('\n'); setIOR(line.substring(12)); } else if (TestUtils.patternMatcher(pattern, line) > 0) { buffer.append("Detected Exception: " + new Date()); buffer.append('\n'); System.out.println("[ SERVER " + id + " " + line + " ]"); setException(line); } else { System.out.println("[ SERVER " + id + " " + line + " ]"); } } catch (IOException ex) { if (active) { System.out.println(id + ": IOException reading from server: " + ex); ex.printStackTrace(); } break; } catch (NullPointerException ex) { System.out.println(id + ": NullPointerException reading from server."); if (active) { ex.printStackTrace(); } else { System.out.println (id + ": Server has been destroyed so likely this is JDK bugs 4956099, 4505257 or 4728096"); } break; } catch (Exception ex) { System.out.println(id + ": Exception reading from server: " + ex); System.out.println(id + ": StreamListener exiting"); break; } } try { in.close(); } catch (IOException e) { } } private void setException(String line) { synchronized(this) { exception = line; notifyAll(); } } private void setIOR(String line) { synchronized (this) { ior = line; notifyAll(); } } public String toString() { StringBuffer details = new StringBuffer(); details.append("Details from " + id + ":\n"); details.append("Active: " + active + "\n"); details.append("IOR: " + ior + "\n"); details.append("Exception: " + exception + "\n"); details.append("Raw Buffer:\n"); details.append(getBuffer()); details.append('.'); details.append('\n'); return details.toString(); } }