blob: 18f697366cf51c12194970fda695aba978cda1bd [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5
6/*
7 * Copyright 1999-2004 The Apache Software Foundation.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
10 * use this file except in compliance with the License. You may obtain a copy of
11 * the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 * License for the specific language governing permissions and limitations under
19 * the License.
20 *
21 */
22package com.sun.org.apache.xml.internal.security.c14n.implementations;
23
24import java.util.Iterator;
25import java.util.Set;
26import java.util.SortedSet;
27import java.util.TreeSet;
28
29import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
30import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
31import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
32import com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
33import com.sun.org.apache.xml.internal.security.utils.Constants;
34import org.w3c.dom.Attr;
35import org.w3c.dom.Element;
36import org.w3c.dom.NamedNodeMap;
37import org.w3c.dom.Node;
38/**
39 * Implements &quot; <A
40 * HREF="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">Exclusive XML
41 * Canonicalization, Version 1.0 </A>&quot; <BR />
42 * Credits: During restructuring of the Canonicalizer framework, Ren??
43 * Kollmorgen from Software AG submitted an implementation of ExclC14n which
44 * fitted into the old architecture and which based heavily on my old (and slow)
45 * implementation of "Canonical XML". A big "thank you" to Ren?? for this.
46 * <BR />
47 * <i>THIS </i> implementation is a complete rewrite of the algorithm.
48 *
49 * @author Christian Geuer-Pollmann <geuerp@apache.org>
50 * @see <a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/ Exclusive#">
51 * XML Canonicalization, Version 1.0</a>
52 */
53public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
54 /**
55 * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
56 * the inclusive namespaces.
57 */
58 TreeSet _inclusiveNSSet = null;
59 static final String XMLNS_URI=Constants.NamespaceSpecNS;
60 final SortedSet result = new TreeSet(COMPARE);
61 /**
62 * Constructor Canonicalizer20010315Excl
63 *
64 * @param includeComments
65 */
66 public Canonicalizer20010315Excl(boolean includeComments) {
67 super(includeComments);
68 }
69
70 /**
71 * Method engineCanonicalizeSubTree
72 * @inheritDoc
73 * @param rootNode
74 *
75 * @throws CanonicalizationException
76 */
77 public byte[] engineCanonicalizeSubTree(Node rootNode)
78 throws CanonicalizationException {
79 return this.engineCanonicalizeSubTree(rootNode, "",null);
80 }
81 /**
82 * Method engineCanonicalizeSubTree
83 * @inheritDoc
84 * @param rootNode
85 * @param inclusiveNamespaces
86 *
87 * @throws CanonicalizationException
88 */
89 public byte[] engineCanonicalizeSubTree(Node rootNode,
90 String inclusiveNamespaces) throws CanonicalizationException {
91 return this.engineCanonicalizeSubTree(rootNode, inclusiveNamespaces,null);
92 }
93 /**
94 * Method engineCanonicalizeSubTree
95 * @param rootNode
96 * @param inclusiveNamespaces
97 * @param excl A element to exclude from the c14n process.
98 * @return the rootNode c14n.
99 * @throws CanonicalizationException
100 */
101 public byte[] engineCanonicalizeSubTree(Node rootNode,
102 String inclusiveNamespaces,Node excl) throws CanonicalizationException {
103 this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
104 .prefixStr2Set(inclusiveNamespaces);
105 return super.engineCanonicalizeSubTree(rootNode,excl);
106 }
107 /**
108 *
109 * @param rootNode
110 * @param inclusiveNamespaces
111 * @return the rootNode c14n.
112 * @throws CanonicalizationException
113 */
114 public byte[] engineCanonicalize(XMLSignatureInput rootNode,
115 String inclusiveNamespaces) throws CanonicalizationException {
116 this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
117 .prefixStr2Set(inclusiveNamespaces);
118 return super.engineCanonicalize(rootNode);
119 }
120
121 /**
122 * Method handleAttributesSubtree
123 * @inheritDoc
124 * @param E
125 * @throws CanonicalizationException
126 */
127 Iterator handleAttributesSubtree(Element E,NameSpaceSymbTable ns)
128 throws CanonicalizationException {
129 // System.out.println("During the traversal, I encountered " +
130 // XMLUtils.getXPath(E));
131 // result will contain the attrs which have to be outputted
132 SortedSet result = this.result;
133 result.clear();
134 NamedNodeMap attrs=null;
135
136 int attrsLength = 0;
137 if (E.hasAttributes()) {
138 attrs = E.getAttributes();
139 attrsLength = attrs.getLength();
140 }
141 //The prefix visibly utilized(in the attribute or in the name) in the element
142 SortedSet visiblyUtilized =(SortedSet) _inclusiveNSSet.clone();
143
144 for (int i = 0; i < attrsLength; i++) {
145 Attr N = (Attr) attrs.item(i);
146 String NName=N.getLocalName();
147 String NNodeValue=N.getNodeValue();
148
149 if (!XMLNS_URI.equals(N.getNamespaceURI())) {
150 //Not a namespace definition.
151 //The Element is output element, add his prefix(if used) to visibyUtilized
152 String prefix = N.getPrefix();
153 if ( (prefix != null) && (!prefix.equals(XML) && !prefix.equals(XMLNS)) ) {
154 visiblyUtilized.add(prefix);
155 }
156 //Add to the result.
157 result.add(N);
158 continue;
159 }
160
161 if (ns.addMapping(NName, NNodeValue,N)) {
162 //New definition check if it is relative.
163 if (C14nHelper.namespaceIsRelative(NNodeValue)) {
164 Object exArgs[] = {E.getTagName(), NName,
165 N.getNodeValue()};
166 throw new CanonicalizationException(
167 "c14n.Canonicalizer.RelativeNamespace", exArgs);
168 }
169 }
170 }
171
172 if (E.getNamespaceURI() != null) {
173 String prefix = E.getPrefix();
174 if ((prefix == null) || (prefix.length() == 0)) {
175 visiblyUtilized.add(XMLNS);
176 } else {
177 visiblyUtilized.add(prefix);
178 }
179 } else {
180 visiblyUtilized.add(XMLNS);
181 }
182
183 //This can be optimezed by I don't have time
184 Iterator it=visiblyUtilized.iterator();
185 while (it.hasNext()) {
186 String s=(String)it.next();
187 Attr key=ns.getMapping(s);
188 if (key==null) {
189 continue;
190 }
191 result.add(key);
192 }
193
194 return result.iterator();
195 }
196
197 /**
198 * Method engineCanonicalizeXPathNodeSet
199 * @inheritDoc
200 * @param xpathNodeSet
201 * @param inclusiveNamespaces
202 * @throws CanonicalizationException
203 */
204 public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet,
205 String inclusiveNamespaces) throws CanonicalizationException {
206
207
208 this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
209 .prefixStr2Set(inclusiveNamespaces);
210 return super.engineCanonicalizeXPathNodeSet(xpathNodeSet);
211
212 }
213
214 /** @inheritDoc */
215 public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet
216 ) throws CanonicalizationException {
217 return engineCanonicalizeXPathNodeSet(xpathNodeSet,"");
218 }
219
220 /**
221 * @inheritDoc
222 * @param E
223 * @throws CanonicalizationException
224 */
225 final Iterator handleAttributes(Element E, NameSpaceSymbTable ns)
226 throws CanonicalizationException {
227 // result will contain the attrs which have to be outputted
228 SortedSet result = this.result;
229 result.clear();
230 NamedNodeMap attrs = null;
231 int attrsLength = 0;
232 if (E.hasAttributes()) {
233 attrs = E.getAttributes();
234 attrsLength = attrs.getLength();
235 }
236 //The prefix visibly utilized(in the attribute or in the name) in the element
237 Set visiblyUtilized =null;
238 //It's the output selected.
239 boolean isOutputElement = isVisible(E);
240 if (isOutputElement) {
241 visiblyUtilized = (Set) this._inclusiveNSSet.clone();
242 }
243
244 for (int i = 0; i < attrsLength; i++) {
245 Attr N = (Attr) attrs.item(i);
246 String NName=N.getLocalName();
247 String NNodeValue=N.getNodeValue();
248 if ( !isVisible(N) ) {
249 //The node is not in the nodeset(if there is a nodeset)
250 continue;
251 }
252
253 if (!XMLNS_URI.equals(N.getNamespaceURI())) {
254 //Not a namespace definition.
255 if (isOutputElement) {
256 //The Element is output element, add his prefix(if used) to visibyUtilized
257 String prefix = N.getPrefix();
258 if ((prefix != null) && (!prefix.equals(XML) && !prefix.equals(XMLNS)) ){
259 visiblyUtilized.add(prefix);
260 }
261 //Add to the result.
262 result.add(N);
263 }
264 continue;
265 }
266
267
268 if (ns.addMapping(NName, NNodeValue,N)) {
269 //New definiton check if it is relative
270 if (C14nHelper.namespaceIsRelative(NNodeValue)) {
271 Object exArgs[] = {E.getTagName(), NName,
272 N.getNodeValue()};
273 throw new CanonicalizationException(
274 "c14n.Canonicalizer.RelativeNamespace", exArgs);
275 }
276 }
277 }
278
279 if (isOutputElement) {
280 //The element is visible, handle the xmlns definition
281 Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS);
282 if ((xmlns!=null) && (!isVisible(xmlns))) {
283 //There is a definition but the xmlns is not selected by the xpath.
284 //then xmlns=""
285 ns.addMapping(XMLNS,"",nullNode);
286 }
287
288 if (E.getNamespaceURI() != null) {
289 String prefix = E.getPrefix();
290 if ((prefix == null) || (prefix.length() == 0)) {
291 visiblyUtilized.add(XMLNS);
292 } else {
293 visiblyUtilized.add( prefix);
294 }
295 } else {
296 visiblyUtilized.add(XMLNS);
297 }
298 //This can be optimezed by I don't have time
299 //visiblyUtilized.addAll(this._inclusiveNSSet);
300 Iterator it=visiblyUtilized.iterator();
301 while (it.hasNext()) {
302 String s=(String)it.next();
303 Attr key=ns.getMapping(s);
304 if (key==null) {
305 continue;
306 }
307 result.add(key);
308 }
309 } else /*if (_circunvented)*/ {
310 Iterator it=this._inclusiveNSSet.iterator();
311 while (it.hasNext()) {
312 String s=(String)it.next();
313 Attr key=ns.getMappingWithoutRendered(s);
314 if (key==null) {
315 continue;
316 }
317 result.add(key);
318 }
319 }
320
321 return result.iterator();
322 }
323}