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
26 package org.jrobin.inspector;
27
28 import org.jrobin.core.*;
29
30 import javax.swing.*;
31 import javax.swing.table.DefaultTableCellRenderer;
32 import javax.swing.filechooser.FileFilter;
33 import javax.swing.event.TreeSelectionListener;
34 import javax.swing.event.TreeSelectionEvent;
35 import javax.swing.tree.TreeSelectionModel;
36 import javax.swing.tree.DefaultMutableTreeNode;
37 import javax.swing.tree.TreePath;
38 import java.awt.*;
39 import java.awt.event.*;
40 import java.io.File;
41 import java.io.IOException;
42
43
44
45
46 public class RrdInspector extends JFrame {
47 private static final long serialVersionUID = 1L;
48 static final boolean SHOULD_CREATE_BACKUPS = true;
49 static final String TITLE = "RRD File Inspector";
50 static final boolean SHOULD_FIX_ARCHIVED_VALUES = false;
51 static final Dimension MAIN_TREE_SIZE = new Dimension(250, 400);
52 static final Dimension INFO_PANE_SIZE = new Dimension(450, 400);
53 static final String ABOUT = "JRobinLite project\nRrdInspector utility\n" +
54 "Copyright (C) 2003-2005 Sasa Markovic. All rights reserved.";
55
56 JTabbedPane tabbedPane = new JTabbedPane();
57 private JTree mainTree = new JTree();
58 private JTable generalTable = new JTable();
59 private JTable datasourceTable = new JTable();
60 private JTable archiveTable = new JTable();
61 private JTable dataTable = new JTable();
62
63 private InspectorModel inspectorModel = new InspectorModel();
64
65 private String lastDirectory = null;
66
67 private RrdInspector(String path) {
68 super(TITLE);
69 constructUI();
70 pack();
71 Util.placeWindow(this);
72 setVisible(true);
73 if (path == null) {
74 selectFile();
75 }
76 else {
77 loadFile(new File(path));
78 }
79 }
80
81 private void constructUI() {
82 JPanel content = (JPanel) getContentPane();
83 content.setLayout(new BorderLayout());
84
85
86 JPanel leftPanel = new JPanel();
87 leftPanel.setLayout(new BorderLayout());
88 JScrollPane treePane = new JScrollPane(mainTree);
89 leftPanel.add(treePane);
90 leftPanel.setPreferredSize(MAIN_TREE_SIZE);
91 content.add(leftPanel, BorderLayout.WEST);
92 mainTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
93 mainTree.addTreeSelectionListener(new TreeSelectionListener() {
94 public void valueChanged(TreeSelectionEvent e) {
95 nodeChangedAction();
96 }
97 });
98 mainTree.setModel(inspectorModel.getMainTreeModel());
99
100
101
102
103
104
105 JScrollPane spGeneral = new JScrollPane(generalTable);
106 spGeneral.setPreferredSize(INFO_PANE_SIZE);
107 tabbedPane.add("General info", spGeneral);
108 generalTable.setModel(inspectorModel.getGeneralTableModel());
109 generalTable.getColumnModel().getColumn(0).setPreferredWidth(150);
110 generalTable.getColumnModel().getColumn(0).setMaxWidth(150);
111
112
113 JScrollPane spDatasource = new JScrollPane(datasourceTable);
114 spDatasource.setPreferredSize(INFO_PANE_SIZE);
115 tabbedPane.add("Datasource info", spDatasource);
116 datasourceTable.setModel(inspectorModel.getDatasourceTableModel());
117 datasourceTable.getColumnModel().getColumn(0).setPreferredWidth(150);
118 datasourceTable.getColumnModel().getColumn(0).setMaxWidth(150);
119
120
121 JScrollPane spArchive = new JScrollPane(archiveTable);
122 archiveTable.setModel(inspectorModel.getArchiveTableModel());
123 archiveTable.getColumnModel().getColumn(0).setPreferredWidth(150);
124 archiveTable.getColumnModel().getColumn(0).setMaxWidth(150);
125 spArchive.setPreferredSize(INFO_PANE_SIZE);
126 tabbedPane.add("Archive info", spArchive);
127
128
129 JScrollPane spData = new JScrollPane(dataTable);
130 dataTable.setModel(inspectorModel.getDataTableModel());
131 dataTable.getColumnModel().getColumn(0).setPreferredWidth(100);
132 dataTable.getColumnModel().getColumn(0).setMaxWidth(100);
133 dataTable.getColumnModel().getColumn(1).setPreferredWidth(150);
134 dataTable.getColumnModel().getColumn(2).setCellRenderer(new DefaultTableCellRenderer() {
135 private static final long serialVersionUID = 1L;
136 {
137 setBackground(Color.YELLOW);
138 }
139 });
140 spData.setPreferredSize(INFO_PANE_SIZE);
141 tabbedPane.add("Archive data", spData);
142
143 content.add(tabbedPane, BorderLayout.CENTER);
144
145
146
147
148 JMenuBar menuBar = new JMenuBar();
149
150
151 JMenu fileMenu = new JMenu("File");
152 fileMenu.setMnemonic(KeyEvent.VK_F);
153
154
155 JMenuItem fileMenuItem = new JMenuItem("Open RRD file...", KeyEvent.VK_O);
156 fileMenuItem.addActionListener(new ActionListener() {
157 public void actionPerformed(ActionEvent e) {
158 selectFile();
159 }
160 });
161 fileMenu.add(fileMenuItem);
162
163
164 JMenuItem fileMenuItem2 = new JMenuItem("Open RRD file in new window...");
165 fileMenuItem2.addActionListener(new ActionListener() {
166 public void actionPerformed(ActionEvent e) {
167 new RrdInspector(null);
168 }
169 });
170 fileMenu.add(fileMenuItem2);
171 fileMenu.addSeparator();
172
173
174 JMenuItem addDatasourceMenuItem = new JMenuItem("Add datasource...");
175 addDatasourceMenuItem.addActionListener(new ActionListener() {
176 public void actionPerformed(ActionEvent e) {
177 addDatasource();
178 }
179 });
180 fileMenu.add(addDatasourceMenuItem);
181
182
183 JMenuItem editDatasourceMenuItem = new JMenuItem("Edit datasource...");
184 editDatasourceMenuItem.addActionListener(new ActionListener() {
185 public void actionPerformed(ActionEvent e) {
186 editDatasource();
187 }
188 });
189 fileMenu.add(editDatasourceMenuItem);
190
191
192 JMenuItem removeDatasourceMenuItem = new JMenuItem("Remove datasource");
193 removeDatasourceMenuItem.addActionListener(new ActionListener() {
194 public void actionPerformed(ActionEvent e) {
195 removeDatasource();
196 }
197 });
198 fileMenu.add(removeDatasourceMenuItem);
199 fileMenu.addSeparator();
200
201
202 JMenuItem addArchiveMenuItem = new JMenuItem("Add archive...");
203 addArchiveMenuItem.addActionListener(new ActionListener() {
204 public void actionPerformed(ActionEvent e) {
205 addArchive();
206 }
207 });
208 fileMenu.add(addArchiveMenuItem);
209
210
211 JMenuItem editArchiveMenuItem = new JMenuItem("Edit archive...");
212 editArchiveMenuItem.addActionListener(new ActionListener() {
213 public void actionPerformed(ActionEvent e) {
214 editArchive();
215 }
216 });
217 fileMenu.add(editArchiveMenuItem);
218
219
220 JMenuItem removeArchiveMenuItem = new JMenuItem("Remove archive...");
221 removeArchiveMenuItem.addActionListener(new ActionListener() {
222 public void actionPerformed(ActionEvent e) {
223 removeArchive();
224 }
225 });
226 fileMenu.add(removeArchiveMenuItem);
227
228
229 JMenuItem plotArchiveMenuItem = new JMenuItem("Plot archive values...");
230 plotArchiveMenuItem.addActionListener(new ActionListener() {
231 public void actionPerformed(ActionEvent e) {
232 plotArchive();
233 }
234 });
235 fileMenu.add(plotArchiveMenuItem);
236 fileMenu.addSeparator();
237
238
239 JMenuItem exitMenuItem = new JMenuItem("Exit", KeyEvent.VK_X);
240 exitMenuItem.addActionListener(new ActionListener() {
241 public void actionPerformed(ActionEvent e) {
242 System.exit(0);
243 }
244 });
245 fileMenu.add(exitMenuItem);
246
247
248 JMenu helpMenu = new JMenu("Help");
249 fileMenu.setMnemonic(KeyEvent.VK_H);
250
251
252 JMenuItem aboutMenuItem = new JMenuItem("About...");
253 aboutMenuItem.addActionListener(new ActionListener() {
254 public void actionPerformed(ActionEvent e) {
255 about();
256 }
257 });
258 helpMenu.add(aboutMenuItem);
259
260 menuBar.add(fileMenu);
261 menuBar.add(helpMenu);
262 setJMenuBar(menuBar);
263
264
265 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
266 addWindowListener(new WindowAdapter() {
267 public void windowClosing(WindowEvent e) {
268 closeWindow();
269 }
270 });
271 }
272
273 private void closeWindow() {
274 Util.dismissWindow(this);
275 }
276
277 private void about() {
278 JOptionPane.showMessageDialog(this, ABOUT, "About", JOptionPane.INFORMATION_MESSAGE);
279 }
280
281 private void nodeChangedAction() {
282 RrdNode rrdNode = getSelectedRrdNode();
283 if (rrdNode != null) {
284 inspectorModel.selectModel(rrdNode.getDsIndex(), rrdNode.getArcIndex());
285 if (rrdNode.getDsIndex() >= 0 && rrdNode.getArcIndex() >= 0) {
286
287 if (tabbedPane.getSelectedIndex() < 2) {
288 tabbedPane.setSelectedIndex(2);
289 }
290 }
291 else if (rrdNode.getDsIndex() >= 0) {
292 tabbedPane.setSelectedIndex(1);
293 }
294 else {
295 tabbedPane.setSelectedIndex(0);
296 }
297 }
298 }
299
300 private RrdNode getSelectedRrdNode() {
301 TreePath path = mainTree.getSelectionPath();
302 if (path != null) {
303 DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
304 Object obj = node.getUserObject();
305 if (obj instanceof RrdNode) {
306 return (RrdNode) obj;
307 }
308 }
309 return null;
310 }
311
312 private void selectFile() {
313 JFileChooser chooser = new JFileChooser(lastDirectory);
314 FileFilter filter = new FileFilter() {
315 public boolean accept(File file) {
316 String path = file.getAbsolutePath().toLowerCase();
317 return file.isDirectory() || path.endsWith(".rrd") ||
318 path.endsWith(".jrb") || path.endsWith(".jrobin");
319 }
320
321 public String getDescription() {
322 return "JRobin RRD files (*.rrd;*.jrb;*.jrobin)";
323 }
324 };
325 chooser.setFileFilter(filter);
326 int returnVal = chooser.showOpenDialog(this);
327 if (returnVal == JFileChooser.APPROVE_OPTION) {
328 File file = chooser.getSelectedFile();
329 if (file != null) {
330 lastDirectory = file.getParent();
331
332
333 loadFile(file);
334 }
335 }
336 }
337
338 private void loadFile(File file) {
339 inspectorModel.setFile(file);
340 tabbedPane.setSelectedIndex(0);
341 }
342
343
344 private void addDatasource() {
345 if (!inspectorModel.isOk()) {
346 Util.error(this, "Open a valid RRD file first.");
347 return;
348 }
349 DsDef newDsDef = new EditDatasourceDialog(this, null).getDsDef();
350 if (newDsDef != null) {
351
352 try {
353 String sourcePath = inspectorModel.getFile().getCanonicalPath();
354 RrdToolkit .addDatasource(sourcePath, newDsDef, SHOULD_CREATE_BACKUPS);
355 inspectorModel.refresh();
356 tabbedPane.setSelectedIndex(0);
357 }
358 catch (IOException e) {
359 Util.error(this, e);
360 }
361 catch (RrdException e) {
362 Util.error(this, e);
363 }
364 }
365 }
366
367 private void addArchive() {
368 if (!inspectorModel.isOk()) {
369 Util.error(this, "Open a valid RRD file first.");
370 return;
371 }
372 ArcDef newArcDef = new EditArchiveDialog(this, null).getArcDef();
373 if (newArcDef != null) {
374
375 try {
376 String sourcePath = inspectorModel.getFile().getCanonicalPath();
377 RrdToolkit.addArchive(sourcePath, newArcDef, SHOULD_CREATE_BACKUPS);
378 inspectorModel.refresh();
379 tabbedPane.setSelectedIndex(0);
380 }
381 catch (IOException e) {
382 Util.error(this, e);
383 }
384 catch (RrdException e) {
385 Util.error(this, e);
386 }
387 }
388 }
389
390 private void editDatasource() {
391 if (!inspectorModel.isOk()) {
392 Util.error(this, "Open a valid RRD file first.");
393 return;
394 }
395 RrdNode rrdNode = getSelectedRrdNode();
396 int dsIndex;
397 if (rrdNode == null || (dsIndex = rrdNode.getDsIndex()) < 0) {
398 Util.error(this, "Select datasource first");
399 return;
400 }
401 try {
402 String sourcePath = inspectorModel.getFile().getCanonicalPath();
403 RrdDb rrd = new RrdDb(sourcePath, true);
404 try {
405 DsDef dsDef = rrd.getRrdDef().getDsDefs()[dsIndex];
406 rrd.close();
407 DsDef newDsDef = new EditDatasourceDialog(this, dsDef).getDsDef();
408 if (newDsDef != null) {
409
410 RrdToolkit.setDsHeartbeat(sourcePath, newDsDef.getDsName(),
411 newDsDef.getHeartbeat());
412 RrdToolkit.setDsMinMaxValue(sourcePath, newDsDef.getDsName(),
413 newDsDef.getMinValue(), newDsDef.getMaxValue(), SHOULD_FIX_ARCHIVED_VALUES);
414 inspectorModel.refresh();
415 tabbedPane.setSelectedIndex(0);
416 }
417 }
418 finally {
419 rrd.close();
420 }
421 }
422 catch (IOException e) {
423 Util.error(this, e);
424 }
425 catch (RrdException e) {
426 Util.error(this, e);
427 }
428 }
429
430 private void editArchive() {
431 if (!inspectorModel.isOk()) {
432 Util.error(this, "Open a valid RRD file first.");
433 return;
434 }
435 RrdNode rrdNode = getSelectedRrdNode();
436 int arcIndex;
437 if (rrdNode == null || (arcIndex = rrdNode.getArcIndex()) < 0) {
438 Util.error(this, "Select archive first");
439 return;
440 }
441 try {
442 String sourcePath = inspectorModel.getFile().getCanonicalPath();
443 RrdDb rrd = new RrdDb(sourcePath, true);
444 try {
445 ArcDef arcDef = rrd.getRrdDef().getArcDefs()[arcIndex];
446 rrd.close();
447 ArcDef newArcDef = new EditArchiveDialog(this, arcDef).getArcDef();
448 if (newArcDef != null) {
449
450
451 RrdToolkit.setArcXff(sourcePath, newArcDef.getConsolFun(),
452 newArcDef.getSteps(), newArcDef.getXff());
453
454 RrdToolkit.resizeArchive(sourcePath, newArcDef.getConsolFun(),
455 newArcDef.getSteps(), newArcDef.getRows(), SHOULD_CREATE_BACKUPS);
456 inspectorModel.refresh();
457 tabbedPane.setSelectedIndex(0);
458 }
459 }
460 finally {
461 rrd.close();
462 }
463 }
464 catch (IOException e) {
465 Util.error(this, e);
466 }
467 catch (RrdException e) {
468 Util.error(this, e);
469 }
470 }
471
472 private void removeDatasource() {
473 if (!inspectorModel.isOk()) {
474 Util.error(this, "Open a valid RRD file first.");
475 return;
476 }
477 RrdNode rrdNode = getSelectedRrdNode();
478 int dsIndex;
479 if (rrdNode == null || (dsIndex = rrdNode.getDsIndex()) < 0) {
480 Util.error(this, "Select datasource first");
481 return;
482 }
483 try {
484 String sourcePath = inspectorModel.getFile().getCanonicalPath(), dsName;
485 RrdDb rrd = new RrdDb(sourcePath, true);
486 try {
487 dsName = rrd.getRrdDef().getDsDefs()[dsIndex].getDsName();
488 }
489 finally {
490 rrd.close();
491 }
492 RrdToolkit.removeDatasource(sourcePath, dsName, SHOULD_CREATE_BACKUPS);
493 inspectorModel.refresh();
494 tabbedPane.setSelectedIndex(0);
495 }
496 catch (IOException e) {
497 Util.error(this, e);
498 }
499 catch (RrdException e) {
500 Util.error(this, e);
501 }
502 }
503
504 private void removeArchive() {
505 if (!inspectorModel.isOk()) {
506 Util.error(this, "Open a valid RRD file first.");
507 return;
508 }
509 RrdNode rrdNode = getSelectedRrdNode();
510 int arcIndex;
511 if (rrdNode == null || (arcIndex = rrdNode.getArcIndex()) < 0) {
512 Util.error(this, "Select archive first");
513 return;
514 }
515 try {
516 String sourcePath = inspectorModel.getFile().getCanonicalPath(), consolFun;
517 int steps;
518 RrdDb rrd = new RrdDb(sourcePath, true);
519 try {
520 ArcDef arcDef = rrd.getRrdDef().getArcDefs()[arcIndex];
521 consolFun = arcDef.getConsolFun();
522 steps = arcDef.getSteps();
523 }
524 finally {
525 rrd.close();
526 }
527 RrdToolkit.removeArchive(sourcePath, consolFun, steps, SHOULD_CREATE_BACKUPS);
528 inspectorModel.refresh();
529 tabbedPane.setSelectedIndex(0);
530 }
531 catch (IOException e) {
532 Util.error(this, e);
533 }
534 catch (RrdException e) {
535 Util.error(this, e);
536 }
537 }
538
539 private void plotArchive() {
540 if (!inspectorModel.isOk()) {
541 Util.error(this, "Open a valid RRD file first.");
542 return;
543 }
544 RrdNode rrdNode = getSelectedRrdNode();
545 int arcIndex;
546 if (rrdNode == null || (arcIndex = rrdNode.getArcIndex()) < 0) {
547 Util.error(this, "Select archive first");
548 return;
549 }
550 String sourcePath = inspectorModel.getFile().getAbsolutePath();
551 int dsIndex = rrdNode.getDsIndex();
552 new GraphFrame(sourcePath, dsIndex, arcIndex);
553 }
554
555 private static void printUsageAndExit() {
556 System.err.println("usage: " + RrdInspector.class.getName() + " [<filename>]");
557 System.exit(1);
558 }
559
560
561
562
563
564
565
566
567
568
569 public static void main(String[] args) {
570 if (args.length > 1) {
571 printUsageAndExit();
572 }
573 String path = (args.length == 1) ? args[0] : null;
574 new RrdInspector(path);
575 }
576 }