1 /**********************************************************************
2 * Copyright (c) 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - Initial API and implementation
10 **********************************************************************/
11 package net.sourceforge.phpdt.httpquery.config;
13 import java.io.ByteArrayInputStream;
14 import java.io.ByteArrayOutputStream;
15 import java.io.FileReader;
16 import java.io.FileWriter;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.InputStreamReader;
20 import java.io.OutputStream;
21 import java.io.Reader;
22 import java.io.Writer;
24 import java.util.ArrayList;
25 import java.util.List;
27 import javax.xml.parsers.DocumentBuilder;
28 import javax.xml.parsers.DocumentBuilderFactory;
29 import javax.xml.parsers.ParserConfigurationException;
30 import javax.xml.transform.OutputKeys;
31 import javax.xml.transform.Result;
32 import javax.xml.transform.Source;
33 import javax.xml.transform.Transformer;
34 import javax.xml.transform.TransformerFactory;
35 import javax.xml.transform.dom.DOMSource;
36 import javax.xml.transform.stream.StreamResult;
38 import org.w3c.dom.Attr;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.Element;
41 import org.w3c.dom.NamedNodeMap;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.NodeList;
44 import org.xml.sax.InputSource;
45 import org.xml.sax.SAXException;
48 * A Memento is a class independent container for persistence info. It is a
49 * reflection of 3 storage requirements.
51 * 1) We need the ability to persist an object and restore it. 2) The class for
52 * an object may be absent. If so we would like to skip the object and keep
53 * reading. 3) The class for an object may change. If so the new class should be
54 * able to read the old persistence info.
56 * We could ask the objects to serialize themselves into an ObjectOutputStream,
57 * DataOutputStream, or Hashtable. However all of these approaches fail to meet
58 * the second requirement.
60 * Memento supports binary persistance with a version ID.
62 public final class XMLMemento implements IMemento {
63 private Document factory;
65 private Element element;
68 * Answer a memento for the document and element. For simplicity you should
69 * use createReadRoot and createWriteRoot to create the initial mementos on
72 public XMLMemento(Document doc, Element el) {
80 public IMemento createChild(String type) {
81 Element child = factory.createElement(type);
82 element.appendChild(child);
83 return new XMLMemento(factory, child);
89 public IMemento createChild(String type, String id) {
90 Element child = factory.createElement(type);
91 child.setAttribute(TAG_ID, id);
92 element.appendChild(child);
93 return new XMLMemento(factory, child);
97 * Create a Document from a Reader and answer a root memento for reading a
100 protected static XMLMemento createReadRoot(Reader reader) {
101 Document document = null;
103 DocumentBuilderFactory factory = DocumentBuilderFactory
105 DocumentBuilder parser = factory.newDocumentBuilder();
106 document = parser.parse(new InputSource(reader));
107 Node node = document.getFirstChild();
108 if (node instanceof Element)
109 return new XMLMemento(document, (Element) node);
110 } catch (ParserConfigurationException e) {
111 } catch (IOException e) {
112 } catch (SAXException e) {
116 } catch (Exception e) {
123 * Answer a root memento for writing a document.
125 public static XMLMemento createWriteRoot(String type) {
128 document = DocumentBuilderFactory.newInstance()
129 .newDocumentBuilder().newDocument();
130 Element element = document.createElement(type);
131 document.appendChild(element);
132 return new XMLMemento(document, element);
133 } catch (ParserConfigurationException e) {
141 public IMemento getChild(String type) {
143 NodeList nodes = element.getChildNodes();
144 int size = nodes.getLength();
148 // Find the first node which is a child of this node.
149 for (int nX = 0; nX < size; nX++) {
150 Node node = nodes.item(nX);
151 if (node instanceof Element) {
152 Element element2 = (Element) node;
153 if (element2.getNodeName().equals(type))
154 return new XMLMemento(factory, element2);
158 // A child was not found.
165 public IMemento[] getChildren(String type) {
167 NodeList nodes = element.getChildNodes();
168 int size = nodes.getLength();
170 return new IMemento[0];
172 // Extract each node with given fType.
173 ArrayList list = new ArrayList(size);
174 for (int nX = 0; nX < size; nX++) {
175 Node node = nodes.item(nX);
176 if (node instanceof Element) {
177 Element element2 = (Element) node;
178 if (element2.getNodeName().equals(type))
183 // Create a memento for each node.
185 IMemento[] results = new IMemento[size];
186 for (int x = 0; x < size; x++) {
187 results[x] = new XMLMemento(factory, (Element) list.get(x));
193 * Return the contents of this memento as a byte array.
197 public byte[] getContents() throws IOException {
198 ByteArrayOutputStream out = new ByteArrayOutputStream();
200 return out.toByteArray();
204 * Returns an input stream for writing to the disk with a local locale.
206 * @return java.io.InputStream
208 public InputStream getInputStream() throws IOException {
209 ByteArrayOutputStream out = new ByteArrayOutputStream();
211 return new ByteArrayInputStream(out.toByteArray());
217 public Float getFloat(String key) {
218 Attr attr = element.getAttributeNode(key);
221 String strValue = attr.getValue();
223 return new Float(strValue);
224 } catch (NumberFormatException e) {
232 public String getId() {
233 return element.getAttribute(TAG_ID);
239 public String getName() {
240 return element.getNodeName();
246 public Integer getInteger(String key) {
247 Attr attr = element.getAttributeNode(key);
250 String strValue = attr.getValue();
252 return new Integer(strValue);
253 } catch (NumberFormatException e) {
261 public String getString(String key) {
262 Attr attr = element.getAttributeNode(key);
265 return attr.getValue();
268 public List getNames() {
269 NamedNodeMap map = element.getAttributes();
270 int size = map.getLength();
271 List list = new ArrayList();
272 for (int i = 0; i < size; i++) {
273 Node node = map.item(i);
274 String name = node.getNodeName();
281 * Loads a memento from the given filename.
284 * java.io.InputStream
285 * @return org.eclipse.ui.IMemento
286 * @exception java.io.IOException
288 public static IMemento loadMemento(InputStream in) {
289 return createReadRoot(new InputStreamReader(in));
293 * Loads a memento from the given filename.
296 * java.io.InputStream
297 * @return org.eclipse.ui.IMemento
298 * @exception java.io.IOException
300 public static IMemento loadCorruptMemento(InputStream in) {
301 Document document = null;
303 DocumentBuilderFactory factory = DocumentBuilderFactory
305 DocumentBuilder parser = factory.newDocumentBuilder();
306 document = parser.parse(in);
307 Node node = document.getFirstChild();
308 if (node instanceof Element)
309 return new XMLMemento(document, (Element) node);
310 } catch (ParserConfigurationException e) {
311 } catch (IOException e) {
312 } catch (SAXException e) {
316 } catch (Exception e) {
323 * Loads a memento from the given filename.
327 * @return org.eclipse.ui.IMemento
328 * @exception java.io.IOException
330 public static IMemento loadMemento(String filename) throws IOException {
331 return XMLMemento.createReadRoot(new FileReader(filename));
335 * Loads a memento from the given filename.
339 * @return org.eclipse.ui.IMemento
340 * @exception java.io.IOException
342 public static IMemento loadMemento(URL url) throws IOException {
344 .createReadRoot(new InputStreamReader(url.openStream()));
350 private void putElement(Element element2) {
351 NamedNodeMap nodeMap = element2.getAttributes();
352 int size = nodeMap.getLength();
353 for (int i = 0; i < size; i++) {
354 Attr attr = (Attr) nodeMap.item(i);
355 putString(attr.getName(), attr.getValue());
358 NodeList nodes = element2.getChildNodes();
359 size = nodes.getLength();
360 for (int i = 0; i < size; i++) {
361 Node node = nodes.item(i);
362 if (node instanceof Element) {
363 XMLMemento child = (XMLMemento) createChild(node.getNodeName());
364 child.putElement((Element) node);
372 public void putFloat(String key, float f) {
373 element.setAttribute(key, String.valueOf(f));
379 public void putInteger(String key, int n) {
380 element.setAttribute(key, String.valueOf(n));
386 public void putMemento(IMemento memento) {
387 XMLMemento xmlMemento = (XMLMemento) memento;
388 putElement(xmlMemento.element);
394 public void putString(String key, String value) {
397 element.setAttribute(key, value);
401 * Save this Memento to a Writer.
403 public void save(Writer writer) throws IOException {
404 Result result = new StreamResult(writer);
405 Source source = new DOMSource(factory);
407 Transformer transformer = TransformerFactory.newInstance()
409 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
410 transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
411 transformer.transform(source, result);
412 } catch (Exception e) {
413 throw (IOException) (new IOException().initCause(e));
418 * Save this Memento to a Writer.
420 public void save(OutputStream os) throws IOException {
421 Result result = new StreamResult(os);
422 Source source = new DOMSource(factory);
424 Transformer transformer = TransformerFactory.newInstance()
426 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
427 transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
428 transformer.transform(source, result);
429 } catch (Exception e) {
430 throw (IOException) (new IOException().initCause(e));
435 * Saves the memento to the given file.
439 * @exception java.io.IOException
441 public void saveToFile(String filename) throws IOException {
444 w = new FileWriter(filename);
446 } catch (IOException e) {
448 } catch (Exception e) {
449 throw new IOException(e.getLocalizedMessage());
454 } catch (Exception e) {
460 public String saveToString() throws IOException {
461 ByteArrayOutputStream out = new ByteArrayOutputStream();
463 return out.toString("UTF-8");
467 * @see IMemento#getBoolean(String)
469 public Boolean getBoolean(String key) {
470 Attr attr = element.getAttributeNode(key);
473 String strValue = attr.getValue();
474 if ("true".equalsIgnoreCase(strValue))
475 return new Boolean(true);
477 return new Boolean(false);
481 * @see IMemento#putBoolean(String, boolean)
483 public void putBoolean(String key, boolean value) {
484 element.setAttribute(key, value ? "true" : "false");