/*
 * 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 org.apache.xml.security.transforms.implementations;



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;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
 * Implements the <CODE>http://www.w3.org/2000/09/xmldsig#enveloped-signature</CODE>
 * transform.
 *
 * @author Christian Geuer-Pollmann
 */
public class TransformEnvelopedSignature extends TransformSpi {

   /** Field implementedTransformURI */
   public static final String implementedTransformURI =
      Transforms.TRANSFORM_ENVELOPED_SIGNATURE;

   /**
    * Method engineGetURI
    *
    * @inheritDoc
    */
   protected String engineGetURI() {
      return implementedTransformURI;
   }

   /**
    * @inheritDoc
    */
   protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
           throws TransformationException {



         /**
          * If the actual input is an octet stream, then the application MUST
          * convert the octet stream to an XPath node-set suitable for use by
          * Canonical XML with Comments. (A subsequent application of the
          * REQUIRED Canonical XML algorithm would strip away these comments.)
          *
          * ...
          *
          * The evaluation of this expression includes all of the document's nodes
          * (including comments) in the node-set representing the octet stream.
          */

         /*
         if (input.isOctetStream()) {
            input.setNodesetXPath(Canonicalizer.XPATH_C14N_WITH_COMMENTS);
         }
         */
         
         Element transformElement = this._transformObject.getElement();
         Node signatureElement = transformElement;
         

         signatureElement = searchSignatureElement(signatureElement);        
         	input.setExcludeNode(signatureElement);   
         	input.addNodeFilter(new EnvelopedNodeFilter(signatureElement));
         	return input;
         
         //
         
      
   }

   /**
    * @param signatureElement    
    * @return the node that is the signature
    * @throws TransformationException
    */
    private static Node searchSignatureElement(Node signatureElement) throws TransformationException {
	    boolean found=false;
        
	    while (true) {
	    	if ((signatureElement == null)
	            || (signatureElement.getNodeType() == Node.DOCUMENT_NODE)) {
	    		break;
	    	}
	    	Element el=(Element)signatureElement;
	    	if (el.getNamespaceURI().equals(Constants.SignatureSpecNS)
                    && 
	               el.getLocalName().equals(Constants._TAG_SIGNATURE)) {
	    		found = true;
	    		break;
	    	}

	    	signatureElement = signatureElement.getParentNode();
	    }

	    if (!found) {
	      throw new TransformationException(
	       "envelopedSignatureTransformNotInSignatureElement");
	    }
	    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);
		}
    	
    }
}

@@ -687,18 +687,16 @@
 tions;%0A%0A
-%0A%0A
 import o
@@ -1126,17 +1126,16 @@
 .Node;%0A%0A
-%0A
 /**%0A * I
@@ -3795,16 +3795,23 @@
   %7D%0A    
+static 
 class En
@@ -3911,22 +3911,21 @@
 de n) %7B%0A
+%09
     
-%09%09
 exclude=
@@ -3938,15 +3938,14 @@
  %09%7D%0A
-%09
+%0A
 %09/**%0A
-%09
 %09 * 
@@ -4030,15 +4030,13 @@
 de)%0A
-%09
 %09 */%0A
-%09
 %09pub
@@ -4072,18 +4072,20 @@
 e n) %7B%0A%09
-%09%09
+    
 // TODO 
@@ -4098,18 +4098,20 @@
 ze me.%0A%09
-%09%09
+    
 return !
@@ -4155,16 +4155,9 @@
 );%0A%09
-%09%7D%0A    %09
+%7D
 %0A   

Fix findbugs bug: EnvelopedNodeFilter should be a static inner class.