001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime.java.util;
032:
033: import java.io.*;
034: import java.util.*;
035: import javax.xml.parsers.*;
036: import javax.xml.transform.*;
037: import javax.xml.transform.dom.DOMSource;
038: import javax.xml.transform.stream.StreamResult;
039: import org.w3c.dom.*;
040: import org.xml.sax.*;
041:
042: /**
043: * @author Taras Puchko
044: */
045: public class _Properties {
046:
047: private static final String SYSTEM_ID = "http://java.sun.com/dtd/properties.dtd";
048:
049: private static final String DTD_CONTENT = "<?xml version='1.0' encoding='UTF-8'?>"
050: + "<!ELEMENT properties ( comment?, entry* ) >"
051: + "<!ATTLIST properties version CDATA #FIXED '1.0'>"
052: + "<!ELEMENT comment (#PCDATA) >"
053: + "<!ELEMENT entry (#PCDATA) >"
054: + "<!ATTLIST entry key CDATA #REQUIRED>";
055:
056: private static final ErrorHandler STRICT_ERROR_HANDLER = new ErrorHandler() {
057: public void warning(SAXParseException exception)
058: throws SAXException {
059: throw exception;
060: }
061:
062: public void error(SAXParseException exception)
063: throws SAXException {
064: throw exception;
065: }
066:
067: public void fatalError(SAXParseException exception)
068: throws SAXException {
069: throw exception;
070: }
071: };
072:
073: public static void loadFromXML(Properties properties,
074: InputStream stream) throws IOException {
075: if (stream == null) {
076: throw new NullPointerException();
077: }
078: NodeList entryList = parseStream(stream).getDocumentElement()
079: .getElementsByTagName("entry");
080: int length = entryList.getLength();
081: for (int i = 0; i < length; i++) {
082: Element entry = (Element) entryList.item(i);
083: String key = entry.getAttribute("key");
084: Node textNode = entry.getFirstChild();
085: String value = textNode == null ? "" : textNode
086: .getNodeValue();
087: properties.setProperty(key, value);
088: }
089: stream.close();
090: }
091:
092: public static void storeToXML(Properties properties,
093: OutputStream stream, String comment) throws IOException {
094: storeToXML(properties, stream, comment, "UTF-8");
095: }
096:
097: public static void storeToXML(Properties properties,
098: OutputStream stream, String comment, String encoding)
099: throws IOException {
100: if (stream == null) {
101: throw new NullPointerException();
102: }
103: Document document = createDocument();
104: Element propertiesElement = document
105: .createElement("properties");
106: document.appendChild(propertiesElement);
107: if (comment != null) {
108: Element commentElement = document.createElement("comment");
109: propertiesElement.appendChild(commentElement);
110: commentElement
111: .appendChild(document.createTextNode(comment));
112: }
113: for (Object keyObject : properties.keySet()) {
114: String key = (String) keyObject;
115: String value = properties.getProperty(key);
116: Element entryElement = document.createElement("entry");
117: propertiesElement.appendChild(entryElement);
118: entryElement.setAttribute("key", key);
119: entryElement.appendChild(document.createTextNode(value));
120: }
121: Transformer transformer = createTransformer();
122: transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
123: SYSTEM_ID);
124: transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
125: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
126: transformer.setOutputProperty(OutputKeys.METHOD, "xml");
127: transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
128: try {
129: transformer.transform(new DOMSource(document),
130: new StreamResult(stream));
131: } catch (TransformerException e) {
132: IOException exception = new IOException(e.getMessage());
133: exception.initCause(e);
134: throw exception;
135: }
136: }
137:
138: private static Document parseStream(InputStream stream)
139: throws IOException {
140: DocumentBuilderFactory factory = DocumentBuilderFactory
141: .newInstance();
142: factory.setCoalescing(true);
143: factory.setValidating(true);
144: DocumentBuilder builder;
145: try {
146: builder = factory.newDocumentBuilder();
147: } catch (ParserConfigurationException e) {
148: throw new Error(e);
149: }
150: builder.setEntityResolver(new EntityResolver() {
151: public InputSource resolveEntity(String publicId,
152: String systemId) throws SAXException, IOException {
153: if (systemId.equals(SYSTEM_ID)) {
154: InputSource source = new InputSource();
155: source.setSystemId(SYSTEM_ID);
156: source.setCharacterStream(new StringReader(
157: DTD_CONTENT));
158: return source;
159: }
160: return null;
161: }
162: });
163: builder.setErrorHandler(STRICT_ERROR_HANDLER);
164: try {
165: return builder.parse(stream);
166: } catch (SAXException e) {
167: throw new InvalidPropertiesFormatException(e);
168: }
169: }
170:
171: private static Document createDocument() {
172: try {
173: return DocumentBuilderFactory.newInstance()
174: .newDocumentBuilder().newDocument();
175: } catch (ParserConfigurationException e) {
176: throw new Error(e);
177: }
178: }
179:
180: private static Transformer createTransformer() {
181: try {
182: return TransformerFactory.newInstance().newTransformer();
183: } catch (TransformerConfigurationException e) {
184: throw new Error(e);
185: }
186: }
187:
188: }
|