1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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();
101 w.closeTag();
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();
111 }
112 w.closeTag();
113 w.closeTag();
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
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
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
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 }