1 package net.logAnalyzer.gui.messages;
2
3 import java.awt.BorderLayout;
4 import java.awt.Dimension;
5 import java.awt.GridLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.util.Hashtable;
9
10 import javax.swing.JButton;
11 import javax.swing.JComboBox;
12 import javax.swing.JPanel;
13 import javax.swing.JScrollPane;
14 import javax.swing.JSeparator;
15 import javax.swing.JTextField;
16 import javax.swing.JToolBar;
17 import javax.swing.JTree;
18 import javax.swing.event.TreeSelectionEvent;
19 import javax.swing.event.TreeSelectionListener;
20 import javax.swing.tree.DefaultMutableTreeNode;
21 import javax.swing.tree.DefaultTreeModel;
22 import javax.swing.tree.TreeNode;
23
24 import net.logAnalyzer.converters.LAConverter;
25 import net.logAnalyzer.gui.messages.filters.AndFilter;
26 import net.logAnalyzer.gui.messages.filters.ContainsFilter;
27 import net.logAnalyzer.gui.messages.filters.EqualFilter;
28 import net.logAnalyzer.gui.messages.filters.GreaterFilter;
29 import net.logAnalyzer.gui.messages.filters.LAMessagesFilter;
30 import net.logAnalyzer.gui.messages.filters.LowerFilter;
31 import net.logAnalyzer.gui.messages.filters.NotFilter;
32 import net.logAnalyzer.gui.messages.filters.OperatorFilter;
33 import net.logAnalyzer.gui.messages.filters.OrFilter;
34 import net.logAnalyzer.gui.messages.filters.StartWithFilter;
35 import net.logAnalyzer.gui.messages.filters.UnaryFilter;
36 import net.logAnalyzer.gui.messages.filters.YesFilter;
37 import net.logAnalyzer.handlers.LALogHandler;
38 import net.logAnalyzer.handlers.LALogHandlerListener;
39 import net.logAnalyzer.resources.LAResourceBundle;
40
41 public class FiltersManager extends JPanel implements ActionListener,
42 TreeSelectionListener, LALogHandlerListener {
43 private static final long serialVersionUID = 1L;
44
45 /***
46 * View displaying the tree.
47 */
48 private FilteredMessagesView view;
49
50 /***
51 * View attributes.
52 */
53 private Hashtable attributes;
54
55 /***
56 * Filters tree.
57 */
58 private JTree filtersTree;
59
60 /***
61 * Converters list.
62 */
63 private JComboBox convertersList;
64
65 private static final String FILTER_TYPE_EQUAL = "x = y";
66
67 private static final String FILTER_TYPE_GREATER = "x > y";
68
69 private static final String FILTER_TYPE_LOWER = "x < y";
70
71 private static final String FILTER_TYPE_START = "START WITH";
72
73 private static final String FILTER_TYPE_CONTAINS = "CONTAINS";
74
75 private static final String FILTER_TYPE_AND = "AND";
76
77 private static final String FILTER_TYPE_OR = "OR";
78
79 private static final String FILTER_TYPE_NOT = "NOT";
80
81 /***
82 * Filters types list.
83 */
84 private JComboBox filtersList = new JComboBox(new String[] {
85 FILTER_TYPE_EQUAL, FILTER_TYPE_GREATER, FILTER_TYPE_LOWER,
86 FILTER_TYPE_START, FILTER_TYPE_CONTAINS, FILTER_TYPE_AND,
87 FILTER_TYPE_OR, FILTER_TYPE_NOT });
88
89 /***
90 * Input for filters check value.
91 */
92 private JTextField checkValue;
93
94 /***
95 * Tree model.
96 */
97 private DefaultTreeModel treeModel;
98
99 /***
100 * New filter button.
101 */
102 private JButton newFilterButton;
103
104 /***
105 * Delete filter button.
106 */
107 private JButton deleteFilterButton;
108
109 /***
110 * Start filtering button.
111 */
112 private JButton startFilteringButton;
113
114 /***
115 * Start filtering button.
116 */
117 private JButton stopFilteringButton;
118
119 /***
120 * Root node containing the filter.
121 */
122 private DefaultMutableTreeNode rootFilter;
123
124 /***
125 * Constructs a new filters manager with the specified attributes.
126 *
127 * @param view
128 * View displaying the componenet.
129 * @param attributes
130 * Component attributes.
131 */
132 public FiltersManager(FilteredMessagesView view, Hashtable attributes) {
133 super(new BorderLayout());
134 this.view = view;
135 this.attributes = attributes;
136 setPreferredSize(new Dimension(250, 200));
137 addComponents();
138 }
139
140 /***
141 * Returns the filer manager attributes.
142 *
143 * @return Attributes.
144 */
145 protected Hashtable getAttributes() {
146 return attributes;
147 }
148
149 /***
150 * Adds components.
151 */
152 public void addComponents() {
153
154 JPanel commandPanel = new JPanel(new BorderLayout());
155 add(commandPanel, BorderLayout.NORTH);
156
157 JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL);
158 toolbar.setFloatable(false);
159 toolbar.setRollover(true);
160 toolbar.setFocusable(false);
161 commandPanel.add(toolbar, BorderLayout.NORTH);
162
163 newFilterButton = new JButton(LAResourceBundle
164 .getIcon("FilteredMessagesView.filters.newfilter.icon"));
165 newFilterButton.setToolTipText(LAResourceBundle
166 .getLocalizedString("FilteredMessagesView.filters.newfilter"));
167 newFilterButton.addActionListener(this);
168 toolbar.add(newFilterButton);
169
170 deleteFilterButton = new JButton(LAResourceBundle
171 .getIcon("FilteredMessagesView.filters.deletefilter.icon"));
172 deleteFilterButton
173 .setToolTipText(LAResourceBundle
174 .getLocalizedString("FilteredMessagesView.filters.deletefilter"));
175 deleteFilterButton.setEnabled(false);
176 deleteFilterButton.addActionListener(this);
177 toolbar.add(deleteFilterButton);
178
179 toolbar.add(new JSeparator(JSeparator.VERTICAL));
180
181 startFilteringButton = new JButton(LAResourceBundle
182 .getIcon("FilteredMessagesView.filters.startfiltering.icon"));
183 startFilteringButton
184 .setToolTipText(LAResourceBundle
185 .getLocalizedString("FilteredMessagesView.filters.startfiltering"));
186 startFilteringButton.setEnabled(false);
187 startFilteringButton.addActionListener(this);
188 toolbar.add(startFilteringButton);
189
190 stopFilteringButton = new JButton(LAResourceBundle
191 .getIcon("FilteredMessagesView.filters.stopfiltering.icon"));
192 stopFilteringButton
193 .setToolTipText(LAResourceBundle
194 .getLocalizedString("FilteredMessagesView.filters.stopfiltering"));
195 stopFilteringButton.setEnabled(false);
196 stopFilteringButton.setVisible(false);
197 stopFilteringButton.addActionListener(this);
198 toolbar.add(stopFilteringButton);
199
200
201 JPanel fieldsPanel = new JPanel(new GridLayout(0, 1));
202 commandPanel.add(fieldsPanel, BorderLayout.CENTER);
203
204 convertersList = new JComboBox();
205 LAConverter[] converters = view.getFilteredLogHandler().getConverters();
206 for (int i = 0; i < converters.length; i++) {
207 if (!converters[i].isLiteral()) {
208 convertersList.addItem(converters[i]);
209 }
210 }
211 convertersList
212 .setToolTipText(LAResourceBundle
213 .getLocalizedString("FilteredMessagesView.filters.converterslist"));
214 fieldsPanel.add(convertersList);
215
216 filtersList
217 .setToolTipText(LAResourceBundle
218 .getLocalizedString("FilteredMessagesView.filters.filterslist"));
219 fieldsPanel.add(filtersList);
220
221 checkValue = new JTextField();
222 checkValue.setToolTipText(LAResourceBundle
223 .getLocalizedString("FilteredMessagesView.filters.checkvalue"));
224 fieldsPanel.add(checkValue);
225
226
227 filtersTree = new JTree();
228 JScrollPane treeScrollPane = new JScrollPane(filtersTree);
229 add(treeScrollPane, BorderLayout.CENTER);
230
231 filtersTree.addTreeSelectionListener(this);
232 setFilter(null);
233 }
234
235 /***
236 * Creates a new filter from the selected item in the filters tree.
237 *
238 * @return New filter.
239 */
240 private LAMessagesFilter createFilter() {
241 LAMessagesFilter newfilter = null;
242 if (view.getFilteredLogHandler() != null) {
243 if (FILTER_TYPE_AND.equals(filtersList.getSelectedItem())) {
244 newfilter = new AndFilter(new YesFilter(), new YesFilter());
245 } else if (FILTER_TYPE_OR.equals(filtersList.getSelectedItem())) {
246 newfilter = new OrFilter(new YesFilter(), new YesFilter());
247 } else if (FILTER_TYPE_NOT.equals(filtersList.getSelectedItem())) {
248 newfilter = new NotFilter(new YesFilter());
249 } else if (FILTER_TYPE_EQUAL.equals(filtersList.getSelectedItem())) {
250 newfilter = new EqualFilter(((LAConverter) convertersList
251 .getSelectedItem()), checkValue.getText());
252 } else if (FILTER_TYPE_GREATER
253 .equals(filtersList.getSelectedItem())) {
254 newfilter = new GreaterFilter(((LAConverter) convertersList
255 .getSelectedItem()), checkValue.getText());
256 } else if (FILTER_TYPE_LOWER.equals(filtersList.getSelectedItem())) {
257 newfilter = new LowerFilter(((LAConverter) convertersList
258 .getSelectedItem()), checkValue.getText());
259 } else if (FILTER_TYPE_START.equals(filtersList.getSelectedItem())) {
260 newfilter = new StartWithFilter(((LAConverter) convertersList
261 .getSelectedItem()), checkValue.getText());
262 } else if (FILTER_TYPE_CONTAINS.equals(filtersList
263 .getSelectedItem())) {
264 newfilter = new ContainsFilter(((LAConverter) convertersList
265 .getSelectedItem()), checkValue.getText());
266 }
267 }
268 return newfilter;
269 }
270
271 /***
272 * Sets a new filter as tree root.
273 *
274 * @param filter
275 * New root filter.
276 */
277 public void setFilter(LAMessagesFilter filter) {
278 filtersTree.removeAll();
279 rootFilter = null;
280 if (filter != null) {
281 rootFilter = filterToNode(filter);
282 } else {
283 rootFilter = new DefaultMutableTreeNode(
284 LAResourceBundle
285 .getLocalizedString("FilteredMessagesView.filters.nofilter"));
286 }
287 treeModel = new DefaultTreeModel(rootFilter);
288 filtersTree.setModel(treeModel);
289 }
290
291 /***
292 * Recursivelly creates a node from a filter.
293 *
294 * @param filter
295 * Filter to convert as node.
296 * @return New node.
297 */
298 private DefaultMutableTreeNode filterToNode(LAMessagesFilter filter) {
299 return filterToNode(filter, null);
300 }
301
302 /***
303 * Recursivelly creates a node from a filter. If an existing node is
304 * specified, it is modified and returned.
305 *
306 * @param filter
307 * Filter to convert as node.
308 * @param existingNode
309 * Node to modify and return if not <tt>null</tt>.
310 * @return New node or modified node if specified.
311 */
312 private DefaultMutableTreeNode filterToNode(LAMessagesFilter filter,
313 DefaultMutableTreeNode existingNode) {
314 DefaultMutableTreeNode node = existingNode;
315 if (node == null) {
316 node = new DefaultMutableTreeNode();
317 }
318 node.setUserObject(filter);
319 if (filter instanceof UnaryFilter) {
320 setChildren(node, filterToNode(((UnaryFilter) filter).getFilter()));
321 treeModel.nodesWereInserted(node, new int[] { 0 });
322 } else if (filter instanceof OperatorFilter) {
323 DefaultMutableTreeNode[] children = new DefaultMutableTreeNode[] {
324 filterToNode(((OperatorFilter) filter).getLeft()),
325 filterToNode(((OperatorFilter) filter).getRight()) };
326 setChildren(node, children);
327 } else if (node.getChildCount() > 0) {
328 removeChildren(node, 0);
329 }
330 return node;
331 }
332
333 private void setChildren(DefaultMutableTreeNode node,
334 DefaultMutableTreeNode child) {
335 setChildren(node, new DefaultMutableTreeNode[] { child });
336 }
337
338 private void setChildren(DefaultMutableTreeNode node,
339 DefaultMutableTreeNode[] children) {
340 int countChildren = node.getChildCount();
341 if (children.length < countChildren) {
342 removeChildren(node, children.length);
343 } else if (children.length > countChildren) {
344 int[] indices = new int[children.length - countChildren];
345 for (int i = countChildren; i < children.length; i++) {
346 indices[i - countChildren] = i;
347 node.add(children[i]);
348 }
349 treeModel.nodesWereInserted(node, indices);
350 }
351 }
352
353 /***
354 * Removes node children from the specified index.
355 *
356 * @param node
357 * Node to modify
358 * @param fromIndex
359 * Index of the first child to remove.
360 */
361 private void removeChildren(DefaultMutableTreeNode node, int fromIndex) {
362 TreeNode[] removedChildren = new TreeNode[node.getChildCount()
363 - fromIndex];
364 int[] childIndices = new int[removedChildren.length];
365 for (int i = 0; i < removedChildren.length; i++) {
366 removedChildren[i] = node.getChildAt(fromIndex);
367 node.remove(fromIndex);
368 }
369 treeModel.nodesWereRemoved(node, childIndices, removedChildren);
370 }
371
372 /***
373 * Recursively creates a filter from a node tree.
374 *
375 * @param node
376 * @return New filter
377 */
378 private LAMessagesFilter nodeToFilter(DefaultMutableTreeNode node) {
379 LAMessagesFilter filter = (LAMessagesFilter) node.getUserObject();
380 if (filter instanceof UnaryFilter) {
381 ((UnaryFilter) filter)
382 .setFilter(nodeToFilter((DefaultMutableTreeNode) node
383 .getChildAt(0)));
384 } else if (filter instanceof OperatorFilter) {
385 ((OperatorFilter) filter)
386 .setLeft(nodeToFilter((DefaultMutableTreeNode) node
387 .getChildAt(0)));
388 ((OperatorFilter) filter)
389 .setRight(nodeToFilter((DefaultMutableTreeNode) node
390 .getChildAt(1)));
391 }
392 return filter;
393 }
394
395 /***
396 * Returns the root filter.
397 *
398 * @return Root filter.
399 */
400 public LAMessagesFilter getFilter() {
401 if (!hasFilter()) {
402 return null;
403 } else {
404 return nodeToFilter(rootFilter);
405 }
406 }
407
408 /***
409 * Returns <tt>true</tt> if there is one or more filters.
410 *
411 * @return <tt>true</tt> if there is a filter.
412 */
413 public boolean hasFilter() {
414 return rootFilter != null
415 && rootFilter.getUserObject() instanceof LAMessagesFilter
416 && !(rootFilter.getUserObject() instanceof YesFilter);
417 }
418
419 /***
420 * Filters action.
421 *
422 * @param e
423 * Action event.
424 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
425 */
426 public void actionPerformed(ActionEvent e) {
427 DefaultMutableTreeNode node = (DefaultMutableTreeNode) filtersTree
428 .getLastSelectedPathComponent();
429 if (newFilterButton.equals(e.getSource())) {
430 if (rootFilter == null
431 || (rootFilter.equals(node) && !(rootFilter.getUserObject() instanceof LAMessagesFilter))) {
432
433 setFilter(createFilter());
434 } else if (rootFilter.equals(node)) {
435
436 setFilter(createFilter());
437 } else if (node != null) {
438
439 filterToNode(createFilter(), node);
440 treeModel.nodeChanged(node);
441
442 }
443 } else if (node != null && deleteFilterButton.equals((e.getSource()))) {
444
445 if (rootFilter.equals(node)
446 && rootFilter.getUserObject() instanceof LAMessagesFilter) {
447
448 setFilter(null);
449 } else if (!(node.getUserObject() instanceof YesFilter)) {
450
451 filterToNode(new YesFilter(), node);
452 treeModel.nodeChanged(node);
453
454 }
455 } else if (startFilteringButton.equals((e.getSource()))) {
456
457 view.startFiltering(getFilter());
458 } else if (stopFilteringButton.equals((e.getSource()))) {
459
460 view.stopFiltering();
461 }
462 }
463
464 /***
465 * Enables or disables filters buttons regarding to the selected node.
466 *
467 * @param e
468 * Tree selection event.
469 * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
470 */
471 public void valueChanged(TreeSelectionEvent e) {
472 DefaultMutableTreeNode node = (DefaultMutableTreeNode) filtersTree
473 .getLastSelectedPathComponent();
474
475 newFilterButton.setEnabled(true);
476 if (node != null && node.getUserObject() != null
477 && node.getUserObject() instanceof LAMessagesFilter) {
478 deleteFilterButton.setEnabled(true);
479 } else {
480 deleteFilterButton.setEnabled(false);
481 }
482 startFilteringButton.setEnabled(true);
483 }
484
485
486
487
488
489
490 public void startParsing(LALogHandler logHandler) {
491 stopFilteringButton.setEnabled(false);
492 startFilteringButton.setVisible(false);
493 stopFilteringButton.setVisible(true);
494 stopFilteringButton.setEnabled(true);
495 }
496
497
498
499
500
501
502 public void stepParsing(LALogHandler logHandler) {
503 }
504
505
506
507
508
509
510 public void endParsing(LALogHandler logHandler) {
511 stopFilteringButton.setEnabled(false);
512 stopFilteringButton.setVisible(false);
513 startFilteringButton.setVisible(true);
514 stopFilteringButton.setEnabled(true);
515 }
516
517 }