1 package org.jrobin.graph; 2 3 import org.jrobin.core.RrdException; 4 5 import java.awt.*; 6 7 14 public class RrdtoolGraph 15 { 16 private static final int SAVE_PNG = 0; 20 private static final int SAVE_GIF = 1; 21 22 private static final int DS_DEF = 0; 23 private static final int DS_CDEF = 1; 24 25 private static final int TXT_COMMENT = 0; 26 private static final int TXT_GPRINT = 1; 27 28 private static final int GRAPH_LINE = 0; 29 private static final int GRAPH_AREA = 1; 30 private static final int GRAPH_STACK = 2; 31 32 private static final int TKN_IGNORE = -2; 33 private static final int TKN_UNKNOWN = -1; 34 private static final int TKN_RRDTOOL = 0; 35 private static final int TKN_GRAPH = 1; 36 private static final int TKN_START = 2; 37 private static final int TKN_END = 3; 38 private static final int TKN_COMMENT = 4; 39 private static final int TKN_LINE = 5; 40 private static final int TKN_AREA = 6; 41 private static final int TKN_STACK = 7; 42 private static final int TKN_CDEF = 8; 43 private static final int TKN_DEF = 9; 44 private static final int TKN_GPRINT = 11; 45 private static final int TKN_HRULE = 12; 46 private static final int TKN_VRULE = 13; 47 private static final int TKN_STEP = 14; 48 private static final int TKN_TITLE = 15; 49 private static final int TKN_NOLEGEND = 16; 50 private static final int TKN_COLOR = 17; 51 private static final int TKN_RIGID = 18; 52 private static final int TKN_LOWERLIMIT = 19; 53 private static final int TKN_UPPERLIMIT = 20; 54 private static final int TKN_LAZY = 21; 55 private static final int TKN_OVERLAY = 23; 56 private static final int TKN_BACKGROUND = 24; 57 private static final int TKN_IMGFORMAT = 25; 58 private static final int TKN_WIDTH = 26; 59 private static final int TKN_HEIGHT = 27; 60 private static final int TKN_VERT_LABEL = 28; 61 private static final int TKN_UNITS_EXP = 29; 62 private static final int TKN_NOMINOR = 30; 63 private static final int TKN_XGRID = 31; 64 private static final int TKN_YGRID = 32; 65 private static final int TKN_BASE = 33; 66 67 68 private String token = ""; 72 private String script = null; 73 private RrdGraphDef graphDef = null; 74 75 private int tokenPos = 0; 76 private char[] parseCmd = new char[0]; 77 78 private boolean gridRigid = false; 79 private double gridLower = Double.MAX_VALUE; 80 private double gridUpper = Double.MIN_VALUE; 81 82 private int width = 0; 83 private int height = 0; 84 private int fileType = SAVE_PNG; 85 private String fileName = ""; 86 87 public RrdtoolGraph( String script ) 91 { 92 this.script = script; 93 } 94 95 96 public RrdGraphDef getRrdGraphDef() throws RrdException 100 { 101 parseRrdtoolScript(); 102 103 return graphDef; 104 } 105 106 107 115 private boolean parseRrdtoolScript() throws RrdException 116 { 117 long startTime = 0, stopTime = 0; 118 119 graphDef = new RrdGraphDef(); 120 121 parseCmd = script.replace( '\n', ' ' ).replace( '\r', ' ' ).replace( '\t', ' ' ).toCharArray(); 123 124 while ( nextToken() > 0 ) 125 { 126 System.err.println( token ); 127 switch ( parseToken( token ) ) 128 { 129 case TKN_RRDTOOL: break; 131 132 case TKN_GRAPH: nextToken(); 134 break; 135 136 case TKN_START: nextToken(); 138 startTime = Long.parseLong( token ); 139 break; 140 141 case TKN_END: nextToken(); 143 stopTime = Long.parseLong( token ); 144 break; 145 146 case TKN_NOMINOR: graphDef.setMinorGridX( false ); 148 graphDef.setMinorGridY( false ); 149 break; 150 151 case TKN_WIDTH: nextToken(); 153 width = Integer.parseInt( token ); 154 break; 155 156 case TKN_HEIGHT: nextToken(); 158 height = Integer.parseInt( token ); 159 break; 160 161 case TKN_UNITS_EXP: nextToken(); 163 graphDef.setUnitsExponent( Integer.parseInt( token ) ); 164 break; 165 166 case TKN_VERT_LABEL: nextToken(); 168 graphDef.setVerticalLabel( unescape(token) ); 169 break; 170 171 case TKN_TITLE: nextToken(); 173 graphDef.setTitle( unescape(token) ); 174 break; 175 176 case TKN_IMGFORMAT: nextToken(); 178 if ( token.equalsIgnoreCase("gif") ) 179 fileType = SAVE_GIF; 180 break; 181 182 case TKN_BACKGROUND: nextToken(); 184 graphDef.setBackground( unescape(token) ); 185 break; 186 187 case TKN_OVERLAY: nextToken(); 189 graphDef.setOverlay( unescape(token) ); 190 break; 191 192 case TKN_NOLEGEND: graphDef.setShowLegend( false ); 194 break; 195 196 case TKN_LOWERLIMIT: nextToken(); 198 gridLower = Double.parseDouble(token); 199 break; 200 201 case TKN_UPPERLIMIT: nextToken(); 203 gridUpper = Double.parseDouble(token); 204 break; 205 206 case TKN_RIGID: gridRigid = true; 208 break; 209 210 case TKN_BASE: nextToken(); 212 graphDef.setBaseValue( Double.parseDouble(token) ); 213 break; 214 215 case TKN_COMMENT: 216 parseTextCommand( TXT_COMMENT ); 217 break; 218 219 case TKN_GPRINT: 220 parseTextCommand( TXT_GPRINT ); 221 break; 222 223 case TKN_LINE: 224 parseGraphCommand( GRAPH_LINE ); 225 break; 226 227 case TKN_AREA: 228 parseGraphCommand( GRAPH_AREA ); 229 break; 230 231 case TKN_STACK: 232 parseGraphCommand( GRAPH_STACK ); 233 break; 234 235 case TKN_DEF: 236 parseDatasource( DS_DEF ); 237 break; 238 239 case TKN_CDEF: 240 parseDatasource( DS_CDEF ); 241 break; 242 243 case TKN_IGNORE: break; 245 246 case TKN_UNKNOWN: 247 throw new RrdException( "Unknown token: " + token ); 248 } 249 } 250 251 if ( gridRigid || ( gridLower == Double.MAX_VALUE ) || ( gridUpper == Double.MIN_VALUE ) ) 253 graphDef.setGridRange( gridLower, gridUpper, gridRigid ); 254 255 return true; 256 } 257 258 263 private void parseGraphCommand( int type ) throws RrdException 264 { 265 if ( type == GRAPH_LINE ) 266 { 267 int w = Integer.parseInt( "" + token.charAt( 4 ) ); 268 269 int pos = token.indexOf( '#', 6 ); 271 int npos = token.indexOf( ':', 6 ); 272 if ( pos < 0 ) pos = npos; 273 274 String ds = ( pos > 0 ? token.substring( 6, pos ) : token.substring( 6 ) ); 275 Color color = null; 276 String legend = null; 277 278 if ( pos > 0 && token.charAt(pos) == '#' ) 280 color = Color.decode( npos > 0 ? token.substring( pos, npos ) : token.substring( pos ) ); 281 282 if ( npos > 0 ) 284 legend = unescape( token.substring( npos + 1 ) ); 285 286 graphDef.line( ds, color, legend, w ); 287 } 288 else 289 { 290 if ( type == GRAPH_STACK ) 291 token = token.substring( 6 ); 292 else 293 token = token.substring( 5 ); 294 295 int pos = token.indexOf( '#' ); 296 int npos = token.indexOf( ':' ); 297 298 String ds = ( pos > 0 ? token.substring( 0, pos ) : token.substring( 0 ) ); 299 Color color = null; 300 String legend = null; 301 302 if ( pos > 0 && token.charAt(pos) == '#' ) 304 color = Color.decode( npos > 0 ? token.substring( pos, npos ) : token.substring( pos ) ); 305 306 if ( npos > 0 ) 308 legend = unescape( token.substring( npos + 1 ) ); 309 310 if ( type == GRAPH_AREA ) 311 graphDef.area( ds, color, legend ); 312 else if ( type == GRAPH_STACK ) 313 graphDef.stack( ds, color, legend ); 314 } 315 } 316 317 322 private String unescape( String text ) 323 { 324 if ( text.startsWith( "'" ) || text.startsWith( "\"" ) ) 325 return text.substring( 1, text.length() - 1 ); 326 327 return text; 328 } 329 330 335 private void parseTextCommand( int type ) throws RrdException 336 { 337 int pos = token.indexOf( ':' ); 338 339 if ( type == TXT_COMMENT ) 340 { 341 String text = unescape( token.substring( pos + 1 ) ); 342 343 graphDef.comment( text ); 344 } 345 else if ( type == TXT_GPRINT ) 346 { 347 int npos = token.indexOf( ':', ++pos ); 349 350 String ds = token.substring( pos, npos ); 351 pos = token.indexOf( ':', ++npos ); 352 353 String cf = token.substring( npos, pos ); 354 String text = unescape( token.substring( pos + 1 ) ); 355 356 } 359 } 360 361 366 private void parseDatasource( int type ) throws RrdException 367 { 368 int pos = token.indexOf( ':' ); 370 int npos = token.indexOf( '=', ++pos ); 371 372 String name = token.substring( pos, npos ); 373 374 if ( type == DS_DEF ) 375 { 376 token = token.substring( npos + 1 ); 378 379 pos = token.lastIndexOf( ':' ); 381 String cf = token.substring( pos + 1 ); 382 383 npos = token.lastIndexOf( ':', pos - 1 ); 384 String dsName = token.substring( npos + 1, pos ); 385 String rrdFile = token.substring( 0, npos ); 386 387 graphDef.datasource( name, rrdFile, dsName, cf ); 388 } 389 else 390 { 391 graphDef.datasource( name, token.substring( npos + 1 ) ); 393 } 394 } 395 396 401 private int nextToken() 402 { 403 char[] tknChars = new char[512]; 404 int charPos = 0; 405 int cmdPos = tokenPos; 406 boolean found = false; 407 408 boolean stringComplete = true; 409 char findChar = ' '; 410 411 415 while ( charPos < 512 && (cmdPos < parseCmd.length) && !found ) 416 { 417 if ( parseCmd[cmdPos] == '"' ) 418 { 419 if ( stringComplete ) { 420 stringComplete = false; 421 findChar = '"'; 422 } 423 else if ( findChar == '"' && !(parseCmd[cmdPos - 1] == '\\') ) 424 stringComplete = true; 425 } 426 else if ( parseCmd[cmdPos] == '\'' ) 427 { 428 if ( stringComplete ) { 429 stringComplete = false; 430 findChar = '\''; 431 } 432 else if ( findChar == '\'' && !(parseCmd[cmdPos - 1] == '\\') ) 433 stringComplete = true; 434 } 435 if ( stringComplete && parseCmd[cmdPos] == ' ' ) 436 found = true; 437 else 438 tknChars[charPos++] = parseCmd[cmdPos++]; 439 } 440 441 token = new String ( tknChars, 0, charPos ).trim(); 442 443 tokenPos = cmdPos + 1; 444 445 return charPos; 446 } 447 448 453 private int parseToken( String token ) 454 { 455 if ( token.equalsIgnoreCase("rrdtool") ) 456 return TKN_RRDTOOL; 457 458 if ( token.equalsIgnoreCase("graph") ) 459 return TKN_GRAPH; 460 461 if ( token.equalsIgnoreCase("--start") || token.equals("-s") ) 462 return TKN_START; 463 464 if ( token.equalsIgnoreCase("--end") || token.equals("-e") ) 465 return TKN_END; 466 467 if ( token.equalsIgnoreCase("--width") || token.equals("-w") ) 468 return TKN_WIDTH; 469 470 if ( token.equalsIgnoreCase("--height") || token.equals("-h") ) 471 return TKN_HEIGHT; 472 473 if ( token.equalsIgnoreCase("--no-minor") ) 474 return TKN_NOMINOR; 475 476 if ( token.equalsIgnoreCase("--units-exponent") || token.equals("-X") ) 477 return TKN_UNITS_EXP; 478 479 if ( token.equalsIgnoreCase("--vertical-label") || token.equals("-v") ) 480 return TKN_VERT_LABEL; 481 482 if ( token.equalsIgnoreCase("--imgformat") || token.equals("-a") ) 483 return TKN_IMGFORMAT; 484 485 if ( token.equalsIgnoreCase("--background") || token.equals("-B") ) 486 return TKN_BACKGROUND; 487 488 if ( token.equalsIgnoreCase("--overlay") || token.equals("-O") ) 489 return TKN_OVERLAY; 490 491 if ( token.equalsIgnoreCase("--title") || token.equals("-t") ) 492 return TKN_TITLE; 493 494 if ( token.equalsIgnoreCase("--step") || token.equals("-S") ) 495 return TKN_STEP; 496 497 if ( token.equalsIgnoreCase("--no-legend") || token.equals("-g") ) 498 return TKN_NOLEGEND; 499 500 if ( token.equalsIgnoreCase("--base") || token.equals("-b") ) 501 return TKN_BASE; 502 503 if ( token.equalsIgnoreCase("--lower-limit") || token.equals("-l") ) 504 return TKN_LOWERLIMIT; 505 506 if ( token.equalsIgnoreCase("--upper-limit") || token.equals("-u") ) 507 return TKN_UPPERLIMIT; 508 509 if ( token.equalsIgnoreCase("--rigid") || token.equals("-r") ) 510 return TKN_RIGID; 511 512 if ( token.startsWith("COMMENT") ) 513 return TKN_COMMENT; 514 515 if ( token.startsWith("GPRINT") ) 516 return TKN_GPRINT; 517 518 if ( token.startsWith("LINE") ) 519 return TKN_LINE; 520 521 if ( token.startsWith("AREA") ) 522 return TKN_AREA; 523 524 if ( token.startsWith("STACK") ) 525 return TKN_STACK; 526 527 if ( token.startsWith("HRULE") ) 528 return TKN_HRULE; 529 530 if ( token.startsWith("VRULE") ) 531 return TKN_VRULE; 532 533 if ( token.startsWith("CDEF") ) 534 return TKN_CDEF; 535 536 if ( token.startsWith("DEF") ) 537 return TKN_DEF; 538 539 if ( token.equals("-Y") || token.equals("--alt-y-grid") || token.equals("-R") || token.equals("--alt-y-mrtg") 540 || token.equals("-A") || token.equals("--alt-autoscale") || token.equals("-M") 541 || token.equals("--alt-autoscale-max") || token.equals("-L") 542 || token.equals("--units-length") || token.equals("-i") || token.equals("--interlaced") 543 || token.equals("-f") || token.equals("--imginfo") || token.equals("-o") 544 || token.equals("--logarithmic") || token.equals("-j") || token.equals("--only-graph") 545 || token.equals("-F") || token.equals("--force-rules-legend") || token.startsWith("PRINT") 546 || token.equals("-U") || token.startsWith("--unit") ) 547 return TKN_IGNORE; 548 549 return TKN_UNKNOWN; 550 } 551 552 553 public static void main( String [] args ) throws Exception 554 { 555 String str = "rrdtool graph FNAME --start 100 --end 700\n" 556 + "DEF:inOctets=c:/file.rrd:test-run:AVERAGE " 557 + "CDEF:bitIn=inOctets,8,* " 558 + "COMMENT:'commentaar \"nr\" 1'\n" 559 + "AREA:test#ffa9b3:'this is the legend'\n" 560 + "COMMENT:\"commentaar 'nr' 2\"\n" 561 + "LINE2:test2:'this is the legend two' " 562 + "GPRINT:bitIn:AVG:'Average %2.5'"; 563 564 RrdtoolGraph rg = new RrdtoolGraph( str ); 565 566 rg.getRrdGraphDef(); 567 } 568 } 569 | Popular Tags |