package agg.gui.cpa; //import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Vector; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import agg.cons.AtomConstraint; import agg.xt_basis.GraGra; import agg.xt_basis.OrdinaryMorphism; import agg.xt_basis.Rule; /** * This class models a set of rules as a tree. This tree is used to display all * rules of a selected graph grammar. * * @version $Id: RuleModel.java,v 1.4 2010/09/23 08:18:50 olga Exp $ * @author $Author: olga $ */ public class RuleModel implements TreeModel { @SuppressWarnings("serial") public class TreeData extends DefaultMutableTreeNode { boolean atomic; boolean rule; boolean nac; boolean root; TreeData(Object o) { super(o); // initialisieren this.rule = false; this.nac = false; this.root = false; if (o instanceof String) this.root = true; else if (o instanceof AtomConstraint) this.atomic = true; else if (o instanceof Rule) this.rule = true; else if (o instanceof OrdinaryMorphism) this.nac = true; } public OrdinaryMorphism getData() { Object tmpObj = getUserObject(); if (isRule() || isNAC() || isAtomic()) return (OrdinaryMorphism) tmpObj; return null; } public String toString() { Object tmpObj = getUserObject(); if (isRule() || isNAC() || isAtomic()) return ((OrdinaryMorphism) tmpObj).getName(); return tmpObj.toString(); } public boolean isAtomic() { return this.atomic; } public boolean isNAC() { return this.nac; } public boolean isRule() { return this.rule; } public boolean isRoot() { return this.root; } } private Vector<TreeModelListener> treeModelListeners; private TreeData rootNode; private GraGra grammar; // private boolean showAtomics; private boolean withNACs; /** * Creates a new model for a set of rule. These rules are given by a graph * grammar. * * @param gragra * The grammar provides the set of rules. */ public RuleModel(GraGra gragra, boolean atomics, boolean nacs) { this.treeModelListeners = new Vector<TreeModelListener>(); if (gragra != null) this.rootNode = new TreeData((atomics ? "Atomics of" : "Rules of ") + gragra.getName()); else this.rootNode = new TreeData("--EMPTY--"); this.grammar = gragra; // showAtomics = atomics; this.withNACs = nacs; } /* private Vector<TreeData> getAtomics() { Vector<TreeData> tmpVector = new Vector<TreeData>(); if (grammar != null) { Enumeration<?> en = grammar.getAtomics(); while (en.hasMoreElements()) { tmpVector.addElement(new TreeData(en.nextElement())); } } return tmpVector; } */ private Vector<TreeData> getRules() { Vector<TreeData> tmpVector = new Vector<TreeData>(); if (this.grammar != null) { Iterator<?> en = this.grammar.getListOfRules().iterator(); while (en.hasNext()) { tmpVector.add(new TreeData(en.next())); } } return tmpVector; } private Vector<TreeData> getNACs(Rule r) { Vector<TreeData> tmpVector = new Vector<TreeData>(); final List<OrdinaryMorphism> nacs = r.getNACsList(); for (int l=0; l<nacs.size(); l++) { tmpVector.addElement(new TreeData(nacs.get(l))); } return tmpVector; } // ////////////// TreeModel interface implementation /////////////////////// /** * Adds a listener for the TreeModelEvent posted after the tree changes. * * @param l * The listen will be registered. */ public void addTreeModelListener(TreeModelListener l) { if (!this.treeModelListeners.contains(l)) this.treeModelListeners.addElement(l); } /** * Returns the child of parent at index index in the parent's child array. * * @param parent * The parent of a leave in the tree. * @param index * The index of the child. * @return The child */ public Object getChild(Object parent, int index) { if (parent == getRoot()) { return getRules().elementAt(index); } TreeData td = (TreeData) parent; OrdinaryMorphism morph = td.getData(); if (morph != null && this.withNACs && morph instanceof Rule) { return getNACs((Rule) morph).elementAt(index); } // hier muessen NACs sein. NACs haben keine Kinder return null; } /** * Returns the number of children of parent. * * @param parent * The parent of the child. * @return The amount of children of the given parent. */ public int getChildCount(Object parent) { if (parent == getRoot()) return getRules().size(); TreeData td = (TreeData) parent; OrdinaryMorphism morph = td.getData(); if (morph != null && this.withNACs && morph instanceof Rule) { int result = getNACs((Rule) morph).size(); return result; } // NACs haben Null Kinder return 0; } /** * Returns the index of child in parent. * * @param parent * The parent of the child. * @param child * The child the index is searched for. * @return The index of the given child. */ public int getIndexOfChild(Object parent, Object child) { if (parent == getRoot()) return getRules().indexOf(child); TreeData td = (TreeData) parent; OrdinaryMorphism morph = td.getData(); if (morph != null && this.withNACs && morph instanceof Rule) return getNACs((Rule) morph).indexOf(child); return 0; } /** * Returns the root of the tree. * * @return The root of the tree. */ public Object getRoot() { return this.rootNode; } /** * Returns true if node is a leaf. * * @param node * The examined node in a tree. * @return For rules true is returned. */ public boolean isLeaf(Object node) { if (node == getRoot()) return false; // getChildCount liefert fuer NACs immer Null // bei Rules ist es abhaengig, ob NACs vorhanden sind. return getChildCount(node) == 0; } /** * Removes a listener previously added with addTreeModelListener(). * * @param l * The listener */ public void removeTreeModelListener(TreeModelListener l) { this.treeModelListeners.removeElement(l); } /** * Messaged when the user has altered the value for the item identified by * path to newValue. Not used by this model. * * @param path * The path to a node. * @param newValue * The new value for a node. */ public void valueForPathChanged(TreePath path, Object newValue) { System.out.println("*** valueForPathChanged : " + path + " --> " + newValue); } } /* * $Log: RuleModel.java,v $ * Revision 1.4 2010/09/23 08:18:50 olga * tuning * * Revision 1.3 2010/03/08 15:41:21 olga * code optimizing * * Revision 1.2 2009/05/12 10:37:02 olga * CPA: bug fixed * Applicability of Rule Seq. : bug fixed * * Revision 1.1 2008/10/29 09:04:12 olga * new sub packages of the package agg.gui: typeeditor, editor, trafo, cpa, options, treeview, popupmenu, saveload * * Revision 1.4 2008/04/07 09:36:56 olga * Code tuning: refactoring + profiling * Extension: CPA - two new options added * * Revision 1.3 2007/11/01 09:58:18 olga * Code refactoring: generic types- done * * Revision 1.2 2007/09/10 13:05:45 olga * In this update: * - package xerces2.5.0 is not used anymore; * - class com.objectspace.jgl.Pair is replaced by the agg own generic class agg.util.Pair; * - bugs fixed in: usage of PACs in rules; match completion; * usage of static method calls in attr. conditions * - graph editing: added some new features * Revision 1.1 2005/08/25 11:56:55 enrico *** empty * log message *** * * Revision 1.1 2005/05/30 12:58:03 olga Version with Eclipse * * Revision 1.4 2004/12/20 14:53:48 olga Changes because of matching * optimisation. * * Revision 1.3 2004/04/15 10:49:48 olga Kommentare * * Revision 1.2 2003/03/05 18:24:10 komm sorted/optimized import statements * * Revision 1.1.1.1 2002/07/11 12:17:19 olga Imported sources * * Revision 1.2 2001/03/08 11:02:49 olga Parser Anbindung gemacht. Stand nach * AGG GUI Reimplementierung. Stand nach der AGG GUI Reimplementierung.Das ist * Stand nach der AGG GUI Reimplementierung und Parser Anbindung. * * Revision 1.1.2.4 2001/01/28 13:14:47 shultzke API fertig * * Revision 1.1.2.3 2000/08/10 12:22:12 shultzke Ausserdem wird nicht mehr eine * neues GUIObject erzeugt, wenn zur ParserGUI umgeschaltet wird. Einige Klassen * wurden umbenannt. Alle Events sind in ein eigenes Eventpackage geflogen. * * Revision 1.1.2.2 2000/07/09 17:12:39 shultzke grob die GUI eingebunden * */