001: package net.sf.saxon.event;
002:
003: import net.sf.saxon.om.Item;
004: import net.sf.saxon.om.NodeInfo;
005: import net.sf.saxon.trans.XPathException;
006:
007: /**
008: * TeeOutputter: a SequenceReceiver that duplicates received events to two different destinations
009: */
010:
011: public class TeeOutputter extends SequenceReceiver {
012:
013: SequenceReceiver seq1;
014: SequenceReceiver seq2;
015:
016: public TeeOutputter(Receiver seq1, Receiver seq2) {
017: if (seq1 instanceof SequenceReceiver) {
018: this .seq1 = (SequenceReceiver) seq1;
019: } else {
020: this .seq1 = new TreeReceiver(seq1);
021: }
022: if (seq2 instanceof SequenceReceiver) {
023: this .seq2 = (SequenceReceiver) seq2;
024: } else {
025: this .seq2 = new TreeReceiver(seq2);
026: }
027: }
028:
029: /**
030: * Output an item (atomic value or node) to the sequence
031: */
032:
033: public void append(Item item, int locationId, int copyNamespaces)
034: throws XPathException {
035: seq1.append(item, locationId, NodeInfo.ALL_NAMESPACES);
036: seq2.append(item, locationId, NodeInfo.ALL_NAMESPACES);
037: }
038:
039: /**
040: * Notify the start of a document node
041: */
042:
043: public void startDocument(int properties) throws XPathException {
044: seq1.startDocument(properties);
045: seq2.startDocument(properties);
046: }
047:
048: /**
049: * Notify the end of a document node
050: */
051:
052: public void endDocument() throws XPathException {
053: seq1.endDocument();
054: seq2.endDocument();
055: }
056:
057: /**
058: * Notify the start of an element
059: *
060: * @param nameCode integer code identifying the name of the element within the name pool.
061: * @param typeCode integer code identifying the element's type within the name pool. The value -1
062: * indicates the default type, xdt:untyped.
063: * @param locationId an integer which can be interpreted using a LocationMap to return
064: * information such as line number and system ID. If no location information is available,
065: * the value zero is supplied.
066: * @param properties bit-significant properties of the element node. If there are no revelant
067: * properties, zero is supplied.
068: */
069:
070: public void startElement(int nameCode, int typeCode,
071: int locationId, int properties) throws XPathException {
072: seq1.startElement(nameCode, typeCode, locationId, properties);
073: seq2.startElement(nameCode, typeCode, locationId, properties);
074: }
075:
076: /**
077: * Notify a namespace. Namespaces are notified <b>after</b> the startElement event, and before
078: * any children for the element. The namespaces that are reported are only required
079: * to include those that are different from the parent element; however, duplicates may be reported.
080: * A namespace must not conflict with any namespaces already used for element or attribute names.
081: *
082: * @param namespaceCode an integer: the top half is a prefix code, the bottom half a URI code.
083: * These may be translated into an actual prefix and URI using the name pool. A prefix code of
084: * zero represents the empty prefix (that is, the default namespace). A URI code of zero represents
085: * a URI of "", that is, a namespace undeclaration.
086: * @throws IllegalStateException: attempt to output a namespace when there is no open element
087: * start tag
088: */
089:
090: public void namespace(int namespaceCode, int properties)
091: throws XPathException {
092: seq1.namespace(namespaceCode, properties);
093: seq2.namespace(namespaceCode, properties);
094: }
095:
096: /**
097: * Notify an attribute. Attributes are notified after the startElement event, and before any
098: * children. Namespaces and attributes may be intermingled.
099: *
100: * @param nameCode The name of the attribute, as held in the name pool
101: * @param typeCode The type of the attribute, as held in the name pool
102: * @param locationId an integer which can be interpreted using a LocationMap to return
103: * information such as line number and system ID. If no location information is available,
104: * the value zero is supplied.
105: * @param properties Bit significant value. The following bits are defined:
106: * <dt>DISABLE_ESCAPING</dt> <dd>Disable escaping for this attribute</dd>
107: * <dt>NO_SPECIAL_CHARACTERS</dt> <dd>Attribute value contains no special characters</dd>
108: * @throws IllegalStateException: attempt to output an attribute when there is no open element
109: * start tag
110: */
111:
112: public void attribute(int nameCode, int typeCode,
113: CharSequence value, int locationId, int properties)
114: throws XPathException {
115: seq1.attribute(nameCode, typeCode, value, locationId,
116: properties);
117: seq2.attribute(nameCode, typeCode, value, locationId,
118: properties);
119: }
120:
121: /**
122: * Notify the start of the content, that is, the completion of all attributes and namespaces.
123: * Note that the initial receiver of output from XSLT instructions will not receive this event,
124: * it has to detect it itself. Note that this event is reported for every element even if it has
125: * no attributes, no namespaces, and no content.
126: */
127:
128: public void startContent() throws XPathException {
129: seq1.startContent();
130: seq2.startContent();
131: }
132:
133: /**
134: * Notify the end of an element. The receiver must maintain a stack if it needs to know which
135: * element is ending.
136: */
137:
138: public void endElement() throws XPathException {
139: seq1.endElement();
140: seq2.endElement();
141: }
142:
143: /**
144: * Notify character data. Note that some receivers may require the character data to be
145: * sent in a single event, but in general this is not a requirement.
146: *
147: * @param chars The characters
148: * @param locationId an integer which can be interpreted using a LocationMap to return
149: * information such as line number and system ID. If no location information is available,
150: * the value zero is supplied.
151: * @param properties Bit significant value. The following bits are defined:
152: * <dt>DISABLE_ESCAPING</dt> <dd>Disable escaping for this text node</dd>
153: * <dt>USE_CDATA</dt> <dd>Output as a CDATA section</dd>
154: * <dt>NO_SPECIAL_CHARACTERS</dt> <dd>Value contains no special characters</dd>
155: * <dt>WHITESPACE</dt> <dd>Text is all whitespace</dd>
156: */
157:
158: public void characters(CharSequence chars, int locationId,
159: int properties) throws XPathException {
160: seq1.characters(chars, locationId, properties);
161: seq2.characters(chars, locationId, properties);
162: }
163:
164: /**
165: * Output a processing instruction
166: *
167: * @param name The PI name. This must be a legal name (it will not be checked).
168: * @param data The data portion of the processing instruction
169: * @param locationId an integer which can be interpreted using a LocationMap to return
170: * information such as line number and system ID. If no location information is available,
171: * the value zero is supplied.
172: * @param properties Additional information about the PI. The following bits are
173: * defined:
174: * <dt>CHECKED</dt> <dd>Data is known to be legal (e.g. doesn't contain "?>")</dd>
175: * @throws IllegalArgumentException: the content is invalid for an XML processing instruction
176: */
177:
178: public void processingInstruction(String name, CharSequence data,
179: int locationId, int properties) throws XPathException {
180: seq1.processingInstruction(name, data, locationId, properties);
181: seq2.processingInstruction(name, data, locationId, properties);
182: }
183:
184: /**
185: * Notify a comment. Comments are only notified if they are outside the DTD.
186: *
187: * @param content The content of the comment
188: * @param locationId an integer which can be interpreted using a LocationMap to return
189: * information such as line number and system ID. If no location information is available,
190: * the value zero is supplied.
191: * @param properties Additional information about the comment. The following bits are
192: * defined:
193: * <dt>CHECKED</dt> <dd>Comment is known to be legal (e.g. doesn't contain "--")</dd>
194: * @throws IllegalArgumentException: the content is invalid for an XML comment
195: */
196:
197: public void comment(CharSequence content, int locationId,
198: int properties) throws XPathException {
199: seq1.comment(content, locationId, properties);
200: seq2.comment(content, locationId, properties);
201: }
202:
203: /**
204: * Notify the end of the event stream
205: */
206:
207: public void close() throws XPathException {
208: seq1.close();
209: seq2.close();
210: }
211: }
212:
213: //
214: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
215: // you may not use this file except in compliance with the License. You may obtain a copy of the
216: // License at http://www.mozilla.org/MPL/
217: //
218: // Software distributed under the License is distributed on an "AS IS" basis,
219: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
220: // See the License for the specific language governing rights and limitations under the License.
221: //
222: // The Original Code is: all this file.
223: //
224: // The Initial Developer of the Original Code is Michael H. Kay
225: //
226: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
227: //
228: // Contributor(s): none.
229: //
|