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, 2013, 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                 String name = child.getLocalName();
 113                 if (!name.equals("SignatureProperty")) {
 114                     throw new MarshalException("Invalid element name: " + name +
 115                                                ", expected SignatureProperty");
 116                 }
 117                 properties.add(new DOMSignatureProperty((Element)child,
 118                                                         context));
 119             }
 120         }
 121         if (properties.isEmpty()) {
 122             throw new MarshalException("properties cannot be empty");
 123         } else {
 124             this.properties = Collections.unmodifiableList(properties);
 125         }
 126     }
 127 
 128     public List<SignatureProperty> getProperties() {
 129         return properties;
 130     }
 131 
 132     public String getId() {
 133         return id;
 134     }
 135 
 136     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
 137         throws MarshalException
 138     {
 139         Document ownerDoc = DOMUtils.getOwnerDocument(parent);
 140         Element propsElem = DOMUtils.createElement(ownerDoc,
 141                                                    "SignatureProperties",
 142                                                    XMLSignature.XMLNS,
 143                                                    dsPrefix);
 144 
 145         // set attributes
 146         DOMUtils.setAttributeID(propsElem, "Id", id);
 147 
 148         // create and append any properties
 149         for (SignatureProperty property : properties) {
 150             ((DOMSignatureProperty)property).marshal(propsElem, dsPrefix,
 151                                                      context);
 152         }
 153 
 154         parent.appendChild(propsElem);
 155     }
 156 
 157     @Override
 158     public boolean equals(Object o) {
 159         if (this == o) {
 160             return true;
 161         }
 162 
 163         if (!(o instanceof SignatureProperties)) {
 164             return false;
 165         }
 166         SignatureProperties osp = (SignatureProperties)o;
 167 
 168         boolean idsEqual = (id == null ? osp.getId() == null
 169                                        : id.equals(osp.getId()));
 170 
 171         return (properties.equals(osp.getProperties()) && idsEqual);
 172     }
 173 
 174     @Override
 175     public int hashCode() {
 176         int result = 17;
 177         if (id != null) {
 178             result = 31 * result + id.hashCode();
 179         }
 180         result = 31 * result + properties.hashCode();
 181 
 182         return result;
 183     }
 184 }
--- EOF ---