1 11 12 package org.eclipse.ui; 13 14 import java.io.IOException ; 15 import java.io.PrintWriter ; 16 import java.io.Reader ; 17 import java.io.Writer ; 18 import java.util.ArrayList ; 19 20 import javax.xml.parsers.DocumentBuilder ; 21 import javax.xml.parsers.DocumentBuilderFactory ; 22 import javax.xml.parsers.ParserConfigurationException ; 23 24 import org.eclipse.ui.internal.WorkbenchMessages; 25 import org.eclipse.ui.internal.WorkbenchPlugin; 26 import org.w3c.dom.Attr ; 27 import org.w3c.dom.Document ; 28 import org.w3c.dom.Element ; 29 import org.w3c.dom.NamedNodeMap ; 30 import org.w3c.dom.Node ; 31 import org.w3c.dom.NodeList ; 32 import org.w3c.dom.Text ; 33 import org.xml.sax.InputSource ; 34 import org.xml.sax.SAXException ; 35 36 45 public final class XMLMemento implements IMemento { 46 private Document factory; 47 48 private Element element; 49 50 62 public static XMLMemento createReadRoot(Reader reader) 63 throws WorkbenchException { 64 return createReadRoot(reader, null); 65 } 66 67 81 public static XMLMemento createReadRoot(Reader reader, String baseDir) 82 throws WorkbenchException { 83 String errorMessage = null; 84 Exception exception = null; 85 86 try { 87 DocumentBuilderFactory factory = DocumentBuilderFactory 88 .newInstance(); 89 DocumentBuilder parser = factory.newDocumentBuilder(); 90 InputSource source = new InputSource (reader); 91 if (baseDir != null) { 92 source.setSystemId(baseDir); 93 } 94 Document document = parser.parse(source); 95 NodeList list = document.getChildNodes(); 96 for (int i = 0; i < list.getLength(); i++) { 97 Node node = list.item(i); 98 if (node instanceof Element ) { 99 return new XMLMemento(document, (Element ) node); 100 } 101 } 102 } catch (ParserConfigurationException e) { 103 exception = e; 104 errorMessage = WorkbenchMessages.XMLMemento_parserConfigError; 105 } catch (IOException e) { 106 exception = e; 107 errorMessage = WorkbenchMessages.XMLMemento_ioError; 108 } catch (SAXException e) { 109 exception = e; 110 errorMessage = WorkbenchMessages.XMLMemento_formatError; 111 } 112 113 String problemText = null; 114 if (exception != null) { 115 problemText = exception.getMessage(); 116 } 117 if (problemText == null || problemText.length() == 0) { 118 problemText = errorMessage != null ? errorMessage 119 : WorkbenchMessages.XMLMemento_noElement; 120 } 121 throw new WorkbenchException(problemText, exception); 122 } 123 124 130 public static XMLMemento createWriteRoot(String type) { 131 Document document; 132 try { 133 document = DocumentBuilderFactory.newInstance() 134 .newDocumentBuilder().newDocument(); 135 Element element = document.createElement(type); 136 document.appendChild(element); 137 return new XMLMemento(document, element); 138 } catch (ParserConfigurationException e) { 139 throw new Error (e.getMessage()); 141 } 142 } 143 144 155 public XMLMemento(Document document, Element element) { 156 super(); 157 this.factory = document; 158 this.element = element; 159 } 160 161 164 public IMemento createChild(String type) { 165 Element child = factory.createElement(type); 166 element.appendChild(child); 167 return new XMLMemento(factory, child); 168 } 169 170 173 public IMemento createChild(String type, String id) { 174 Element child = factory.createElement(type); 175 child.setAttribute(TAG_ID, id == null ? "" : id); element.appendChild(child); 177 return new XMLMemento(factory, child); 178 } 179 180 183 public IMemento copyChild(IMemento child) { 184 Element childElement = ((XMLMemento) child).element; 185 Element newElement = (Element ) factory.importNode(childElement, true); 186 element.appendChild(newElement); 187 return new XMLMemento(factory, newElement); 188 } 189 190 193 public IMemento getChild(String type) { 194 195 NodeList nodes = element.getChildNodes(); 197 int size = nodes.getLength(); 198 if (size == 0) { 199 return null; 200 } 201 202 for (int nX = 0; nX < size; nX++) { 204 Node node = nodes.item(nX); 205 if (node instanceof Element ) { 206 Element element = (Element ) node; 207 if (element.getNodeName().equals(type)) { 208 return new XMLMemento(factory, element); 209 } 210 } 211 } 212 213 return null; 215 } 216 217 220 public IMemento[] getChildren(String type) { 221 222 NodeList nodes = element.getChildNodes(); 224 int size = nodes.getLength(); 225 if (size == 0) { 226 return new IMemento[0]; 227 } 228 229 ArrayList list = new ArrayList (size); 231 for (int nX = 0; nX < size; nX++) { 232 Node node = nodes.item(nX); 233 if (node instanceof Element ) { 234 Element element = (Element ) node; 235 if (element.getNodeName().equals(type)) { 236 list.add(element); 237 } 238 } 239 } 240 241 size = list.size(); 243 IMemento[] results = new IMemento[size]; 244 for (int x = 0; x < size; x++) { 245 results[x] = new XMLMemento(factory, (Element ) list.get(x)); 246 } 247 return results; 248 } 249 250 253 public Float getFloat(String key) { 254 Attr attr = element.getAttributeNode(key); 255 if (attr == null) { 256 return null; 257 } 258 String strValue = attr.getValue(); 259 try { 260 return new Float (strValue); 261 } catch (NumberFormatException e) { 262 WorkbenchPlugin.log("Memento problem - Invalid float for key: " + key + " value: " + strValue, e); return null; 265 } 266 } 267 268 271 public String getID() { 272 return element.getAttribute(TAG_ID); 273 } 274 275 278 public Integer getInteger(String key) { 279 Attr attr = element.getAttributeNode(key); 280 if (attr == null) { 281 return null; 282 } 283 String strValue = attr.getValue(); 284 try { 285 return new Integer (strValue); 286 } catch (NumberFormatException e) { 287 WorkbenchPlugin 288 .log("Memento problem - invalid integer for key: " + key + " value: " + strValue, e); return null; 291 } 292 } 293 294 297 public String getString(String key) { 298 Attr attr = element.getAttributeNode(key); 299 if (attr == null) { 300 return null; 301 } 302 return attr.getValue(); 303 } 304 305 308 public String getTextData() { 309 Text textNode = getTextNode(); 310 if (textNode != null) { 311 return textNode.getData(); 312 } 313 return null; 314 } 315 316 323 private Text getTextNode() { 324 NodeList nodes = element.getChildNodes(); 326 int size = nodes.getLength(); 327 if (size == 0) { 328 return null; 329 } 330 for (int nX = 0; nX < size; nX++) { 331 Node node = nodes.item(nX); 332 if (node instanceof Text ) { 333 return (Text ) node; 334 } 335 } 336 return null; 338 } 339 340 344 private void putElement(Element element, boolean copyText) { 345 NamedNodeMap nodeMap = element.getAttributes(); 346 int size = nodeMap.getLength(); 347 for (int i = 0; i < size; i++) { 348 Attr attr = (Attr ) nodeMap.item(i); 349 putString(attr.getName(), attr.getValue()); 350 } 351 352 NodeList nodes = element.getChildNodes(); 353 size = nodes.getLength(); 354 boolean needToCopyText = copyText; 357 for (int i = 0; i < size; i++) { 358 Node node = nodes.item(i); 359 if (node instanceof Element ) { 360 XMLMemento child = (XMLMemento) createChild(node.getNodeName()); 361 child.putElement((Element ) node, true); 362 } else if (node instanceof Text && needToCopyText) { 363 putTextData(((Text ) node).getData()); 364 needToCopyText = false; 365 } 366 } 367 } 368 369 372 public void putFloat(String key, float f) { 373 element.setAttribute(key, String.valueOf(f)); 374 } 375 376 379 public void putInteger(String key, int n) { 380 element.setAttribute(key, String.valueOf(n)); 381 } 382 383 386 public void putMemento(IMemento memento) { 387 putElement(((XMLMemento) memento).element, false); 390 } 391 392 395 public void putString(String key, String value) { 396 if (value == null) { 397 return; 398 } 399 element.setAttribute(key, value); 400 } 401 402 405 public void putTextData(String data) { 406 Text textNode = getTextNode(); 407 if (textNode == null) { 408 textNode = factory.createTextNode(data); 409 element.insertBefore(textNode, element.getFirstChild()); 411 } else { 412 textNode.setData(data); 413 } 414 } 415 416 423 public void save(Writer writer) throws IOException { 424 DOMWriter out = new DOMWriter(writer); 425 try { 426 out.print(element); 427 } finally { 428 out.close(); 429 } 430 } 431 432 436 private static final class DOMWriter extends PrintWriter { 437 438 private int tab; 439 440 441 private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 443 448 public DOMWriter(Writer output) { 449 super(output); 450 tab = 0; 451 println(XML_VERSION); 452 } 453 454 459 public void print(Element element) { 460 boolean hasChildren = element.hasChildNodes(); 464 startTag(element, hasChildren); 465 if (hasChildren) { 466 tab++; 467 boolean prevWasText = false; 468 NodeList children = element.getChildNodes(); 469 for (int i = 0; i < children.getLength(); i++) { 470 Node node = children.item(i); 471 if (node instanceof Element ) { 472 if (!prevWasText) { 473 println(); 474 printTabulation(); 475 } 476 print((Element ) children.item(i)); 477 prevWasText = false; 478 } 479 else if (node instanceof Text ) { 480 print(getEscaped(node.getNodeValue())); 481 prevWasText = true; 482 } 483 } 484 tab--; 485 if (!prevWasText) { 486 println(); 487 printTabulation(); 488 } 489 endTag(element); 490 } 491 } 492 493 private void printTabulation() { 494 499 } 502 503 private void startTag(Element element, boolean hasChildren) { 504 StringBuffer sb = new StringBuffer (); 505 sb.append("<"); sb.append(element.getTagName()); 507 NamedNodeMap attributes = element.getAttributes(); 508 for (int i = 0; i < attributes.getLength(); i++) { 509 Attr attribute = (Attr )attributes.item(i); 510 sb.append(" "); sb.append(attribute.getName()); 512 sb.append("=\""); sb.append(getEscaped(String.valueOf(attribute.getValue()))); 514 sb.append("\""); } 516 sb.append(hasChildren ? ">" : "/>"); print(sb.toString()); 518 } 519 520 private void endTag(Element element) { 521 StringBuffer sb = new StringBuffer (); 522 sb.append("</"); sb.append(element.getNodeName()); 524 sb.append(">"); print(sb.toString()); 526 } 527 528 private static void appendEscapedChar(StringBuffer buffer, char c) { 529 String replacement = getReplacement(c); 530 if (replacement != null) { 531 buffer.append('&'); 532 buffer.append(replacement); 533 buffer.append(';'); 534 } else { 535 buffer.append(c); 536 } 537 } 538 539 private static String getEscaped(String s) { 540 StringBuffer result = new StringBuffer (s.length() + 10); 541 for (int i = 0; i < s.length(); ++i) { 542 appendEscapedChar(result, s.charAt(i)); 543 } 544 return result.toString(); 545 } 546 547 private static String getReplacement(char c) { 548 switch (c) { 554 case '<' : 555 return "lt"; case '>' : 557 return "gt"; case '"' : 559 return "quot"; case '\'' : 561 return "apos"; case '&' : 563 return "amp"; case '\r': 565 return "#x0D"; case '\n': 567 return "#x0A"; case '\u0009': 569 return "#x09"; } 571 return null; 572 } 573 } 574 } 575 | Popular Tags |