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: DOMSignatureProperty.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.dom.DOMCryptoContext; 31 import javax.xml.crypto.dsig.*; 32 33 import java.util.*; 34 import org.w3c.dom.Attr; 35 import org.w3c.dom.Document; 36 import org.w3c.dom.Element; 37 import org.w3c.dom.Node; 38 import org.w3c.dom.NodeList; 39 40 /** 41 * DOM-based implementation of SignatureProperty. 42 * 43 * @author Sean Mullan 44 */ 45 public final class DOMSignatureProperty extends DOMStructure 46 implements SignatureProperty { 47 48 private final String id; 49 private final String target; 50 private final List content; 51 52 /** 53 * Creates a <code>SignatureProperty</code> from the specified parameters. 54 * 55 * @param content a list of one or more {@link XMLStructure}s. The list 56 * is defensively copied to protect against subsequent modification. 57 * @param target the target URI 58 * @param id the Id (may be <code>null</code>) 59 * @return a <code>SignatureProperty</code> 60 * @throws ClassCastException if <code>content</code> contains any 61 * entries that are not of type {@link XMLStructure} 62 * @throws IllegalArgumentException if <code>content</code> is empty 63 * @throws NullPointerException if <code>content</code> or 64 * <code>target</code> is <code>null</code> 65 */ 66 public DOMSignatureProperty(List content, String target, String id) { 67 if (target == null) { 68 throw new NullPointerException("target cannot be null"); 69 } else if (content == null) { 70 throw new NullPointerException("content cannot be null"); 71 } else if (content.isEmpty()) { 72 throw new IllegalArgumentException("content cannot be empty"); 73 } else { 74 List contentCopy = new ArrayList(content); 75 for (int i = 0, size = contentCopy.size(); i < size; i++) { 76 if (!(contentCopy.get(i) instanceof XMLStructure)) { 77 throw new ClassCastException 78 ("content["+i+"] is not a valid type"); 79 } 80 } 81 this.content = Collections.unmodifiableList(contentCopy); 82 } 83 this.target = target; 84 this.id = id; 85 } 86 87 /** 88 * Creates a <code>DOMSignatureProperty</code> from an element. 89 * 90 * @param propElem a SignatureProperty element 91 */ 92 public DOMSignatureProperty(Element propElem) throws MarshalException { 93 // unmarshal attributes 94 target = DOMUtils.getAttributeValue(propElem, "Target"); 95 if (target == null) { 96 throw new MarshalException("target cannot be null"); 97 } 98 Attr attr = propElem.getAttributeNodeNS(null, "Id"); 99 if (attr != null) { 100 id = attr.getValue(); 101 propElem.setIdAttributeNode(attr, true); 102 } else { 103 id = null; 104 } 105 106 NodeList nodes = propElem.getChildNodes(); 107 int length = nodes.getLength(); 108 List content = new ArrayList(length); 109 for (int i = 0; i < length; i++) { 110 content.add(new javax.xml.crypto.dom.DOMStructure(nodes.item(i))); 111 } 112 if (content.isEmpty()) { 113 throw new MarshalException("content cannot be empty"); 114 } else { 115 this.content = Collections.unmodifiableList(content); 116 } 117 } 118 119 public List getContent() { 120 return content; 121 } 122 123 public String getId() { 124 return id; 125 } 126 127 public String getTarget() { 128 return target; 129 } 130 131 public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) 132 throws MarshalException { 133 Document ownerDoc = DOMUtils.getOwnerDocument(parent); 134 135 Element propElem = DOMUtils.createElement 136 (ownerDoc, "SignatureProperty", XMLSignature.XMLNS, dsPrefix); 137 138 // set attributes 139 DOMUtils.setAttributeID(propElem, "Id", id); 140 DOMUtils.setAttribute(propElem, "Target", target); 141 142 // create and append any elements and mixed content 143 for (int i = 0, size = content.size(); i < size; i++) { 144 javax.xml.crypto.dom.DOMStructure property = 145 (javax.xml.crypto.dom.DOMStructure) content.get(i); 146 DOMUtils.appendChild(propElem, property.getNode()); 147 } 148 149 parent.appendChild(propElem); 150 } 151 152 public boolean equals(Object o) { 153 if (this == o) { 154 return true; 155 } 156 157 if (!(o instanceof SignatureProperty)) { 158 return false; 159 } 160 SignatureProperty osp = (SignatureProperty) o; 161 162 boolean idsEqual = (id == null ? osp.getId() == null : 163 id.equals(osp.getId())); 164 165 return (equalsContent(osp.getContent()) && 166 target.equals(osp.getTarget()) && idsEqual); 167 } 168 169 private boolean equalsContent(List otherContent) { 170 int osize = otherContent.size(); 171 if (content.size() != osize) { 172 return false; 173 } 174 for (int i = 0; i < osize; i++) { 175 XMLStructure oxs = (XMLStructure) otherContent.get(i); 176 XMLStructure xs = (XMLStructure) content.get(i); 177 if (oxs instanceof javax.xml.crypto.dom.DOMStructure) { 178 if (!(xs instanceof javax.xml.crypto.dom.DOMStructure)) { 179 return false; 180 } 181 Node onode = 182 ((javax.xml.crypto.dom.DOMStructure) oxs).getNode(); 183 Node node = 184 ((javax.xml.crypto.dom.DOMStructure) xs).getNode(); 185 if (!DOMUtils.nodesEqual(node, onode)) { 186 return false; 187 } 188 } else { 189 if (!(xs.equals(oxs))) { 190 return false; 191 } 192 } 193 } 194 195 return true; 196 } 197 } | 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 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 25 */ 26 /* 27 * $Id: DOMSignatureProperty.java 1333415 2012-05-03 12:03:51Z coheigea $ 28 */ 29 package org.jcp.xml.dsig.internal.dom; 30 31 import javax.xml.crypto.*; 32 import javax.xml.crypto.dom.DOMCryptoContext; 33 import javax.xml.crypto.dsig.*; 34 35 import java.util.*; 36 37 import org.w3c.dom.Attr; 38 import org.w3c.dom.Document; 39 import org.w3c.dom.Element; 40 import org.w3c.dom.Node; 41 import org.w3c.dom.NodeList; 42 43 /** 44 * DOM-based implementation of SignatureProperty. 45 * 46 * @author Sean Mullan 47 */ 48 public final class DOMSignatureProperty extends DOMStructure 49 implements SignatureProperty { 50 51 private final String id; 52 private final String target; 53 private final List<XMLStructure> content; 54 55 /** 56 * Creates a <code>SignatureProperty</code> from the specified parameters. 57 * 58 * @param content a list of one or more {@link XMLStructure}s. The list 59 * is defensively copied to protect against subsequent modification. 60 * @param target the target URI 61 * @param id the Id (may be <code>null</code>) 62 * @return a <code>SignatureProperty</code> 63 * @throws ClassCastException if <code>content</code> contains any 64 * entries that are not of type {@link XMLStructure} 65 * @throws IllegalArgumentException if <code>content</code> is empty 66 * @throws NullPointerException if <code>content</code> or 67 * <code>target</code> is <code>null</code> 68 */ 69 public DOMSignatureProperty(List<? extends XMLStructure> content, 70 String target, String id) 71 { 72 if (target == null) { 73 throw new NullPointerException("target cannot be null"); 74 } else if (content == null) { 75 throw new NullPointerException("content cannot be null"); 76 } else if (content.isEmpty()) { 77 throw new IllegalArgumentException("content cannot be empty"); 78 } else { 79 this.content = Collections.unmodifiableList( 80 new ArrayList<XMLStructure>(content)); 81 for (int i = 0, size = this.content.size(); i < size; i++) { 82 if (!(this.content.get(i) instanceof XMLStructure)) { 83 throw new ClassCastException 84 ("content["+i+"] is not a valid type"); 85 } 86 } 87 } 88 this.target = target; 89 this.id = id; 90 } 91 92 /** 93 * Creates a <code>DOMSignatureProperty</code> from an element. 94 * 95 * @param propElem a SignatureProperty element 96 */ 97 public DOMSignatureProperty(Element propElem, XMLCryptoContext context) 98 throws MarshalException 99 { 100 // unmarshal attributes 101 target = DOMUtils.getAttributeValue(propElem, "Target"); 102 if (target == null) { 103 throw new MarshalException("target cannot be null"); 104 } 105 Attr attr = propElem.getAttributeNodeNS(null, "Id"); 106 if (attr != null) { 107 id = attr.getValue(); 108 propElem.setIdAttributeNode(attr, true); 109 } else { 110 id = null; 111 } 112 113 NodeList nodes = propElem.getChildNodes(); 114 int length = nodes.getLength(); 115 List<XMLStructure> content = new ArrayList<XMLStructure>(length); 116 for (int i = 0; i < length; i++) { 117 content.add(new javax.xml.crypto.dom.DOMStructure(nodes.item(i))); 118 } 119 if (content.isEmpty()) { 120 throw new MarshalException("content cannot be empty"); 121 } else { 122 this.content = Collections.unmodifiableList(content); 123 } 124 } 125 126 public List getContent() { 127 return content; 128 } 129 130 public String getId() { 131 return id; 132 } 133 134 public String getTarget() { 135 return target; 136 } 137 138 public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) 139 throws MarshalException 140 { 141 Document ownerDoc = DOMUtils.getOwnerDocument(parent); 142 Element propElem = DOMUtils.createElement(ownerDoc, "SignatureProperty", 143 XMLSignature.XMLNS, dsPrefix); 144 145 // set attributes 146 DOMUtils.setAttributeID(propElem, "Id", id); 147 DOMUtils.setAttribute(propElem, "Target", target); 148 149 // create and append any elements and mixed content 150 for (XMLStructure property : content) { 151 DOMUtils.appendChild(propElem, 152 ((javax.xml.crypto.dom.DOMStructure)property).getNode()); 153 } 154 155 parent.appendChild(propElem); 156 } 157 158 @Override 159 public boolean equals(Object o) { 160 if (this == o) { 161 return true; 162 } 163 164 if (!(o instanceof SignatureProperty)) { 165 return false; 166 } 167 SignatureProperty osp = (SignatureProperty)o; 168 169 boolean idsEqual = (id == null ? osp.getId() == null 170 : id.equals(osp.getId())); 171 172 @SuppressWarnings("unchecked") 173 List<XMLStructure> ospContent = osp.getContent(); 174 return (equalsContent(ospContent) && 175 target.equals(osp.getTarget()) && idsEqual); 176 } 177 178 @Override 179 public int hashCode() { 180 int result = 17; 181 if (id != null) { 182 result = 31 * result + id.hashCode(); 183 } 184 result = 31 * result + target.hashCode(); 185 result = 31 * result + content.hashCode(); 186 187 return result; 188 } 189 190 private boolean equalsContent(List<XMLStructure> otherContent) { 191 int osize = otherContent.size(); 192 if (content.size() != osize) { 193 return false; 194 } 195 for (int i = 0; i < osize; i++) { 196 XMLStructure oxs = otherContent.get(i); 197 XMLStructure xs = content.get(i); 198 if (oxs instanceof javax.xml.crypto.dom.DOMStructure) { 199 if (!(xs instanceof javax.xml.crypto.dom.DOMStructure)) { 200 return false; 201 } 202 Node onode = ((javax.xml.crypto.dom.DOMStructure)oxs).getNode(); 203 Node node = ((javax.xml.crypto.dom.DOMStructure)xs).getNode(); 204 if (!DOMUtils.nodesEqual(node, onode)) { 205 return false; 206 } 207 } else { 208 if (!(xs.equals(oxs))) { 209 return false; 210 } 211 } 212 } 213 214 return true; 215 } 216 } |