001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package anttasks;
018:
019: import java.io.File;
020: import java.io.FileNotFoundException;
021: import java.io.FileOutputStream;
022: import java.io.IOException;
023: import java.io.StringReader;
024: import java.util.HashMap;
025: import java.util.Map;
026: import java.util.Properties;
027:
028: import javax.xml.parsers.DocumentBuilder;
029: import javax.xml.parsers.DocumentBuilderFactory;
030: import javax.xml.parsers.ParserConfigurationException;
031: import javax.xml.transform.OutputKeys;
032: import javax.xml.transform.Transformer;
033: import javax.xml.transform.TransformerException;
034: import javax.xml.transform.TransformerFactory;
035: import javax.xml.transform.dom.DOMSource;
036: import javax.xml.transform.stream.StreamResult;
037:
038: import org.apache.tools.ant.BuildException;
039: import org.apache.tools.ant.Project;
040: import org.apache.tools.ant.Task;
041: import org.w3c.dom.Document;
042: import org.w3c.dom.DocumentType;
043: import org.xml.sax.InputSource;
044: import org.xml.sax.SAXException;
045:
046: /**
047: * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
048: * @version CVS $Id: DocumentCache.java 433543 2006-08-22 06:22:54Z crossley $
049: */
050: public final class DocumentCache {
051:
052: /** Cache the read configuration files (Documents) */
053: protected final static Map fileCache = new HashMap();
054:
055: /** The document builder */
056: private static DocumentBuilder builder;
057: private static Transformer transformer;
058:
059: /**
060: * Initialize internal instance of XMLCatalog
061: */
062: static {
063: try {
064: DocumentBuilderFactory builderFactory = DocumentBuilderFactory
065: .newInstance();
066: builderFactory.setValidating(false);
067: builderFactory.setExpandEntityReferences(false);
068: builderFactory.setNamespaceAware(false);
069: builderFactory
070: .setAttribute(
071: "http://apache.org/xml/features/nonvalidating/load-external-dtd",
072: Boolean.FALSE);
073: builder = builderFactory.newDocumentBuilder();
074: transformer = TransformerFactory.newInstance()
075: .newTransformer();
076: } catch (TransformerException e) {
077: throw new BuildException("TransformerException: " + e);
078: } catch (ParserConfigurationException e) {
079: throw new BuildException("ParserConfigurationException: "
080: + e);
081: }
082: }
083:
084: public static Document getDocument(File file, Task task)
085: throws SAXException, IOException {
086: final String fileName = file.toURL().toExternalForm();
087: Document document = (Document) fileCache.get(fileName);
088: if (document != null) {
089: if (task != null) {
090: task.log("Using file from cache: " + fileName,
091: Project.MSG_DEBUG);
092: }
093: fileCache.remove(fileName);
094: } else {
095: try {
096: // load xml
097: if (task != null) {
098: task.log("Reading: " + fileName, Project.MSG_DEBUG);
099: }
100: document = builder.parse(fileName);
101: } catch (IOException e) {
102: throw new BuildException("IOException: " + e);
103: }
104: }
105: return document;
106: }
107:
108: public static Document getDocument(String string, String systemURI) {
109: try {
110: final InputSource is = new InputSource(new StringReader(
111: string));
112: if (systemURI != null) {
113: is.setSystemId(systemURI);
114: }
115: return builder.parse(is);
116: } catch (Exception e) {
117: throw new BuildException("Unable to parse string.", e);
118: }
119: }
120:
121: public static void storeDocument(File file, Document document,
122: Task task) throws IOException {
123: task.log("Storing file in cache: " + file, Project.MSG_DEBUG);
124: final String fileName = file.toURL().toExternalForm();
125: fileCache.put(fileName, document);
126: }
127:
128: public static void writeDocument(File file, Document document,
129: Task task) {
130: if (task != null) {
131: task.log("Writing: " + file);
132: }
133: // Set the DOCTYPE output option on the transformer
134: // if we have any DOCTYPE declaration in the input xml document
135: final DocumentType doctype = document.getDoctype();
136: Properties props = new Properties();
137: if (null != doctype) {
138: if (null != doctype.getPublicId()) {
139: props.put(OutputKeys.DOCTYPE_PUBLIC, doctype
140: .getPublicId());
141: }
142: if (null != doctype.getSystemId()) {
143: props.put(OutputKeys.DOCTYPE_SYSTEM, doctype
144: .getSystemId());
145: }
146: }
147: transformer.setOutputProperties(props);
148:
149: try {
150: StreamResult s = new StreamResult(file);
151: // for JDK 5.0 we explicitly have to set the output stream
152: // otherwise we get FileNotFoundExceptions (at least on
153: // windows)
154: s.setOutputStream(new FileOutputStream(file));
155: transformer.transform(new DOMSource(document), s);
156: } catch (FileNotFoundException e) {
157: throw new BuildException("FileNotFoundException: " + e);
158: } catch (TransformerException e) {
159: throw new BuildException("TransformerException: " + e);
160: }
161: }
162: }
|