X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse.phphelp/src/net/sourceforge/phpdt/httpquery/config/XMLMemento.java b/net.sourceforge.phpeclipse.phphelp/src/net/sourceforge/phpdt/httpquery/config/XMLMemento.java new file mode 100644 index 0000000..dc1954d --- /dev/null +++ b/net.sourceforge.phpeclipse.phphelp/src/net/sourceforge/phpdt/httpquery/config/XMLMemento.java @@ -0,0 +1,471 @@ +/********************************************************************** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - Initial API and implementation + **********************************************************************/ +package net.sourceforge.phpdt.httpquery.config; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +/** + * A Memento is a class independent container for persistence + * info. It is a reflection of 3 storage requirements. + * + * 1) We need the ability to persist an object and restore it. + * 2) The class for an object may be absent. If so we would + * like to skip the object and keep reading. + * 3) The class for an object may change. If so the new class + * should be able to read the old persistence info. + * + * We could ask the objects to serialize themselves into an + * ObjectOutputStream, DataOutputStream, or Hashtable. However + * all of these approaches fail to meet the second requirement. + * + * Memento supports binary persistance with a version ID. + */ +public final class XMLMemento implements IMemento { + private Document factory; + private Element element; + + /** + * Answer a memento for the document and element. For simplicity + * you should use createReadRoot and createWriteRoot to create the initial + * mementos on a document. + */ + public XMLMemento(Document doc, Element el) { + factory = doc; + element = el; + } + + /** + * @see IMemento. + */ + public IMemento createChild(String type) { + Element child = factory.createElement(type); + element.appendChild(child); + return new XMLMemento(factory, child); + } + + /** + * @see IMemento. + */ + public IMemento createChild(String type, String id) { + Element child = factory.createElement(type); + child.setAttribute(TAG_ID, id); + element.appendChild(child); + return new XMLMemento(factory, child); + } + + /** + * Create a Document from a Reader and answer a root memento for reading + * a document. + */ + protected static XMLMemento createReadRoot(Reader reader) { + Document document = null; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder parser = factory.newDocumentBuilder(); + document = parser.parse(new InputSource(reader)); + Node node = document.getFirstChild(); + if (node instanceof Element) + return new XMLMemento(document, (Element) node); + } catch (ParserConfigurationException e) { + } catch (IOException e) { + } catch (SAXException e) { + } finally { + try { + reader.close(); + } catch (Exception e) { } + } + return null; + } + + /** + * Answer a root memento for writing a document. + */ + public static XMLMemento createWriteRoot(String type) { + Document document; + try { + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + Element element = document.createElement(type); + document.appendChild(element); + return new XMLMemento(document, element); + } catch (ParserConfigurationException e) { + throw new Error(e); + } + } + + /** + * @see IMemento. + */ + public IMemento getChild(String type) { + // Get the nodes. + NodeList nodes = element.getChildNodes(); + int size = nodes.getLength(); + if (size == 0) + return null; + + // Find the first node which is a child of this node. + for (int nX = 0; nX < size; nX ++) { + Node node = nodes.item(nX); + if (node instanceof Element) { + Element element2 = (Element)node; + if (element2.getNodeName().equals(type)) + return new XMLMemento(factory, element2); + } + } + + // A child was not found. + return null; + } + + /** + * @see IMemento. + */ + public IMemento [] getChildren(String type) { + // Get the nodes. + NodeList nodes = element.getChildNodes(); + int size = nodes.getLength(); + if (size == 0) + return new IMemento[0]; + + // Extract each node with given fType. + ArrayList list = new ArrayList(size); + for (int nX = 0; nX < size; nX ++) { + Node node = nodes.item(nX); + if (node instanceof Element) { + Element element2 = (Element)node; + if (element2.getNodeName().equals(type)) + list.add(element2); + } + } + + // Create a memento for each node. + size = list.size(); + IMemento [] results = new IMemento[size]; + for (int x = 0; x < size; x ++) { + results[x] = new XMLMemento(factory, (Element)list.get(x)); + } + return results; + } + + /** + * Return the contents of this memento as a byte array. + * + * @return byte[] + */ + public byte[] getContents() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + save(out); + return out.toByteArray(); + } + + /** + * Returns an input stream for writing to the disk with a local locale. + * + * @return java.io.InputStream + */ + public InputStream getInputStream() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + save(out); + return new ByteArrayInputStream(out.toByteArray()); + } + + /** + * @see IMemento. + */ + public Float getFloat(String key) { + Attr attr = element.getAttributeNode(key); + if (attr == null) + return null; + String strValue = attr.getValue(); + try { + return new Float(strValue); + } catch (NumberFormatException e) { + return null; + } + } + + /** + * @see IMemento. + */ + public String getId() { + return element.getAttribute(TAG_ID); + } + + /** + * @see IMemento. + */ + public String getName() { + return element.getNodeName(); + } + + /** + * @see IMemento. + */ + public Integer getInteger(String key) { + Attr attr = element.getAttributeNode(key); + if (attr == null) + return null; + String strValue = attr.getValue(); + try { + return new Integer(strValue); + } catch (NumberFormatException e) { + return null; + } + } + + /** + * @see IMemento. + */ + public String getString(String key) { + Attr attr = element.getAttributeNode(key); + if (attr == null) + return null; + return attr.getValue(); + } + + public List getNames() { + NamedNodeMap map = element.getAttributes(); + int size = map.getLength(); + List list = new ArrayList(); + for (int i = 0; i < size; i++) { + Node node = map.item(i); + String name = node.getNodeName(); + list.add(name); + } + return list; + } + + /** + * Loads a memento from the given filename. + * + * @param in java.io.InputStream + * @return org.eclipse.ui.IMemento + * @exception java.io.IOException + */ + public static IMemento loadMemento(InputStream in) { + return createReadRoot(new InputStreamReader(in)); + } + + /** + * Loads a memento from the given filename. + * + * @param in java.io.InputStream + * @return org.eclipse.ui.IMemento + * @exception java.io.IOException + */ + public static IMemento loadCorruptMemento(InputStream in) { + Document document = null; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder parser = factory.newDocumentBuilder(); + document = parser.parse(in); + Node node = document.getFirstChild(); + if (node instanceof Element) + return new XMLMemento(document, (Element) node); + } catch (ParserConfigurationException e) { + } catch (IOException e) { + } catch (SAXException e) { + } finally { + try { + in.close(); + } catch (Exception e) { } + } + return null; + } + + /** + * Loads a memento from the given filename. + * + * @param filename java.lang.String + * @return org.eclipse.ui.IMemento + * @exception java.io.IOException + */ + public static IMemento loadMemento(String filename) throws IOException { + return XMLMemento.createReadRoot(new FileReader(filename)); + } + + /** + * Loads a memento from the given filename. + * + * @param url java.net.URL + * @return org.eclipse.ui.IMemento + * @exception java.io.IOException + */ + public static IMemento loadMemento(URL url) throws IOException { + return XMLMemento.createReadRoot(new InputStreamReader(url.openStream())); + } + + /** + * @see IMemento. + */ + private void putElement(Element element2) { + NamedNodeMap nodeMap = element2.getAttributes(); + int size = nodeMap.getLength(); + for (int i = 0; i < size; i++){ + Attr attr = (Attr)nodeMap.item(i); + putString(attr.getName(),attr.getValue()); + } + + NodeList nodes = element2.getChildNodes(); + size = nodes.getLength(); + for (int i = 0; i < size; i ++) { + Node node = nodes.item(i); + if (node instanceof Element) { + XMLMemento child = (XMLMemento)createChild(node.getNodeName()); + child.putElement((Element)node); + } + } + } + + /** + * @see IMemento. + */ + public void putFloat(String key, float f) { + element.setAttribute(key, String.valueOf(f)); + } + + /** + * @see IMemento. + */ + public void putInteger(String key, int n) { + element.setAttribute(key, String.valueOf(n)); + } + + /** + * @see IMemento. + */ + public void putMemento(IMemento memento) { + XMLMemento xmlMemento = (XMLMemento) memento; + putElement(xmlMemento.element); + } + + /** + * @see IMemento. + */ + public void putString(String key, String value) { + if (value == null) + return; + element.setAttribute(key, value); + } + + /** + * Save this Memento to a Writer. + */ + public void save(Writer writer) throws IOException { + Result result = new StreamResult(writer); + Source source = new DOMSource(factory); + try { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.transform(source, result); + } catch (Exception e) { + throw (IOException) (new IOException().initCause(e)); + } + } + + /** + * Save this Memento to a Writer. + */ + public void save(OutputStream os) throws IOException { + Result result = new StreamResult(os); + Source source = new DOMSource(factory); + try { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.transform(source, result); + } catch (Exception e) { + throw (IOException) (new IOException().initCause(e)); + } + } + + /** + * Saves the memento to the given file. + * + * @param filename java.lang.String + * @exception java.io.IOException + */ + public void saveToFile(String filename) throws IOException { + Writer w = null; + try { + w = new FileWriter(filename); + save(w); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException(e.getLocalizedMessage()); + } finally { + if (w != null) { + try { + w.close(); + } catch (Exception e) { } + } + } + } + + public String saveToString() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + save(out); + return out.toString("UTF-8"); + } + + /* + * @see IMemento#getBoolean(String) + */ + public Boolean getBoolean(String key) { + Attr attr = element.getAttributeNode(key); + if (attr == null) + return null; + String strValue = attr.getValue(); + if ("true".equalsIgnoreCase(strValue)) + return new Boolean(true); + else + return new Boolean(false); + } + + /* + * @see IMemento#putBoolean(String, boolean) + */ + public void putBoolean(String key, boolean value) { + element.setAttribute(key, value ? "true" : "false"); + } +} \ No newline at end of file