KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > c14n > implementations > Canonicalizer20010315


1
2 /*
3  * Copyright 1999-2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package com.sun.org.apache.xml.internal.security.c14n.implementations;
19
20
21
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.SortedSet JavaDoc;
27 import java.util.TreeSet JavaDoc;
28
29 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
30 import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
31 import com.sun.org.apache.xml.internal.security.utils.Constants;
32 import org.w3c.dom.Attr JavaDoc;
33 import org.w3c.dom.Element JavaDoc;
34 import org.w3c.dom.NamedNodeMap JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36
37
38 /**
39  * Implements <A HREF="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical
40  * XML Version 1.0</A>, a W3C Recommendation from 15 March 2001.
41  *
42  * @author Christian Geuer-Pollmann <geuerp@apache.org>
43  * @version $Revision: 1.37 $
44  */

45 public abstract class Canonicalizer20010315 extends CanonicalizerBase {
46     boolean firstCall=true;
47     final SortedSet JavaDoc result= new TreeSet JavaDoc(COMPARE);
48     static final String JavaDoc XMLNS_URI=Constants.NamespaceSpecNS;
49     static final String JavaDoc XML_LANG_URI=Constants.XML_LANG_SPACE_SpecNS;
50    /**
51     * Constructor Canonicalizer20010315
52     *
53     * @param includeComments
54     */

55    public Canonicalizer20010315(boolean includeComments) {
56       super(includeComments);
57    }
58
59    /**
60     * Returns the Attr[]s to be outputted for the given element.
61     * <br>
62     * The code of this method is a copy of {@link #handleAttributes(Element,
63     * NameSpaceSymbTable)},
64     * whereas it takes into account that subtree-c14n is -- well -- subtree-based.
65     * So if the element in question isRoot of c14n, it's parent is not in the
66     * node set, as well as all other ancestors.
67     *
68     * @param E
69     * @param ns
70     * @return the Attr[]s to be outputted
71     * @throws CanonicalizationException
72     */

73    Iterator JavaDoc handleAttributesSubtree(Element JavaDoc E, NameSpaceSymbTable ns )
74            throws CanonicalizationException {
75       if (!E.hasAttributes() && !firstCall) {
76          return null;
77       }
78       // result will contain the attrs which have to be outputted
79
final SortedSet JavaDoc result = this.result;
80       result.clear();
81       NamedNodeMap JavaDoc attrs = E.getAttributes();
82       int attrsLength = attrs.getLength();
83             
84       for (int i = 0; i < attrsLength; i++) {
85          Attr JavaDoc N = (Attr JavaDoc) attrs.item(i);
86          String JavaDoc NName=N.getLocalName();
87          String JavaDoc NValue=N.getValue();
88          String JavaDoc NUri =N.getNamespaceURI();
89
90          if (!XMLNS_URI.equals(NUri)) {
91             //It's not a namespace attr node. Add to the result and continue.
92
result.add(N);
93             continue;
94          }
95          
96          if (XML.equals(NName)
97                  && XML_LANG_URI.equals(NValue)) {
98             //The default mapping for xml must not be output.
99
continue;
100          }
101          
102          Node JavaDoc n=ns.addMappingAndRender(NName,NValue,N);
103              
104           if (n!=null) {
105              //Render the ns definition
106
result.add(n);
107              if (C14nHelper.namespaceIsRelative(N)) {
108                 Object JavaDoc exArgs[] = { E.getTagName(), NName, N.getNodeValue() };
109                 throw new CanonicalizationException(
110                    "c14n.Canonicalizer.RelativeNamespace", exArgs);
111              }
112           }
113       }
114                    
115       if (firstCall) {
116         //It is the first node of the subtree
117
//Obtain all the namespaces defined in the parents, and added to the output.
118
ns.getUnrenderedNodes(result);
119         //output the attributes in the xml namespace.
120
addXmlAttributesSubtree(E, result);
121         firstCall=false;
122       }
123       
124       return result.iterator();
125    }
126
127    /**
128     * Float the xml:* attributes of the parent nodes to the root node of c14n
129     * @param E the root node.
130     * @param result the xml:* attributes to output.
131     */

132    private void addXmlAttributesSubtree(Element JavaDoc E, SortedSet JavaDoc result) {
133          // E is in the node-set
134
Node JavaDoc parent = E.getParentNode();
135          Map JavaDoc loa = new HashMap JavaDoc();
136
137          if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) {
138
139             // parent element is not in node set
140
for (Node JavaDoc ancestor = parent;
141                     (ancestor != null)
142                     && (ancestor.getNodeType() == Node.ELEMENT_NODE);
143                     ancestor = ancestor.getParentNode()) {
144                Element JavaDoc el=((Element JavaDoc) ancestor);
145                if (!el.hasAttributes()) {
146                     continue;
147                }
148                // for all ancestor elements
149
NamedNodeMap JavaDoc ancestorAttrs = el.getAttributes();
150
151                for (int i = 0; i < ancestorAttrs.getLength(); i++) {
152                   // for all attributes in the ancestor element
153
Attr JavaDoc currentAncestorAttr = (Attr JavaDoc) ancestorAttrs.item(i);
154
155                   if (XML_LANG_URI.equals(
156                           currentAncestorAttr.getNamespaceURI())) {
157
158                      // do we have an xml:* ?
159
if (!E.hasAttributeNS(
160                              XML_LANG_URI,
161                              currentAncestorAttr.getLocalName())) {
162
163                         // the xml:* attr is not in E
164
if (!loa.containsKey(currentAncestorAttr.getName())) {
165                            loa.put(currentAncestorAttr.getName(),
166                                    currentAncestorAttr);
167                         }
168                      }
169                   }
170                }
171             }
172          }
173
174          result.addAll( loa.values());
175          
176       }
177
178    /**
179     * Returns the Attr[]s to be outputted for the given element.
180     * <br>
181     * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has
182     * been prepared using {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650(
183     * org.w3c.dom.Document)}.
184     *
185     * @param E
186     * @param ns
187     * @return the Attr[]s to be outputted
188     * @throws CanonicalizationException
189     */

190    Iterator JavaDoc handleAttributes(Element JavaDoc E, NameSpaceSymbTable ns ) throws CanonicalizationException {
191     // result will contain the attrs which have to be outputted
192
boolean isRealVisible=isVisible(E);
193     NamedNodeMap JavaDoc attrs = null;
194     int attrsLength = 0;
195     if (E.hasAttributes()) {
196         attrs=E.getAttributes();
197        attrsLength= attrs.getLength();
198     }
199     
200     
201     SortedSet JavaDoc result = this.result;
202     result.clear();
203     
204             
205     for (int i = 0; i < attrsLength; i++) {
206        Attr JavaDoc N = (Attr JavaDoc) attrs.item(i);
207        String JavaDoc NName=N.getLocalName();
208        String JavaDoc NValue=N.getValue();
209        String JavaDoc NUri =N.getNamespaceURI();
210        
211        if (!XMLNS_URI.equals(NUri)) {
212           //A non namespace definition node.
213
if (isRealVisible){
214             //The node is visible add the attribute to the list of output attributes.
215
result.add(N);
216           }
217           //keep working
218
continue;
219        }
220
221               
222        if ("xml".equals(NName)
223                && XML_LANG_URI.equals(NValue)) {
224           /* except omit namespace node with local name xml, which defines
225            * the xml prefix, if its string value is http://www.w3.org/XML/1998/namespace.
226            */

227           continue;
228        }
229        //add the prefix binding to the ns symb table.
230
//ns.addInclusiveMapping(NName,NValue,N,isRealVisible);
231
if (isVisible(N)) {
232                 //The xpath select this node output it if needed.
233
Node JavaDoc n=ns.addMappingAndRenderXNodeSet(NName,NValue,N,isRealVisible);
234                 if (n!=null) {
235                     result.add(n);
236                     if (C14nHelper.namespaceIsRelative(N)) {
237                        Object JavaDoc exArgs[] = { E.getTagName(), NName, N.getNodeValue() };
238                        throw new CanonicalizationException(
239                           "c14n.Canonicalizer.RelativeNamespace", exArgs);
240                     }
241                 }
242         }
243     }
244     if (isRealVisible) {
245         //The element is visible, handle the xmlns definition
246
Attr JavaDoc xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS);
247         Node JavaDoc n=null;
248         if (xmlns == null) {
249             //No xmlns def just get the already defined.
250
n=ns.getMapping(XMLNS);
251         } else if ( !isVisible(xmlns)) {
252             //There is a definition but the xmlns is not selected by the xpath.
253
//then xmlns=""
254
n=ns.addMappingAndRenderXNodeSet(XMLNS,"",nullNode,true);
255         }
256         //output the xmlns def if needed.
257
if (n!=null) {
258                 result.add(n);
259         }
260         //Float all xml:* attributes of the unselected parent elements to this one.
261
addXmlAttributes(E,result);
262     }
263     
264     return result.iterator();
265    }
266    /**
267     * Float the xml:* attributes of the unselected parent nodes to the ciurrent node.
268     * @param E
269     * @param result
270     */

271    private void addXmlAttributes(Element JavaDoc E, SortedSet JavaDoc result) {
272     /* The processing of an element node E MUST be modified slightly when an
273        * XPath node-set is given as input and the element's parent is omitted
274        * from the node-set. The method for processing the attribute axis of an
275        * element E in the node-set is enhanced. All element nodes along E's
276        * ancestor axis are examined for nearest occurrences of attributes in
277        * the xml namespace, such as xml:lang and xml:space (whether or not they
278        * are in the node-set). From this list of attributes, remove any that are
279        * in E's attribute axis (whether or not they are in the node-set). Then,
280        * lexicographically merge this attribute list with the nodes of E's
281        * attribute axis that are in the node-set. The result of visiting the
282        * attribute axis is computed by processing the attribute nodes in this
283        * merged attribute list.
284        */

285       
286          // E is in the node-set
287
Node JavaDoc parent = E.getParentNode();
288          Map JavaDoc loa = new HashMap JavaDoc();
289
290          if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)
291                  &&!isVisible(parent)) {
292
293             // parent element is not in node set
294
for (Node JavaDoc ancestor = parent;
295                     (ancestor != null)
296                     && (ancestor.getNodeType() == Node.ELEMENT_NODE);
297                     ancestor = ancestor.getParentNode()) {
298                 Element JavaDoc el=((Element JavaDoc) ancestor);
299                 if (!el.hasAttributes()) {
300                     continue;
301                 }
302                // for all ancestor elements
303
NamedNodeMap JavaDoc ancestorAttrs =el.getAttributes();
304
305                for (int i = 0; i < ancestorAttrs.getLength(); i++) {
306
307                   // for all attributes in the ancestor element
308
Attr JavaDoc currentAncestorAttr = (Attr JavaDoc) ancestorAttrs.item(i);
309
310                   if (XML_LANG_URI.equals(
311                           currentAncestorAttr.getNamespaceURI())) {
312
313                      // do we have an xml:* ?
314
if (!E.hasAttributeNS(
315                              XML_LANG_URI,
316                              currentAncestorAttr.getLocalName())) {
317
318                         // the xml:* attr is not in E
319
if (!loa.containsKey(currentAncestorAttr.getName())) {
320                            loa.put(currentAncestorAttr.getName(),
321                                    currentAncestorAttr);
322                         }
323                      }
324                   }
325                }
326             }
327          }
328          result.addAll(loa.values());
329                
330 }
331
332    /**
333     * Always throws a CanonicalizationException because this is inclusive c14n.
334     *
335     * @param xpathNodeSet
336     * @param inclusiveNamespaces
337     * @return none it always fails
338     * @throws CanonicalizationException always
339     */

340    public byte[] engineCanonicalizeXPathNodeSet(Set JavaDoc xpathNodeSet, String JavaDoc inclusiveNamespaces)
341            throws CanonicalizationException {
342
343       /** $todo$ well, should we throw UnsupportedOperationException ? */
344       throw new CanonicalizationException(
345          "c14n.Canonicalizer.UnsupportedOperation");
346    }
347
348    /**
349     * Always throws a CanonicalizationException because this is inclusive c14n.
350     *
351     * @param rootNode
352     * @param inclusiveNamespaces
353     * @return none it always fails
354     * @throws CanonicalizationException
355     */

356    public byte[] engineCanonicalizeSubTree(Node JavaDoc rootNode, String JavaDoc inclusiveNamespaces)
357            throws CanonicalizationException {
358
359       /** $todo$ well, should we throw UnsupportedOperationException ? */
360       throw new CanonicalizationException(
361          "c14n.Canonicalizer.UnsupportedOperation");
362    }
363 }
364
Popular Tags