From: Arne V. <cob...@us...> - 2004-06-09 07:35:46
|
Update of /cvsroot/jrobin/src/org/jrobin/graph In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4540/org/jrobin/graph Modified Files: Comment.java FetchSource.java Gprint.java Grapher.java RrdGraph.java RrdGraphDef.java Log Message: JRobin 1.4.0 - Added setLazy() option for lazy graph regeneration - Added setDatasources() option for GraphDef def management - Fxed 0 as end timestamp option - Fixed GraphDef reuse issue with gprint() Index: Grapher.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Grapher.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Grapher.java 31 May 2004 17:13:21 -0000 1.12 --- Grapher.java 9 Jun 2004 07:35:36 -0000 1.13 *************** *** 27,34 **** import java.io.File; import java.io.IOException; ! import java.util.Vector; ! import java.util.HashMap; ! import java.util.Iterator; ! import java.util.LinkedList; import javax.imageio.ImageIO; import java.awt.Font; --- 27,31 ---- import java.io.File; import java.io.IOException; ! import java.util.*; import javax.imageio.ImageIO; import java.awt.Font; *************** *** 90,98 **** private RrdGraphDef graphDef; ! private RrdGraph rrdGraph; ! private Source[] sources; private HashMap sourceIndex; ! private long[] timestamps; private ValueFormatter valueFormat; --- 87,95 ---- private RrdGraphDef graphDef; ! ! private long[] timestamps; private Source[] sources; private HashMap sourceIndex; ! private FetchSourceList fetchSources; private ValueFormatter valueFormat; *************** *** 116,120 **** { this.graphDef = graphDef; - this.rrdGraph = rrdGraph; // Set font dimension specifics --- 113,116 ---- *************** *** 137,140 **** --- 133,140 ---- // Set default graph stroke defaultStroke = new BasicStroke(); + + // Get the fetch sources list + fetchSources = graphDef.getFetchSources(); + fetchSources.setRrdOpener( rrdGraph ); // Set the RrdOpener } *************** *** 281,284 **** --- 281,311 ---- /** + * If the lazy flag of the GraphDef has been set, this method will + * check the most recent update stamp of the FetchSources, and return + * true if the update timestamp is larger than the timestamp of the + * previous graph generation (passed on as a parameter). + * + * @param prevGenTime Timestamp of the previous graph generation. + * @return True if the graph should be generated, false if not. + */ + protected boolean shouldGenerate( long prevGenTime ) throws RrdException, IOException + { + fetchSources.openAll(); + + if ( graphDef.isLazy() && fetchSources.getLastUpdateTime() * 1000 < prevGenTime ) + { + // Should not generate, release immediately + fetchSources.releaseAll(); + + return false; + } + + return true; + } + + // ================================================================ + // -- Private methods + // ================================================================ + /** * Renders the actual graph onto the specified Graphics2D object * @param graphics The handle to the Graphics2D object to render the graph on. *************** *** 305,311 **** } - // ================================================================ - // -- Private methods - // ================================================================ /** * Fetches and calculates all datasources used in the graph. --- 332,335 ---- *************** *** 322,330 **** long finalEndTime = 0; boolean changingEndTime = false; ! long startTime = graphDef.getStartTime(); long endTime = graphDef.getEndTime(); changingEndTime = (endTime == 0); ! int numDefs = graphDef.getNumDefs(); int numSdefs = graphDef.getNumSdefs(); --- 346,354 ---- long finalEndTime = 0; boolean changingEndTime = false; ! long startTime = graphDef.getStartTime(); long endTime = graphDef.getEndTime(); changingEndTime = (endTime == 0); ! int numDefs = graphDef.getNumDefs(); int numSdefs = graphDef.getNumSdefs(); *************** *** 332,336 **** Cdef[] cdefList = graphDef.getCdefs(); int numCdefs = cdefList.length; ! Pdef[] pdefList = graphDef.getPdefs(); int numPdefs = pdefList.length; --- 356,360 ---- Cdef[] cdefList = graphDef.getCdefs(); int numCdefs = cdefList.length; ! Pdef[] pdefList = graphDef.getPdefs(); int numPdefs = pdefList.length; *************** *** 341,385 **** int tblPos = 0; int vePos = 0; ! ! ValueExtractor[] veList = new ValueExtractor[ graphDef.getFetchSources().size() ]; ! Iterator fetchSources = graphDef.getFetchSources().values().iterator(); ! ! while ( fetchSources.hasNext() ) { ! // Get the rrdDb ! src = (FetchSource) fetchSources.next(); ! String rrdFile = src.getRrdFile(); ! rrd = rrdGraph.getRrd( rrdFile, src.getRrdBackendFactory() ); ! ! // If the endtime is 0, use the last time a database was updated ! if ( changingEndTime ) { ! long step = rrd.getRrdDef().getStep(); ! endTime = rrd.getLastUpdateTime() - (endTime % step) - step; ! if ( endTime > finalEndTime ) ! finalEndTime = endTime; ! } ! ! // Fetch all required datasources ! ve = src.fetch( rrd, startTime, endTime, graphDef.getResolution() ); ! varList = ve.getNames(); ! // BUGFIX: Release the rrdDb ! rrdGraph.releaseRrd(rrd); ! for (int i= 0; i < varList.length; i++) { ! sources[tblPos] = new Def(varList[i], numPoints); ! sourceIndex.put( varList[i], new Integer(tblPos++) ); } - - veList[ vePos++ ] = ve; } ! // Add all Pdefs to the source table for ( int i = 0; i < pdefList.length; i++ ) { pdefList[i].prepare( numPoints ); ! sources[tblPos] = pdefList[i]; sourceIndex.put( pdefList[i].getName(), new Integer(tblPos++) ); --- 365,411 ---- int tblPos = 0; int vePos = 0; ! ! ValueExtractor[] veList = new ValueExtractor[ fetchSources.size() ]; ! ! // Open all datasources ! try { ! fetchSources.openAll(); ! ! for ( int i = 0; i < fetchSources.size(); i++ ) { ! src = fetchSources.get( i ); ! if ( changingEndTime ) ! { ! endTime = src.getLastSampleTime( endTime ); ! if ( endTime > finalEndTime ) ! finalEndTime = endTime; ! } ! // Fetch all required datasources ! ve = src.fetch( startTime, endTime, graphDef.getResolution() ); ! varList = ve.getNames(); ! ! for (int j= 0; j < varList.length; j++) { ! sources[tblPos] = new Def(varList[j], numPoints); ! sourceIndex.put( varList[j], new Integer(tblPos++) ); ! } ! ! veList[ vePos++ ] = ve; } } ! finally ! { ! // Release all datasources again ! fetchSources.releaseAll(); ! } ! // Add all Pdefs to the source table for ( int i = 0; i < pdefList.length; i++ ) { pdefList[i].prepare( numPoints ); ! sources[tblPos] = pdefList[i]; sourceIndex.put( pdefList[i].getName(), new Integer(tblPos++) ); *************** *** 393,399 **** { cdefList[i].prepare( sourceIndex, numPoints ); ! sources[tblPos] = cdefList[i]; ! sourceIndex.put( cdefList[i].getName(), new Integer(tblPos++) ); } --- 419,425 ---- { cdefList[i].prepare( sourceIndex, numPoints ); ! sources[tblPos] = cdefList[i]; ! sourceIndex.put( cdefList[i].getName(), new Integer(tblPos++) ); } *************** *** 874,883 **** ((Gprint) clist[i]).setValue( sources, sourceIndex, valueFormat ); ! Vector tknpairs = clist[i].getTokens(); for (int j = 0; j < tknpairs.size(); j++) { ! String str = (String) tknpairs.elementAt(j++); ! Byte tkn = (Byte) tknpairs.elementAt(j); if ( clist[i].trimString() ) --- 900,909 ---- ((Gprint) clist[i]).setValue( sources, sourceIndex, valueFormat ); ! ArrayList tknpairs = clist[i].getTokens(); for (int j = 0; j < tknpairs.size(); j++) { ! String str = (String) tknpairs.get(j++); ! Byte tkn = (Byte) tknpairs.get(j); if ( clist[i].trimString() ) *************** *** 1019,1027 **** boolean newLine = false; ! Vector tknpairs = graphTitle.getTokens(); for (int j = 0; j < tknpairs.size(); j++) { ! String str = (String) tknpairs.elementAt(j++); ! Byte tkn = (Byte) tknpairs.elementAt(j); tmpStr.append( str ); --- 1045,1053 ---- boolean newLine = false; ! ArrayList tknpairs = graphTitle.getTokens(); for (int j = 0; j < tknpairs.size(); j++) { ! String str = (String) tknpairs.get(j++); ! Byte tkn = (Byte) tknpairs.get(j); tmpStr.append( str ); Index: Gprint.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Gprint.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Gprint.java 26 Apr 2004 22:28:33 -0000 1.5 --- Gprint.java 9 Jun 2004 07:35:36 -0000 1.6 *************** *** 26,29 **** --- 26,30 ---- import java.util.HashMap; + import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; *************** *** 55,60 **** private boolean normalScale = false; private boolean uniformScale = false; ! ! // ================================================================ // -- Constructors --- 56,63 ---- private boolean normalScale = false; private boolean uniformScale = false; ! ! protected ArrayList parsedList; ! ! // ================================================================ // -- Constructors *************** *** 75,79 **** checkValuePlacement(); // First see if this GPRINT is valid super.parseComment(); ! this.commentType = Comment.CMT_GPRINT; this.sourceName = sourceName; --- 78,82 ---- checkValuePlacement(); // First see if this GPRINT is valid super.parseComment(); ! this.commentType = Comment.CMT_GPRINT; this.sourceName = sourceName; *************** *** 143,151 **** String valueStr = vFormat.getFormattedValue(); String prefix = vFormat.getPrefix(); ! // Replace all values for (int i = 0; i < oList.size(); i += 2 ) { ! String str = (String) oList.elementAt(i); str = str.replaceAll(VALUE_MARKER, valueStr); --- 146,157 ---- String valueStr = vFormat.getFormattedValue(); String prefix = vFormat.getPrefix(); ! ! // Create a copy of the token/pair list ! parsedList = new ArrayList( oList ); ! // Replace all values for (int i = 0; i < oList.size(); i += 2 ) { ! String str = (String) oList.get(i); str = str.replaceAll(VALUE_MARKER, valueStr); *************** *** 153,157 **** if ( uniformScale ) str = str.replaceAll(UNIFORM_SCALE_MARKER, prefix); ! oList.set( i, str ); } --- 159,163 ---- if ( uniformScale ) str = str.replaceAll(UNIFORM_SCALE_MARKER, prefix); ! parsedList.set( i, str ); } *************** *** 164,169 **** } } ! ! // ================================================================ // -- Private methods --- 170,184 ---- } } ! ! /** ! * Retrieves a <code>ArrayList</code> containing all string/token pairs in order of <code>String</code> - <code>Byte</code>. ! * @return ArrayList containing all string/token pairs of this Comment. ! */ ! ArrayList getTokens() ! { ! return parsedList; ! } ! ! // ================================================================ // -- Private methods Index: RrdGraph.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/RrdGraph.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** RrdGraph.java 30 May 2004 19:49:56 -0000 1.8 --- RrdGraph.java 9 Jun 2004 07:35:36 -0000 1.9 *************** *** 52,66 **** * @author Sasa Markovic (sa...@jr...) */ ! public class RrdGraph implements Serializable { // ================================================================ // -- Members // ================================================================ - private Grapher grapher; private BufferedImage img; - private RrdDbPool pool; - private boolean useImageSize = false; --- 52,63 ---- * @author Sasa Markovic (sa...@jr...) */ ! public class RrdGraph extends RrdOpener implements Serializable { // ================================================================ // -- Members // ================================================================ private Grapher grapher; private BufferedImage img; private boolean useImageSize = false; *************** *** 73,77 **** */ public RrdGraph() ! { } --- 70,75 ---- */ public RrdGraph() ! { ! super( false, true ); } *************** *** 82,87 **** public RrdGraph( boolean usePool ) { ! if ( usePool ) ! this.pool = RrdDbPool.getInstance(); } --- 80,84 ---- public RrdGraph( boolean usePool ) { ! super( usePool, true ); } *************** *** 102,107 **** public RrdGraph( RrdGraphDef graphDef, boolean usePool ) { ! if ( usePool ) ! this.pool = RrdDbPool.getInstance(); grapher = new Grapher( graphDef, this ); } --- 99,103 ---- public RrdGraph( RrdGraphDef graphDef, boolean usePool ) { ! super( usePool, true ); grapher = new Grapher( graphDef, this ); } *************** *** 156,162 **** public void saveAsPNG( String path, int width, int height ) throws RrdException, IOException { ! ImageIO.write( getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB), "png", new File(path) ); } ! /** * Creates and saves a graph image with default dimensions as a GIF file. --- 152,161 ---- public void saveAsPNG( String path, int width, int height ) throws RrdException, IOException { ! File imgFile = new File( path ); ! ! if ( shouldGenerate(imgFile) ) ! ImageIO.write( getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB), "png", imgFile ); } ! /** * Creates and saves a graph image with default dimensions as a GIF file. *************** *** 183,192 **** public void saveAsGIF(String path, int width, int height) throws RrdException, IOException { ! GifEncoder gifEncoder = new GifEncoder( getBufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED) ); ! FileOutputStream stream = new FileOutputStream( path, false ); ! ! gifEncoder.encode(stream); ! ! stream.close(); } --- 182,196 ---- public void saveAsGIF(String path, int width, int height) throws RrdException, IOException { ! File imgFile = new File( path ); ! ! if ( shouldGenerate(imgFile) ) ! { ! GifEncoder gifEncoder = new GifEncoder( getBufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED) ); ! FileOutputStream stream = new FileOutputStream( path, false ); ! ! gifEncoder.encode(stream); ! ! stream.close(); ! } } *************** *** 215,218 **** --- 219,227 ---- public void saveAsJPEG( String path, int width, int height, float quality ) throws RrdException, IOException { + File imgFile = new File( path ); + + if ( !shouldGenerate(imgFile) ) + return; + // Based on http://javaalmanac.com/egs/javax.imageio/JpegWrite.html?l=rel // Retrieve jpg image to be compressed *************** *** 265,270 **** ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ! ImageIO.write(getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB), ! "png", outputStream ); return outputStream.toByteArray(); --- 274,278 ---- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ! ImageIO.write(getBufferedImage(width, height, BufferedImage.TYPE_INT_RGB), "png", outputStream ); return outputStream.toByteArray(); *************** *** 396,420 **** // ================================================================ ! // -- Protected (package) methods // ================================================================ ! RrdDb getRrd( String rrdFile, RrdBackendFactory backendFactory ) throws IOException, RrdException { ! if ( pool != null ) ! return pool.requestRrdDb( rrdFile ); ! else ! return new RrdDb( rrdFile, true, backendFactory ); ! } ! void releaseRrd(RrdDb rrdDb) throws RrdException, IOException ! { ! if ( pool != null ) ! pool.release(rrdDb); ! else ! rrdDb.close(); } - // ================================================================ - // -- Private methods - // ================================================================ private BufferedImage getBufferedImage(int width, int height, int colorType) throws RrdException, IOException { --- 404,426 ---- // ================================================================ ! // -- Private methods // ================================================================ ! /** ! * This method checks if the graph should be generated. This would be the case if the requested ! * image file does not yet exist, or (in case the generation is set to be lazy) the last modified ! * timestamp of the image file is before the last updated timestamp of the used datasources. ! * @param imgFile Image file to check against. ! * @return True if graph generation should be done, false if not. ! * @throws IOException Thrown in case of I/O error. ! * @throws RrdException Thrown in case of JRobin specific error. ! */ ! private boolean shouldGenerate( File imgFile ) throws RrdException, IOException { ! if ( !imgFile.exists() ) ! return true; ! return grapher.shouldGenerate( imgFile.lastModified() ); } private BufferedImage getBufferedImage(int width, int height, int colorType) throws RrdException, IOException { Index: FetchSource.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/FetchSource.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** FetchSource.java 31 May 2004 17:13:21 -0000 1.5 --- FetchSource.java 9 Jun 2004 07:35:36 -0000 1.6 *************** *** 25,29 **** package org.jrobin.graph; - import java.util.Vector; import java.util.ArrayList; import java.io.IOException; --- 25,28 ---- *************** *** 52,56 **** protected static final String[] cfNames = new String[] { "AVERAGE", "MAX", "MIN", "LAST" }; ! private String rrdFile; // Holds the name of the RRD file private String backendName; --- 51,57 ---- protected static final String[] cfNames = new String[] { "AVERAGE", "MAX", "MIN", "LAST" }; ! ! private RrdDb rrd; ! private String rrdFile; // Holds the name of the RRD file private String backendName; *************** *** 58,63 **** private int numSources = 0; private ArrayList[] datasources = new ArrayList[MAX_CF]; ! ! // ================================================================ // -- Constructors --- 59,66 ---- private int numSources = 0; private ArrayList[] datasources = new ArrayList[MAX_CF]; ! ! private FetchSourceList listReference = null; ! ! // ================================================================ // -- Constructors *************** *** 65,74 **** /** * Constructs a FetchSource object based on a RRD file name. * @param rrdFile Name of the RRD file holding all datasources. */ ! protected FetchSource( String rrdFile ) { ! this.rrdFile = rrdFile; ! // Initialization of datasource lists per CF for (int i = 0; i < datasources.length; i++) --- 68,80 ---- /** * Constructs a FetchSource object based on a RRD file name. + * * @param rrdFile Name of the RRD file holding all datasources. + * @param listRef Reference to the FetchSourceList this FetchSource belongs to. */ ! protected FetchSource( String rrdFile, FetchSourceList listRef ) { ! this.rrdFile = rrdFile; ! listReference = listRef; ! // Initialization of datasource lists per CF for (int i = 0; i < datasources.length; i++) *************** *** 79,91 **** * Constructs a FetchSource object based on a RRD file name, and * adds a given datasource to the datasources list. * @param rrdFile Name of the RRD file holding all datasources. * @param consolFunc Consolidation function of the datasource to fetch. * @param dsName Internal name of the datasource in the RRD file. * @param name Variable name of the datasource in the graph definition. * @throws RrdException Thrown in case of a JRobin specific error. */ ! FetchSource( String rrdFile, String consolFunc, String dsName, String name ) throws RrdException { ! this( rrdFile ); addSource( consolFunc, dsName, name ); } --- 85,99 ---- * Constructs a FetchSource object based on a RRD file name, and * adds a given datasource to the datasources list. + * * @param rrdFile Name of the RRD file holding all datasources. * @param consolFunc Consolidation function of the datasource to fetch. * @param dsName Internal name of the datasource in the RRD file. * @param name Variable name of the datasource in the graph definition. + * @param listRef Reference to the FetchSourceList this FetchSource belongs to. * @throws RrdException Thrown in case of a JRobin specific error. */ ! protected FetchSource( String rrdFile, String consolFunc, String dsName, String name, FetchSourceList listRef ) throws RrdException { ! this( rrdFile, listRef ); addSource( consolFunc, dsName, name ); } *************** *** 94,97 **** --- 102,106 ---- * Constructs a FetchSource object based on a RRD file name, and * adds a given datasource to the datasources list. + * * @param rrdFile Name of the RRD file holding all datasources. * @param consolFunc Consolidation function of the datasource to fetch. *************** *** 99,107 **** * @param name Variable name of the datasource in the graph definition. * @param backendName Name of the RrdBackendFactory to use for this RrdDb. * @throws RrdException Thrown in case of a JRobin specific error. */ ! FetchSource( String rrdFile, String consolFunc, String dsName, String name, String backendName ) throws RrdException { ! this( rrdFile, consolFunc, dsName, name ); setBackendFactory( backendName ); } --- 108,117 ---- * @param name Variable name of the datasource in the graph definition. * @param backendName Name of the RrdBackendFactory to use for this RrdDb. + * @param listRef Reference to the FetchSourceList this FetchSource belongs to. * @throws RrdException Thrown in case of a JRobin specific error. */ ! protected FetchSource( String rrdFile, String consolFunc, String dsName, String name, String backendName, FetchSourceList listRef ) throws RrdException { ! this( rrdFile, consolFunc, dsName, name, listRef ); setBackendFactory( backendName ); } *************** *** 112,115 **** --- 122,126 ---- /** * Adds a given datasource to the datasources list for this FetchSource. + * * @param consolFunc Consolidation function of the datasource to fetch. * @param dsName Internal name of the datasource in the RRD file. *************** *** 136,139 **** --- 147,151 ---- * Sets the name of the RrdBackendFactory that should be used for this FetchSource. * The factory should be registered with RrdBackendFactory static. + * * @param backendName Name of the RrdBackendFactory to use for this RrdDb. */ *************** *** 144,148 **** /** * Fetches all datavalues for a given timespan out of the provided RRD file. ! * @param rrd An open <code>RrdDb</code> object holding the necessary datasources. * @param startTime Start time of the given timespan. * @param endTime End time of the given timespan. --- 156,160 ---- /** * Fetches all datavalues for a given timespan out of the provided RRD file. ! * * @param startTime Start time of the given timespan. * @param endTime End time of the given timespan. *************** *** 152,157 **** * @throws RrdException Thrown in case of a JRobin specific error. */ ! protected ValueExtractor fetch ( RrdDb rrd, long startTime, long endTime, long resolution ) throws IOException, RrdException { int dsSize = 0; String[] dsNames, vNames; --- 164,172 ---- * @throws RrdException Thrown in case of a JRobin specific error. */ ! protected ValueExtractor fetch ( long startTime, long endTime, long resolution ) throws IOException, RrdException { + if ( rrd == null ) + openRrd(); + int dsSize = 0; String[] dsNames, vNames; *************** *** 195,198 **** --- 210,298 ---- } + /** + * Retrieves the RrdDb connected to this FetchSource. + * The RrdDb instance is retrieved through the use of the + * RrdOpener that is referred internally in the FetchSourceList. + * It is okay to call this method multiple times in a row. + * + * @throws IOException Thrown in case of fetching I/O error. + * @throws RrdException Thrown in case of a JRobin specific error. + */ + protected void openRrd() throws RrdException, IOException + { + if ( rrd == null ) + { + RrdOpener opener = listReference.getRrdOpener(); + + if ( opener == null ) + throw new RrdException( "No RrdOpener specified for RRD management." ); + + // Only open if not open yet + if ( rrd == null ) + rrd = opener.getRrd( rrdFile, getRrdBackendFactory() ); + } + } + + /** + * Gets the RrdDb instance for this FetchSource. If the + * RrdDb has not been retrieved yet, it is before this + * method returns. It is okay to call this method multiple + * times in a row. + * + * @return Reference to the RrdDb instance. + * @throws IOException Thrown in case of fetching I/O error. + * @throws RrdException Thrown in case of a JRobin specific error. + */ + protected RrdDb getRrd() throws RrdException, IOException + { + if ( rrd == null ) + openRrd(); + + return rrd; + } + + /** + * Releases the internal RrdDb reference for this FetchSource. + * It is okay to call this method multiple times in a row. + * + * @throws IOException Thrown in case of fetching I/O error. + * @throws RrdException Thrown in case of a JRobin specific error. + */ + protected void release() throws RrdException, IOException + { + if ( rrd != null ) + { + RrdOpener opener = listReference.getRrdOpener(); + + if ( opener == null ) + throw new RrdException( "No RrdOpener specified for RRD management." ); + + opener.releaseRrd( rrd ); + rrd = null; + } + } + + /** + * Returns the timestamp of the last completed sample before or on the given time. + * This method is useful to find out the actual last timestamp for graphing, if the + * current time is after the last update time. This sample can contain bad (Unknown) + * values, as long as the interval for it has been completed. This is not the + * timestamp of the last non-unknown sample! + * + * @param endTime Timestamp for which the last sample time should be calculated. + * @return Last sample timestamp in seconds. + * @throws IOException Thrown in case of fetching I/O error. + * @throws RrdException Thrown in case of a JRobin specific error. + */ + protected long getLastSampleTime( long endTime ) throws RrdException, IOException + { + if ( rrd == null ) + openRrd(); + + long step = rrd.getRrdDef().getStep(); + + return endTime = rrd.getLastUpdateTime() - (endTime % step) - step; + } + protected String getRrdFile() { return rrdFile; Index: RrdGraphDef.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/RrdGraphDef.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** RrdGraphDef.java 31 May 2004 17:13:21 -0000 1.14 --- RrdGraphDef.java 9 Jun 2004 07:35:36 -0000 1.15 *************** *** 61,123 **** // -- Members // ================================================================ ! private long endTime = Util.getTime(); // default time span of the last 24 hours ! private long startTime = Util.getTime() - 86400L; ! private long resolution = 1; // resolution to fetch from the RRD databases ! private Title title = null; // no title ! private String valueAxisLabel = null; // no vertical label ! private TimeAxisLabel timeAxisLabel = null; // no horizontal label ! ! private boolean gridX = true; // hide entire X axis grid (default: no) ! private boolean gridY = true; // hide entire Y axis grid (default: no) ! private boolean minorGridX = true; // hide minor X axis grid (default: no) ! private boolean minorGridY = true; // hide minor Y axis grid (default: no) ! private boolean majorGridX = true; // hide major X axis grid with labels (default: no) ! private boolean majorGridY = true; // hide major Y axis grid with labels (default: no) ! private boolean frontGrid = true; // show grid in front of the chart (default: yes) ! private boolean antiAliasing = true; // use anti-aliasing for the chart (default: yes) ! private boolean showLegend = true; // show legend and comments (default: yes) ! private boolean drawSignature = true; // show JRobin url signature (default: yes) ! private Color backColor = new Color( 245, 245, 245 ); // variation of light gray ! private Color canvasColor = Color.WHITE; // white ! private Color borderColor = Color.LIGHT_GRAY; // light gray, only applicable with a borderStroke ! private Color normalFontColor = Color.BLACK; // black ! private Color titleFontColor = Color.BLACK; // black ! private Color majorGridColor = new Color(130,30,30); // variation of dark red ! private Color minorGridColor = new Color(140,140,140); // variation of gray ! private Color axisColor = new Color(130,30,30); // variation of dark red ! private Color arrowColor = Color.RED; // red ! private Color frameColor = Color.LIGHT_GRAY; // light gray ! private Font titleFont = null; // use default 'grapher' font ! private Font normalFont = null; // use default 'grapher' font ! private File background = null; // no background image by default ! private File overlay = null; // no overlay image by default ! private int chart_lpadding = Grapher.CHART_LPADDING; // padding space on the left of the chart area ! private int firstDayOfWeek = TimeAxisUnit.MONDAY; // first day of a calendar week, default: monday ! private double baseValue = ValueFormatter.DEFAULT_BASE; // unit base value to use (default: 1000) ! private int scaleIndex = ValueFormatter.NO_SCALE; // fixed units exponent value to use ! private BasicStroke borderStroke = null; // defaults to standard beveled border ! private TimeAxisUnit tAxis = null; // custom time axis grid, defaults to no custom ! private ValueAxisUnit vAxis = null; // custom value axis grid, defaults to no custom ! private GridRange gridRange = null; // custom value range definition, defaults to auto-scale // -- Non-settable members ! private int numSdefs = 0; ! private int numDefs = 0; // number of Def datasources added ! private int commentLines = 0; // number of complete lines in the list of comment items ! private int commentLineShift = 0; // modifier to add to get minimum one complete line of comments ! private HashMap fetchSources = new HashMap( 10 ); // holds the list of FetchSources ! private ArrayList cdefList = new ArrayList( 10 ); // holds the list of Cdef datasources ! private ArrayList pdefList = new ArrayList( 10 ); // holds the list of Plottable datasources ! private ArrayList plotDefs = new ArrayList( 10 ); // holds the list of PlotDefs ! private ArrayList comments = new ArrayList( 10 ); // holds the list of comment items --- 61,124 ---- // -- Members // ================================================================ ! private long endTime = Util.getTime(); // default time span of the last 24 hours ! private long startTime = Util.getTime() - 86400L; ! private long resolution = 1; // resolution to fetch from the RRD databases ! private Title title = null; // no title ! private String valueAxisLabel = null; // no vertical label ! private TimeAxisLabel timeAxisLabel = null; // no horizontal label ! ! private boolean lazyGeneration = false; // generate only if the file is outdated ! private boolean gridX = true; // hide entire X axis grid (default: no) ! private boolean gridY = true; // hide entire Y axis grid (default: no) ! private boolean minorGridX = true; // hide minor X axis grid (default: no) ! private boolean minorGridY = true; // hide minor Y axis grid (default: no) ! private boolean majorGridX = true; // hide major X axis grid with labels (default: no) ! private boolean majorGridY = true; // hide major Y axis grid with labels (default: no) ! private boolean frontGrid = true; // show grid in front of the chart (default: yes) ! private boolean antiAliasing = true; // use anti-aliasing for the chart (default: yes) ! private boolean showLegend = true; // show legend and comments (default: yes) ! private boolean drawSignature = true; // show JRobin url signature (default: yes) ! private Color backColor = new Color( 245, 245, 245 ); // variation of light gray ! private Color canvasColor = Color.WHITE; // white ! private Color borderColor = Color.LIGHT_GRAY; // light gray, only applicable with a borderStroke ! private Color normalFontColor = Color.BLACK; // black ! private Color titleFontColor = Color.BLACK; // black ! private Color majorGridColor = new Color(130,30,30); // variation of dark red ! private Color minorGridColor = new Color(140,140,140); // variation of gray ! private Color axisColor = new Color(130,30,30); // variation of dark red ! private Color arrowColor = Color.RED; // red ! private Color frameColor = Color.LIGHT_GRAY; // light gray ! private Font titleFont = null; // use default 'grapher' font ! private Font normalFont = null; // use default 'grapher' font ! private File background = null; // no background image by default ! private File overlay = null; // no overlay image by default ! private int chart_lpadding = Grapher.CHART_LPADDING; // padding space on the left of the chart area ! private int firstDayOfWeek = TimeAxisUnit.MONDAY; // first day of a calendar week, default: monday ! private double baseValue = ValueFormatter.DEFAULT_BASE; // unit base value to use (default: 1000) ! private int scaleIndex = ValueFormatter.NO_SCALE; // fixed units exponent value to use ! private BasicStroke borderStroke = null; // defaults to standard beveled border ! private TimeAxisUnit tAxis = null; // custom time axis grid, defaults to no custom ! private ValueAxisUnit vAxis = null; // custom value axis grid, defaults to no custom ! private GridRange gridRange = null; // custom value range definition, defaults to auto-scale // -- Non-settable members ! private int numSdefs = 0; ! private int numDefs = 0; // number of Def datasources added ! private int commentLines = 0; // number of complete lines in the list of comment items ! private int commentLineShift = 0; // modifier to add to get minimum one complete line of comments ! private FetchSourceList fetchSources = new FetchSourceList( 10 ); // holds the list of FetchSources ! private ArrayList cdefList = new ArrayList( 10 ); // holds the list of Cdef datasources ! private ArrayList pdefList = new ArrayList( 10 ); // holds the list of Plottable datasources ! private ArrayList plotDefs = new ArrayList( 10 ); // holds the list of PlotDefs ! private ArrayList comments = new ArrayList( 10 ); // holds the list of comment items *************** *** 210,213 **** --- 211,227 ---- /** + * Sets the 'lazy' flag for this GraphDef. This means that upon graph generation and saving to a file, + * JRobin will first check that if that file already exists, the 'last modified' timestamp + * of the file is smaller than 'last update' timestamp of the used datasources. Only if that is indeed + * the case and the image file is outdated, will the graph be generated. + * + * @param lazyGeneration True if the script should only generate. + */ + public void setLazy( boolean lazyGeneration ) + { + this.lazyGeneration = lazyGeneration; + } + + /** * Sets the resolution with which data will be fetched from the RRD sources. * JRobin will try to match the requested resolution as closely as possible. *************** *** 656,665 **** public void datasource( String name, String file, String dsName, String consolFunc ) throws RrdException { ! if ( fetchSources.containsKey(file) ) { ! FetchSource rf = (FetchSource) fetchSources.get(file); ! rf.addSource( consolFunc, dsName, name ); ! } ! else ! fetchSources.put( file, new FetchSource(file, consolFunc, dsName, name) ); numDefs++; --- 670,674 ---- public void datasource( String name, String file, String dsName, String consolFunc ) throws RrdException { ! fetchSources.add( name, file, dsName, consolFunc ); numDefs++; *************** *** 687,698 **** public void datasource( String name, String file, String dsName, String consolFunc, String backend ) throws RrdException { ! if ( fetchSources.containsKey(file) ) ! { ! FetchSource rf = (FetchSource) fetchSources.get(file); ! rf.setBackendFactory( backend ); ! rf.addSource( consolFunc, dsName, name ); ! } ! else ! fetchSources.put( file, new FetchSource(file, consolFunc, dsName, name, backend ) ); numDefs++; --- 696,700 ---- public void datasource( String name, String file, String dsName, String consolFunc, String backend ) throws RrdException { ! fetchSources.add( name, file, dsName, consolFunc, backend ); numDefs++; *************** *** 700,703 **** --- 702,718 ---- /** + * <p>Clears the list of RRD datasources for this GraphDef and sets it to the FetchSourceList + * passed as aparameter. This does not alter any Cdef, Sdef or Pdef definitions. The datasources + * should be passed on as a FetchSourceList {@see FetchSourceList}.</p> + * @param datasourceList FetchSourceList of the datasources to use. + */ + public void setDatasources( FetchSourceList datasourceList ) + { + fetchSources = datasourceList; + + numDefs = fetchSources.defCount(); + } + + /** * <p>Adds complex graph source with the given name to the graph definition. * Complex graph sources are evaluated using the supplied <code>rpn</code> expression. *************** *** 1086,1094 **** xml.startTag("datasources"); // defs ! Iterator fsIterator = fetchSources.values().iterator(); ! while (fsIterator.hasNext()) { ! FetchSource fs = (FetchSource) fsIterator.next(); ! fs.exportXml(xml); ! } // cdefs and sdefs for (int i = 0; i < cdefList.size(); i++ ) { --- 1101,1106 ---- xml.startTag("datasources"); // defs ! for ( int i = 0; i < fetchSources.size(); i++ ) ! fetchSources.get( i ).exportXml(xml); // cdefs and sdefs for (int i = 0; i < cdefList.size(); i++ ) { *************** *** 1167,1170 **** --- 1179,1186 ---- } + protected boolean isLazy() { + return lazyGeneration; + } + protected Title getTitle() { return title; *************** *** 1350,1354 **** } ! protected HashMap getFetchSources() { return fetchSources; --- 1366,1370 ---- } ! protected FetchSourceList getFetchSources() { return fetchSources; Index: Comment.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Comment.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Comment.java 1 Mar 2004 08:50:25 -0000 1.3 --- Comment.java 9 Jun 2004 07:35:35 -0000 1.4 *************** *** 26,29 **** --- 26,30 ---- import java.util.Vector; + import java.util.ArrayList; import org.jrobin.core.RrdException; *************** *** 61,65 **** protected String text; ! protected Vector oList = new Vector(); --- 62,66 ---- protected String text; ! protected ArrayList oList = new ArrayList(3); *************** *** 226,233 **** /** ! * Retrieves a <code>Vector</code> containing all string/token pairs in order of <code>String</code> - <code>Byte</code>. ! * @return Vector containing all string/token pairs of this Comment. */ ! Vector getTokens() { return oList; --- 227,234 ---- /** ! * Retrieves a <code>ArrayList</code> containing all string/token pairs in order of <code>String</code> - <code>Byte</code>. ! * @return ArrayList containing all string/token pairs of this Comment. */ ! ArrayList getTokens() { return oList; |