1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2005 The Apache Software Foundation.
   7  *
   8  *  Licensed under the Apache License, Version 2.0 (the "License");
   9  *  you may not use this file except in compliance with the License.
  10  *  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  *  Unless required by applicable law or agreed to in writing, software
  15  *  distributed under the License is distributed on an "AS IS" BASIS,
  16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  *  See the License for the specific language governing permissions and
  18  *  limitations under the License.
  19  *
  20  */
  21 /*
  22  * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 /*
  25  * $Id: DOMXPathTransform.java,v 1.2 2008/07/24 15:20:32 mullan Exp $
  26  */
  27 package org.jcp.xml.dsig.internal.dom;
  28 
  29 import javax.xml.crypto.*;
  30 import javax.xml.crypto.dsig.*;
  31 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
  32 import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
  33 import java.security.InvalidAlgorithmParameterException;
  34 import java.util.Iterator;
  35 import java.util.Map;
  36 import java.util.HashMap;
  37 import org.w3c.dom.Attr;
  38 import org.w3c.dom.Element;
  39 import org.w3c.dom.NamedNodeMap;
  40 
  41 /**
  42  * DOM-based implementation of XPath Filtering Transform.
  43  * (Uses Apache XML-Sec Transform implementation)
  44  *
  45  * @author Sean Mullan
  46  */
  47 public final class DOMXPathTransform extends ApacheTransform {
  48 
  49     public void init(TransformParameterSpec params)
  50         throws InvalidAlgorithmParameterException {
  51         if (params == null) {
  52             throw new InvalidAlgorithmParameterException("params are required");
  53         } else if (!(params instanceof XPathFilterParameterSpec)) {
  54             throw new InvalidAlgorithmParameterException
  55                 ("params must be of type XPathFilterParameterSpec");
  56         }
  57         this.params = params;
  58     }
  59 
  60     public void init(XMLStructure parent, XMLCryptoContext context)
  61         throws InvalidAlgorithmParameterException {
  62 
  63         super.init(parent, context);
  64         unmarshalParams(DOMUtils.getFirstChildElement(transformElem));
  65     }
  66 
  67     private void unmarshalParams(Element paramsElem) {
  68         String xPath = paramsElem.getFirstChild().getNodeValue();
  69         // create a Map of namespace prefixes
  70         NamedNodeMap attributes = paramsElem.getAttributes();
  71         if (attributes != null) {
  72             int length = attributes.getLength();
  73             Map namespaceMap = new HashMap(length);
  74             for (int i = 0; i < length; i++) {
  75                 Attr attr = (Attr) attributes.item(i);
  76                 String prefix = attr.getPrefix();
  77                 if (prefix != null && prefix.equals("xmlns")) {
  78                     namespaceMap.put(attr.getLocalName(), attr.getValue());
  79                 }
  80             }
  81             this.params = new XPathFilterParameterSpec(xPath, namespaceMap);
  82         } else {
  83             this.params = new XPathFilterParameterSpec(xPath);
  84         }
  85     }
  86 
  87     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
  88         throws MarshalException {
  89 
  90         super.marshalParams(parent, context);
  91         XPathFilterParameterSpec xp =
  92             (XPathFilterParameterSpec) getParameterSpec();
  93         Element xpathElem = DOMUtils.createElement
  94             (ownerDoc, "XPath", XMLSignature.XMLNS,
  95              DOMUtils.getSignaturePrefix(context));
  96         xpathElem.appendChild(ownerDoc.createTextNode(xp.getXPath()));
  97 
  98         // add namespace attributes, if necessary
  99         Iterator i = xp.getNamespaceMap().entrySet().iterator();
 100         while (i.hasNext()) {
 101             Map.Entry entry = (Map.Entry) i.next();
 102             xpathElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:"
 103                 + (String) entry.getKey(), (String) entry.getValue());
 104         }
 105 
 106         transformElem.appendChild(xpathElem);
 107     }
 108 }