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 }