1 18 package org.apache.batik.dom.util; 19 20 import java.io.IOException ; 21 import java.io.Writer ; 22 23 import org.apache.batik.xml.XMLUtilities; 24 import org.w3c.dom.Attr ; 25 import org.w3c.dom.DOMException ; 26 import org.w3c.dom.DOMImplementation ; 27 import org.w3c.dom.Document ; 28 import org.w3c.dom.DocumentType ; 29 import org.w3c.dom.Element ; 30 import org.w3c.dom.NamedNodeMap ; 31 import org.w3c.dom.Node ; 32 33 39 public class DOMUtilities extends XMLUtilities { 40 43 protected DOMUtilities() { 44 } 45 46 49 public static void writeDocument(Document doc, Writer w) throws IOException { 50 for (Node n = doc.getFirstChild(); 51 n != null; 52 n = n.getNextSibling()) { 53 writeNode(n, w); 54 } 55 } 56 57 60 public static void writeNode(Node n, Writer w) throws IOException { 61 switch (n.getNodeType()) { 62 case Node.ELEMENT_NODE: 63 w.write("<"); 64 w.write(n.getNodeName()); 65 66 if (n.hasAttributes()) { 67 NamedNodeMap attr = n.getAttributes(); 68 int len = attr.getLength(); 69 for (int i = 0; i < len; i++) { 70 Attr a = (Attr )attr.item(i); 71 w.write(" "); 72 w.write(a.getNodeName()); 73 w.write("=\""); 74 w.write(contentToString(a.getNodeValue())); 75 w.write("\""); 76 } 77 } 78 79 Node c = n.getFirstChild(); 80 if (c != null) { 81 w.write(">"); 82 for (; c != null; 83 c = c.getNextSibling()) { 84 writeNode(c, w); 85 } 86 w.write("</"); 87 w.write(n.getNodeName()); 88 w.write(">"); 89 } else { 90 w.write("/>"); 91 } 92 break; 93 case Node.TEXT_NODE: 94 w.write(contentToString(n.getNodeValue())); 95 break; 96 case Node.CDATA_SECTION_NODE: 97 w.write("<![CDATA["); 98 w.write(n.getNodeValue()); 99 w.write("]]>"); 100 break; 101 case Node.ENTITY_REFERENCE_NODE: 102 w.write("&"); 103 w.write(n.getNodeName()); 104 w.write(";"); 105 break; 106 case Node.PROCESSING_INSTRUCTION_NODE: 107 w.write("<?"); 108 w.write(n.getNodeName()); 109 w.write(" "); 111 w.write(n.getNodeValue()); 112 w.write("?>"); 113 break; 114 case Node.COMMENT_NODE: 115 w.write("<!--"); 116 w.write(n.getNodeValue()); 117 w.write("-->"); 118 break; 119 case Node.DOCUMENT_TYPE_NODE: { 120 DocumentType dt = (DocumentType )n; 121 w.write ("<!DOCTYPE "); 122 w.write (n.getOwnerDocument().getDocumentElement().getNodeName()); 123 String pubID = dt.getPublicId(); 124 if (pubID != null) { 125 w.write (" PUBLIC \"" + dt.getNodeName() + "\" \"" + 126 pubID + "\">"); 127 } else { 128 String sysID = dt.getSystemId(); 129 if (sysID != null) 130 w.write (" SYSTEM \"" + sysID + "\">"); 131 } 132 } 133 break; 134 default: 135 throw new Error ("Internal error (" + n.getNodeType() + ")"); 136 } 137 } 138 139 143 public static String contentToString(String s) { 144 StringBuffer result = new StringBuffer (); 145 146 for (int i = 0; i < s.length(); i++) { 147 char c = s.charAt(i); 148 149 switch (c) { 150 case '<': 151 result.append("<"); 152 break; 153 case '>': 154 result.append(">"); 155 break; 156 case '&': 157 result.append("&"); 158 break; 159 case '"': 160 result.append("""); 161 break; 162 case '\'': 163 result.append("'"); 164 break; 165 default: 166 result.append(c); 167 } 168 } 169 170 return result.toString(); 171 } 172 173 176 public static Document deepCloneDocument(Document doc, DOMImplementation impl) { 177 Element root = doc.getDocumentElement(); 178 Document result = impl.createDocument(root.getNamespaceURI(), 179 root.getNodeName(), 180 null); 181 Element rroot = result.getDocumentElement(); 182 boolean before = true; 183 for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) { 184 if (n == root) { 185 before = false; 186 if (root.hasAttributes()) { 187 NamedNodeMap attr = root.getAttributes(); 188 int len = attr.getLength(); 189 for (int i = 0; i < len; i++) { 190 rroot.setAttributeNode((Attr )result.importNode(attr.item(i), 191 true)); 192 } 193 } 194 for (Node c = root.getFirstChild(); 195 c != null; 196 c = c.getNextSibling()) { 197 rroot.appendChild(result.importNode(c, true)); 198 } 199 } else { 200 if (n.getNodeType() != Node.DOCUMENT_TYPE_NODE) { 201 if (before) { 202 result.insertBefore(result.importNode(n, true), rroot); 203 } else { 204 result.appendChild(result.importNode(n, true)); 205 } 206 } 207 } 208 } 209 return result; 210 } 211 212 215 public static boolean isValidName(String s) { 216 char c = s.charAt(0); 217 int d = c / 32; 218 int m = c % 32; 219 if ((NAME_FIRST_CHARACTER[d] & (1 << m)) == 0) { 220 return false; 221 } 222 int len = s.length(); 223 for (int i = 1; i < len; i++) { 224 c = s.charAt(i); 225 d = c / 32; 226 m = c % 32; 227 if ((NAME_CHARACTER[d] & (1 << m)) == 0) { 228 return false; 229 } 230 } 231 return true; 232 } 233 234 238 public static boolean isValidPrefix(String s) { 239 return s.indexOf(':') == -1; 240 } 241 242 246 public static String getPrefix(String s) { 247 int i = s.indexOf(':'); 248 return (i == -1 || i == s.length()-1) 249 ? null 250 : s.substring(0, i); 251 } 252 253 257 public static String getLocalName(String s) { 258 int i = s.indexOf(':'); 259 return (i == -1 || i == s.length()-1) 260 ? s 261 : s.substring(i + 1); 262 } 263 264 268 public static void parseStyleSheetPIData(String data, HashTable table) { 269 char c; 271 int i = 0; 272 while (i < data.length()) { 274 c = data.charAt(i); 275 if (!XMLUtilities.isXMLSpace(c)) { 276 break; 277 } 278 i++; 279 } 280 while (i < data.length()) { 281 c = data.charAt(i); 283 int d = c / 32; 284 int m = c % 32; 285 if ((NAME_FIRST_CHARACTER[d] & (1 << m)) == 0) { 286 throw new DOMException (DOMException.INVALID_CHARACTER_ERR, 287 "Wrong name initial: " + c); 288 } 289 StringBuffer ident = new StringBuffer (); 290 ident.append(c); 291 while (++i < data.length()) { 292 c = data.charAt(i); 293 d = c / 32; 294 m = c % 32; 295 if ((NAME_CHARACTER[d] & (1 << m)) == 0) { 296 break; 297 } 298 ident.append(c); 299 } 300 if (i >= data.length()) { 301 throw new DOMException (DOMException.SYNTAX_ERR, 302 "Wrong xml-stylesheet data: " + data); 303 } 304 while (i < data.length()) { 306 c = data.charAt(i); 307 if (!XMLUtilities.isXMLSpace(c)) { 308 break; 309 } 310 i++; 311 } 312 if (i >= data.length()) { 313 throw new DOMException (DOMException.SYNTAX_ERR, 314 "Wrong xml-stylesheet data: " + data); 315 } 316 if (data.charAt(i) != '=') { 318 throw new DOMException (DOMException.SYNTAX_ERR, 319 "Wrong xml-stylesheet data: " + data); 320 } 321 i++; 322 while (i < data.length()) { 324 c = data.charAt(i); 325 if (!XMLUtilities.isXMLSpace(c)) { 326 break; 327 } 328 i++; 329 } 330 if (i >= data.length()) { 331 throw new DOMException (DOMException.SYNTAX_ERR, 332 "Wrong xml-stylesheet data: " + data); 333 } 334 c = data.charAt(i); 336 i++; 337 StringBuffer value = new StringBuffer (); 338 if (c == '\'') { 339 while (i < data.length()) { 340 c = data.charAt(i); 341 if (c == '\'') { 342 break; 343 } 344 value.append(c); 345 i++; 346 } 347 if (i >= data.length()) { 348 throw new DOMException (DOMException.SYNTAX_ERR, 349 "Wrong xml-stylesheet data: " + 350 data); 351 } 352 } else if (c == '"') { 353 while (i < data.length()) { 354 c = data.charAt(i); 355 if (c == '"') { 356 break; 357 } 358 value.append(c); 359 i++; 360 } 361 if (i >= data.length()) { 362 throw new DOMException (DOMException.SYNTAX_ERR, 363 "Wrong xml-stylesheet data: " + 364 data); 365 } 366 } else { 367 throw new DOMException (DOMException.SYNTAX_ERR, 368 "Wrong xml-stylesheet data: " + data); 369 } 370 table.put(ident.toString().intern(), value.toString()); 371 i++; 372 while (i < data.length()) { 374 c = data.charAt(i); 375 if (!XMLUtilities.isXMLSpace(c)) { 376 break; 377 } 378 i++; 379 } 380 } 381 } 382 } 383 | Popular Tags |