001: package net.sf.saxon;
002:
003: import net.sf.saxon.event.Builder;
004: import net.sf.saxon.event.Receiver;
005: import net.sf.saxon.event.ReceivingContentHandler;
006: import net.sf.saxon.om.DocumentInfo;
007: import net.sf.saxon.trans.XPathException;
008: import org.xml.sax.SAXException;
009:
010: import javax.xml.transform.Result;
011: import javax.xml.transform.Transformer;
012: import javax.xml.transform.TransformerException;
013: import javax.xml.transform.sax.TransformerHandler;
014:
015: /**
016: * <b>TransformerHandlerImpl</b> implements the javax.xml.transform.sax.TransformerHandler
017: * interface. It acts as a ContentHandler and LexicalHandler which receives a stream of
018: * SAX events representing an input document, and performs a transformation treating this
019: * SAX stream as the source document of the transformation.
020: * @author Michael H. Kay
021: */
022:
023: public class TransformerHandlerImpl extends ReceivingContentHandler
024: implements TransformerHandler {
025:
026: // TODO: if requested, apply schema validation to the source document
027:
028: Controller controller;
029: Builder builder;
030: Result result;
031: String systemId;
032: boolean started = false;
033:
034: /**
035: * Create a TransformerHandlerImpl and initialise variables. The constructor is protected, because
036: * the Filter should be created using newTransformerHandler() in the SAXTransformerFactory
037: * class
038: */
039:
040: protected TransformerHandlerImpl(Controller controller) {
041: this .controller = controller;
042: setPipelineConfiguration(controller.makePipelineConfiguration());
043: builder = controller.makeBuilder();
044: builder.setPipelineConfiguration(getPipelineConfiguration());
045: Receiver stripper = controller.makeStripper(builder);
046: if (controller.getExecutable().stripsInputTypeAnnotations()) {
047: stripper = controller.getConfiguration()
048: .getAnnotationStripper(stripper);
049: }
050: this .setReceiver(stripper);
051: }
052:
053: /**
054: * Start of a new document. The TransformerHandler is not serially reusable, so this method
055: * must only be called once.
056: * @throws SAXException only if an overriding subclass throws this exception
057: * @throws UnsupportedOperationException if an attempt is made to reuse the TransformerHandler by calling
058: * startDocument() more than once.
059: */
060:
061: public void startDocument() throws SAXException {
062: if (started) {
063: throw new UnsupportedOperationException(
064: "The TransformerHandler is not serially reusable. The startDocument() method must be called once only.");
065: }
066: started = true;
067: super .startDocument();
068: }
069:
070: /**
071: * Get the Transformer used for this transformation
072: */
073:
074: public Transformer getTransformer() {
075: return controller;
076: }
077:
078: /**
079: * Set the SystemId of the document
080: */
081:
082: public void setSystemId(String url) {
083: systemId = url;
084: builder.setSystemId(url);
085: }
086:
087: /**
088: * Get the systemId of the document
089: */
090:
091: public String getSystemId() {
092: return systemId;
093: }
094:
095: /**
096: * Set the output destination of the transformation
097: */
098:
099: public void setResult(Result result) {
100: if (result == null) {
101: throw new IllegalArgumentException(
102: "Result must not be null");
103: }
104: this .result = result;
105: }
106:
107: /**
108: * Get the output destination of the transformation
109: */
110:
111: public Result getResult() {
112: return result;
113: }
114:
115: /**
116: * Override the behaviour of endDocument() in ReceivingContentHandler, so that it fires off
117: * the transformation of the constructed document
118: */
119:
120: public void endDocument() throws SAXException {
121: super .endDocument();
122: DocumentInfo doc = (DocumentInfo) builder.getCurrentRoot();
123: if (doc == null) {
124: throw new SAXException("No source document has been built");
125: }
126:
127: try {
128: controller.transformDocument(doc, result);
129: } catch (TransformerException err) {
130: if (err instanceof XPathException) {
131: controller.reportFatalError((XPathException) err);
132: }
133: throw new SAXException(err);
134: }
135: }
136:
137: }
138:
139: //
140: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
141: // you may not use this file except in compliance with the License. You may obtain a copy of the
142: // License at http://www.mozilla.org/MPL/
143: //
144: // Software distributed under the License is distributed on an "AS IS" basis,
145: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
146: // See the License for the specific language governing rights and limitations under the License.
147: //
148: // The Original Code is: all this file.
149: //
150: // The Initial Developer of the Original Code is Michael H. Kay.
151: //
152: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
153: //
154: // Contributor(s): None
155: //
|