1 18 19 package org.apache.batik.svggen; 20 21 import java.io.IOException ; 22 import java.io.OutputStreamWriter ; 23 import java.io.Writer ; 24 25 import org.apache.batik.util.SVGConstants; 26 import org.w3c.dom.Attr ; 27 import org.w3c.dom.CDATASection ; 28 import org.w3c.dom.Comment ; 29 import org.w3c.dom.Document ; 30 import org.w3c.dom.Element ; 31 import org.w3c.dom.NamedNodeMap ; 32 import org.w3c.dom.Node ; 33 import org.w3c.dom.NodeList ; 34 import org.w3c.dom.Text ; 35 36 46 class XmlWriter implements SVGConstants { 47 48 static private String EOL; 49 static private final String TAG_END = " />"; 50 static private final String TAG_START = "</"; 51 static private final String SPACE = " "; 52 53 static private final char[] SPACES = 54 { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 55 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' }; 56 static private final int SPACES_LEN = SPACES.length; 57 58 static { 59 String temp; 60 try { temp = System.getProperty ("line.separator", "\n"); } 61 catch (SecurityException e) { temp = "\n"; } 62 EOL = temp; 63 } 64 65 static class IndentWriter extends Writer { 66 protected Writer proxied; 67 protected int indentLevel; 68 protected int column; 69 70 public IndentWriter(Writer proxied){ 71 if (proxied == null) 72 throw new SVGGraphics2DRuntimeException(ErrorConstants.ERR_PROXY); 73 74 this.proxied = proxied; 75 } 76 77 public void setIndentLevel(int indentLevel){ 78 this.indentLevel = indentLevel; 79 } 80 81 public int getIndentLevel(){ 82 return indentLevel; 83 } 84 85 public void printIndent() throws IOException { 86 proxied.write(EOL); 87 int temp = indentLevel; 88 while(temp > 0){ 89 if (temp > SPACES_LEN) { 90 proxied.write(SPACES, 0, SPACES_LEN); 91 temp -= SPACES_LEN; 92 } else { 93 proxied.write(SPACES, 0, temp); 94 break; 95 } 96 } 97 column = indentLevel; 98 } 99 100 public Writer getProxied(){ 101 return proxied; 102 } 103 104 public int getColumn() { return column; } 105 106 public void write(int c) throws IOException { 107 column++; 108 proxied.write(c); 109 } 110 111 public void write(char cbuf[]) throws IOException { 112 column+=cbuf.length; 113 proxied.write(cbuf); 114 } 115 116 public void write(char cbuf[], int off, int len) throws IOException { 117 column+=len; 118 proxied.write(cbuf, off, len); 119 } 120 121 public void write(String str) throws IOException { 122 column+=str.length(); 123 proxied.write(str); 124 } 125 126 public void write(String str, int off, int len) throws IOException { 127 column+=len; 128 proxied.write(str, off, len); 129 } 130 131 public void flush() throws IOException { 132 proxied.flush(); 133 } 134 135 public void close() throws IOException { 136 column = -1; 137 proxied.close(); 138 } 139 } 140 141 private static void writeXml(Attr attr, IndentWriter out) 142 throws IOException { 143 String name = attr.getName(); 144 out.write (name); 145 out.write ("=\""); 146 writeChildrenXml(attr, out); 147 out.write ('"'); 148 } 149 150 153 private static void writeChildrenXml(Attr attr, IndentWriter out) 154 throws IOException { 155 char data[] = attr.getValue().toCharArray(); 156 if (data == null) return; 157 158 int length = data.length; 159 int start=0, last=0; 160 while (last < length) { 161 char c = data[last]; 162 switch (c) { 163 case '<': 164 out.write (data, start, last - start); 165 start = last + 1; 166 out.write ("<"); 167 break; 168 case '>': 169 out.write (data, start, last - start); 170 start = last + 1; 171 out.write (">"); 172 break; 173 case '&': 174 out.write (data, start, last - start); 175 start = last + 1; 176 out.write ("&"); 177 break; 178 case '\'': 179 out.write (data, start, last - start); 180 start = last + 1; 181 out.write ("'"); 182 break; 183 case '"': 184 out.write (data, start, last - start); 185 start = last + 1; 186 out.write ("""); 187 break; 188 default: 189 } 190 last++; 191 } 192 out.write (data, start, last - start); 193 } 194 195 200 private static void writeXml(Comment comment, IndentWriter out) 201 throws IOException { 202 203 char data[] = comment.getData().toCharArray(); 204 205 if (data == null) { 206 out.write("<!---->"); 207 return; 208 } 209 210 out.write ("<!--"); 211 boolean sawDash = false; 212 int length = data.length; 213 int start=0, last=0; 214 215 while (last < length) { 217 char c = data[last]; 218 if (c == '-') { 219 if (sawDash) { 220 out.write (data, start, last - start); 221 start = last; 222 out.write (' '); 223 } 224 sawDash = true; 225 } else { 226 sawDash = false; 227 } 228 last++; 229 } 230 out.write (data, start, last - start); 231 if (sawDash) 232 out.write (' '); 233 out.write ("-->"); 234 } 235 236 private static void writeXml(Text text, IndentWriter out) 237 throws IOException { 238 writeXml(text, out, false); 239 } 240 241 private static void writeXml(Text text, IndentWriter out, boolean trimWS) 242 throws IOException { 243 char data[] = text.getData().toCharArray(); 244 245 if (data == null) 247 { System.err.println ("Null text data??"); return; } 248 249 int length = data.length; 250 int start = 0, last = 0; 251 if (trimWS) { 252 while (last < length) { 253 char c = data[last]; 254 switch (c) { 255 case ' ': case '\t': case '\n': case '\r': last++; continue; 256 default: break; 257 } 258 break; 259 } 260 start = last; 261 } 262 263 while (last < length) { 264 char c = data [last]; 265 266 switch(c) { 275 case ' ': case '\t': case '\n': case '\r': 276 if (trimWS) { 277 int wsStart = last; last++; 278 while (last < length) { 279 switch(data[last]) { 280 case ' ': case '\t': case '\n': case '\r': 281 last++; continue; 282 default: break; 283 } 284 break; 285 } 286 if (last == length) { 287 out.write(data, start, wsStart-start); 288 return; 289 } else { 290 continue; 291 } 292 } 293 break; 294 case '<': out.write (data, start, last - start); 296 start = last + 1; 297 out.write ("<"); 298 break; 299 case '>': out.write (data, start, last - start); 301 start = last + 1; 302 out.write (">"); 303 break; 304 case '&': out.write (data, start, last - start); 306 start = last + 1; 307 out.write ("&"); 308 break; 309 } 310 last++; 311 } 312 out.write (data, start, last - start); 313 } 314 315 private static void writeXml(CDATASection cdataSection, IndentWriter out) 316 throws IOException { 317 char[] data = cdataSection.getData().toCharArray(); 318 if (data == null) { 319 out.write ("<![CDATA[]]>"); 320 return; 321 } 322 323 out.write ("<![CDATA["); 324 int length = data.length; 325 int start = 0, last = 0; 326 while (last < length) { 327 char c = data [last]; 328 329 if (c == ']') { 332 if (((last + 2) < data.length) && 333 (data [last + 1] == ']') && 334 (data [last + 2] == '>')) { 335 out.write (data, start, last - start); 336 start = last + 1; 337 out.write ("]]]]><![CDATA[>"); 338 continue; 339 } 340 } 341 last++; 342 } 343 out.write (data, start, last - start); 344 out.write ("]]>"); 345 } 346 347 private static void writeXml(Element element, IndentWriter out) 348 throws IOException , SVGGraphics2DIOException { 349 out.write (TAG_START, 0, 1); out.write (element.getTagName()); 351 352 NamedNodeMap attributes = element.getAttributes(); 353 if (attributes != null){ 354 int nAttr = attributes.getLength(); 355 for(int i=0; i<nAttr; i++){ 356 Attr attr = (Attr )attributes.item(i); 357 out.write(' '); 358 writeXml(attr, out); 359 } 360 } 361 362 if (!element.hasChildNodes()) 368 out.write(TAG_END, 0, 3); else { 370 out.write(TAG_END, 2, 1); writeChildrenXml(element, out); 372 out.write (TAG_START, 0, 2); out.write (element.getTagName()); 374 out.write (TAG_END, 2, 1); } 376 } 377 378 private static void writeChildrenXml(Element element, IndentWriter out) 379 throws IOException , SVGGraphics2DIOException { 380 NodeList children = element.getChildNodes(); 381 if (children == null) 382 return; 383 384 int length = children.getLength(); 385 int oldIndent = 0; 386 oldIndent = out.getIndentLevel(); 387 try { 388 out.setIndentLevel(oldIndent + 2); 389 for(int i = 0; i < length; i++) { 390 if(children.item(i).getNodeType () != Node.TEXT_NODE) { 391 out.printIndent (); 392 } 393 writeXml(children.item(i), out); 394 } 395 } finally { 396 out.setIndentLevel(oldIndent); 397 if (length > 0 && children.item(length-1).getNodeType() != Node.TEXT_NODE){ 398 out.printIndent(); } 400 } 401 } 402 403 private static void writeDocumentHeader(IndentWriter out) 404 throws IOException { 405 String encoding = null; 406 407 if (out.getProxied() instanceof OutputStreamWriter ) 408 encoding = 409 java2std(((OutputStreamWriter )out.getProxied()).getEncoding()); 410 411 out.write ("<?xml version=\"1.0\""); 412 if (encoding != null) { 413 out.write (" encoding=\""); 414 out.write (encoding); 415 out.write ('\"'); 416 } 417 out.write ("?>"); 418 out.write (EOL); 419 out.write (EOL); 420 421 out.write ("<!DOCTYPE svg PUBLIC '"); 423 out.write (SVG_PUBLIC_ID); 424 out.write ("' '"); 425 out.write (SVG_SYSTEM_ID); 426 out.write ("'"); 427 428 out.write (">"); 429 out.write (EOL); 430 } 431 432 private static void writeXml(Document document, IndentWriter out) 433 throws IOException , SVGGraphics2DIOException { 434 writeDocumentHeader(out); 435 NodeList childList = document.getChildNodes(); 436 writeXml(childList, out); 437 } 438 439 private static void writeXml(NodeList childList, IndentWriter out) 440 throws IOException , SVGGraphics2DIOException { 441 int length = childList.getLength (); 442 443 if (length == 0) 444 return; 445 for (int i = 0; i < length; i++) { 446 Node child = childList.item(i); 447 writeXml(child, out); 448 out.write (EOL); 449 } 450 } 451 452 static String java2std(String encodingName) { 453 if (encodingName == null) 454 return null; 455 456 if (encodingName.startsWith ("ISO8859_")) return "ISO-8859-" + encodingName.substring (8); 463 if (encodingName.startsWith ("8859_")) return "ISO-8859-" + encodingName.substring (5); 465 466 469 if ("ASCII7".equalsIgnoreCase (encodingName) 470 || "ASCII".equalsIgnoreCase (encodingName)) 471 return "US-ASCII"; 472 473 if ("UTF8".equalsIgnoreCase (encodingName)) 478 return "UTF-8"; 479 if (encodingName.startsWith ("Unicode")) 480 return "UTF-16"; 481 482 if ("SJIS".equalsIgnoreCase (encodingName)) 486 return "Shift_JIS"; 487 if ("JIS".equalsIgnoreCase (encodingName)) 488 return "ISO-2022-JP"; 489 if ("EUCJIS".equalsIgnoreCase (encodingName)) 490 return "EUC-JP"; 491 492 return encodingName; 494 } 495 496 public static void writeXml(Node node, Writer writer) 497 throws SVGGraphics2DIOException { 498 try { 499 IndentWriter out = null; 500 if (writer instanceof IndentWriter) 501 out = (IndentWriter)writer; 502 else 503 out = new IndentWriter(writer); 504 505 switch (node.getNodeType()) { 506 case Node.ATTRIBUTE_NODE: 507 writeXml((Attr )node, out); 508 break; 509 case Node.COMMENT_NODE: 510 writeXml((Comment )node, out); 511 break; 512 case Node.TEXT_NODE: 513 writeXml((Text )node, out); 514 break; 515 case Node.CDATA_SECTION_NODE: 516 writeXml((CDATASection )node, out); 517 break; 518 case Node.DOCUMENT_NODE: 519 writeXml((Document )node, out); 520 break; 521 case Node.DOCUMENT_FRAGMENT_NODE: 522 writeDocumentHeader(out); 523 NodeList childList = node.getChildNodes(); 524 writeXml(childList, out); 525 break; 526 case Node.ELEMENT_NODE: 527 writeXml((Element )node, out); 528 break; 529 default: 530 throw 531 new SVGGraphics2DRuntimeException(ErrorConstants.INVALID_NODE+ 532 node.getClass(). 533 getName()); 534 } 535 } catch (IOException io) { 536 throw new SVGGraphics2DIOException(io); 537 } 538 } 539 } 540 | Popular Tags |