KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > graph > ExportData


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org)
7  *
8  * Developers: Sasa Markovic (saxon@jrobin.org)
9  * Arne Vandamme (cobralord@jrobin.org)
10  *
11  * (C) Copyright 2003, by Sasa Markovic.
12  *
13  * This library is free software; you can redistribute it and/or modify it under the terms
14  * of the GNU Lesser General Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License along with this
22  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */

25 package org.jrobin.graph;
26
27 import org.jrobin.core.RrdDataSet;
28 import org.jrobin.core.RrdException;
29 import org.jrobin.core.Util;
30 import org.w3c.dom.Element JavaDoc;
31 import org.w3c.dom.Node JavaDoc;
32
33 import java.util.HashMap JavaDoc;
34 import java.io.*;
35
36 /**
37  * <p>ExportData represents a reduced dataset that is the result of a JRobin rrd export.</p>
38  *
39  * @author Arne Vandamme (cobralord@jrobin.org)
40  */

41 public class ExportData implements RrdDataSet
42 {
43     // ================================================================
44
// -- Members
45
// ================================================================
46
private int arraySize;
47     private long[] timestamps;
48
49     private HashMap JavaDoc sourceByName, legends;
50     private Source[] sources;
51
52     private Print printer;
53
54     // ================================================================
55
// -- Constructors
56
// ================================================================
57
ExportData()
58     {
59         sourceByName = new HashMap JavaDoc();
60         legends = new HashMap JavaDoc();
61     }
62
63     ExportData( long[] timestamps, Source[] sources, HashMap JavaDoc legends )
64     {
65         this.timestamps = timestamps;
66         this.sources = sources;
67         this.legends = legends;
68         this.arraySize = timestamps.length;
69
70         sourceByName = new HashMap JavaDoc( sources.length );
71         for ( int i = 0; i < sources.length; i++ )
72             sourceByName.put( sources[i].getName(), sources[i] );
73     }
74
75     /**
76      * Create an ExportData object based on export XML string..
77      *
78      * @param xportXml File containing export xml.
79      * @throws RrdException Thrown in case of JRobin specific exception.
80      * @throws IOException Thrown in case of I/O related exception.
81      */

82     public ExportData( String JavaDoc xportXml ) throws RrdException, IOException
83     {
84         this();
85
86         importXml( xportXml );
87     }
88
89     /**
90      * Create an ExportData object based on export XML string..
91      *
92      * @param xportXml File containing export xml.
93      * @param useLegendNames Map datasources to legend items in the export xml.
94      * @throws RrdException Thrown in case of JRobin specific exception.
95      * @throws IOException Thrown in case of I/O related exception.
96      */

97     public ExportData( String JavaDoc xportXml, boolean useLegendNames ) throws RrdException, IOException
98     {
99         this();
100
101         importXml( xportXml, useLegendNames );
102     }
103
104     /**
105      * Create an ExportData object based on export XML string..
106      *
107      * @param xportXml File containing export xml.
108      * @param dsNamePrefix Prefix of the datasource names.
109      * @throws RrdException Thrown in case of JRobin specific exception.
110      * @throws IOException Thrown in case of I/O related exception.
111      */

112     public ExportData( String JavaDoc xportXml, String JavaDoc dsNamePrefix ) throws RrdException, IOException
113     {
114         this();
115
116         importXml( xportXml, dsNamePrefix );
117     }
118
119     /**
120      * Create an ExportData object based on export XML file.
121      *
122      * @param xmlFile File containing export xml.
123      * @throws RrdException Thrown in case of JRobin specific exception.
124      * @throws IOException Thrown in case of I/O related exception.
125      */

126     public ExportData( File xmlFile ) throws RrdException, IOException
127     {
128         this();
129
130         importXml( xmlFile );
131     }
132
133     /**
134      * Create an ExportData object based on export XML file.
135      *
136      * @param xmlFile File containing export xml.
137      * @param useLegendNames Map datasources to legend items in the export xml.
138      * @throws RrdException Thrown in case of JRobin specific exception.
139      * @throws IOException Thrown in case of I/O related exception.
140      */

141     public ExportData( File xmlFile, boolean useLegendNames ) throws RrdException, IOException
142     {
143         this();
144
145         importXml( xmlFile, useLegendNames );
146     }
147
148     /**
149      * Create an ExportData object based on export XML file.
150      *
151      * @param xmlFile File containing export xml.
152      * @param dsNamePrefix Prefix of the datasource names.
153      * @throws RrdException Thrown in case of JRobin specific exception.
154      * @throws IOException Thrown in case of I/O related exception.
155      */

156     public ExportData( File xmlFile, String JavaDoc dsNamePrefix ) throws RrdException, IOException
157     {
158         this();
159
160         importXml( xmlFile, dsNamePrefix );
161     }
162
163
164     // ================================================================
165
// -- Public methods
166
// ================================================================
167
/**
168      * Returns the number of rows in this dataset.
169      *
170      * @return Number of rows (data samples).
171      */

172     public int getRowCount() {
173         return sources.length;
174     }
175
176     /**
177      * Returns the number of columns in this dataset.
178      *
179      * @return Number of columns (datasources).
180      */

181     public int getColumnCount() {
182         return arraySize;
183     }
184
185     /**
186      * Returns an array of timestamps covering the whole range specified in the
187      * dataset object.
188      *
189      * @return Array of equidistant timestamps.
190      */

191     public long[] getTimestamps()
192     {
193         return timestamps;
194     }
195
196     /**
197      * Returns the step with which this data was fetched.
198      *
199      * @return Step as long.
200      */

201     public long getStep()
202     {
203         return timestamps[1] - timestamps[0];
204     }
205
206     /**
207      * Returns all values for a single datasource, the returned values
208      * correspond to the timestamps returned with the {@link #getTimestamps() getTimestamps()} method.
209      *
210      * @param dsIndex Datasource index.
211      * @return Array of single datasource values.
212      */

213     public double[] getValues( int dsIndex )
214     {
215         return sources[dsIndex].getValues();
216     }
217
218     /**
219      * Returns all values for all datasources, the returned values
220      * correspond to the timestamps returned with the {@link #getTimestamps() getTimestamps()} method.
221      *
222      * @return Two-dimensional aray of all datasource values.
223      */

224     public double[][] getValues()
225     {
226         double[][] values = new double[ sources.length ][ arraySize ];
227
228         for ( int i = 0; i < sources.length; i++ )
229             values[i] = sources[i].getValues();
230
231         return values;
232     }
233
234     /**
235      * Returns all values for a single datasource. The returned values
236      * correspond to the timestamps returned with the {@link #getTimestamps() getTimestamps()} method.
237      *
238      * @param dsName Datasource name.
239      * @return Array of single datasource values.
240      * @throws RrdException Thrown if no matching datasource name is found.
241      */

242     public double[] getValues( String JavaDoc dsName ) throws RrdException
243     {
244         Source src = getSource( dsName );
245
246         return src.getValues();
247     }
248
249     /**
250      * Returns the first timestamp in the dataset.
251      *
252      * @return The smallest timestamp.
253      */

254     public long getFirstTimestamp() {
255         return timestamps[0];
256     }
257
258     /**
259      * Returns the last timestamp in the dataset.
260      *
261      * @return The biggest timestamp.
262      */

263     public long getLastTimestamp() {
264         return timestamps[ arraySize - 1 ];
265     }
266
267     /**
268      * Returns array of the names of all datasources in the set.
269      *
270      * @return Array of datasource names.
271      */

272     public String JavaDoc[] getDsNames()
273     {
274         String JavaDoc[] names = new String JavaDoc[ sources.length ];
275
276         for ( int i = 0; i < sources.length; i++ )
277             names[i] = sources[i].getName();
278
279         return names;
280     }
281
282     /**
283      * Retrieve the table index number of a datasource by name.
284      * Names are case sensitive.
285      *
286      * @param dsName Name of the datasource for which to find the index.
287      * @return Index number of the datasource in the value table.
288      * @throws RrdException Thrown if the given datasource name cannot be found in the dataset.
289      */

290     public int getDsIndex( String JavaDoc dsName ) throws RrdException
291     {
292         for ( int i = 0; i < sources.length; i++ )
293             if ( sources[i].getName().equals(dsName) )
294                 return i;
295
296         throw new RrdException( "No such datasource: " + dsName );
297     }
298
299     /**
300      * Returns aggregated value from the dataset for a single datasource.
301      *
302      * @param dsName Datasource name
303      * @param consolFun Consolidation function to be applied to set datasource values datasource.
304      * Valid consolidation functions are MIN, MAX, LAST, FIRST, AVERAGE and TOTAL
305      * @return MIN, MAX, LAST, FIRST, AVERAGE or TOTAL value calculated from the dataset for the given datasource name
306      * @throws RrdException Thrown if the given datasource name cannot be found in the dataset.
307      */

308     public double getAggregate( String JavaDoc dsName, String JavaDoc consolFun ) throws RrdException
309     {
310         Source src = getSource( dsName );
311
312         if( consolFun.equalsIgnoreCase("MAX") )
313             return src.getAggregate( Source.AGG_MAXIMUM );
314         else if ( consolFun.equalsIgnoreCase("MIN") )
315             return src.getAggregate( Source.AGG_MINIMUM );
316         else if ( consolFun.equalsIgnoreCase("LAST") )
317             return src.getAggregate( Source.AGG_LAST);
318         else if ( consolFun.equalsIgnoreCase("FIRST") )
319             return src.getAggregate( Source.AGG_FIRST );
320         else if ( consolFun.equalsIgnoreCase("TOTAL") )
321             return src.getAggregate( Source.AGG_TOTAL );
322         else if ( consolFun.equalsIgnoreCase("AVERAGE") )
323             return src.getAggregate( Source.AGG_AVERAGE );
324         else
325             throw new RrdException("Unsupported consolidation function [" + consolFun + "]");
326     }
327
328     /**
329      * <p>Calculate the chosen consolidation function <code>consolFun</code> over
330      * the <code>sourceName</code> and returns the result as a string using the
331      * specified <code>format</code>.</p>
332      *
333      * <p>In the format string there should be a
334      * <code>@n.d</code> marker (replace <code>n</code> with the total number of spaces the
335      * value should at minimum take up, and replace <code>d</code> with the desired number of decimals)
336      * in the place where the number should be printed. If an additional <code>@s</code> is
337      * found in the format, the value will be scaled and an appropriate SI magnitude
338      * unit will be printed in place of the <code>@s</code> marker. If you specify
339      * <code>@S</code> instead of <code>@s</code>, the value will be scaled with the scale
340      * factor used in the last gprint directive (uniform value scaling).</p>
341      *
342      * @param sourceName Source name
343      * @param consolFun Consolidation function to be used for calculation ("AVERAGE",
344      * "MIN", "MAX", "LAST" or "TOTAL" (since 1.3.1)
345      * @param format Format string. For example: "speed is @5.2 @sbits/sec@c",
346      * "temperature = @0 degrees"
347      * @throws RrdException Thrown in case of JRobin specific error
348      */

349     public String JavaDoc print( String JavaDoc sourceName, String JavaDoc consolFun, String JavaDoc format ) throws RrdException {
350         return print( sourceName, consolFun, format, ValueFormatter.DEFAULT_BASE );
351     }
352
353     /**
354      * <p>Calculate the chosen consolidation function <code>consolFun</code> over
355      * the <code>sourceName</code> and returns the result as a string using the
356      * specified <code>format</code>.</p>
357      *
358      * <p>In the format string there should be a
359      * <code>@n.d</code> marker (replace <code>n</code> with the total number of spaces the
360      * value should at minimum take up, and replace <code>d</code> with the desired number of decimals)
361      * in the place where the number should be printed. If an additional <code>@s</code> is
362      * found in the format, the value will be scaled and an appropriate SI magnitude
363      * unit will be printed in place of the <code>@s</code> marker. If you specify
364      * <code>@S</code> instead of <code>@s</code>, the value will be scaled with the scale
365      * factor used in the last gprint directive (uniform value scaling).</p>
366      *
367      * @param sourceName Source name
368      * @param consolFun Consolidation function to be used for calculation ("AVERAGE",
369      * "MIN", "MAX", "LAST" or "TOTAL" (since 1.3.1)
370      * @param format Format string. For example: "speed is @5.2 @sbits/sec@c",
371      * "temperature = @0 degrees"
372      * @param base Base value used to calculate the appriopriate scaling SI magnitude.
373      * @throws RrdException Thrown in case of JRobin specific error
374      */

375     public String JavaDoc print( String JavaDoc sourceName, String JavaDoc consolFun, String JavaDoc format, double base ) throws RrdException
376     {
377         double value = getAggregate( sourceName, consolFun );
378
379         if ( printer == null )
380             printer = new Print( base, ValueFormatter.NO_SCALE );
381
382         return printer.getFormattedString( value, format, base );
383     }
384
385     /**
386      * Imports a export XML string and maps it back to this ExportData object.
387      * The XML can be from either a JRobin or RRDtool export.
388      *
389      * Datasources found will be named d1, d2, ...
390      *
391      * @param xportXml String containing the XML result of an export.
392      */

393     public void importXml( String JavaDoc xportXml ) throws RrdException, IOException {
394         importXml( xportXml, true );
395     }
396
397     /**
398      * Imports a export XML string and maps it back to this ExportData object.
399      * The XML can be from either a JRobin or RRDtool export.
400      *
401      * Datasources found will be named d1, d2, ...
402      *
403      * @param xmlFile File containing export XML dump.
404      */

405     public void importXml( File xmlFile ) throws RrdException, IOException {
406         importXml( xmlFile, true );
407     }
408
409     /**
410      * Imports a export XML string and maps it back to this ExportData object.
411      * The XML can be from either a JRobin or RRDtool export.
412      *
413      * The name of the datasources found will depend on the 'useLegendNames' flag.
414      *
415      * @param xmlFile File containing export XML dump.
416      * @param useLegendNames True if the names for the datasources should be set to
417      * the legend values, false if they should be d1, d2, ...
418      */

419     public void importXml( File xmlFile , boolean useLegendNames ) throws RrdException, IOException
420     {
421         Element JavaDoc root = Util.Xml.getRootElement( xmlFile );
422         importXml( root, useLegendNames, "d" );
423     }
424
425     /**
426      * Imports a export XML string and maps it back to this ExportData object.
427      * The XML can be from either a JRobin or RRDtool export.
428      *
429      * The name of the datasources found will be the prefix passed as parameter,
430      * followed by a number, making the name unique.
431      *
432      * @param xportXml String containing the XML result of an export.
433      * @param dsNamePrefix Prefix of the datasource names.
434      */

435     public void importXml( String JavaDoc xportXml, String JavaDoc dsNamePrefix ) throws RrdException, IOException
436     {
437         Element JavaDoc root = Util.Xml.getRootElement( xportXml );
438         importXml( root, false, dsNamePrefix );
439     }
440
441     /**
442      * Imports a export XML string and maps it back to this ExportData object.
443      * The XML can be from either a JRobin or RRDtool export.
444      *
445      * The name of the datasources found will be the prefix passed as parameter,
446      * followed by a number, making the name unique.
447      *
448      * @param xmlFile File containing export XML dump.
449      * @param dsNamePrefix Prefix of the datasource names.
450      */

451     public void importXml( File xmlFile, String JavaDoc dsNamePrefix ) throws RrdException, IOException
452     {
453         Element JavaDoc root = Util.Xml.getRootElement( xmlFile );
454         importXml( root, false, dsNamePrefix );
455     }
456
457     /**
458      * Imports a export XML string and maps it back to this ExportData object.
459      * The XML can be from either a JRobin or RRDtool export.
460      *
461      * The name of the datasources found will depend on the 'useLegendNames' flag.
462      *
463      * @param xportXml String containing the XML result of an export.
464      * @param useLegendNames True if the names for the datasources should be set to
465      * the legend values, false if they should be d1, d2, ...
466      */

467     public void importXml( String JavaDoc xportXml, boolean useLegendNames ) throws RrdException, IOException
468     {
469         Element JavaDoc root = Util.Xml.getRootElement( xportXml );
470         importXml( root, useLegendNames, "d" );
471     }
472
473     /**
474      * Dumps fetch data to output stream in XML format.
475      *
476      * @param outputStream Output stream to dump dataset to
477      * @throws RrdException Thrown in case of JRobin specific error.
478      * @throws IOException Thrown in case of I/O error
479      */

480     public void exportXml( OutputStream outputStream ) throws RrdException, IOException
481     {
482         PrintWriter pw = new PrintWriter( outputStream );
483         pw.write( exportXml() );
484         pw.flush();
485     }
486
487     /**
488      * Dumps dataset to file in XML format.
489      *
490      * @param filepath Path to destination file
491      * @throws RrdException Thrown in case of JRobin specific error.
492      * @throws IOException Thrown in case of I/O error
493      */

494     public void exportXml( String JavaDoc filepath ) throws RrdException, IOException
495     {
496         FileWriter fw = new FileWriter( filepath );
497         fw.write( exportXml() );
498         fw.close();
499     }
500
501     /**
502      * Dumps the dataset to XML.
503      *
504      * @return XML string format of the dataset.
505      * @throws RrdException Thrown in case of JRobin specific error.
506      * @throws java.io.IOException Thrown in case of an I/O related error.
507      */

508     public String JavaDoc exportXml() throws RrdException, IOException
509     {
510         StringBuffer JavaDoc xml = new StringBuffer JavaDoc( "<xport>\n" );
511
512         // Add metadata section
513
xml.append( "\t<meta>\n" );
514         xml.append( "\t\t<start>" + timestamps[0] + "</start>\n" );
515         xml.append( "\t\t<step>" + (timestamps[1] - timestamps[0]) + "</step>\n" );
516         xml.append( "\t\t<end>" + timestamps[arraySize - 1] + "</end>\n" );
517         xml.append( "\t\t<rows>" + arraySize + "</rows>\n" );
518         xml.append( "\t\t<columns>" + sources.length + "</columns>\n" );
519         xml.append( "\t\t<legend>\n" );
520         for ( int i = 0; i < sources.length; i++ )
521             xml.append( "\t\t\t<entry>" + getExportLegend( sources[i].getName() ) + "</entry>\n" );
522         xml.append( "\t\t</legend>\n" );
523         xml.append( "\t</meta>\n" );
524
525         // Add data section
526
xml.append( "\t<data>\n" );
527
528         for ( int i = 0; i < arraySize; i++ )
529         {
530             xml.append( "\t\t<row>" );
531             xml.append( "<t>" + timestamps[i] + "</t>" );
532             for ( int j = 0; j < sources.length; j++ )
533                 xml.append( "<v>" + sources[ j ].get( i ) + "</v>" );
534             xml.append( "</row>\n" );
535         }
536         xml.append( "\t</data>\n" );
537
538         xml.append( "</xport>\n" );
539
540         return xml.toString();
541     }
542
543     // ================================================================
544
// -- Protected methods
545
// ================================================================
546
protected Source[] getSources() {
547         return sources;
548     }
549
550     // ================================================================
551
// -- Private methods
552
// ================================================================
553
private String JavaDoc getExportLegend( String JavaDoc name )
554     {
555         if ( !legends.containsKey(name) )
556             return "";
557
558         return (String JavaDoc) legends.get(name);
559     }
560
561     private Source getSource( String JavaDoc name ) throws RrdException
562     {
563         if ( !sourceByName.containsKey(name) )
564             throw new RrdException( "No such datasource: " + name );
565
566         return (Source) sourceByName.get(name);
567     }
568
569     private void importXml( Element JavaDoc root, boolean useLegendNames, String JavaDoc dsNamePrefix ) throws RrdException
570     {
571         Node JavaDoc meta = Util.Xml.getFirstChildNode( root, "meta" );
572         Node JavaDoc[] dataRows = Util.Xml.getChildNodes( Util.Xml.getFirstChildNode( root, "data" ), "row" );
573
574         sourceByName.clear();
575         legends.clear();
576
577         // -- Parse the metadata
578
int columns = Util.Xml.getChildValueAsInt( meta, "columns" );
579         long step = Util.Xml.getChildValueAsLong( meta, "step" );
580         String JavaDoc[] dsNames = new String JavaDoc[ columns ];
581         Node JavaDoc[] legendNodes = Util.Xml.getChildNodes( Util.Xml.getFirstChildNode( meta, "legend"), "entry" );
582         for ( int i = 0; i < legendNodes.length; i++ )
583         {
584             String JavaDoc legend = Util.Xml.getValue( legendNodes[i] );
585             if ( useLegendNames )
586                 dsNames[i] = legend;
587             else
588                 dsNames[i] = dsNamePrefix + (i + 1);
589
590             legends.put( dsNames[i], legend );
591         }
592
593         // -- Parse the data
594
timestamps = new long[ dataRows.length ];
595         sources = new Source[ columns ];
596         arraySize = timestamps.length;
597
598         for ( int i = 0; i < sources.length; i++ )
599         {
600             sources[i] = new Def( dsNames[i], arraySize, arraySize );
601             sources[i].setFetchedStep( step );
602         }
603
604         for ( int i = 0; i < dataRows.length; i++ )
605         {
606             timestamps[i] = Util.Xml.getChildValueAsLong( dataRows[i], "t" );
607             Node JavaDoc[] data = Util.Xml.getChildNodes( dataRows[i], "v" );
608
609             for ( int j = 0; j < data.length; j++ )
610                 sources[j].set( i, timestamps[i], Util.Xml.getValueAsDouble(data[j]) );
611         }
612
613         // -- Set the datasource - name
614
for ( int i = 0; i < sources.length; i++ )
615             sourceByName.put( sources[i].getName(), sources[i] );
616     }
617 }
618
Popular Tags