/*
 * 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.test;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xml.security.signature.ObjectContainer;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.transforms.params.InclusiveNamespaces;
import org.apache.xml.security.transforms.params.XPathContainer;
import org.apache.xml.security.utils.JavaUtils;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;


/**
 * Class CreateExclC14nInteropValues
 *
 * @author $Author$
 * @version $Revision$
 */
public class CreateExclC14nInteropValues {

   /**
    * Method main
    *
    * @param unused
    * @throws Exception
    */
   public static void main(String unused[]) throws Exception {

      org.apache.xml.security.Init.init();

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

      dbf.setNamespaceAware(true);

      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.newDocument();
      String directory = "data/org/apache/xml/security/c14n/outExcl/";
      File signatureFile = new File(directory + "apacheSignature.xml");
      XMLSignature xmlSignature = new XMLSignature(doc,
                                     signatureFile.toURL().toString(),
                                     XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

      doc.appendChild(xmlSignature.getElement());

      {

         // ref 0
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath(
               "self::Parent or (parent::Parent and not(self::Child)) or self::GrandChild or parent::GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("iaikTests.example1.xml", tf);
      }

      {

         // ref 1
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath(
               "self::Parent or (parent::Parent and not(self::Child)) or self::GrandChild or parent::GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         tf.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
         xmlSignature.addDocument("iaikTests.example1.xml", tf);
      }

      {

         // ref 2
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPathNamespaceContext("xmlns:default", "http://example.org");
            xc.setXPath(
               "self::Parent or (parent::Parent and not(self::default:Child)) or self::GrandChild or parent::GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("iaikTests.example2.xml", tf);
      }

      {

         // ref 3
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPathNamespaceContext("xmlns:default", "http://example.org");
            xc.setXPath(
               "self::Parent or (parent::Parent and not(self::default:Child)) or self::GrandChild or parent::GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         tf.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
         xmlSignature.addDocument("iaikTests.example2.xml", tf);
      }

      {

         // ref 4
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPathNamespaceContext("xmlns:default",
                                        "http://example.org/default");
            xc.setXPathNamespaceContext("xmlns:ns1", "http://example.org/ns1");
            xc.setXPath(
               "self::default:Parent or (parent::default:Parent and not(self::default:Child)) or self::ns1:GrandChild or parent::ns1:GrandChild or self::default:GrandChild or parent::default:GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("iaikTests.example3.xml", tf);
      }

      {

         // ref 5
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPathNamespaceContext("xmlns:default",
                                        "http://example.org/default");
            xc.setXPathNamespaceContext("xmlns:ns1", "http://example.org/ns1");
            xc.setXPath(
               "self::default:Parent or (parent::default:Parent and not(self::default:Child)) or self::ns1:GrandChild or parent::ns1:GrandChild or self::default:GrandChild or parent::default:GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         tf.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
         xmlSignature.addDocument("iaikTests.example3.xml", tf);
      }

      {

         // ref 6
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPathNamespaceContext("xmlns:ns1", "http://example.org/ns1");
            xc.setXPath(
               "self::Parent or (parent::Parent and not(self::Child)) or self::ns1:GrandChild or parent::ns1:GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("iaikTests.example4.xml", tf);
      }

      {

         // ref 7
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPathNamespaceContext("xmlns:ns1", "http://example.org/ns1");
            xc.setXPath(
               "self::Parent or (parent::Parent and not(self::Child)) or self::ns1:GrandChild or parent::ns1:GrandChild");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         {
            InclusiveNamespaces incNS = new InclusiveNamespaces(doc, "ns2");

            tf.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS,
                            incNS.getElement());
         }

         xmlSignature.addDocument("iaikTests.example4.xml", tf);
      }

      {

         // ref 8
         ObjectContainer obj = new ObjectContainer(doc);
         String id = "object1";

         obj.setId(id);

         String xmlStr = "" + "<included    xml:lang='de'>" + "\n"
                         + "<notIncluded xml:lang='de'>" + "\n"
                         + "<notIncluded xml:lang='uk'>" + "\n"
                         + "<included                 >" + "\n" + "</included>"
                         + "\n" + "</notIncluded>" + "\n" + "</notIncluded>"
                         + "\n" + "</included>";
         Document importDoc =
            db.parse(new ByteArrayInputStream(xmlStr.getBytes()));

         obj.getElement().appendChild(doc.createTextNode("\n"));
         obj.getElement()
            .appendChild(doc.importNode(importDoc.getDocumentElement(), true));
         obj.getElement().appendChild(doc.createTextNode("\n"));
         xmlSignature.appendObject(obj);

         // ref apache_8
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 9
         ObjectContainer obj = new ObjectContainer(doc);
         String id = "object2";

         obj.setId(id);

         String xmlStr = "" + "<included    xml:lang='uk'>" + "\n"
                         + "<notIncluded xml:lang='de'>" + "\n"
                         + "<notIncluded xml:lang='uk'>" + "\n"
                         + "<included                 >" + "\n" + "</included>"
                         + "\n" + "</notIncluded>" + "\n" + "</notIncluded>"
                         + "\n" + "</included>";
         Document importDoc =
            db.parse(new ByteArrayInputStream(xmlStr.getBytes()));

         obj.getElement().appendChild(doc.createTextNode("\n"));
         obj.getElement()
            .appendChild(doc.importNode(importDoc.getDocumentElement(), true));
         obj.getElement().appendChild(doc.createTextNode("\n"));
         xmlSignature.appendObject(obj);

         // ref apache_8
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 10
         ObjectContainer obj = new ObjectContainer(doc);
         String id = "object3";

         obj.setId(id);

         String xmlStr = "" + "<included    xml:lang='de'>" + "\n"
                         + "<notIncluded xml:lang='de'>" + "\n"
                         + "<notIncluded xml:lang='uk'>" + "\n"
                         + "<included    xml:lang='de'>" + "\n" + "</included>"
                         + "\n" + "</notIncluded>" + "\n" + "</notIncluded>"
                         + "\n" + "</included>";
         Document importDoc =
            db.parse(new ByteArrayInputStream(xmlStr.getBytes()));

         obj.getElement().appendChild(doc.createTextNode("\n"));
         obj.getElement()
            .appendChild(doc.importNode(importDoc.getDocumentElement(), true));
         obj.getElement().appendChild(doc.createTextNode("\n"));
         xmlSignature.appendObject(obj);

         // ref apache_8
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 11
         ObjectContainer obj = new ObjectContainer(doc);
         String id = "object4";

         obj.setId(id);

         String xmlStr = "" + "<included    xml:lang='de'>" + "\n"
                         + "<included    xml:lang='de'>" + "\n"
                         + "<notIncluded xml:lang='uk'>" + "\n"
                         + "<included                 >" + "\n" + "</included>"
                         + "\n" + "</notIncluded>" + "\n" + "</included>"
                         + "\n" + "</included>";
         Document importDoc =
            db.parse(new ByteArrayInputStream(xmlStr.getBytes()));

         obj.getElement().appendChild(doc.createTextNode("\n"));
         obj.getElement()
            .appendChild(doc.importNode(importDoc.getDocumentElement(), true));
         obj.getElement().appendChild(doc.createTextNode("\n"));
         xmlSignature.appendObject(obj);

         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 12
         ObjectContainer obj = new ObjectContainer(doc);
         String id = "object5";

         obj.setId(id);

         String xmlStr = "" + "<included                         xml:lang='de'>"
                         + "\n"
                         + "<included                         xml:lang='de'>"
                         + "\n"
                         + "<notIncluded xml:space='preserve' xml:lang='uk'>"
                         + "\n" + "<included                 >" + "\n"
                         + "</included>" + "\n" + "</notIncluded>" + "\n"
                         + "</included>" + "\n" + "</included>";
         Document importDoc =
            db.parse(new ByteArrayInputStream(xmlStr.getBytes()));

         obj.getElement().appendChild(doc.createTextNode("\n"));
         obj.getElement()
            .appendChild(doc.importNode(importDoc.getDocumentElement(), true));
         obj.getElement().appendChild(doc.createTextNode("\n"));
         xmlSignature.appendObject(obj);

         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 13
         ObjectContainer obj = new ObjectContainer(doc);
         String id = "object6";

         obj.setId(id);

         String xmlStr = "" + "<included   xml:space='preserve'  xml:lang='de'>"
                         + "\n"
                         + "<included                         xml:lang='de'>"
                         + "\n"
                         + "<notIncluded                      xml:lang='uk'>"
                         + "\n" + "<included>" + "\n" + "</included>" + "\n"
                         + "</notIncluded>" + "\n" + "</included>" + "\n"
                         + "</included>";
         Document importDoc =
            db.parse(new ByteArrayInputStream(xmlStr.getBytes()));

         obj.getElement().appendChild(doc.createTextNode("\n"));
         obj.getElement()
            .appendChild(doc.importNode(importDoc.getDocumentElement(), true));
         obj.getElement().appendChild(doc.createTextNode("\n"));
         xmlSignature.appendObject(obj);

         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 13b
         String id = "object6";
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
            tf.addTransform(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
         }

         xmlSignature.addDocument("#" + id, tf);
      }

      {

         // ref 13c
         String id = "object6";
         Transforms tf = new Transforms(doc);

         {
            XPathContainer xc = new XPathContainer(doc);

            xc.setXPath("self::node()[local-name()='included']");
            tf.addTransform(Transforms.TRANSFORM_XPATH, xc.getElement());
            tf.addTransform(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
            tf.addTransform(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
         }

         xmlSignature.addDocument("#" + id, tf);
         // xmlSignature.addDocument("#" + id, tf, org.apache.xml.security.algorithms.MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1, "ref13c", null);
      }

      String secretKey = "secret";

      xmlSignature.getKeyInfo().addKeyName("The UTF-8 octets of \"" + secretKey
                                           + "\" are used for signing ("
                                           + secretKey.length() + " octets)");
      xmlSignature.sign(xmlSignature.createSecretKey(secretKey.getBytes()));

      FileOutputStream fos = new FileOutputStream(signatureFile);

      XMLUtils.outputDOM(doc, fos);
      fos.close();

      int length = xmlSignature.getSignedInfo().getLength();

      for (int i = 0; i < length; i++) {
         String fname = directory + "c14n-" + i + "-apache.xml";

         System.out.println(fname);
         JavaUtils.writeBytesToFilename(fname, xmlSignature.getSignedInfo().getReferencedContentAfterTransformsItem(i).getBytes());
      }

      XMLSignature s = new XMLSignature(doc.getDocumentElement(),
                                        signatureFile.toURL().toString());
      boolean verify =
         s.checkSignatureValue(s.createSecretKey("secret".getBytes()));

      System.out.println("verify=" + verify);

      System.out.println("");

      XMLUtils.outputDOMc14nWithComments(doc, System.out);
   }
}
