[jboss-svn-commits] JBL Code SVN: r9279 - labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Feb 1 20:25:17 EST 2007
Author: woolfel
Date: 2007-02-01 20:25:17 -0500 (Thu, 01 Feb 2007)
New Revision: 9279
Added:
labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/DSLTree.java
labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/Node.java
Log:
adding the DSLTree utility for improved dsl auto-completion support
peter
Added: labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/DSLTree.java
===================================================================
--- labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/DSLTree.java (rev 0)
+++ labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/DSLTree.java 2007-02-02 01:25:17 UTC (rev 9279)
@@ -0,0 +1,398 @@
+package org.drools.ide.editors.completion;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+public class DSLTree {
+
+ public static final String when = "[when]";
+ public static final String then = "[then]";
+ public static final String wildcard = "[*]";
+ public static final String separator = "=";
+ public static final String tab = " ";
+
+ private Node current = null;
+ private Node last = null;
+ private Node root = null;
+ private boolean empty = true;
+ private ArrayList suggestions = new ArrayList();
+ private HashMap objToNL = new HashMap();
+
+ public DSLTree() {
+ this.root = new Node("root");
+ }
+
+ /**
+ * the method will take the dsl file and build a DSLTree using
+ * the Node class.
+ * @param dslFile
+ */
+ public void buildTree(String dslFile) {
+ // first we clear the children
+ this.root.clearChildren();
+ BufferedReader breader = openDSLFile(dslFile);
+ parseFile(breader);
+ try {
+ breader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ this.empty = false;
+ }
+
+ /**
+ * the method uses the DSLAdapter to get the contents of the
+ * DSL mapping file.
+ * @param dslcontents
+ */
+ public void buildTree(Reader dslcontents) {
+ this.root.clearChildren();
+ BufferedReader breader = this.createBufferedReader(dslcontents);
+ parseFile(breader);
+ try {
+ breader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ this.empty = false;
+ }
+
+ /**
+ * method will create a BufferedReader to read the file.
+ * @param filename
+ * @return
+ */
+ protected BufferedReader openDSLFile(String filename) {
+ try {
+ FileReader reader = new FileReader(filename);
+ BufferedReader breader = new BufferedReader(reader);
+ return breader;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Create a buffered reader for the reader created by the DSLAdapater
+ * @param reader
+ * @return
+ */
+ protected BufferedReader createBufferedReader(Reader reader) {
+ return new BufferedReader(reader);
+ }
+
+ /**
+ * if the DSL mapping hasn't been loaded, the method will return
+ * true. If the DSL mapping has been loaded, the method returns
+ * false.
+ * @return
+ */
+ public boolean isEmpty() {
+ return this.empty;
+ }
+
+ /**
+ * method will use the BufferedReader to read the contents of the file.
+ * It calls other methods to parse the line and build the tree.
+ * @param reader
+ */
+ protected void parseFile(BufferedReader reader) {
+ String line = null;
+ try {
+ while ( (line = reader.readLine()) != null) {
+ String nl = stripHeadingAndCode(line);
+ String objname = this.getObjMetadata(nl);
+ nl = this.stripObjMetadata(nl);
+ if (!nl.startsWith("-")) {
+ this.addObjToNLMap(objname, nl);
+ StringTokenizer tokenz = new StringTokenizer(nl);
+ addTokens(tokenz);
+ } else {
+ String res = (String)this.objToNL.get(objname);
+ StringTokenizer tokenz = new StringTokenizer(nl);
+ addTokens(res,tokenz);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addObjToNLMap(String objname, String nl) {
+ if (!objname.startsWith("-")) {
+ this.objToNL.put(objname, nl);
+ }
+ }
+
+ /**
+ * method will strip out the when, then, * at the beginning of each
+ * line and the mapped drl expression
+ * @param text
+ * @return
+ */
+ protected String stripHeadingAndCode(String text) {
+ if (text.startsWith(when)) {
+ return text.substring(6,text.indexOf("="));
+ } else if (text.startsWith(then)) {
+ return text.substring(6,text.indexOf("="));
+ } else if (text.startsWith(wildcard)) {
+ return text.substring(3,text.indexOf("="));
+ } else if (text.startsWith("#")) {
+ return "";
+ } else {
+ return text;
+ }
+ }
+
+ /**
+ * Method will return just the object metadata
+ * @param text
+ * @return
+ */
+ protected String getObjMetadata(String text) {
+ if (text.startsWith("[")) {
+ return text.substring(1,text.lastIndexOf("]"));
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * method will strip the metadata from the text string
+ * @param text
+ * @return
+ */
+ protected String stripObjMetadata(String text) {
+ if (text.startsWith("[")) {
+ return text.substring(text.lastIndexOf("]") + 1);
+ } else {
+ return text;
+ }
+ }
+
+ /**
+ * The method is different than addTokens(StringTokenizer). this method
+ * expects additional metadata. It expects to get an object name or "*"
+ * meaning all. If the metadata is a wildcard all, it will add the
+ * tokens to all the top level nodes that are immediate child of root.
+ * @param metadata
+ * @param tokens
+ */
+ public void addTokens(String metadata, StringTokenizer tokens) {
+ Node mnode = this.root.addToken(metadata);
+ Node thenode = mnode;
+ while (tokens.hasMoreTokens()) {
+ Node newnode = thenode.addToken(tokens.nextToken());
+ thenode = newnode;
+ }
+ }
+
+ /**
+ * method adds the token to root
+ * @param tokens
+ */
+ public void addTokens(StringTokenizer tokens) {
+ Node thenode = this.root;
+ while (tokens.hasMoreTokens()) {
+ Node newnode = thenode.addToken(tokens.nextToken());
+ thenode = newnode;
+ }
+ }
+
+ /**
+ * the method will tokenize the text and try to find
+ * the node that matches and return the children. the method
+ * will traverse down the network as far as it can and return
+ * the children at that level.
+ * @param text
+ * @return
+ */
+ public Node[] getChildren(String text) {
+ Node thenode = this.root;
+ if (text.length() > 0) {
+ StringTokenizer tokenz = new StringTokenizer(text);
+ this.last = this.current;
+ while (tokenz.hasMoreTokens()) {
+ String strtk = tokenz.nextToken();
+ Node ch = thenode.getChild(strtk);
+ // if a child is found, we set thenode to the child Node
+ if (ch != null) {
+ thenode = ch;
+ } else {
+ break;
+ }
+ }
+ if (thenode != this.root) {
+ this.current = thenode;
+ }
+ }
+ Collection children = thenode.getChildren();
+ Node[] nchild = new Node[children.size()];
+ return (Node[])children.toArray(nchild);
+ }
+
+ /**
+ * the method expects the caller to pass the object
+ * @param obj
+ * @param text
+ * @return
+ */
+ public Node[] getChildren(String obj, String text) {
+ Node thenode = this.root.getChild(obj);
+ if (text.length() > 0) {
+ StringTokenizer tokenz = new StringTokenizer(text);
+ this.last = this.current;
+ while (tokenz.hasMoreTokens()) {
+ String strtk = tokenz.nextToken();
+ Node ch = thenode.getChild(strtk);
+ // if a child is found, we set thenode to the child Node
+ if (ch != null) {
+ thenode = ch;
+ } else {
+ break;
+ }
+ }
+ if (thenode != this.root) {
+ this.current = thenode;
+ }
+ }
+ if (thenode == null) {
+ thenode = this.root;
+ }
+ Collection children = thenode.getChildren();
+ Node[] nchild = new Node[children.size()];
+ return (Node[])children.toArray(nchild);
+ }
+
+ /**
+ * for convienance, the method will return a list of strings
+ * that are children of the last node found. If the editor
+ * wants to generate the children strings, call the method
+ * with true
+ * @param text
+ * @return
+ */
+ public ArrayList getChildrenList(String text, boolean addChildren) {
+ Node[] c = getChildren(text);
+ this.suggestions.clear();
+ for (int idx=0; idx < c.length; idx++) {
+ this.suggestions.add(c[idx].getToken());
+ if (addChildren) {
+ this.addChildToList(c[idx], c[idx].getToken(), this.suggestions);
+ }
+ }
+ return this.suggestions;
+ }
+
+ /**
+ *
+ * @param obj
+ * @param text
+ * @param addChildren
+ * @return
+ */
+ public ArrayList getChildrenList(String obj, String text, boolean addChildren) {
+ Node[] c = getChildren(obj,text);
+ this.suggestions.clear();
+ for (int idx=0; idx < c.length; idx++) {
+ this.suggestions.add(c[idx].getToken());
+ if (addChildren) {
+ this.addChildToList(c[idx], c[idx].getToken(), this.suggestions);
+ }
+ }
+ // in the event the line is zero length after it is trimmed, we also add
+ // the top level nodes
+ if (text.trim().length() == 0) {
+ Iterator top = this.root.getChildren().iterator();
+ while (top.hasNext()) {
+ Node t = (Node)top.next();
+ if (!this.suggestions.contains(t.getToken())) {
+ this.suggestions.add(t.getToken());
+ if (addChildren) {
+ this.addChildToList(t, t.getToken(), this.suggestions);
+ }
+ }
+ }
+ }
+ return this.suggestions;
+ }
+
+ /**
+ * method will prepend the parent text to the child and generate
+ * the possible combinations in text format.
+ * @param n
+ * @param prefix
+ * @param list
+ */
+ public void addChildToList(Node n, String prefix, ArrayList list) {
+ if (n.getChildren().size() > 0) {
+ Iterator itr = n.getChildren().iterator();
+ while (itr.hasNext()) {
+ Node child = (Node)itr.next();
+ String text = prefix + " " + child.getToken();
+ list.add(text);
+ addChildToList(child,text,list);
+ }
+ }
+ }
+
+ public Node getCurrent() {
+ return current;
+ }
+
+ public void setCurrent(Node current) {
+ this.current = current;
+ }
+
+ public Node getLast() {
+ return last;
+ }
+
+ public void setLast(Node last) {
+ this.last = last;
+ }
+
+ /**
+ * The method will print the DSLTree to System.out in text format.
+ */
+ public void printTree() {
+ System.out.println("ROOT");
+ Iterator itr = this.root.getChildren().iterator();
+ while (itr.hasNext()) {
+ Node n = (Node)itr.next();
+ printNode(n);
+ }
+ }
+
+ /**
+ * method will print the node and then iterate over the children
+ * @param n
+ */
+ protected void printNode(Node n) {
+ printTabs(n.getDepth());
+ System.out.println("- \"" + n.getToken() + "\"");
+ Iterator itr = n.getChildren().iterator();
+ while (itr.hasNext()) {
+ Node c = (Node)itr.next();
+ printNode(c);
+ }
+ }
+
+ /**
+ * Method will print n number of tabs
+ * @param count
+ */
+ protected void printTabs(int count) {
+ for (int idx=0; idx < count; idx++) {
+ System.out.print(tab);
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/Node.java
===================================================================
--- labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/Node.java (rev 0)
+++ labs/jbossrules/trunk/drools-ide/src/main/java/org/drools/ide/editors/completion/Node.java 2007-02-02 01:25:17 UTC (rev 9279)
@@ -0,0 +1,110 @@
+package org.drools.ide.editors.completion;
+
+import java.util.Collection;
+import java.util.HashMap;
+
+public class Node {
+ private HashMap children = new HashMap();
+ private Node parent = null;
+ private String token;
+ private int depth = 0;
+
+ public Node(String name) {
+ this.token = name;
+ }
+
+ /**
+ * The method will create a new Node instance and try to add it as
+ * a child node. If an Node with the same string token exists, the
+ * method will return the existing node instead.
+ * @param token
+ * @return
+ */
+ public Node addToken(String token) {
+ Node newnode = new Node(token);
+ // set the depth first
+ newnode.setDepth(depth + 1);
+ // add the node as a child
+ newnode = addChild(newnode);
+ return newnode;
+ }
+
+ /**
+ * if the string matches this node's token, the method will return
+ * true. Otherwise it returns false.
+ * @param input
+ * @return
+ */
+ public boolean isMatch(String input) {
+ return input.equals(token);
+ }
+
+ public boolean isMatch(Node n) {
+ return this.token.equals(n.getToken());
+ }
+
+ /**
+ * The method will check to see if a Node with the same string token
+ * already exists. If it doesn't, it will add the token as a child and
+ * return the same node.
+ *
+ * On the otherhand, if there is an existing Node for the same string
+ * token, the method returns the existing Node instance.
+ * @param n
+ * @return
+ */
+ public Node addChild(Node n) {
+ if (!this.children.containsKey(n.getToken())) {
+ this.children.put(n.getToken(),n);
+ n.setParent(this);
+ return n;
+ } else {
+ return (Node)this.children.get(n.getToken());
+ }
+ }
+
+ public void removeChild(Node n) {
+ this.children.remove(n.getToken());
+ }
+
+ public Collection getChildren() {
+ return this.children.values();
+ }
+
+ /**
+ * The method will get the child matching the string token
+ * @param token
+ * @return
+ */
+ public Node getChild(String token) {
+ return (Node)this.children.get(token);
+ }
+
+ public Node getParent() {
+ return parent;
+ }
+
+ public void setParent(Node parent) {
+ this.parent = parent;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
+ public void clearChildren() {
+ this.children.clear();
+ }
+}
More information about the jboss-svn-commits
mailing list