You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by ra...@apache.org on 2005/05/22 12:35:02 UTC

cvs commit: xml-security/src/org/apache/xml/security/transforms/implementations TransformXPath2Filter.java TransformXPath.java TransformEnvelopedSignature.java

raul        2005/05/22 03:35:02

  Modified:    src/org/apache/xml/security/transforms/implementations
                        TransformXPath2Filter.java TransformXPath.java
                        TransformEnvelopedSignature.java
  Log:
  Refactor the way we handle c14n of nodesets.
  Added NodeFilters implementations.
  
  Revision  Changes    Path
  1.18      +57 -180   xml-security/src/org/apache/xml/security/transforms/implementations/TransformXPath2Filter.java
  
  Index: TransformXPath2Filter.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformXPath2Filter.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- TransformXPath2Filter.java	2 Apr 2005 18:46:23 -0000	1.17
  +++ TransformXPath2Filter.java	22 May 2005 10:35:02 -0000	1.18
  @@ -18,19 +18,15 @@
   
   
   
  -import java.io.IOException;
   import java.util.ArrayList;
  -import java.util.HashSet;
  -import java.util.Iterator;
   import java.util.List;
  -import java.util.Set;
   
  -import javax.xml.parsers.ParserConfigurationException;
   import javax.xml.transform.TransformerException;
   
   import org.apache.xml.security.c14n.CanonicalizationException;
   import org.apache.xml.security.c14n.InvalidCanonicalizerException;
   import org.apache.xml.security.exceptions.XMLSecurityException;
  +import org.apache.xml.security.signature.NodeFilter;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
   import org.apache.xml.security.transforms.TransformationException;
  @@ -38,15 +34,12 @@
   import org.apache.xml.security.transforms.params.XPath2FilterContainer;
   import org.apache.xml.security.utils.CachedXPathAPIHolder;
   import org.apache.xml.security.utils.CachedXPathFuncHereAPI;
  -import org.apache.xml.security.utils.HelperNodeList;
   import org.apache.xml.security.utils.XMLUtils;
   import org.w3c.dom.DOMException;
   import org.w3c.dom.Document;
   import org.w3c.dom.Element;
  -import org.w3c.dom.NamedNodeMap;
   import org.w3c.dom.Node;
   import org.w3c.dom.NodeList;
  -import org.xml.sax.SAXException;
   
   
   /**
  @@ -67,20 +60,10 @@
      public static final String implementedTransformURI =
         Transforms.TRANSFORM_XPATH2FILTER;
      //J-
  -   // contains the type of the filter
  -   List _filterTypes = new ArrayList();
  +   // contains the type of the filter   
   
      // contains the node set
  -   List _filterNodes = new ArrayList();
  -
  -   Set _F = null;
  -   List _ancestors = null;
  -
  -   private static final String FUnion = "union";
  -   private static final String FSubtract = "subtract";
  -   private static final String FIntersect = "intersect";
  -
  -
  +  
      /**
       * Method engineGetURI
       *
  @@ -90,7 +73,7 @@
         return implementedTransformURI;
      }
   
  -   Set _inputSet = null;
  +
   
      /**
       * Method enginePerformTransform
  @@ -103,18 +86,13 @@
              throws TransformationException {
   	  CachedXPathAPIHolder.setDoc(this._transformObject.getElement().getOwnerDocument());
         try {
  -
  -         this._inputSet = input.getNodeSet(true);
  -
  -         if (this._inputSet.size() == 0) {
  -
  -            // input node set contains no nodes
  -            return input;
  -         }
  +    	  List unionNodes=new ArrayList();
  +    	   List substractNodes=new ArrayList();
  +    	   List intersectNodes=new ArrayList();
   
            CachedXPathFuncHereAPI xPathFuncHereAPI =
               new CachedXPathFuncHereAPI(CachedXPathAPIHolder.getCachedXPathAPI());
  -         Document inputDoc = XMLUtils.getOwnerDocument(_inputSet);
  +
            
            Element []xpathElements =XMLUtils.selectNodes(
                   this._transformObject.getElement().getFirstChild(),
  @@ -129,15 +107,8 @@
               throw new TransformationException("xml.WrongContent", exArgs);
            }
   
  -         if (true) {
  -            _filterTypes.add(FUnion);
  +            Document inputDoc = XMLUtils.getOwnerDocument(input.getSubNode());
   
  -            // Set root = new HashSet(); root.add(inputDoc);
  -            HelperNodeList root = new HelperNodeList();
  -
  -            root.appendChild(inputDoc);
  -            _filterNodes.add(root);
  -         }
   
            for (int i = 0; i < noOfSteps; i++) {
               Element xpathElement =XMLUtils.selectNode(
  @@ -147,185 +118,91 @@
               XPath2FilterContainer xpathContainer =
                  XPath2FilterContainer.newInstance(xpathElement,
                                                      input.getSourceURI());
  -
  -            if (xpathContainer.isIntersect()) {
  -               _filterTypes.add(FIntersect);
  -            } else if (xpathContainer.isSubtract()) {
  -               _filterTypes.add(FSubtract);
  -            } else if (xpathContainer.isUnion()) {
  -               _filterTypes.add(FUnion);
  -            } else {
  -               _filterTypes.add(null);
  -            }
  +           
   
               NodeList subtreeRoots = xPathFuncHereAPI.selectNodeList(inputDoc,
                                          xpathContainer.getXPathFilterTextNode(),
                                          CachedXPathFuncHereAPI.getStrFromNode(xpathContainer.getXPathFilterTextNode()),
                                          xpathContainer.getElement());
  -
  -            // _filterNodes.add(XMLUtils.convertNodelistToSet(subtreeRoots));
  -            _filterNodes.add(subtreeRoots);
  -         }
  -
  -         this._F = new HashSet();
  -         this._ancestors = new ArrayList();
  -
  -         this.traversal(inputDoc);
  -
  -         Set resultSet = new HashSet();
  -         Iterator it = this._inputSet.iterator();
  -         while (it.hasNext()) {
  -            Object n = it.next();
  -            if (this._F.contains(n)) {
  -               resultSet.add(n);
  -            }
  +            if (xpathContainer.isIntersect()) {
  +                intersectNodes.add(subtreeRoots);
  +             } else if (xpathContainer.isSubtract()) {
  +            	 substractNodes.add(subtreeRoots);
  +             } else if (xpathContainer.isUnion()) {
  +                unionNodes.add(subtreeRoots);
  +             } 
            }
   
  -         XMLSignatureInput result = new XMLSignatureInput(resultSet);
  -
  -
  -         result.setSourceURI(input.getSourceURI());
  -
  -         return result;
  +         input.setNeedsToBeExpanded(true);
  +         
  +         input.addNodeFilter(new XPath2NodeFilter(unionNodes,substractNodes,intersectNodes));
  +         input.setNodeSet(true);
  +         return input;
         } catch (TransformerException ex) {
            throw new TransformationException("empty", ex);
         } catch (DOMException ex) {
            throw new TransformationException("empty", ex);
  -      } catch (IOException ex) {
  -         throw new TransformationException("empty", ex);
         } catch (CanonicalizationException ex) {
            throw new TransformationException("empty", ex);
         } catch (InvalidCanonicalizerException ex) {
            throw new TransformationException("empty", ex);
  -      } catch (ParserConfigurationException ex) {
  -         throw new TransformationException("empty", ex);
         } catch (XMLSecurityException ex) {
            throw new TransformationException("empty", ex);
  -      } catch (SAXException ex) {
  -         throw new TransformationException("empty", ex);
  -      }
  +      } 
      }
  +}
   
  -   /**
  -    * Method traversal
  -    *
  -    * @param currentNode
  -    */
  -   private void traversal(Node currentNode) {
  -
  -      this._ancestors.add(currentNode);
  -
  -      if (this._inputSet.contains(currentNode)) {
  -
  -      int iMax = this._filterTypes.size();
  -      int i = 0;
  -
  -      searchFirstUnionWhichContainsNode: for (i = iMax - 1; i >= 0; i--) {
  -         NodeList rootNodes = (NodeList) this._filterNodes.get(i);
  -         String type = (String) this._filterTypes.get(i);
  -
  -         if ((type == FUnion)
  -                 && rooted(/*currentNode,*/ this._ancestors, rootNodes)) {
  -
  -            /*
  -            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -               log.debug(i + " " + ((Element) currentNode).getTagName()
  -                         + " is " + type + " of " + rootNode.getNodeName());
  -            }
  -            */
  -            break searchFirstUnionWhichContainsNode;
  -         }
  -      }
  -
  -      int IStart = i;
  -
  -      if (IStart == -1) {
  -         IStart = 0;
  -      }
  -
  -      boolean include = true;
  -
  -      // search in the subsequent steps for
  -      for (int I = IStart; I < iMax; I++) {
  -         NodeList rootNodes = (NodeList) this._filterNodes.get(I);
  -         String type = (String) this._filterTypes.get(I);
  -         boolean rooted = rooted(/*currentNode,*/ this._ancestors, rootNodes);
  -
  -         if ((type == FIntersect) &&!rooted) {
  -
  -            /*
  -            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -               log.debug("The intersect operation from step " + I
  -                         + " does not include " + currentNode.getNodeName());
  -            }
  -            */
  -            include = false;
  -
  -            break;
  -         } else if ((type == FSubtract) && rooted) {
  -
  -            /*
  -            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -               log.debug("The subtract operation from step " + I
  -                         + " does subtract " + currentNode.getNodeName());
  -            }
  -            */
  -            include = false;
  -
  -            break;
  -         } else {
  -			//do nothing
  -         }
  -      }
  -
  -      if (include) {
  -         this._F.add(currentNode);
  -      }
  -      }
  -
  -      {
  -
  -         // here we do the traversal
  -         if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -            NamedNodeMap attributes = ((Element) currentNode).getAttributes();
  -            int attributesLength = attributes.getLength();
  +class XPath2NodeFilter implements NodeFilter {
  +	XPath2NodeFilter(List unionNodes, List substractNodes,
  +			List intersectNodes) {
  +		this.unionNodes=unionNodes;
  +		this.substractNodes=substractNodes;
  +		this.intersectNodes=intersectNodes;
  +	}
  +	List unionNodes=new ArrayList();
  +	List substractNodes=new ArrayList();
  +	List intersectNodes=new ArrayList();
   
  -            for (int x = 0; x < attributesLength; x++) {
  -               Node attr = attributes.item(x);
   
  -               traversal(attr);
  -            }
  -         }
  +   /**
  +    * @see org.apache.xml.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node)
  +    */
  +   public boolean isNodeInclude(Node currentNode) {	 
  +	   boolean notIncluded=false;
  +	   if (rooted(currentNode,substractNodes)) {
  +		   notIncluded=true;
  +	   } else if (!rooted(currentNode,intersectNodes)) {
  +		   notIncluded=true;
  +	   }
  +	   if (notIncluded && rooted(currentNode,unionNodes)) {
  +		   notIncluded=false;
  +	   }
   
  -         for (Node currentChild = currentNode.getFirstChild();
  -                 currentChild != null;
  -                 currentChild = currentChild.getNextSibling()) {
  -            traversal(currentChild);
  -         }
  -      }
  +      return !notIncluded;
   
  -      this._ancestors.remove(currentNode);
      }
   
      /**
       * Method rooted
  +    * @param currentNode 
  +    * @param nodeList 
       *
  -    * @param ancestors
  -    * @param rootNodes
       * @return if rooted bye the rootnodes
       */
  -   boolean rooted(/*Node currentNode,*/ List ancestors, NodeList rootNodes) {
  -
  +   boolean rooted(Node currentNode, List nodeList ) {
  +	   for (int j=0;j<nodeList.size();j++) {
  +		   NodeList rootNodes=(NodeList) nodeList.get(j);	   
         int length = rootNodes.getLength();
   
         for (int i = 0; i < length; i++) {
            Node rootNode = rootNodes.item(i);
   
  -         if (ancestors.contains(rootNode)) {
  +         if (XMLUtils.isDescendantOrSelf(rootNode,currentNode)) {
               return true;
            }
         }
  -
  -      return false;
  +   
  +	   }
  +	   return false;
      }
   }
  
  
  
  1.22      +44 -93    xml-security/src/org/apache/xml/security/transforms/implementations/TransformXPath.java
  
  Index: TransformXPath.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformXPath.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- TransformXPath.java	2 Apr 2005 18:46:24 -0000	1.21
  +++ TransformXPath.java	22 May 2005 10:35:02 -0000	1.22
  @@ -18,16 +18,9 @@
   
   
   
  -import java.io.IOException;
  -import java.util.HashSet;
  -import java.util.Iterator;
  -import java.util.Set;
  -
  -import javax.xml.parsers.ParserConfigurationException;
   import javax.xml.transform.TransformerException;
   
  -import org.apache.xml.security.c14n.CanonicalizationException;
  -import org.apache.xml.security.exceptions.XMLSecurityException;
  +import org.apache.xml.security.signature.NodeFilter;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
   import org.apache.xml.security.transforms.TransformationException;
  @@ -41,7 +34,6 @@
   import org.w3c.dom.DOMException;
   import org.w3c.dom.Element;
   import org.w3c.dom.Node;
  -import org.xml.sax.SAXException;
   
   
   /**
  @@ -99,8 +91,6 @@
             */
   		  CachedXPathAPIHolder.setDoc(this._transformObject.getElement().getOwnerDocument());
            
  -         CachedXPathFuncHereAPI xPathFuncHereAPI =
  -            new CachedXPathFuncHereAPI(CachedXPathAPIHolder.getCachedXPathAPI());
            
   
            Element xpathElement =XMLUtils.selectDsNode(
  @@ -114,99 +104,60 @@
            }
            Node xpathnode = xpathElement.getChildNodes().item(0);
            String str=CachedXPathFuncHereAPI.getStrFromNode(xpathnode);
  -         boolean circumvent=needsCircunvent(str);
  -         Set inputSet = input.getNodeSet(circumvent);
  -         if (inputSet.size() == 0) {
  -            Object exArgs[] = { "input node set contains no nodes" };
  -
  -            throw new TransformationException("empty", exArgs);
  -         }
  -         
  -         /**
  -          * The transform output is also an XPath node-set. The XPath expression
  -          * appearing in the XPath parameter is evaluated once for each node in
  -          * the input node-set. The result is converted to a boolean. If the
  -          * boolean is true, then the node is included in the output node-set.
  -          * If the boolean is false, then the node is omitted from the output
  -          * node-set.
  -          */
  -         Set resultNodes = new HashSet();
  -
  -         /**
  -          * precompile XPath for evaluation; this is taken from {@link XPathAPI#eval}
  -          */
  -         PrefixResolverDefault prefixResolver =
  -            new PrefixResolverDefault(xpathElement);
  -         
  -         
  +         input.setNeedsToBeExpanded(needsCircunvent(str));
            if (xpathnode == null) {
  -            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
  -                                   "Text must be in ds:Xpath");
  -         }
  +     	    throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
  +     	                           "Text must be in ds:Xpath");
  +     	 }
   
  -         Iterator iterator = inputSet.iterator();
  -//		 if (iterator.hasNext()) {
  -//			 System.err.println(str);
  -//			 Node n1=(Node)iterator.next();		 
  -//			 XObject objects=xPathFuncHereAPI.selectNodeList(XMLUtils.getOwnerDocument(n1),
  -//                 xpathnode, str,prefixResolver);
  -//			 NodeList nl=objects.nodelist();
  -//			 int length=nl.getLength();
  -//			 for (int i=0;i<length; i++) {
  -//				 Node n=nl.item(i);
  -//				 if (inputSet.contains(n)) {
  -//					 resultNodes.add(n);
  -//				 }			 				 
  -//			 }
  -//		 }
  -				 
  -         while (iterator.hasNext()) {
  -            Node currentNode = (Node) iterator.next();
  -
  -            /* Same solution as in TransformBase64 ?
  -            if (currentNode.getClass().getName().equals(
  -               "org.apache.xml.dtm.ref.dom2dtm.DOM2DTM$defaultNamespaceDeclarationNode")) {
  -               continue;
  -            }
  -            */            
  -            XObject includeInResult = xPathFuncHereAPI.eval(currentNode,
  -                                         xpathnode, str,prefixResolver);
  -           
  -            if (includeInResult.bool()) {
  -               resultNodes.add(currentNode);
  -               // log.debug("    Added " + org.apache.xml.security.c14n.implementations.Canonicalizer20010315.getXPath(currentNode));
  -             } else {
  -               // log.debug("Not added " + org.apache.xml.security.c14n.implementations.Canonicalizer20010315.getXPath(currentNode));
  -            }
  -         }
  -
  -         XMLSignatureInput result = new XMLSignatureInput(resultNodes);
  -
  -         result.setSourceURI(input.getSourceURI());
   
  -         return result;
  -      } catch (TransformerException ex) {
  -         throw new TransformationException("empty", ex);
  +         input.addNodeFilter(new XPathNodeFilter( xpathElement, xpathnode, str));
  +         input.setNodeSet(true);
  +         return input;
         } catch (DOMException ex) {
            throw new TransformationException("empty", ex);
  -      } catch (IOException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (CanonicalizationException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (ParserConfigurationException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (XMLSecurityException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (SAXException ex) {
  -         throw new TransformationException("empty", ex);
  -      }
  +      } 
      }
  +
      /**
       *  @param str
       * @return true if needs to be circunvent for bug.
       */
       private boolean needsCircunvent(String str) {
  -    	return true; //str.indexOf("namespace")>0;
  +    	return true;
  +    	//return str.contains("namespace");
       	
       }
  +    class XPathNodeFilter implements NodeFilter {
  +    	 PrefixResolverDefault prefixResolver;
  +    	 CachedXPathFuncHereAPI xPathFuncHereAPI =
  +             new CachedXPathFuncHereAPI(CachedXPathAPIHolder.getCachedXPathAPI());
  +          ;
  +    	Node xpathnode; 
  +    	String str;
  +    	XPathNodeFilter(Element xpathElement,
  +    			Node xpathnode, String str) {
  +    		this.xpathnode=xpathnode;
  +    		this.str=str;
  +    		prefixResolver =new PrefixResolverDefault(xpathElement);
  +    	}
  +    	    
  +
  +		/**
  +		 * @see org.apache.xml.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node)
  +		 */
  +		public boolean isNodeInclude(Node currentNode) {			
  +			XObject includeInResult;
  +			try {
  +				includeInResult = xPathFuncHereAPI.eval(currentNode,
  +				        xpathnode, str,prefixResolver);
  +				return includeInResult.bool();
  +			} catch (TransformerException e) {				
  +				throw new RuntimeException("currentNode:"+currentNode,e);
  +			}	
  +			catch (Exception e) {
  +				throw new RuntimeException("currentNode:"+currentNode+",type:"+currentNode.getNodeType(),e);
  +			}
  +		}
  +    }
   }
  
  
  
  1.17      +22 -36    xml-security/src/org/apache/xml/security/transforms/implementations/TransformEnvelopedSignature.java
  
  Index: TransformEnvelopedSignature.java
  ===================================================================
  RCS file: /home/cvs/xml-security/src/org/apache/xml/security/transforms/implementations/TransformEnvelopedSignature.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- TransformEnvelopedSignature.java	2 Apr 2005 18:46:24 -0000	1.16
  +++ TransformEnvelopedSignature.java	22 May 2005 10:35:02 -0000	1.17
  @@ -18,12 +18,7 @@
   
   
   
  -import java.io.IOException;
  -import java.util.Set;
  -
  -import javax.xml.parsers.ParserConfigurationException;
  -
  -import org.apache.xml.security.c14n.CanonicalizationException;
  +import org.apache.xml.security.signature.NodeFilter;
   import org.apache.xml.security.signature.XMLSignatureInput;
   import org.apache.xml.security.transforms.TransformSpi;
   import org.apache.xml.security.transforms.TransformationException;
  @@ -32,7 +27,6 @@
   import org.apache.xml.security.utils.XMLUtils;
   import org.w3c.dom.Element;
   import org.w3c.dom.Node;
  -import org.xml.sax.SAXException;
   
   
   /**
  @@ -62,7 +56,7 @@
      protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
              throws TransformationException {
   
  -      try {
  +
   
            /**
             * If the actual input is an octet stream, then the application MUST
  @@ -86,36 +80,14 @@
            Node signatureElement = transformElement;
            
   
  -         signatureElement = searchSignatureElement(signatureElement);
  -         if (input.isElement()) {
  -         	XMLSignatureInput result = new XMLSignatureInput(input.getSubNode());
  -         	result.setExcludeNode(signatureElement);
  -         	result.setExcludeComments(input.isExcludeComments());
  -         	return result;
  -         }
  +         signatureElement = searchSignatureElement(signatureElement);        
  +         	input.setExcludeNode(signatureElement);   
  +         	input.addNodeFilter(new EnvelopedNodeFilter(signatureElement));
  +         	return input;
  +         
            //
  -         Set inputSet = input.getNodeSet();
  -
  -         if (inputSet.isEmpty()) {
  -            Object exArgs[] = { "input node set contains no nodes" };
  -
  -            throw new TransformationException("generic.EmptyMessage", exArgs);
  -         }
            
  -         Set resultSet=XMLUtils.excludeNodeFromSet(signatureElement, inputSet);
  -
  -         XMLSignatureInput result = new XMLSignatureInput(resultSet);
  -
  -         return result;
  -      } catch (IOException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (SAXException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (ParserConfigurationException ex) {
  -         throw new TransformationException("empty", ex);
  -      } catch (CanonicalizationException ex) {
  -         throw new TransformationException("empty", ex);
  -      } 
  +      
      }
   
      /**
  @@ -148,4 +120,18 @@
   	    }
   	    return signatureElement;
       }
  +    class EnvelopedNodeFilter implements NodeFilter {
  +    	Node exclude;    	
  +    	EnvelopedNodeFilter(Node n) {
  +    		exclude=n;
  +    	}
  +		/**
  +		 * @see org.apache.xml.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node)
  +		 */
  +		public boolean isNodeInclude(Node n) {
  +			// TODO Optimize me.
  +			return !XMLUtils.isDescendantOrSelf(exclude,n);
  +		}
  +    	
  +    }
   }