Commit in lcsim on MAIN
src/org/lcsim/util/Driver.java+133-631.10 -> 1.11
                  /DriverAdapter.java+32-71.3 -> 1.4
test/org/lcsim/util/DriverTest.java+76added 1.1
src/org/lcsim/plugin/LCSimPlugin.java+26-51.10 -> 1.11
+267-75
1 added + 3 modified, total 4 files
First set of changes for driver and associated classes
Fixes LCSIM-128 (redirection of output driver output to JAS console)
Fixes LCSIM-106 (Driver output to logger does not go to JAS3 console window)
Fixes logger inheritance

lcsim/src/org/lcsim/util
Driver.java 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- Driver.java	13 Sep 2006 22:11:26 -0000	1.10
+++ Driver.java	2 Apr 2007 22:55:51 -0000	1.11
@@ -1,9 +1,15 @@
 package org.lcsim.util;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
 import java.util.logging.Logger;
+import java.util.logging.StreamHandler;
 import org.lcsim.conditions.ConditionsManager;
 import org.lcsim.event.EventHeader;
 
@@ -16,7 +22,7 @@
  * and handles coordination of random numbers between Monte Carlo processors.
  *
  * @author Tony Johnson
- * @version $Id: Driver.java,v 1.10 2006/09/13 22:11:26 tonyj Exp $
+ * @version $Id: Driver.java,v 1.11 2007/04/02 22:55:51 tonyj Exp $
  */
 
 public class Driver
@@ -25,7 +31,27 @@
    private final List<Driver> subDrivers = new ArrayList<Driver>();
    private Driver parent = mother;
    private int histogramLevel = -1;
-   private Logger logger;
+   private Random random;
+   private final String driverName;
+
+   public Driver()
+   {
+      this(null);
+   }
+
+   Driver(String name)
+   {
+      if (name == null || name.length() == 0)
+      {
+         String id = getClass().getName();
+         int pos = id.lastIndexOf('.');
+         driverName = id.substring(pos < 0 ? 0 : pos+1);
+      }
+      else
+      {
+         driverName = name;
+      }
+   }
    
    /**
     * Add a sub-Driver to this Driver. Sub-drivers are automatically
@@ -38,9 +64,9 @@
       driver.parent = this;
    }
    /**
-     * Removes a sub-Driver from this Driver
-     * @param driver The Driver to be removed
-     */
+    * Removes a sub-Driver from this Driver
+    * @param driver The Driver to be removed
+    */
    public void remove(Driver driver)
    {
       subDrivers.remove(driver);
@@ -66,105 +92,121 @@
     */
    public Logger getLogger()
    {
-      if (logger == null) return parent.getLogger();
-      return logger;
+      return Logger.getLogger(pathToMother());
+   }
+   
+   /** 
+    * Get the name of this driver. Normally this will be the class name of the 
+    * driver (without the packaging information).
+    */
+   public String getName()
+   {
+      return driverName;
+   }
+   
+   String pathToMother()
+   {
+      return parent.pathToMother() + "." + driverName;
    }
+   
    /**
     * Get the default histogram level for this driver
     */
    public int getHistogramLevel()
    {
-      if (histogramLevel < 0) return parent.getHistogramLevel();
-      return histogramLevel;
+      return histogramLevel < 0 ? parent.getHistogramLevel() : histogramLevel;
    }
    
    public void setHistogramLevel(int level)
    {
       histogramLevel = level;
    }
+   
    public ConditionsManager getConditionsManager()
    {
       return parent.getConditionsManager();
    }
    
-    /**
-     * Called by the framework when event processing is suspended.
-     */
+   /**
+    * Called by the framework when event processing is suspended.
+    */
    protected void suspend()
    {
-      for (int i=0; i<subDrivers.size(); i++)
-      {
-         ((Driver) subDrivers.get(i)).suspend();
-      }      
+      for (Driver driver : subDrivers) driver.suspend();
    }
-    /**
-     * Called by the framework when event processing is resumed.
-     */
+   /**
+    * Called by the framework when event processing is resumed.
+    */
    protected void resume()
    {
-      for (int i=0; i<subDrivers.size(); i++)
-      {
-         ((Driver) subDrivers.get(i)).resume();
-      }       
+      for (Driver driver : subDrivers) driver.resume();
    }
-    /**
-     * Called when all data processing is finished.
-     */
+   /**
+    * Called when all data processing is finished.
+    */
    protected void endOfData()
    {
-      for (int i=0; i<subDrivers.size(); i++)
-      {
-         ((Driver) subDrivers.get(i)).endOfData();
-      }       
+      for (Driver driver : subDrivers) driver.endOfData();
    }
-    /**
-     * Called before the first event is processed, or after a rewind.
-     */
+   /**
+    * Called before the first event is processed, or after a rewind.
+    */
    protected void startOfData()
    {
-      for (int i=0; i<subDrivers.size(); i++)
-      {
-         ((Driver) subDrivers.get(i)).startOfData();
-      }   
+      for (Driver driver : subDrivers) driver.startOfData();
    }
    /**
-     * Called by the framework to process an event. Don't forget to call
-     * <code>super.process(event)</code> to cause the child processes to 
-     * be executed. In addition the process event can call throw some special
-     * exceptions:
-     * <ul>
-     * <li>NextEventException - aborts further processing of this event</li>
-     * <li>StopRunException - causes event processing to be stopped</li>
-     * </ul>
-     * @param event The event to be processed
-     * @see Driver.NextEventException
-     * @see Driver.AbortRunException
-     */
+    * Called by the framework to process an event. Don't forget to call
+    * <code>super.process(event)</code> to cause the child processes to
+    * be executed. In addition the process event can call throw some special
+    * exceptions:
+    * <ul>
+    * <li>NextEventException - aborts further processing of this event</li>
+    * <li>StopRunException - causes event processing to be stopped</li>
+    * </ul>
+    * @param event The event to be processed
+    * @see Driver.NextEventException
+    * @see Driver.AbortRunException
+    */
    protected void process(EventHeader event)
    {
       processChildren(event);
    }
    /**
-    * Calls the sub-Drivers process() method. 
+    * Calls the sub-Drivers process() method.
     * <b>Note:</b> This method is only public so that it can be called from
     * Jython, see LCSIM-30
     */
    public void processChildren(EventHeader event)
    {
-      for (int i=0; i<subDrivers.size(); i++)
-      {
-         ((Driver) subDrivers.get(i)).process(event);
-      }       
+      for (Driver driver : subDrivers) driver.process(event);
    }
    public Random getRandom()
    {
-      return parent.getRandom();
+      return random == null ?  parent.getRandom() : random;
+   }
+   /** Set default random number generator for this driver and all child drivers.
+    * @param random The random number generator, or <code>null</code> to reset to default
+    */
+   public void setRandom(Random random)
+   {
+      this.random = random;
    }
    // The only driver that does not have a parent
+   // This is used to set defaults for "inherited" items
    private static class MotherOfAllDrivers extends Driver
    {
       private Random random = new Random();
-      private Logger logger = Logger.getLogger("global");
+      MotherOfAllDrivers()
+      {
+         super ("TOP");
+         StreamHandler handler = new StreamHandler(System.out,new DriverFormatter());
+         handler.setLevel(Level.ALL);
+         getLogger().setUseParentHandlers(false);
+         getLogger().addHandler(handler);
+         getLogger().setLevel(Level.WARNING);
+      }
+      
       public Random getRandom()
       {
          return random;
@@ -173,18 +215,46 @@
       {
          return 0;
       }
-      public Logger getLogger()
-      {
-         return logger;
-      }
       public ConditionsManager getConditionsManager()
       {
          return ConditionsManager.defaultInstance();
       }
+      String pathToMother()
+      {
+         return getName();
+      }
+   }
+   private static class DriverFormatter extends Formatter
+   {
+      public synchronized String format(LogRecord record)
+      {
+         StringBuilder sb = new StringBuilder();
+         sb.append(record.getLoggerName().substring("TOP".length()+1));
+         sb.append(": ");
+         sb.append(record.getLevel().getLocalizedName());
+         sb.append(": ");
+         sb.append(formatMessage(record));
+         sb.append('\n');
+         if (record.getThrown() != null)
+         {
+            try
+            {
+               StringWriter sw = new StringWriter();
+               PrintWriter pw = new PrintWriter(sw);
+               record.getThrown().printStackTrace(pw);
+               pw.close();
+               sb.append(sw.toString());
+            }
+            catch (Exception ex)
+            {
+            }
+         }
+         return sb.toString();
+      }
    }
    /**
-    * If thrown during the process method of a driver, causes 
-    * processing of the current event to be aborted. Event procssing skips 
+    * If thrown during the process method of a driver, causes
+    * processing of the current event to be aborted. Event procssing skips
     * immediately to the next event.
     */
    public static class NextEventException extends RuntimeException
@@ -195,7 +265,7 @@
       }
    }
    /**
-    * If thrown during the process method of a driver, causes 
+    * If thrown during the process method of a driver, causes
     * processing of events to be aborted.
     */
    public static class AbortRunException extends RuntimeException

lcsim/src/org/lcsim/util
DriverAdapter.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- DriverAdapter.java	8 Nov 2005 16:49:39 -0000	1.3
+++ DriverAdapter.java	2 Apr 2007 22:55:51 -0000	1.4
@@ -1,5 +1,8 @@
 package org.lcsim.util;
 
+import java.io.IOException;
+import org.freehep.jas.plugin.console.ConsoleOutputStream;
+import org.freehep.jas.plugin.console.ConsoleService;
 import org.freehep.record.loop.event.ConfigurationEvent;
 import org.freehep.record.loop.event.RecordAdapter;
 import org.freehep.record.loop.event.RecordEvent;
@@ -10,31 +13,49 @@
 /**
  * Drive a Driver from a Record loop
  * @author Tony Johnson
- * @version $Id: DriverAdapter.java,v 1.3 2005/11/08 16:49:39 tonyj Exp $
+ * @version $Id: DriverAdapter.java,v 1.4 2007/04/02 22:55:51 tonyj Exp $
  */
 public class DriverAdapter extends RecordAdapter
 {
    private Driver driver;
+   // The console stuff is here to fix LCSMI-128. More logically this stuff should 
+   // probably be part of the JAS3 record loop adapter (which currently handles 
+   // redirection of the recordSupplied method)
+   private ConsoleService cs;
+   private ConsoleOutputStream out;
+   
    public DriverAdapter(Driver driver)
    {
       this.driver = driver;
    }
-
+   public DriverAdapter(Driver driver, ConsoleService cs) throws IOException
+   {
+      this.driver = driver;
+      this.cs = cs;
+      if (cs != null) out = cs.getConsoleOutputStream("Record Loop", null);
+   }
+   
    public void finish(RecordEvent event)
    {
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
       driver.endOfData();
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),null);
    }
-
+   
    public void suspend(RecordEvent event)
    {
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
       driver.suspend();
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),null);
    }
-
+   
    public void resume(RecordEvent event)
    {
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
       driver.resume();
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),null);
    }
-
+   
    public void recordSupplied(RecordSuppliedEvent rse)
    {
       try
@@ -47,14 +68,18 @@
          // OK, just continue with next event.
       }
    }
-
+   
    public void configure(ConfigurationEvent event)
    {
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
       driver.startOfData();
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),null);
    }
-
+   
    public void reconfigure(ConfigurationEvent event)
    {
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
       driver.startOfData();
+      if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),null);
    }
 }

lcsim/test/org/lcsim/util
DriverTest.java added at 1.1
diff -N DriverTest.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ DriverTest.java	2 Apr 2007 22:55:52 -0000	1.1
@@ -0,0 +1,76 @@
+package org.lcsim.util;
+
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ *
+ * @author tonyj
+ */
+public class DriverTest extends TestCase
+{
+   
+   public DriverTest(String testName)
+   {
+      super(testName);
+   }
+   
+   public static Test suite()
+   {
+      return new TestSuite(DriverTest.class);
+   }
+   
+   public void testLogging()
+   {
+      TestHandler handler = new TestHandler();
+      Driver parent = new Driver("parent");
+      parent.getLogger().addHandler(handler);
+      parent.getLogger().setUseParentHandlers(false);
+      Driver child = new Driver("child");
+      parent.add(child);
+      
+      assertEquals(0,handler.getCount());
+      child.getLogger().warning("Hello World");
+      assertEquals(1,handler.getCount());
+      child.getLogger().fine("I'm fine");
+      assertEquals(1,handler.getCount());
+      child.getLogger().setLevel(Level.ALL);
+      child.getLogger().fine("I'm still fine");
+      assertEquals(2,handler.getCount());
+      child.getLogger().setLevel(null);
+      child.getLogger().warning("Hello World");
+      assertEquals(3,handler.getCount());
+      child.getLogger().fine("Feeling a little down");
+      assertEquals(3,handler.getCount());
+      parent.getLogger().setLevel(Level.ALL);
+      child.getLogger().fine("That's better");
+      assertEquals(4,handler.getCount());
+      child.getLogger().setLevel(Level.ALL);
+      child.getLogger().fine("Now what!");
+      assertEquals(5,handler.getCount());
+   }
+   private static class TestHandler extends Handler
+   {
+      private int count;
+      public void publish(LogRecord record)
+      {
+         count++;
+      }
+      
+      public void flush()
+      {
+      }
+      
+      public void close() throws SecurityException
+      {
+      }
+      int getCount()
+      {
+         return count;
+      }
+   }
+}

lcsim/src/org/lcsim/plugin
LCSimPlugin.java 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- LCSimPlugin.java	15 Mar 2007 06:39:39 -0000	1.10
+++ LCSimPlugin.java	2 Apr 2007 22:55:52 -0000	1.11
@@ -16,7 +16,8 @@
 import org.freehep.jas.event.ClassLoadedEvent;
 import org.freehep.jas.event.ClassUnloadEvent;
 import org.freehep.jas.event.ScriptEvent;
-import org.freehep.jas.plugin.datasource.FileHandlerDataSource;
+import org.freehep.jas.plugin.console.ConsoleOutputStream;
+import org.freehep.jas.plugin.console.ConsoleService;
 import org.freehep.jas.services.ScriptEngine;
 import org.freehep.jas.services.WebBrowser;
 import org.freehep.record.loop.SequentialRecordLoop;
@@ -41,7 +42,7 @@
 /**
  *
  * @author tonyj
- * @version $Id: LCSimPlugin.java,v 1.10 2007/03/15 06:39:39 tonyj Exp $
+ * @version $Id: LCSimPlugin.java,v 1.11 2007/04/02 22:55:52 tonyj Exp $
  */
 
 public class LCSimPlugin extends Plugin implements StudioListener, PageListener
@@ -49,6 +50,8 @@
     private LCSim lcsim;
     private final LCSimCommands commands = new LCSimCommands();
     private JToolBar toolbar;
+    private ConsoleOutputStream out;
+    private ConsoleService cs;
     
     protected void init() throws SAXException, IOException
     {        
@@ -127,6 +130,18 @@
 
         SequentialRecordLoop loop = (SequentialRecordLoop) getApplication().getLookup().lookup(SequentialRecordLoop.class);
         loop.addRecordLoopListener(commands);
+        
+        try
+        {
+           Studio app = getApplication();
+           FreeHEPLookup lookup = app.getLookup();
+           cs = (ConsoleService) lookup.lookup(ConsoleService.class);
+           if (cs != null) out = cs.getConsoleOutputStream("Record Loop", null);
+        }
+        catch (IOException x)
+        {
+           System.err.println("Warning: Unable to create console output stream");
+        }
     }
     public void handleEvent(EventObject event)
     {
@@ -137,13 +152,19 @@
             {
                 if (Driver.class.isAssignableFrom(x))
                 {
-                    Driver driver = (Driver) x.newInstance();
-                    DriverAdapter listener = new DriverAdapter(driver);
-                    getApplication().getLookup().add(listener);
+                   if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
+                   Driver driver = (Driver) x.newInstance();
+                   if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),null);
+                   
+                   DriverAdapter listener = new DriverAdapter(driver, cs);
+                   getApplication().getLookup().add(listener);
                 }
                 else if (LCSimEventGenerator.class.isAssignableFrom(x))
                 {
+                    if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
                     LCSimEventGenerator gen = (LCSimEventGenerator) x.newInstance();
+                    if (cs != null) cs.redirectStandardOutputOnThreadToConsole(Thread.currentThread(),out);
+
                     String name = x.getName();
                     int pos = name.lastIndexOf('.');
                     if (pos >= 0) name = name.substring(pos+1);
CVSspam 0.2.8