001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.query.parser.serql.ast;
007:
008: import java.io.IOException;
009: import java.io.StringWriter;
010: import java.util.ArrayList;
011: import java.util.List;
012:
013: public class SimpleNode implements Node {
014:
015: private static final String LINE_SEPARATOR = System
016: .getProperty("line.separator");
017:
018: protected Node parent;
019:
020: protected List<Node> children;
021:
022: protected int id;
023:
024: protected SyntaxTreeBuilder parser;
025:
026: public SimpleNode(int id) {
027: this .id = id;
028: children = new ArrayList<Node>();
029: }
030:
031: public SimpleNode(SyntaxTreeBuilder parser, int id) {
032: this (id);
033: this .parser = parser;
034: }
035:
036: public void jjtOpen() {
037: }
038:
039: public void jjtClose() {
040: }
041:
042: public void jjtSetParent(Node n) {
043: parent = n;
044: }
045:
046: public Node jjtGetParent() {
047: return parent;
048: }
049:
050: public void jjtAddChild(Node n, int i) {
051: while (i >= children.size()) {
052: // Add dummy nodes
053: children.add(null);
054: }
055:
056: children.set(i, n);
057: }
058:
059: public void jjtAppendChild(Node n) {
060: children.add(n);
061: }
062:
063: public void jjtInsertChild(Node n, int i) {
064: children.add(i, n);
065: }
066:
067: public void jjtReplaceChild(Node oldNode, Node newNode) {
068: for (int i = 0; i < children.size(); i++) {
069: if (children.get(i) == oldNode) {
070: children.set(i, newNode);
071: }
072: }
073: }
074:
075: /**
076: * Replaces this node with the supplied one in the AST.
077: *
078: * @param newNode The replacement node.
079: */
080: public void jjtReplaceWith(Node newNode) {
081: if (parent != null) {
082: parent.jjtReplaceChild(this , newNode);
083: }
084:
085: for (Node childNode : children) {
086: childNode.jjtSetParent(newNode);
087: }
088: }
089:
090: public List<Node> jjtGetChildren() {
091: return children;
092: }
093:
094: public Node jjtGetChild(int i) {
095: return children.get(i);
096: }
097:
098: /**
099: * Gets the (first) child of this node that is of the specific type.
100: *
101: * @param type The type of the child node that should be returned.
102: * @return The (first) child node of the specified type, or <tt>null</tt>
103: * if no such child node was found.
104: */
105: public <T extends Node> T jjtGetChild(Class<T> type) {
106: for (Node n : children) {
107: if (type.isInstance(n)) {
108: return (T) n;
109: }
110: }
111:
112: return null;
113: }
114:
115: public <T extends Node> List<T> jjtGetChildren(Class<T> type) {
116: List<T> result = new ArrayList<T>(children.size());
117:
118: for (Node n : children) {
119: if (type.isInstance(n)) {
120: result.add((T) n);
121: }
122: }
123:
124: return result;
125: }
126:
127: public int jjtGetNumChildren() {
128: return children.size();
129: }
130:
131: /** Accept the visitor. */
132: public Object jjtAccept(SyntaxTreeBuilderVisitor visitor,
133: Object data) throws VisitorException {
134: return visitor.visit(this , data);
135: }
136:
137: /** Accept the visitor. */
138: public Object childrenAccept(SyntaxTreeBuilderVisitor visitor,
139: Object data) throws VisitorException {
140: for (Node childNode : children) {
141: // Note: modified JavaCC code, child's data no longer ignored
142: data = childNode.jjtAccept(visitor, data);
143: }
144:
145: return data;
146: }
147:
148: /*
149: * You can override these two methods in subclasses of SimpleNode to
150: * customize the way the node appears when the tree is dumped. If your output
151: * uses more than one line you should override toString(String), otherwise
152: * overriding toString() is probably all you need to do.
153: */
154:
155: @Override
156: public String toString() {
157: return SyntaxTreeBuilderTreeConstants.jjtNodeName[id];
158: }
159:
160: public String toString(String prefix) {
161: return prefix + toString();
162: }
163:
164: /**
165: * Writes a tree-like representation of this node and all of its subnodes
166: * (recursively) to the supplied Appendable.
167: */
168: public void dump(String prefix, Appendable out) throws IOException {
169: out.append(prefix).append(this .toString());
170:
171: for (Node childNode : children) {
172: if (childNode != null) {
173: out.append(LINE_SEPARATOR);
174: ((SimpleNode) childNode).dump(prefix + " ", out);
175: }
176: }
177: }
178:
179: /**
180: * Writes a tree-like representation of this node and all of its subnodes
181: * (recursively) and returns it as a string.
182: */
183: public String dump(String prefix) {
184: StringWriter out = new StringWriter(256);
185: try {
186: dump(prefix, out);
187: return out.toString();
188: } catch (IOException e) {
189: throw new RuntimeException(
190: "Unexpected I/O error while writing to StringWriter",
191: e);
192: }
193: }
194: }
|