001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the License). You may not use this file except in
005: * compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * Header Notice in each file and include the License file
014: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * If applicable, add the following below the CDDL Header,
016: * with the fields enclosed by brackets [] replaced by
017: * you own identifying information:
018: * "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
021: */
022:
023: package com.sun.xml.wss.impl.c14n;
024:
025: import com.sun.xml.wss.impl.dsig.NamespaceContextImpl;
026: import com.sun.xml.wss.impl.misc.UnsyncByteArrayOutputStream;
027: import java.io.IOException;
028: import java.io.OutputStream;
029: import java.util.ArrayList;
030: import java.util.HashSet;
031: import java.util.Iterator;
032: import java.util.List;
033: import static javax.xml.stream.XMLStreamConstants.*;
034: import javax.xml.stream.XMLStreamException;
035: import javax.xml.stream.XMLStreamReader;
036:
037: /**
038: *
039: * @author K.Venugopal@sun.com
040: */
041: public class EXC14nStAXReaderBasedCanonicalizer extends
042: BaseCanonicalizer {
043: private NamespaceContextImpl _exC14NContext = new NamespaceContextImpl();
044: private List _inclusivePrefixList = null;
045: private UnsyncByteArrayOutputStream _tmpBuffer = null;
046: private HashSet _visiblyUtilized = new HashSet();
047: private int _index = 0;
048:
049: /** Creates a new instance of EXC14nStAXReaderBasedCanonicalizer */
050: public EXC14nStAXReaderBasedCanonicalizer() {
051: _attrResult = new ArrayList();
052: for (int i = 0; i < 4; i++) {
053: _attrs.add(new StAXAttr());
054: }
055: _tmpBuffer = new UnsyncByteArrayOutputStream();
056: }
057:
058: public void canonicalize(XMLStreamReader reader,
059: OutputStream stream, List inclusiveList)
060: throws XMLStreamException, IOException {
061:
062: if (reader.hasNext() && reader.getEventType() != START_ELEMENT) {
063: throw new XMLStreamException(
064: "Reader should point to START_ELEMENT EVENT");
065: }
066:
067: updatedNamespaceContext(reader);
068: this ._stream = stream;
069: this ._inclusivePrefixList = inclusiveList;
070: int eventType = reader.getEventType();
071: do {
072: switch (eventType) {
073: case START_ELEMENT: {
074: _exC14NContext.push();
075: _index++;
076: writeStartElement(reader);
077: break;
078: }
079: case END_ELEMENT: {
080: _exC14NContext.pop();
081: _index--;
082: writeEndElement(reader);
083: break;
084: }
085: case CDATA: {
086: outputTextToWriter(reader.getTextCharacters(), reader
087: .getTextStart(), reader.getTextLength(),
088: _stream);
089: break;
090: }
091: case CHARACTERS: {
092: if (!reader.isWhiteSpace()) {
093: outputTextToWriter(reader.getText(), _stream);
094: }
095: break;
096: }
097: case COMMENT: {
098: break;
099: }
100: case DTD: {
101: break;
102: }
103: case END_DOCUMENT: {
104:
105: break;
106: }
107: case ENTITY_DECLARATION: {
108: break;
109: }
110: case ENTITY_REFERENCE: {
111: break;
112: }
113: case NOTATION_DECLARATION: {
114: break;
115: }
116: case PROCESSING_INSTRUCTION: {
117: break;
118: }
119: case SPACE: {
120: break;
121: }
122:
123: case START_DOCUMENT: {
124: break;
125: }
126: default: {
127: break;
128: }
129:
130: }
131: eventType = reader.next();
132: } while (reader.hasNext() && _index > 0);
133: }
134:
135: private void writeStartElement(XMLStreamReader reader)
136: throws IOException {
137: final String localName = reader.getLocalName();
138: final String prefix = reader.getPrefix();
139: final String uri = reader.getNamespaceURI();
140: writeCharToUtf8('<', _stream);
141: if (prefix == null && uri == null) {
142: writeStringToUtf8(localName, _stream);
143: } else if (prefix != null && prefix.length() > 0) {
144: writeStringToUtf8(prefix, _stream);
145: writeStringToUtf8(":", _stream);
146: writeStringToUtf8(localName, _stream);
147: } else if (prefix == null) {
148: writeStringToUtf8(localName, _stream);
149: }
150: updatedNamespaceContext(reader);
151: updateAttributes(reader);
152:
153: if (prefix != null) {
154: _visiblyUtilized.add(prefix);
155: }
156: if (_elementPrefix.length() > 0) {
157: AttributeNS eDecl = _exC14NContext
158: .getNamespaceDeclaration(_elementPrefix);
159:
160: if (eDecl != null && !eDecl.isWritten()) {
161: eDecl.setWritten(true);
162: _nsResult.add(eDecl);
163: }
164:
165: }
166:
167: if (_visiblyUtilized.size() > 0) {
168: Iterator prefixItr = _visiblyUtilized.iterator();
169: populateNamespaceDecl(prefixItr);
170: }
171: if (_inclusivePrefixList != null) {
172: populateNamespaceDecl(_inclusivePrefixList.iterator());
173: }
174:
175: if (_nsResult.size() > 0) {
176: BaseCanonicalizer.sort(_nsResult);
177: writeAttributesNS(_nsResult);
178: }
179: if (_attrResult.size() > 0) {
180: BaseCanonicalizer.sort(_attrResult);
181: writeAttributes(_attrResult);
182: }
183: writeCharToUtf8('>', _stream);
184: _nsResult.clear();
185: _attrResult.clear();
186: _visiblyUtilized.clear();
187: }
188:
189: private void populateNamespaceDecl(Iterator prefixItr) {
190: AttributeNS nsDecl = null;
191: while (prefixItr.hasNext()) {
192: String prefix = (String) prefixItr.next();
193: nsDecl = _exC14NContext.getNamespaceDeclaration(prefix);
194:
195: if (nsDecl != null && !nsDecl.isWritten()) {
196: nsDecl.setWritten(true);
197: _nsResult.add(nsDecl);
198: }
199: }
200: }
201:
202: private void updatedNamespaceContext(XMLStreamReader reader) {
203: if (reader.getEventType() != reader.START_ELEMENT) {
204: return;
205: }
206: int count = reader.getNamespaceCount();
207: for (int i = 0; i < count; i++) {
208: final String prefix = reader.getNamespacePrefix(i);
209: final String uri = reader.getNamespaceURI(i);
210: _exC14NContext.declareNamespace(prefix, uri);
211: }
212: }
213:
214: private void updateAttributes(XMLStreamReader reader)
215: throws IOException {
216: int count = reader.getAttributeCount();
217: for (int i = 0; i < count; i++) {
218: final String localName = reader.getAttributeLocalName(i);
219: final String uri = reader.getAttributeNamespace(i);
220: final String prefix = reader.getAttributePrefix(i);
221: final String value = reader.getAttributeValue(i);
222: StAXAttr attr = getAttribute();
223: attr.setLocalName(localName);
224: attr.setValue(value);
225: attr.setPrefix(prefix);
226: attr.setUri(uri);
227: _attrResult.add(attr);
228: }
229: }
230:
231: private void writeEndElement(XMLStreamReader reader)
232: throws IOException {
233: final String localName = reader.getLocalName();
234: final String prefix = reader.getPrefix();
235: final String uri = reader.getNamespaceURI();
236: writeStringToUtf8("</", _stream);
237: if (prefix == null && uri == null) {
238: writeStringToUtf8(localName, _stream);
239: } else if (prefix != null && prefix.length() > 0) {
240: writeStringToUtf8(prefix, _stream);
241: writeStringToUtf8(":", _stream);
242: writeStringToUtf8(localName, _stream);
243: } else if (prefix == null) {
244: writeStringToUtf8(localName, _stream);
245: }
246: writeCharToUtf8('>', _stream);
247: }
248:
249: protected StAXAttr getAttribute() {
250: if (_attrPos < _attrs.size()) {
251: return (StAXAttr) _attrs.get(_attrPos++);
252: } else {
253: for (int i = 0; i < initalCacheSize; i++) {
254: _attrs.add(new StAXAttr());
255: }
256: return (StAXAttr) _attrs.get(_attrPos++);
257: }
258: }
259:
260: protected void writeAttributesNS(List itr) throws IOException {
261:
262: AttributeNS attr = null;
263: int size = itr.size();
264: for (int i = 0; i < size; i++) {
265: attr = (AttributeNS) itr.get(i);
266: _tmpBuffer.reset();
267: _stream.write(attr.getUTF8Data(_tmpBuffer));
268: }
269:
270: }
271:
272: protected void writeAttributes(List itr) throws IOException {
273:
274: int size = itr.size();
275: for (int i = 0; i < size; i++) {
276: StAXAttr attr = (StAXAttr) itr.get(i);
277: String prefix = attr.getPrefix();
278: if (prefix.length() != 0) {
279: outputAttrToWriter(prefix, attr.getLocalName(), attr
280: .getValue(), _stream);
281: } else {
282: prefix = attr.getLocalName();
283: outputAttrToWriter(prefix, attr.getValue(), _stream);
284: }
285: }
286: }
287: }
|