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.sparql.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
079: * The replacement node.
080: */
081: public void jjtReplaceWith(Node newNode) {
082: if (parent != null) {
083: parent.jjtReplaceChild(this , newNode);
084: }
085:
086: for (Node childNode : children) {
087: childNode.jjtSetParent(newNode);
088: }
089: }
090:
091: public List<Node> jjtGetChildren() {
092: return children;
093: }
094:
095: public Node jjtGetChild(int i) {
096: return children.get(i);
097: }
098:
099: /**
100: * Gets the (first) child of this node that is of the specific type.
101: *
102: * @param type
103: * The type of the child node that should be returned.
104: * @return The (first) child node of the specified type, or <tt>null</tt>
105: * if no such child node was found.
106: */
107: public <T extends Node> T jjtGetChild(Class<T> type) {
108: for (Node n : children) {
109: if (type.isInstance(n)) {
110: return (T) n;
111: }
112: }
113:
114: return null;
115: }
116:
117: public <T extends Node> List<T> jjtGetChildren(Class<T> type) {
118: List<T> result = new ArrayList<T>(children.size());
119:
120: for (Node n : children) {
121: if (type.isInstance(n)) {
122: result.add((T) n);
123: }
124: }
125:
126: return result;
127: }
128:
129: public int jjtGetNumChildren() {
130: return children.size();
131: }
132:
133: public Object jjtAccept(SyntaxTreeBuilderVisitor visitor,
134: Object data) throws VisitorException {
135: return visitor.visit(this , data);
136: }
137:
138: /**
139: * Accept the visitor.
140: */
141: public Object childrenAccept(SyntaxTreeBuilderVisitor visitor,
142: Object data) throws VisitorException {
143: for (Node childNode : children) {
144: // Note: modified JavaCC code, child's data no longer ignored
145: data = childNode.jjtAccept(visitor, data);
146: }
147:
148: return data;
149: }
150:
151: /*
152: * You can override these two methods in subclasses of SimpleNode to
153: * customize the way the node appears when the tree is dumped. If your output
154: * uses more than one line you should override toString(String), otherwise
155: * overriding toString() is probably all you need to do.
156: */
157:
158: @Override
159: public String toString() {
160: return SyntaxTreeBuilderTreeConstants.jjtNodeName[id];
161: }
162:
163: public String toString(String prefix) {
164: return prefix + toString();
165: }
166:
167: /**
168: * Writes a tree-like representation of this node and all of its subnodes
169: * (recursively) to the supplied Appendable.
170: */
171: public void dump(String prefix, Appendable out) throws IOException {
172: out.append(prefix).append(this .toString());
173:
174: for (Node childNode : children) {
175: if (childNode != null) {
176: out.append(LINE_SEPARATOR);
177: ((SimpleNode) childNode).dump(prefix + " ", out);
178: }
179: }
180: }
181:
182: /**
183: * Writes a tree-like representation of this node and all of its subnodes
184: * (recursively) and returns it as a string.
185: */
186: public String dump(String prefix) {
187: StringWriter out = new StringWriter(256);
188: try {
189: dump(prefix, out);
190: return out.toString();
191: } catch (IOException e) {
192: throw new RuntimeException(
193: "Unexpected I/O error while writing to StringWriter",
194: e);
195: }
196: }
197: }
|