001: package org.apache.lenya.xml;
002:
003: import java.io.File;
004: import java.io.FileOutputStream;
005: import java.io.IOException;
006: import java.util.ArrayList;
007: import java.util.List;
008:
009: import javax.xml.parsers.DocumentBuilder;
010: import javax.xml.parsers.DocumentBuilderFactory;
011: import javax.xml.parsers.ParserConfigurationException;
012: import javax.xml.transform.OutputKeys;
013: import javax.xml.transform.Transformer;
014: import javax.xml.transform.TransformerConfigurationException;
015: import javax.xml.transform.TransformerException;
016: import javax.xml.transform.TransformerFactory;
017: import javax.xml.transform.dom.DOMSource;
018: import javax.xml.transform.stream.StreamResult;
019:
020: import org.w3c.dom.DOMException;
021: import org.w3c.dom.Document;
022: import org.w3c.dom.DocumentType;
023: import org.w3c.dom.Element;
024: import org.w3c.dom.Node;
025: import org.w3c.dom.NodeList;
026: import org.w3c.dom.Text;
027: import org.xml.sax.SAXException;
028:
029: /**
030: * Slightly modified version of Lenya's DocumentBuilder to be used in Ant tasks.
031: */
032: public class AntDocumentHelper {
033:
034: /**
035: * Creates a non-validating and namespace-aware DocumentBuilder.
036: * @return A new DocumentBuilder object.
037: * @throws ParserConfigurationException if an error occurs
038: */
039: public static DocumentBuilder createBuilder()
040: throws ParserConfigurationException {
041: DocumentBuilderFactory factory = DocumentBuilderFactory
042: .newInstance();
043: factory.setNamespaceAware(true);
044: DocumentBuilder builder = factory.newDocumentBuilder();
045: return builder;
046: }
047:
048: /**
049: * Creates a document. A xmlns:prefix="namespaceUri" attribute is added to the document element.
050: * @param namespaceUri The namespace URL of the root element.
051: * @param qualifiedName The qualified name of the root element.
052: * @param documentType The type of document to be created or null. When doctype is not null, its
053: * Node.ownerDocument attribute is set to the document being created.
054: * @return A new Document object.
055: * @throws DOMException if an error occurs
056: * @throws ParserConfigurationException if an error occurs
057: * @see org.w3c.dom.DOMImplementation#createDocument(String, String, DocumentType)
058: */
059: public static Document createDocument(String namespaceUri,
060: String qualifiedName, DocumentType documentType)
061: throws DOMException, ParserConfigurationException {
062: DocumentBuilder builder = createBuilder();
063: Document document = builder.getDOMImplementation()
064: .createDocument(namespaceUri, qualifiedName,
065: documentType);
066:
067: // add xmlns:prefix attribute
068: String name = "xmlns";
069: int index = qualifiedName.indexOf(":");
070:
071: if (index > -1) {
072: name += (":" + qualifiedName.substring(0, index));
073: }
074:
075: document.getDocumentElement().setAttributeNS(
076: "http://www.w3.org/2000/xmlns/", name, namespaceUri);
077:
078: return document;
079: }
080:
081: /**
082: * Writes a document to a file. A new file is created if it does not exist.
083: * @param document The document to save.
084: * @param file The file to save the document to.
085: * @throws IOException if an error occurs
086: * @throws TransformerConfigurationException if an error occurs
087: * @throws TransformerException if an error occurs
088: */
089: public static void writeDocument(Document document, File file)
090: throws TransformerConfigurationException,
091: TransformerException, IOException {
092: // sanity checks
093: if (document == null)
094: throw new IllegalArgumentException(
095: "illegal usage, parameter document may not be null");
096: if (file == null)
097: throw new IllegalArgumentException(
098: "illegal usage, parameter file may not be null");
099:
100: file.getParentFile().mkdirs();
101: file.createNewFile();
102:
103: DOMSource source = new DOMSource(document);
104: FileOutputStream out = new FileOutputStream(file);
105: StreamResult result = new StreamResult(out);
106: getTransformer(document.getDoctype()).transform(source, result);
107: out.close();
108: }
109:
110: /**
111: * Get the transformer.
112: * @param documentType the document type
113: * @return a transformer
114: * @throws TransformerConfigurationException if an error occurs
115: */
116: protected static Transformer getTransformer(
117: DocumentType documentType)
118: throws TransformerConfigurationException {
119: TransformerFactory factory = TransformerFactory.newInstance();
120: Transformer transformer = factory.newTransformer();
121: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
122: transformer.setOutputProperty(OutputKeys.METHOD, "xml");
123:
124: if (documentType != null) {
125: if (documentType.getPublicId() != null)
126: transformer.setOutputProperty(
127: OutputKeys.DOCTYPE_PUBLIC, documentType
128: .getPublicId());
129: if (documentType.getSystemId() != null)
130: transformer.setOutputProperty(
131: OutputKeys.DOCTYPE_SYSTEM, documentType
132: .getSystemId());
133: }
134:
135: return transformer;
136: }
137:
138: /**
139: * Reads a document from a file.
140: * @return A document.
141: * @param file The file to load the document from.
142: * @throws ParserConfigurationException if an error occurs
143: * @throws SAXException if an error occurs
144: * @throws IOException if an error occurs
145: */
146: public static Document readDocument(File file)
147: throws ParserConfigurationException, SAXException,
148: IOException {
149: DocumentBuilder builder = createBuilder();
150: return builder.parse(file);
151: }
152:
153: /**
154: * Returns all child elements of an element that belong to a certain
155: * namespace and have a certain local name.
156: * @param element The parent element.
157: * @param namespaceUri The namespace that the childen must belong to.
158: * @param localName The local name of the children.
159: * @return The child elements.
160: */
161: public static Element[] getChildren(Element element,
162: String namespaceUri, String localName) {
163: List childElements = new ArrayList();
164: NodeList children = element.getElementsByTagNameNS(
165: namespaceUri, localName);
166:
167: for (int i = 0; i < children.getLength(); i++) {
168: if (children.item(i).getParentNode() == element) {
169: childElements.add(children.item(i));
170: }
171: }
172:
173: return (Element[]) childElements
174: .toArray(new Element[childElements.size()]);
175: }
176:
177: /**
178: * Returns the text inside an element. Only the child text nodes of this
179: * element are collected.
180: * @param element The element.
181: * @return The text inside the element.
182: */
183: public static String getSimpleElementText(Element element) {
184: StringBuffer buffer = new StringBuffer();
185: NodeList children = element.getChildNodes();
186:
187: for (int i = 0; i < children.getLength(); i++) {
188: Node child = children.item(i);
189:
190: if (child instanceof Text) {
191: buffer.append(child.getNodeValue());
192: }
193: }
194:
195: return buffer.toString();
196: }
197:
198: }
|