Package com.sun.org.apache.xml.internal.security.c14n.implementations

Source Code of com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315

/*
* Copyright  1999-2004 The Apache Software Foundation.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/
package com.sun.org.apache.xml.internal.security.c14n.implementations;



import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;


/**
* Implements <A HREF="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical
* XML Version 1.0</A>, a W3C Recommendation from 15 March 2001.
*
* @author Christian Geuer-Pollmann <geuerp@apache.org>
* @version $Revision: 1.37 $
*/
public abstract class Canonicalizer20010315 extends CanonicalizerBase {
  boolean firstCall=true;
  final SortedSet result= new TreeSet(COMPARE);
    static final String XMLNS_URI=Constants.NamespaceSpecNS;
    static final String XML_LANG_URI=Constants.XML_LANG_SPACE_SpecNS;
   /**
    * Constructor Canonicalizer20010315
    *
    * @param includeComments
    */
   public Canonicalizer20010315(boolean includeComments) {
      super(includeComments);
   }

   /**
    * Returns the Attr[]s to be outputted for the given element.
    * <br>
    * The code of this method is a copy of {@link #handleAttributes(Element,
    * NameSpaceSymbTable)},
    * whereas it takes into account that subtree-c14n is -- well -- subtree-based.
    * So if the element in question isRoot of c14n, it's parent is not in the
    * node set, as well as all other ancestors.
    *
    * @param E
    * @param ns
    * @return the Attr[]s to be outputted
    * @throws CanonicalizationException
    */
   Iterator handleAttributesSubtree(Element E,  NameSpaceSymbTable ns )
           throws CanonicalizationException {
       if (!E.hasAttributes() && !firstCall) {
         return null;
      }
      // result will contain the attrs which have to be outputted      
      final SortedSet result = this.result;      
      result.clear();
      NamedNodeMap attrs = E.getAttributes();
      int attrsLength = attrs.getLength();     
           
      for (int i = 0; i < attrsLength; i++) {
         Attr N = (Attr) attrs.item(i);
         String NName=N.getLocalName();
         String NValue=N.getValue();
         String NUri =N.getNamespaceURI();

         if (!XMLNS_URI.equals(NUri)) {
           //It's not a namespace attr node. Add to the result and continue.
            result.add(N);
            continue;
         }
        
         if (XML.equals(NName)
                 && XML_LANG_URI.equals(NValue)) {
           //The default mapping for xml must not be output.
           continue;
         }
        
         Node n=ns.addMappingAndRender(NName,NValue,N);              
       
          if (n!=null) {
             //Render the ns definition
             result.add(n);
             if (C14nHelper.namespaceIsRelative(N)) {
                Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() };
                throw new CanonicalizationException(
                   "c14n.Canonicalizer.RelativeNamespace", exArgs);
             }
          }       
      }
                
      if (firstCall) {
        //It is the first node of the subtree
        //Obtain all the namespaces defined in the parents, and added to the output.
        ns.getUnrenderedNodes(result);                                 
        //output the attributes in the xml namespace.
    addXmlAttributesSubtree(E, result);
        firstCall=false;
      }
     
      return result.iterator();
   }

   /**
    * Float the xml:* attributes of the parent nodes to the root node of c14n
    * @param E the root node.
    * @param result the xml:* attributes  to output.
    */
   private void addXmlAttributesSubtree(Element E, SortedSet result) {
         // E is in the node-set
         Node parent = E.getParentNode();
         Map loa = new HashMap();

         if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) {

            // parent element is not in node set
            for (Node ancestor = parent;
                    (ancestor != null)
                    && (ancestor.getNodeType() == Node.ELEMENT_NODE);
                    ancestor = ancestor.getParentNode()) {
               Element el=((Element) ancestor);
               if (!el.hasAttributes()) {
                    continue;
               }
               // for all ancestor elements
               NamedNodeMap ancestorAttrs = el.getAttributes();

               for (int i = 0; i < ancestorAttrs.getLength(); i++) {
                  // for all attributes in the ancestor element
                  Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i);

                  if (XML_LANG_URI.equals(
                          currentAncestorAttr.getNamespaceURI())) {

                     // do we have an xml:* ?
                     if (!E.hasAttributeNS(
                             XML_LANG_URI,
                             currentAncestorAttr.getLocalName())) {

                        // the xml:* attr is not in E
                        if (!loa.containsKey(currentAncestorAttr.getName())) {
                           loa.put(currentAncestorAttr.getName(),
                                   currentAncestorAttr);
                        }
                     }
                  }
               }
            }
         }

         result.addAll( loa.values());
        
      }

   /**
    * Returns the Attr[]s to be outputted for the given element.
    * <br>
    * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has
    * been prepared using {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650(
    * org.w3c.dom.Document)}.
    *
    * @param E
    * @param ns
    * @return the Attr[]s to be outputted
    * @throws CanonicalizationException
    */
   Iterator handleAttributes(Element E,  NameSpaceSymbTable ns ) throws CanonicalizationException {   
    // result will contain the attrs which have to be outputted
    boolean isRealVisible=isVisible(E);   
    NamedNodeMap attrs = null;
    int attrsLength = 0;
    if (E.hasAttributes()) {
        attrs=E.getAttributes();
       attrsLength= attrs.getLength();
    }
   
   
    SortedSet result = this.result;      
    result.clear();
   
           
    for (int i = 0; i < attrsLength; i++) {
       Attr N = (Attr) attrs.item(i);
       String NName=N.getLocalName();
       String NValue=N.getValue();
       String NUri =N.getNamespaceURI();
      
       if (!XMLNS_URI.equals(NUri)) {
           //A non namespace definition node.
           if (isRealVisible){
           //The node is visible add the attribute to the list of output attributes.
             result.add(N);
          }
           //keep working
          continue;
       }

             
       if ("xml".equals(NName)
               && XML_LANG_URI.equals(NValue)) {
          /* except omit namespace node with local name xml, which defines
           * the xml prefix, if its string value is http://www.w3.org/XML/1998/namespace.
           */
          continue;
       }
       //add the prefix binding to the ns symb table.
       //ns.addInclusiveMapping(NName,NValue,N,isRealVisible);         
      if  (isVisible(N))  {
          //The xpath select this node output it if needed.
          Node n=ns.addMappingAndRenderXNodeSet(NName,NValue,N,isRealVisible);          
          if (n!=null) {
            result.add(n);
                    if (C14nHelper.namespaceIsRelative(N)) {
                       Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() };
                       throw new CanonicalizationException(
                          "c14n.Canonicalizer.RelativeNamespace", exArgs);
                    }
          }
      }
    }
    if (isRealVisible) {                
      //The element is visible, handle the xmlns definition       
        Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS);
        Node n=null;
        if (xmlns == null) {
          //No xmlns def just get the already defined.
          n=ns.getMapping(XMLNS);           
        } else if ( !isVisible(xmlns)) {
          //There is a definition but the xmlns is not selected by the xpath.
          //then xmlns=""
          n=ns.addMappingAndRenderXNodeSet(XMLNS,"",nullNode,true);                         
        }
        //output the xmlns def if needed.
        if (n!=null) {
          result.add(n);
      }
        //Float all xml:* attributes of the unselected parent elements to this one.
      addXmlAttributes(E,result);
    }
   
    return result.iterator();
   }
   /**
    *  Float the xml:* attributes of the unselected parent nodes to the ciurrent node.
    * @param E
    * @param result
    */
   private void addXmlAttributes(Element E, SortedSet result) {
  /* The processing of an element node E MUST be modified slightly when an
       * XPath node-set is given as input and the element's parent is omitted
       * from the node-set. The method for processing the attribute axis of an
       * element E in the node-set is enhanced. All element nodes along E's
       * ancestor axis are examined for nearest occurrences of attributes in
       * the xml namespace, such as xml:lang and xml:space (whether or not they
       * are in the node-set). From this list of attributes, remove any that are
       * in E's attribute axis (whether or not they are in the node-set). Then,
       * lexicographically merge this attribute list with the nodes of E's
       * attribute axis that are in the node-set. The result of visiting the
       * attribute axis is computed by processing the attribute nodes in this
       * merged attribute list.
       */
     
         // E is in the node-set
         Node parent = E.getParentNode();
         Map loa = new HashMap();

         if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)
                 &&!isVisible(parent)) {

            // parent element is not in node set
            for (Node ancestor = parent;
                    (ancestor != null)
                    && (ancestor.getNodeType() == Node.ELEMENT_NODE);
                    ancestor = ancestor.getParentNode()) {
              Element el=((Element) ancestor);
                if (!el.hasAttributes()) {
                  continue;
                }
               // for all ancestor elements
               NamedNodeMap ancestorAttrs =el.getAttributes();

               for (int i = 0; i < ancestorAttrs.getLength(); i++) {

                  // for all attributes in the ancestor element
                  Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i);

                  if (XML_LANG_URI.equals(
                          currentAncestorAttr.getNamespaceURI())) {

                     // do we have an xml:* ?
                     if (!E.hasAttributeNS(
                             XML_LANG_URI,
                             currentAncestorAttr.getLocalName())) {

                        // the xml:* attr is not in E
                        if (!loa.containsKey(currentAncestorAttr.getName())) {
                           loa.put(currentAncestorAttr.getName(),
                                   currentAncestorAttr);
                        }
                     }
                  }
               }
            }
         }
         result.addAll(loa.values());
              
}

   /**
    * Always throws a CanonicalizationException because this is inclusive c14n.
    *
    * @param xpathNodeSet
    * @param inclusiveNamespaces
    * @return none it always fails
    * @throws CanonicalizationException always
    */
   public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet, String inclusiveNamespaces)
           throws CanonicalizationException {

      /** $todo$ well, should we throw UnsupportedOperationException ? */
      throw new CanonicalizationException(
         "c14n.Canonicalizer.UnsupportedOperation");
   }

   /**
    * Always throws a CanonicalizationException because this is inclusive c14n.
    *
    * @param rootNode
    * @param inclusiveNamespaces
    * @return none it always fails
    * @throws CanonicalizationException
    */
   public byte[] engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces)
           throws CanonicalizationException {

      /** $todo$ well, should we throw UnsupportedOperationException ? */
      throw new CanonicalizationException(
         "c14n.Canonicalizer.UnsupportedOperation");
   }
}
TOP

Related Classes of com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.