001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.xml.javax.converter;
018:
019: import java.io.Reader;
020: import java.io.StringWriter;
021: import javax.xml.parsers.DocumentBuilder;
022: import javax.xml.parsers.DocumentBuilderFactory;
023: import javax.xml.parsers.ParserConfigurationException;
024: import javax.xml.transform.Result;
025: import javax.xml.transform.Source;
026: import javax.xml.transform.Transformer;
027: import javax.xml.transform.TransformerConfigurationException;
028: import javax.xml.transform.TransformerFactory;
029: import javax.xml.transform.dom.DOMSource;
030: import javax.xml.transform.stream.StreamResult;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.compass.core.CompassException;
035: import org.compass.core.config.CompassConfigurable;
036: import org.compass.core.config.CompassEnvironment;
037: import org.compass.core.config.CompassSettings;
038: import org.compass.core.config.ConfigurationException;
039: import org.compass.core.converter.ConversionException;
040: import org.compass.core.converter.xsem.SupportsXmlContentWrapper;
041: import org.compass.core.converter.xsem.XmlContentConverter;
042: import org.compass.core.xml.AliasedXmlObject;
043: import org.compass.core.xml.XmlObject;
044: import org.compass.core.xml.javax.NodeAliasedXmlObject;
045: import org.compass.core.xml.javax.NodeXmlObject;
046: import org.w3c.dom.Document;
047: import org.xml.sax.InputSource;
048:
049: /**
050: * <p>Uses JSE to convert an xml content to and from {@link NodeAliasedXmlObject}.
051: *
052: * @author kimchy
053: */
054: public class NodeXmlContentConverter implements XmlContentConverter,
055: CompassConfigurable, SupportsXmlContentWrapper {
056:
057: private static Log log = LogFactory
058: .getLog(NodeXmlContentConverter.class);
059:
060: private DocumentBuilder documentBuilder;
061:
062: private Transformer transformer;
063:
064: public void configure(CompassSettings settings)
065: throws CompassException {
066: try {
067: this .documentBuilder = doCreateDocumentBuilder(settings);
068: } catch (ParserConfigurationException e) {
069: throw new ConfigurationException(
070: "Failed to create document builder", e);
071: }
072: if (log.isDebugEnabled()) {
073: log.debug("Using document builder ["
074: + documentBuilder.getClass().getName() + "]");
075: }
076: try {
077: this .transformer = doCreateTransformer(settings);
078: } catch (TransformerConfigurationException e) {
079: throw new ConfigurationException(
080: "Failed to create transformer", e);
081: }
082: if (log.isDebugEnabled()) {
083: log.debug("Using transformer ["
084: + transformer.getClass().getName() + "]");
085: }
086: }
087:
088: /**
089: * An extension point allowing to control how a {@link javax.xml.parsers.DocumentBuilder} is
090: * created. By default uses <code>DocumentBuilderFactory.newInstance().newDocumentBuilder()</code>.
091: */
092: protected DocumentBuilder doCreateDocumentBuilder(
093: CompassSettings settings)
094: throws ParserConfigurationException {
095: return DocumentBuilderFactory.newInstance()
096: .newDocumentBuilder();
097: }
098:
099: /**
100: * An extension point allowing to control how a {@link javax.xml.transform.Transformer} is
101: * created. By default uses <code>TransformerFactory.newInstance().newTransformer()</code>.
102: */
103: protected Transformer doCreateTransformer(CompassSettings settings)
104: throws TransformerConfigurationException {
105: return TransformerFactory.newInstance().newTransformer();
106: }
107:
108: /**
109: * This converter does not support a singleton wrapper strategy.
110: */
111: public boolean supports(String wrapper) {
112: return !CompassEnvironment.Converter.XmlContent.WRAPPER_SINGLETON
113: .equals(wrapper);
114: }
115:
116: /**
117: * Uses the already created {@link javax.xml.parsers.DocumentBuilder}
118: * and parse the given xml into a {@link NodeAliasedXmlObject}.
119: *
120: * @param alias The alias that will be associated with the {@link NodeAliasedXmlObject}
121: * @param xml The xml string to parse into {@link NodeAliasedXmlObject}
122: * @return A {@link NodeAliasedXmlObject} parsed from the given xml string and associated with the given alias
123: * @throws ConversionException In case the xml parsing failed
124: */
125: public AliasedXmlObject fromXml(String alias, Reader xml)
126: throws ConversionException {
127: Document document;
128: try {
129: document = documentBuilder.parse(new InputSource(xml));
130: } catch (Exception e) {
131: throw new ConversionException("Failed to parse alias["
132: + alias + "] xml[" + xml + "]", e);
133: }
134: return new NodeAliasedXmlObject(alias, document);
135: }
136:
137: /**
138: * Converts a {@link NodeXmlObject} into an xml string.
139: * Uses the created {@link javax.xml.transform.Transformer} to do it.
140: *
141: * @param xmlObject The {@link NodeXmlObject} to convert into an xml string
142: * @return The xml string representation of the given {@link NodeXmlObject}
143: * @throws ConversionException Should not really happen...
144: */
145: public String toXml(XmlObject xmlObject) throws ConversionException {
146: NodeXmlObject nodeXmlObject = (NodeXmlObject) xmlObject;
147: Source source = new DOMSource(nodeXmlObject.getNode());
148: StringWriter sw = new StringWriter();
149: Result result = new StreamResult(sw);
150: try {
151: transformer.transform(source, result);
152: } catch (Exception e) {
153: throw new ConversionException(
154: "Failed to marshall to xml, this should not happen",
155: e);
156: }
157: return sw.toString();
158: }
159: }
|