All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.gui.HierarchyPropertyParser Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This is the stable version. Apart from bugfixes, this version does not receive any other updates.

There is a newer version: 3.8.6
Show newest version
/*
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 *    HierarchyPropertyParser.java
 *    Copyright (C) 2001 University of Waikato, Hamilton, New Zealand
 *
 */

package weka.gui;

import java.io.Serializable;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * This class implements a parser to read properties that have
 * a hierarchy(i.e. tree) structure.  Conceptually it's similar to 
 * the XML DOM/SAX parser but of course is much simpler and 
 * uses dot as the seperator of levels instead of back-slash.
* It provides interfaces to both build a parser tree and traverse * the tree.
* Note that this implementation does not lock the tree when different * threads are traversing it simultaneously, i.e. it's NOT synchronized * and multi-thread safe. It is recommended that later implementation * extending this class provide a locking scheme and override the * functions with the "synchronized" modifier (most of them are * goToXXX() and information accessing functions).

* * @author Xin Xu ([email protected]) * @version $Revision: 9917 $ */ public class HierarchyPropertyParser implements Serializable { /** for serialization */ private static final long serialVersionUID = -4151103338506077544L; /** Keep track of the root of the tree */ private TreeNode m_Root; /** Keep track of the current node when traversing the tree */ private TreeNode m_Current; /** The level separate in the path */ private String m_Seperator = "."; /** The depth of the tree */ private int m_Depth = 0; /** * The inner class implementing a single tree node. * All fields are made public simply for convenient access, * Although a severe violation of OO Design principle. */ private class TreeNode{ /** The parent of this node */ public TreeNode parent = null; /** The value of this node. Always String */ public String value = null; /** The children of this node */ public Vector children = null; /** The level of this node */ public int level = 0; /** The context of this node */ public String context = null; } /** Default constructor */ public HierarchyPropertyParser(){ m_Root = new TreeNode(); m_Root.parent = null; m_Root.children = new Vector(); goToRoot(); } /** * Constructor that builds a tree from the given property with * the given delimitor * * @param p the given property string * @param delim the given dilimitor */ public HierarchyPropertyParser(String p, String delim) throws Exception { this(); build(p, delim); } /** * Set the seperator between levels. Default is dot. * * @param s the seperator symbol */ public void setSeperator(String s){ m_Seperator = s; } /** * Get the seperator between levels. Default is dot. * * @return the seperator symbol */ public String getSeperator(){ return m_Seperator; } /** * Build a tree from the given property with the given delimitor * * @param p the given property * @param delim the given delimitor */ public void build(String p, String delim) throws Exception { StringTokenizer st = new StringTokenizer(p, delim); //System.err.println("delim: "+delim); while(st.hasMoreTokens()){ String property = st.nextToken().trim(); if(!isHierachic(property)) throw new Exception(Messages.getInstance().getString("HierarchyPropertyParser_Build_Exception_Text")); add(property); } goToRoot(); } /** * Add the given item of property to the tree * * @param property the given item */ public synchronized void add(String property){ String[] values = tokenize(property); if(m_Root.value == null) m_Root.value = values[0]; buildBranch(m_Root, values, 1); } /** * Private function to build one branch of the tree * based on one property * * @param parent the parent of the node to be built * @param values the value of one property * @param lvl the level of the node to be built in the tree */ private void buildBranch(TreeNode parent, String[] values, int lvl){ // Precondition: children is not null if(lvl == values.length){ // Parent is leaf parent.children = null; return; } if(lvl > (m_Depth-1)) m_Depth = lvl+1; // Depth starts from 1 Vector kids = parent.children; int index = search(kids, values[lvl]); if(index != -1){ TreeNode newParent = (TreeNode)kids.elementAt(index); if(newParent.children == null) newParent.children = new Vector(); buildBranch(newParent, values, lvl+1); } else{ TreeNode added = new TreeNode(); added.parent = parent; added.value = values[lvl]; added.children = new Vector(); added.level = lvl; if(parent != m_Root) added.context = parent.context + m_Seperator + parent.value; else added.context = parent.value; kids.addElement(added); buildBranch(added, values, lvl+1); } } /** * Tokenize the given string based on the seperator and * put the tokens into an array of strings * * @param rawString the given string * @return an array of strings */ public String[] tokenize(String rawString){ Vector result = new Vector(); StringTokenizer tk = new StringTokenizer(rawString, m_Seperator); while(tk.hasMoreTokens()) result.addElement(tk.nextToken()); String[] newStrings = new String[result.size()]; for(int i=0; i < result.size(); i++) newStrings[i] = (String)result.elementAt(i); return newStrings; } /** * Whether the HierarchyPropertyParser contains the given * string * * @param string the given string * @return whether contains */ public boolean contains(String string){ String[] item = tokenize(string); if(!item[0].equals(m_Root.value)) return false; return isContained(m_Root, item, 1); } /** * Private function to decide whether one level of one branch * contains the relevant values * * @param parent the parent of the node to be searched * @param values the value of one property * @param lvl the level of the node in question * @return whether this branch contains the corresponding values */ private boolean isContained(TreeNode parent, String[] values, int lvl){ if(lvl == values.length) // Parent is leaf return true; else if(lvl > values.length) return false; else{ Vector kids = parent.children; int index = search(kids, values[lvl]); if(index != -1){ TreeNode newParent = (TreeNode)kids.elementAt(index); return isContained(newParent, values, lvl+1); } else return false; } } /** * Whether the given string has a hierachy structure with * the seperators * * @param string the given string */ public boolean isHierachic(String string){ int index = string.indexOf(m_Seperator); // Seperator not occur or first occurance at the end if((index == (string.length()-1)) || (index == -1)) return false; return true; } /** * Helper function to search for the given target string in a * given vector in which the elements' value may hopefully is equal * to the target. If such elements are found the first index * is returned, otherwise -1 * * @param vct the given vector * @param target the given target string * @return the index of the found element, -1 if not found */ public int search(Vector vct, String target){ if(vct == null) return -1; for(int i=0; i < vct.size(); i++) if(target.equals(((TreeNode)vct.elementAt(i)).value)) return i; return -1; } /** * Go to a certain node of the tree according to the specified path * Note that the path must be absolute path from the root.
* For relative path, see goDown(String path). * * @param path the given absolute path * @return whether the path exists, if false the current position does * not move */ public synchronized boolean goTo(String path){ if(!isHierachic(path)){ if(m_Root.value.equals(path)){ goToRoot(); return true; } else return false; } TreeNode old = m_Current; m_Current = new TreeNode(); goToRoot(); String[] nodes = tokenize(path); if(!m_Current.value.equals(nodes[0])) return false; for(int i=1; i < nodes.length; i++){ int pos = search(m_Current.children, nodes[i]); if(pos == -1){ m_Current = old; return false; } m_Current = (TreeNode)m_Current.children.elementAt(pos); } return true; } /** * Go to a certain node of the tree down from the current node * according to the specified relative path. The path does not * contain the value of current node * * @param path the given relative path * @return whether the path exists, if false the current position does * not move */ public synchronized boolean goDown(String path){ if(!isHierachic(path)) return goToChild(path); TreeNode old = m_Current; m_Current = new TreeNode(); String[] nodes = tokenize(path); int pos = search(old.children, nodes[0]); if(pos == -1){ m_Current = old; return false; } m_Current = (TreeNode)old.children.elementAt(pos); for(int i=1; i < nodes.length; i++){ pos = search(m_Current.children, nodes[i]); if(pos == -1){ m_Current = old; return false; } m_Current = (TreeNode)m_Current.children.elementAt(pos); } return true; } /** * Go to the root of the tree */ public synchronized void goToRoot(){ m_Current=m_Root; } /** * Go to the parent from the current position in the tree * If the current position is the root, it stays there and does * not move */ public synchronized void goToParent(){ if(m_Current.parent != null) // Not root m_Current = m_Current.parent; } /** * Go to one child node from the current position in the tree * according to the given value
* If the child node with the given value cannot be found it * returns false, true otherwise. If false, the current position * does not change * * @param value the value of the given child * @return whether the child can be found */ public synchronized boolean goToChild(String value){ if(m_Current.children == null) // Leaf return false; int pos = search(m_Current.children, value); if(pos == -1) return false; m_Current = (TreeNode)m_Current.children.elementAt(pos); return true; } /** * Go to one child node from the current position in the tree * according to the given position
* * @param pos the position of the given child * @exception Exception if the position is out of range or leaf is reached */ public synchronized void goToChild(int pos) throws Exception { if((m_Current.children == null) || (pos < 0) || (pos >= m_Current.children.size())) throw new Exception(Messages.getInstance().getString("HierarchyPropertyParser_GoToChild_Exception_Text")); m_Current = (TreeNode)m_Current.children.elementAt(pos); } /** * The number of the children nodes. If current node is leaf, it * returns 0. * * @return the number of the children nodes of the current position */ public synchronized int numChildren(){ if(m_Current.children == null) // Leaf return 0; return m_Current.children.size(); } /** * The value in the children nodes. If current node is leaf, it * returns null. * * @return the value in the children nodes */ public synchronized String[] childrenValues(){ if(m_Current.children == null) // Leaf return null; else{ Vector kids = m_Current.children; String[] values = new String[kids.size()]; for(int i=0; i < kids.size(); i++) values[i] = ((TreeNode)kids.elementAt(i)).value; return values; } } /** * The value in the parent node. If current node is root, it * returns null. * * @return the value in the parent node */ public synchronized String parentValue(){ if(m_Current.parent != null) // Not root return m_Current.parent.value; else return null; } /** * Whether the current position is a leaf * * @return whether the current position is a leaf */ public synchronized boolean isLeafReached(){ return (m_Current.children == null); } /** * Whether the current position is the root * * @return whether the current position is the root */ public synchronized boolean isRootReached(){ return (m_Current.parent == null); } /** * Get the value of current node * * @return value level */ public synchronized String getValue(){ return m_Current.value; } /** * Get the level of current node. Note the level starts from 0 * * @return the level */ public synchronized int getLevel(){ return m_Current.level; } /** * Get the depth of the tree, i.e. (the largest level)+1 * * @return the depth of the tree */ public int depth(){ return m_Depth; } /** * The context of the current node, i.e. the path from the * root to the parent node of the current node, seperated by * the seperator. If root, it returns null * * @return the context path */ public synchronized String context(){ return m_Current.context; } /** * The full value of the current node, i.e. its context + seperator * + its value. For root, only its value. * * @return the context path */ public synchronized String fullValue(){ if(m_Current == m_Root) return m_Root.value; else return (m_Current.context + m_Seperator + m_Current.value); } /** * Show the whole tree in text format * * @return the whole tree in text format */ public String showTree(){ return showNode(m_Root, null); } /** * Show one node of the tree in text format * * @param node the node in question * @return the node in text format */ private String showNode(TreeNode node, boolean[] hasBar){ StringBuffer text = new StringBuffer(); for(int i=0; i < (node.level - 1); i++) if(hasBar[i]) text.append(" | "); else text.append(" "); if(node.level != 0) text.append(" |------ "); text.append(node.value+"("+node.level+")"+"["+node.context+"]\n"); if(node.children != null) for(int i=0; i < node.children.size(); i++){ boolean[] newBar = new boolean[node.level+1]; int lvl = node.level; if(hasBar != null) for(int j=0; j < lvl; j++) newBar[j] = hasBar[j]; if((i == (node.children.size()-1))) newBar[lvl] = false; else newBar[lvl] = true; text.append(showNode((TreeNode)node.children.elementAt(i), newBar)); } return text.toString(); } /** * Tests out the parser. * * @param args should contain nothing */ public static void main(String args[]){ StringBuffer sb = new StringBuffer(); sb.append("node1.node1_1.node1_1_1.node1_1_1_1, "); sb.append("node1.node1_1.node1_1_1.node1_1_1_2, "); sb.append("node1.node1_1.node1_1_1.node1_1_1_3, "); sb.append("node1.node1_1.node1_1_2.node1_1_2_1, "); sb.append("node1.node1_1.node1_1_3.node1_1_3_1, "); sb.append("node1.node1_2.node1_2_1.node1_2_1_1, "); sb.append("node1.node1_2.node1_2_3.node1_2_3_1, "); sb.append("node1.node1_3.node1_3_3.node1_3_3_1, "); sb.append("node1.node1_3.node1_3_3.node1_3_3_2, "); String p = sb.toString(); try{ HierarchyPropertyParser hpp = new HierarchyPropertyParser(p, ", "); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_First") + hpp.getSeperator()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Second") + hpp.depth()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Third") + hpp.showTree()); hpp.goToRoot(); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Fourth") + hpp.goTo("node1.node1_2.node1_2_1") +": "+hpp.getValue()+" | "+hpp.fullValue()+ Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Fifth") + hpp.isLeafReached()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Sixth") + hpp.goDown("node1")); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Seventh") + hpp.getValue()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Eighth") + hpp.goToChild("node1_2_1_1") +": "+hpp.getValue()+" | "+hpp.fullValue()+ Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Nineth") + hpp.isLeafReached() + Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Tenth") + hpp.isRootReached()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Eleventh") + hpp.parentValue()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Twelveth") + hpp.getLevel()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Thirteenth") + hpp.context()); hpp.goToRoot(); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Fourteenth") + hpp.isLeafReached() + Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Fifteenth") + hpp.isRootReached()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Sixteenth") + hpp.goDown("node1_1.node1_1_1")+ Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Seventeenth") + hpp.getValue()+" | "+hpp.fullValue() + Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Eighteenth") + hpp.getLevel() + Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Nineteenth") + hpp.isLeafReached() + Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_Twenty") + hpp.isRootReached()); hpp.goToParent(); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentyFirst") + hpp.getValue()+" | "+hpp.fullValue()); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentySecond") + hpp.getLevel()); String[] chd = hpp.childrenValues(); for(int i=0; i < chd.length; i++){ System.out.print(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentyThird") + i + ": " + chd[i]); hpp.goDown(chd[i]); System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentyFourth") + hpp.getValue()+" | "+ hpp.fullValue()+ Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentyFifth") + hpp.getLevel()+Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentySixth")); hpp.goToParent(); } System.out.println(Messages.getInstance().getString("HierarchyPropertyParser_Main_Text_TwentySeventh") + hpp.goTo("node1") +": "+hpp.getValue()+" | "+hpp.fullValue()); }catch(Exception e){ System.out.println(e.getMessage()); e.printStackTrace(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy