View Javadoc

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    * (C) Copyright 2003-2005, by Sasa Markovic.
9    *
10   * Developers:    Sasa Markovic (saxon@jrobin.org)
11   *
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.cmd;
26  
27  import org.jrobin.core.RrdException;
28  import org.jrobin.core.Util;
29  import org.jrobin.core.XmlWriter;
30  import org.jrobin.data.DataProcessor;
31  import org.jrobin.graph.RrdGraphConstants;
32  
33  import java.io.ByteArrayOutputStream;
34  import java.io.IOException;
35  import java.util.ArrayList;
36  import java.util.Date;
37  import java.util.List;
38  
39  class RrdXportCmd extends RrdToolCmd implements RrdGraphConstants {
40  	private DataProcessor dproc;
41  	private List<XPort> xports;
42  
43  	String getCmdType() {
44  		return "xport";
45  	}
46  
47  	Object execute() throws RrdException, IOException {
48  		String startStr = getOptionValue("s", "start", DEFAULT_START);
49  		String endStr = getOptionValue("e", "end", DEFAULT_END);
50  		long span[] = Util.getTimestamps(startStr, endStr);
51  		dproc = new DataProcessor(span[0], span[1]);
52  		xports = new ArrayList<XPort>();
53  		long step = parseLong(getOptionValue(null, "step", "1"));
54  		int maxRows = parseInt(getOptionValue("m", "maxrows", "400"));
55  		long minStep = (long) Math.ceil((span[1] - span[0]) / (double) (maxRows - 1));
56  		step = Math.max(step, minStep);
57  		dproc.setStep(step);
58  		String[] words = getRemainingWords();
59  		if (words.length < 2) {
60  			throw new RrdException("Incomplete XPORT command");
61  		}
62  		for (int i = 1; i < words.length; i++) {
63  			if (words[i].startsWith("DEF:")) {
64  				parseDef(words[i]);
65  			}
66  			else if (words[i].startsWith("CDEF:")) {
67  				parseCDef(words[i]);
68  			}
69  			else if (words[i].startsWith("XPORT:")) {
70  				parseXport(words[i]);
71  			}
72  			else {
73  				throw new RrdException("Invalid XPORT syntax: " + words[i]);
74  			}
75  		}
76  		String result = xports.size() == 0 ? null : xport();
77  		println(xports.size() == 0 ? "No XPORT statement found, nothing done" : result);
78  		return result;
79  	}
80  
81  	private String xport() throws IOException, RrdException {
82  		dproc.processData();
83  		long[] timestamps = dproc.getTimestamps();
84  		for (XPort xport : xports) {
85  			xport.values = dproc.getValues(xport.name);
86  		}
87  		ByteArrayOutputStream stream = new ByteArrayOutputStream();
88  		XmlWriter w = new XmlWriter(stream);
89  		w.startTag("xport");
90  		w.startTag("meta");
91  		w.writeTag("start", timestamps[0]);
92  		w.writeTag("step", timestamps[1] - timestamps[0]);
93  		w.writeTag("end", timestamps[timestamps.length - 1]);
94  		w.writeTag("rows", timestamps.length);
95  		w.writeTag("columns", xports.size());
96  		w.startTag("legend");
97  		for (XPort xport1 : xports) {
98  			w.writeTag("entry", xport1.legend);
99  		}
100 		w.closeTag(); // legend
101 		w.closeTag(); // meta
102 		w.startTag("data");
103 		for (int i = 0; i < timestamps.length; i++) {
104 			w.startTag("row");
105 			w.writeComment(new Date(timestamps[i] * 1000L));
106 			w.writeTag("t", timestamps[i]);
107 			for (XPort xport : xports) {
108 				w.writeTag("v", xport.values[i]);
109 			}
110 			w.closeTag(); // row
111 		}
112 		w.closeTag(); // data
113 		w.closeTag(); // xport
114 		w.flush();
115 		String result = stream.toString();
116 		stream.close();
117 		return result;
118 	}
119 
120 	private void parseDef(String word) throws RrdException {
121 		// DEF:vname=rrd:ds-name:CF
122 		String[] tokens1 = new ColonSplitter(word).split();
123 		if (tokens1.length != 4) {
124 			throw new RrdException("Invalid DEF syntax: " + word);
125 		}
126 		String[] tokens2 = tokens1[1].split("=");
127 		if (tokens2.length != 2) {
128 			throw new RrdException("Invalid DEF syntax: " + word);
129 		}
130 		dproc.addDatasource(tokens2[0], tokens2[1], tokens1[2], tokens1[3]);
131 	}
132 
133 	private void parseCDef(String word) throws RrdException {
134 		// CDEF:vname=rpn-expression
135 		String[] tokens1 = new ColonSplitter(word).split();
136 		if (tokens1.length != 2) {
137 			throw new RrdException("Invalid CDEF syntax: " + word);
138 		}
139 		String[] tokens2 = tokens1[1].split("=");
140 		if (tokens2.length != 2) {
141 			throw new RrdException("Invalid CDEF syntax: " + word);
142 		}
143 		dproc.addDatasource(tokens2[0], tokens2[1]);
144 	}
145 
146 	private void parseXport(String word) throws RrdException {
147 		// XPORT:vname[:legend]
148 		String[] tokens = new ColonSplitter(word).split();
149 		if (tokens.length == 2 || tokens.length == 3) {
150 			XPort xport = new XPort(tokens[1], tokens.length == 3 ? tokens[2] : null);
151 			xports.add(xport);
152 		}
153 		else {
154 			throw new RrdException("Invalid XPORT syntax: " + word);
155 		}
156 	}
157 
158 	static class XPort {
159 		String name, legend;
160 		double[] values;
161 
162 		XPort(String name, String legend) {
163 			this.name = name;
164 			this.legend = legend != null ? legend : "";
165 		}
166 	}
167 }