001 /*
002 * Copyright 2009 - 2010 JEuclid, http://jeuclid.sf.net
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 /* $Id $ */
018
019 package net.sourceforge.jeuclid.biparser;
020
021 import net.sourceforge.jeuclid.elements.generic.DocumentElement;
022
023 import org.w3c.dom.Document;
024 import org.w3c.dom.Node;
025 import org.w3c.dom.NodeList;
026
027 /**
028 * this class if for creating a BiTree with ABiNodes while parsing a text.
029 *
030 * @version $Revision: 0b66106c7ff7 $
031 */
032 public class BiTree {
033
034 /** document (DOM-tree). */
035 private Document doc;
036
037 /** root of tree. */
038 private IBiNode root;
039
040 /** text of tree. */
041 private String text;
042
043 /**
044 * create a new instance of BiTree.
045 */
046 public BiTree() {
047
048 }
049
050 /**
051 * create a new DOM tree from bitree and save it.
052 */
053 public final void createDOMTree() {
054 Node subtree;
055
056 this.doc = new DocumentElement();
057
058 subtree = this.getDOMTree(this.doc);
059
060 if (subtree != null) {
061 this.doc.appendChild(subtree);
062 }
063 }
064
065 /**
066 * create a dom tree from bitree and return root.
067 *
068 * @param d
069 * document to create DOM tree
070 * @return root of DOM tree
071 */
072 public final Node getDOMTree(final Document d) {
073 Node treeRoot;
074
075 if (this.root.getType() == BiType.EMPTY) {
076 treeRoot = this.root.getSibling().createDOMSubtree(d);
077 } else {
078 treeRoot = this.root.createDOMSubtree(d);
079 }
080
081 return treeRoot;
082 }
083
084 /**
085 * get root of BiTree.
086 *
087 * @return root of BiTree
088 */
089 public final IBiNode getRoot() {
090 return this.root;
091 }
092
093 /**
094 * insert characters into BiTree.
095 *
096 * @param offset
097 * insert position in text
098 * @param length
099 * number of characters to insert
100 * @param t
101 * text where characters were inserted
102 * @throws ReparseException
103 * if a sax parse exception occurs
104 * @throws NonIncrementalElementException
105 * if the subtree contains an element which cannot be
106 * incrementally updated.
107 */
108 public final void insert(final int offset, final int length, final String t)
109 throws ReparseException, NonIncrementalElementException {
110 this.text = t;
111 this.root.insert(this, offset, length, 0);
112 }
113
114 /**
115 * remove characters from BiTree.
116 *
117 * @param offset
118 * remove position in text
119 * @param length
120 * number of characters to remove
121 * @param t
122 * text where characters were removed
123 * @throws ReparseException
124 * if a sax parse exception occurs
125 * @throws NonIncrementalElementException
126 * if the subtree contains an element which cannot be
127 * incrementally updated.
128 */
129 public final void remove(final int offset, final int length, final String t)
130 throws ReparseException, NonIncrementalElementException {
131 this.text = t;
132 this.root.remove(this, offset, length, 0);
133 }
134
135 /**
136 * set a new root in BiTree.
137 *
138 * @param r
139 * new root of BiTree
140 */
141 public final void setRoot(final IBiNode r) {
142
143 if (r == null) {
144 this.doc = null;
145 } else {
146 r.setPrevious(null);
147 }
148
149 this.root = r;
150 }
151
152 /**
153 * get text of BiTree.
154 *
155 * @return text of BiTree
156 */
157 public String getText() {
158 return this.text;
159 }
160
161 /**
162 * get document of DOM Tree.
163 *
164 * @return document of DOM Tree
165 */
166 public Node getDocument() {
167 return this.doc;
168 }
169
170 /**
171 * search a DOM node in BiTree and return position of node. if node is not
172 * found return null
173 *
174 * @param node
175 * DOM node to search for
176 * @return search result of node in inputtext
177 */
178 public TextPosition searchNode(final Node node) {
179 if (this.root == null) {
180 return null;
181 } else {
182 return this.root.searchNode(node, 0);
183 }
184 }
185
186 /**
187 * get a formatted output of BiTree.
188 *
189 * @return formatted output of BiTree
190 */
191 @Override
192 public String toString() {
193 if (this.root == null) {
194 return "root is null";
195 } else {
196 return this.root.toString(0);
197 }
198 }
199
200 /**
201 * get formatted output of DOM Tree (for debugging).
202 *
203 * @return formatted ouput of DOM Tree
204 */
205 public String toStringDOM() {
206 return this.toStringDOM(0, this.doc.getDocumentElement());
207 }
208
209 private String toStringDOM(final int level, final Node n) {
210 int i;
211 NodeList nl;
212 final StringBuilder sb = new StringBuilder(128);
213
214 if (n == null) {
215 return "node is null";
216 }
217
218 for (i = 0; i < level; i++) {
219 sb.append(" ");
220 }
221
222 sb.append(" ");
223 if (n.getNodeType() == Node.TEXT_NODE) {
224 sb.append(n.getTextContent());
225 } else {
226 sb.append(n.getNodeName());
227 }
228 sb.append("\n");
229
230 nl = n.getChildNodes();
231 for (i = 0; i < nl.getLength(); i++) {
232 sb.append(this.toStringDOM(level + 1, nl.item(i)));
233 }
234
235 return sb.toString();
236 }
237 }