package com.ibm.nmon.gui.tree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import com.ibm.nmon.data.DataSet; import com.ibm.nmon.data.SystemDataSet; import com.ibm.nmon.data.DataType; import com.ibm.nmon.data.Process; /** * Parse a TreePath based on the JTree built by {@link TreePanel}. Determines the given DataSet, * DataType and field, any of which can be null. */ public abstract class TreePathParser { public final Object parse(TreePath path) { if (path == null) { onNullPath(); return onReturn(null, null, null); } Object[] paths = path.getPath(); if (paths.length == 0) { onNullPath(); return onReturn(null, null, null); } if (paths.length == 1) { onRootPath(); return onReturn(null, null, null); } SystemDataSet data = (SystemDataSet) ((DefaultMutableTreeNode) paths[1]).getUserObject(); // data set if (paths.length == 2) { onDataSetPath(data); return onReturn(data, null, null); } DataType type = null; String field = null; if (paths.length > 2) { Object o = ((DefaultMutableTreeNode) paths[2]).getUserObject(); if (!o.getClass().equals(String.class)) { type = (DataType) o; } // String => TOP, GC or SubDataType } if (paths.length > 3) { Object o = ((DefaultMutableTreeNode) paths[3]).getUserObject(); if (o.getClass().equals(Process.class)) { type = data.getType((Process) o); } else if (o.getClass().equals(String.class)){ field = (String) o; } else { type = (DataType) o; // SubDataType } } if (paths.length > 4) { field = null; // previous string may be a process name Object o = ((DefaultMutableTreeNode) paths[4]).getUserObject(); if (o.getClass().equals(Process.class)) { type = data.getType((Process) o); } else if (o instanceof DataType) { type = (DataType) o; } else { field = (String) o; } } if (paths.length > 5) { Object o = ((DefaultMutableTreeNode) paths[5]).getUserObject(); field = (String) o; } if (type == null) { onProcessPath(data); } else { if (field == null) { onTypePath(data, type); } else { onFieldPath(data, type, field); } } return onReturn(data, type, field); } /** * Called when the TreePath is actually not pointing to any node. After calling this, * <code>parse</code> calls <code>onReturn</code> with all null arguments. */ protected void onNullPath() {} /** * Called when the TreePath is pointing to the root node. After calling this, <code>parse</code> * <code>parse</code> calls <code>onReturn</code> with all null arguments. */ protected void onRootPath() {} /** * Called when the TreePath is pointing to an DataSet. */ protected void onDataSetPath(DataSet data) {} /** * Called when the TreePath is pointing to a DataType. Note this includes Process instances * since each Process also defines its own DataType. */ protected void onTypePath(DataSet data, DataType type) {} /** * Called when the TreePath is pointing to a process name, but not a specific Process instance. */ protected void onProcessPath(DataSet data) {} /** * Called when the TreePath is pointing to a specific field from a DataType. */ protected void onFieldPath(DataSet data, DataType type, String field) {} /** * Called after a TreePath is successfully parsed and the path is on a tree node. Subclasses may * return <code>null</code>. The arguments can be <code>null</code> depending on what type of * node the path points to. */ protected Object onReturn(DataSet data, DataType type, String field) { return null; } }