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: DOMSignatureProperties.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 SignatureProperties. 45 * 46 * @author Sean Mullan 47 */ 48 public final class DOMSignatureProperties extends DOMStructure 49 implements SignatureProperties { 50 51 private final String id; 52 private final List<SignatureProperty> properties; 53 54 /** 55 * Creates a <code>DOMSignatureProperties</code> from the specified 56 * parameters. 57 * 58 * @param properties a list of one or more {@link SignatureProperty}s. The 59 * list is defensively copied to protect against subsequent modification. 60 * @param id the Id (may be <code>null</code>) 61 * @return a <code>DOMSignatureProperties</code> 62 * @throws ClassCastException if <code>properties</code> contains any 63 * entries that are not of type {@link SignatureProperty} 64 * @throws IllegalArgumentException if <code>properties</code> is empty 65 * @throws NullPointerException if <code>properties</code> 66 */ 67 public DOMSignatureProperties(List<? extends SignatureProperty> properties, 68 String id) 69 { 70 if (properties == null) { 71 throw new NullPointerException("properties cannot be null"); 72 } else if (properties.isEmpty()) { 73 throw new IllegalArgumentException("properties cannot be empty"); 74 } else { 75 this.properties = Collections.unmodifiableList( 76 new ArrayList<SignatureProperty>(properties)); 77 for (int i = 0, size = this.properties.size(); i < size; i++) { 78 if (!(this.properties.get(i) instanceof SignatureProperty)) { 79 throw new ClassCastException 80 ("properties["+i+"] is not a valid type"); 81 } 82 } 83 } 84 this.id = id; 85 } 86 87 /** 88 * Creates a <code>DOMSignatureProperties</code> from an element. 89 * 90 * @param propsElem a SignatureProperties element 91 * @throws MarshalException if a marshalling error occurs 92 */ 93 public DOMSignatureProperties(Element propsElem, XMLCryptoContext context) 94 throws MarshalException 95 { 96 // unmarshal attributes 97 Attr attr = propsElem.getAttributeNodeNS(null, "Id"); 98 if (attr != null) { 99 id = attr.getValue(); 100 propsElem.setIdAttributeNode(attr, true); 101 } else { 102 id = null; 103 } 104 105 NodeList nodes = propsElem.getChildNodes(); 106 int length = nodes.getLength(); 107 List<SignatureProperty> properties = 108 new ArrayList<SignatureProperty>(length); 109 for (int i = 0; i < length; i++) { 110 Node child = nodes.item(i); 111 if (child.getNodeType() == Node.ELEMENT_NODE) { 112 properties.add(new DOMSignatureProperty((Element)child, 113 context)); 114 } 115 } 116 if (properties.isEmpty()) { 117 throw new MarshalException("properties cannot be empty"); 118 } else { 119 this.properties = Collections.unmodifiableList(properties); 120 } 121 } 122 123 public List getProperties() { 124 return properties; 125 } 126 127 public String getId() { 128 return id; 129 } 130 131 public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) 132 throws MarshalException 133 { 134 Document ownerDoc = DOMUtils.getOwnerDocument(parent); 135 Element propsElem = DOMUtils.createElement(ownerDoc, 136 "SignatureProperties", 137 XMLSignature.XMLNS, 138 dsPrefix); 139 140 // set attributes 141 DOMUtils.setAttributeID(propsElem, "Id", id); 142 143 // create and append any properties 144 for (SignatureProperty property : properties) { 145 ((DOMSignatureProperty)property).marshal(propsElem, dsPrefix, 146 context); 147 } 148 149 parent.appendChild(propsElem); 150 } 151 152 @Override 153 public boolean equals(Object o) { 154 if (this == o) { 155 return true; 156 } 157 158 if (!(o instanceof SignatureProperties)) { 159 return false; 160 } 161 SignatureProperties osp = (SignatureProperties)o; 162 163 boolean idsEqual = (id == null ? osp.getId() == null 164 : id.equals(osp.getId())); 165 166 return (properties.equals(osp.getProperties()) && idsEqual); 167 } 168 169 @Override 170 public int hashCode() { 171 int result = 17; 172 if (id != null) { 173 result = 31 * result + id.hashCode(); 174 } 175 result = 31 * result + properties.hashCode(); 176 177 return result; 178 } 179 }