/* * BatchMaster.java * * Created on January 31, 2004, 3:03 PM */ package org.das2.components; import org.das2.event.DataRangeSelectionEvent; import org.das2.datum.DatumRange; import org.das2.datum.DatumRangeUtil; import org.das2.util.DasExceptionHandler; import org.das2.util.DasPNGEncoder; import org.das2.util.DasPNGConstants; import org.das2.graph.DasCanvas; import org.das2.system.DasLogger; import java.awt.*; import java.awt.image.*; import java.io.*; import java.text.*; import java.util.*; import java.util.logging.Level; import org.das2.DasApplication; /** * BatchMaster is a object that runs through a batch file, controlling a time axis to produce a series of images. * @author Jeremy */ public class BatchMaster { /* TODO: create ExceptionHandler, set DasExceptionHandler to this handler * to collect all the messages, then display them at the end. Also keep * list of completed/uncompleted tasks */ java.util.List taskList; int itask; DasCanvas canvas; TaskOutputDescriptor tod; boolean exit= true; public static class Timer { long t0= System.currentTimeMillis();; DecimalFormat df= new DecimalFormat( "00000.000" ); public void reportTime( String msg ) { Thread thread= Thread.currentThread(); long elapsed= System.currentTimeMillis() - t0; System.out.println( df.format(elapsed/1000.)+" "+msg + "("+ thread +")" ); } } public static final Timer timer= new Timer(); public interface TaskOutputDescriptor { public void completeTask( DatumRange range ); } /** * * @param pngFilenameTemplate BEGIN,END,RANGE substituted to form name * @return TaskOutputDescriptor describing the task. */ public TaskOutputDescriptor createPngsTaskOutputDescriptor( final String pngFilenameTemplate ) { return new TaskOutputDescriptor() { private String insertRange( String filenameTemplate, DatumRange range ) { String rangeString= range.toString().replaceAll(":","-").replaceAll(" ","_"); String s= filenameTemplate .replaceAll( "BEGIN", range.min().toString().replaceAll(":","-") ) .replaceAll( "END", range.max().toString().replaceAll(":","-") ) .replaceAll( "RANGE", rangeString ); return s; } @Override public void completeTask( DatumRange range ) { Image image= BatchMaster.this.canvas.getImage( canvas.getWidth(), canvas.getHeight() ); String s= insertRange( pngFilenameTemplate, range ); try { OutputStream out= new FileOutputStream( s ); try { DasPNGEncoder encoder = new DasPNGEncoder(); encoder.addText(DasPNGConstants.KEYWORD_CREATION_TIME, new Date().toString()); encoder.write((BufferedImage)image, out); } finally { out.close(); } } catch ( IOException e ) { DasApplication.getDefaultApplication().getExceptionHandler().handle(e); } } }; } private void readStartEndSpecFile( File specFile ) throws ParseException, IOException { BufferedReader r= new BufferedReader( new FileReader( specFile ) ); String s= r.readLine(); while ( s!=null ) { s= s.trim(); if ( !( s.equals("") || s.startsWith("#" ) ) ) { DatumRange dr= DatumRangeUtil.parseTimeRange(s); addTask( dr ); } s= r.readLine(); } } /** * create the pngwalk using the class. * @param canvas the source for images * @param specFile flat text file containing one parsable time range per line. (For example, "1990-01-01T00:00 1990-01-02T00:00" or "1990-01-01") * @param pngFilenameTemplate (For example, "BEGIN_END.png") * @throws java.text.ParseException with the specFile * @throws java.io.IOException with the specFile * @return BatchMaster object. */ public static BatchMaster createPngs( DasCanvas canvas, File specFile, String pngFilenameTemplate ) throws ParseException, IOException { BatchMaster result= new BatchMaster(canvas ); result.setTaskOutputDescriptor( result.createPngsTaskOutputDescriptor( pngFilenameTemplate ) ); result.readStartEndSpecFile( specFile ); return result; } /** * Creates a new instance of BatchMaster * @param canvas the source for images */ public BatchMaster( DasCanvas canvas ) { this.canvas= canvas; taskList= new ArrayList(); itask= 0; } /** * Starts the batch process. */ public void start() { submitNextTask(); } /** * add another range * @param range */ void addTask( DatumRange range ) { taskList.add( new DataRangeSelectionEvent( this, range.min(), range.max() ) ); } /** * The TaskOutputDescriptor is called as each task is completed. * @param tod */ void setTaskOutputDescriptor( TaskOutputDescriptor tod ) { this.tod= tod; } /** * If true, then System.exit is called after running batch. * @param val If true, then System.exit is called after running batch. */ void setExitAfterCompletion( boolean val ) { this.exit= val; } void submitNextTask() { Thread thread= new Thread( new Runnable() { @Override public void run() { if ( itask>=taskList.size() ) { if ( exit ) System.exit(0); } else { DasLogger.getLogger(DasLogger.SYSTEM_LOG).log(Level.INFO, "itask={0}", taskList.get(itask)); DataRangeSelectionEvent ev= (DataRangeSelectionEvent) taskList.get(itask++); fireDataRangeSelectionListenerDataRangeSelected( ev ); canvas.waitUntilIdle(); tod.completeTask( ev.getDatumRange() ); submitNextTask(); } } }); thread.start(); } /** Utility field used by event firing mechanism. */ private javax.swing.event.EventListenerList listenerList = null; /** Registers DataRangeSelectionListener to receive events. * @param listener The listener to register. */ public synchronized void addDataRangeSelectionListener(org.das2.event.DataRangeSelectionListener listener) { if (listenerList == null ) { listenerList = new javax.swing.event.EventListenerList(); } listenerList.add(org.das2.event.DataRangeSelectionListener.class, listener); } /** Removes DataRangeSelectionListener from the list of listeners. * @param listener The listener to remove. */ public synchronized void removeDataRangeSelectionListener(org.das2.event.DataRangeSelectionListener listener) { listenerList.remove(org.das2.event.DataRangeSelectionListener.class, listener); } /** Notifies all registered listeners about the event. * * @param event The event to be fired */ private void fireDataRangeSelectionListenerDataRangeSelected(DataRangeSelectionEvent event) { if (listenerList == null) return; Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==org.das2.event.DataRangeSelectionListener.class) { ((org.das2.event.DataRangeSelectionListener)listeners[i+1]).dataRangeSelected(event); } } } }