1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23/* 24 * =========================================================================== 25 * 26 * (C) Copyright IBM Corp. 2003 All Rights Reserved. 27 * 28 * =========================================================================== 29 */ 30/* 31 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 32 */ 33/* 34 * $Id: DOMXPathFilter2Transform.java 1203789 2011-11-18 18:46:07Z mullan $ 35 */ 36package org.jcp.xml.dsig.internal.dom; 37 38import javax.xml.crypto.*; 39import javax.xml.crypto.dsig.*; 40import javax.xml.crypto.dsig.spec.TransformParameterSpec; 41import javax.xml.crypto.dsig.spec.XPathType; 42import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec; 43import java.security.InvalidAlgorithmParameterException; 44import java.util.ArrayList; 45import java.util.HashMap; 46import java.util.List; 47import java.util.Map; 48import java.util.Set; 49import org.w3c.dom.Attr; 50import org.w3c.dom.Element; 51import org.w3c.dom.NamedNodeMap; 52 53/** 54 * DOM-based implementation of XPath Filter 2.0 Transform. 55 * (Uses Apache XML-Sec Transform implementation) 56 * 57 * @author Joyce Leung 58 */ 59public final class DOMXPathFilter2Transform extends ApacheTransform { 60 61 public void init(TransformParameterSpec params) 62 throws InvalidAlgorithmParameterException 63 { 64 if (params == null) { 65 throw new InvalidAlgorithmParameterException("params are required"); 66 } else if (!(params instanceof XPathFilter2ParameterSpec)) { 67 throw new InvalidAlgorithmParameterException 68 ("params must be of type XPathFilter2ParameterSpec"); 69 } 70 this.params = params; 71 } 72 73 public void init(XMLStructure parent, XMLCryptoContext context) 74 throws InvalidAlgorithmParameterException 75 { 76 super.init(parent, context); 77 try { 78 unmarshalParams(DOMUtils.getFirstChildElement(transformElem)); 79 } catch (MarshalException me) { 80 throw new InvalidAlgorithmParameterException(me); 81 } 82 } 83 84 private void unmarshalParams(Element curXPathElem) throws MarshalException 85 { 86 List<XPathType> list = new ArrayList<XPathType>(); 87 while (curXPathElem != null) { 88 String xPath = curXPathElem.getFirstChild().getNodeValue(); 89 String filterVal = DOMUtils.getAttributeValue(curXPathElem, 90 "Filter"); 91 if (filterVal == null) { 92 throw new MarshalException("filter cannot be null"); 93 } 94 XPathType.Filter filter = null; 95 if (filterVal.equals("intersect")) { 96 filter = XPathType.Filter.INTERSECT; 97 } else if (filterVal.equals("subtract")) { 98 filter = XPathType.Filter.SUBTRACT; 99 } else if (filterVal.equals("union")) { 100 filter = XPathType.Filter.UNION; 101 } else { 102 throw new MarshalException("Unknown XPathType filter type" + 103 filterVal); 104 } 105 NamedNodeMap attributes = curXPathElem.getAttributes(); 106 if (attributes != null) { 107 int length = attributes.getLength(); 108 Map<String, String> namespaceMap = 109 new HashMap<String, String>(length); 110 for (int i = 0; i < length; i++) { 111 Attr attr = (Attr)attributes.item(i); 112 String prefix = attr.getPrefix(); 113 if (prefix != null && prefix.equals("xmlns")) { 114 namespaceMap.put(attr.getLocalName(), attr.getValue()); 115 } 116 } 117 list.add(new XPathType(xPath, filter, namespaceMap)); 118 } else { 119 list.add(new XPathType(xPath, filter)); 120 } 121 122 curXPathElem = DOMUtils.getNextSiblingElement(curXPathElem); 123 } 124 this.params = new XPathFilter2ParameterSpec(list); 125 } 126 127 public void marshalParams(XMLStructure parent, XMLCryptoContext context) 128 throws MarshalException 129 { 130 super.marshalParams(parent, context); 131 XPathFilter2ParameterSpec xp = 132 (XPathFilter2ParameterSpec)getParameterSpec(); 133 String prefix = DOMUtils.getNSPrefix(context, Transform.XPATH2); 134 String qname = (prefix == null || prefix.length() == 0) 135 ? "xmlns" : "xmlns:" + prefix; 136 List<XPathType> xpathList = xp.getXPathList(); 137 for (XPathType xpathType : xpathList) { 138 Element elem = DOMUtils.createElement(ownerDoc, "XPath", 139 Transform.XPATH2, prefix); 140 elem.appendChild 141 (ownerDoc.createTextNode(xpathType.getExpression())); 142 DOMUtils.setAttribute(elem, "Filter", 143 xpathType.getFilter().toString()); 144 elem.setAttributeNS("http://www.w3.org/2000/xmlns/", qname, 145 Transform.XPATH2); 146 147 // add namespace attributes, if necessary 148 Set<Map.Entry<String, String>> entries = 149 xpathType.getNamespaceMap().entrySet(); 150 for (Map.Entry<String, String> entry : entries) { 151 elem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + 152 entry.getKey(), 153 entry.getValue()); 154 } 155 156 transformElem.appendChild(elem); 157 } 158 } 159} 160