diff -r fd16c54261b3 -r 90ce3da70b43 jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,256 @@ +/* + * Portions Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * =========================================================================== + * + * (C) Copyright IBM Corp. 2003 All Rights Reserved. + * + * =========================================================================== + */ +/* + * $Id: DOMRetrievalMethod.java,v 1.24 2005/05/12 19:28:32 mullan Exp $ + */ +package org.jcp.xml.dsig.internal.dom; + +import java.io.ByteArrayInputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.*; +import javax.xml.crypto.*; +import javax.xml.crypto.dsig.*; +import javax.xml.crypto.dom.DOMCryptoContext; +import javax.xml.crypto.dom.DOMURIReference; +import javax.xml.crypto.dsig.keyinfo.RetrievalMethod; +import javax.xml.parsers.*; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; + +/** + * DOM-based implementation of RetrievalMethod. + * + * @author Sean Mullan + * @author Joyce Leung + */ +public final class DOMRetrievalMethod extends DOMStructure + implements RetrievalMethod, DOMURIReference { + + private final List transforms; + private String uri; + private String type; + private Attr here; + + /** + * Creates a DOMRetrievalMethod containing the specified + * URIReference and List of Transforms. + * + * @param uri the URI + * @param type the type + * @param transforms a list of {@link Transform}s. The list is defensively + * copied to prevent subsequent modification. May be null + * or empty. + * @throws IllegalArgumentException if the format of uri is + * invalid, as specified by Reference's URI attribute in the W3C + * specification for XML-Signature Syntax and Processing + * @throws NullPointerException if uriReference + * is null + * @throws ClassCastException if transforms contains any + * entries that are not of type {@link Transform} + */ + public DOMRetrievalMethod(String uri, String type, List transforms) { + if (uri == null) { + throw new NullPointerException("uri cannot be null"); + } + if (transforms == null || transforms.isEmpty()) { + this.transforms = Collections.EMPTY_LIST; + } else { + List transformsCopy = new ArrayList(transforms); + for (int i = 0, size = transformsCopy.size(); i < size; i++) { + if (!(transformsCopy.get(i) instanceof Transform)) { + throw new ClassCastException + ("transforms["+i+"] is not a valid type"); + } + } + this.transforms = Collections.unmodifiableList(transformsCopy); + } + this.uri = uri; + if ((uri != null) && (!uri.equals(""))) { + try { + new URI(uri); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + this.type = type; + } + + /** + * Creates a DOMRetrievalMethod from an element. + * + * @param rmElem a RetrievalMethod element + */ + public DOMRetrievalMethod(Element rmElem, XMLCryptoContext context) + throws MarshalException { + // get URI and Type attributes + uri = DOMUtils.getAttributeValue(rmElem, "URI"); + type = DOMUtils.getAttributeValue(rmElem, "Type"); + + // get here node + here = rmElem.getAttributeNodeNS(null, "URI"); + + // get Transforms, if specified + List transforms = new ArrayList(); + Element transformsElem = DOMUtils.getFirstChildElement(rmElem); + if (transformsElem != null) { + Element transformElem = + DOMUtils.getFirstChildElement(transformsElem); + while (transformElem != null) { + transforms.add(new DOMTransform(transformElem, context)); + transformElem = DOMUtils.getNextSiblingElement(transformElem); + } + } + if (transforms.isEmpty()) { + this.transforms = Collections.EMPTY_LIST; + } else { + this.transforms = Collections.unmodifiableList(transforms); + } + } + + public String getURI() { + return uri; + } + + public String getType() { + return type; + } + + public List getTransforms() { + return transforms; + } + + public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) + throws MarshalException { + Document ownerDoc = DOMUtils.getOwnerDocument(parent); + + Element rmElem = DOMUtils.createElement + (ownerDoc, "RetrievalMethod", XMLSignature.XMLNS, dsPrefix); + + // add URI and Type attributes + DOMUtils.setAttribute(rmElem, "URI", uri); + DOMUtils.setAttribute(rmElem, "Type", type); + + // add Transforms elements + if (!transforms.isEmpty()) { + Element transformsElem = DOMUtils.createElement + (ownerDoc, "Transforms", XMLSignature.XMLNS, dsPrefix); + rmElem.appendChild(transformsElem); + for (int i = 0, size = transforms.size(); i < size; i++) { + ((DOMTransform) transforms.get(i)).marshal + (transformsElem, dsPrefix, context); + } + } + + parent.appendChild(rmElem); + + // save here node + here = rmElem.getAttributeNodeNS(null, "URI"); + } + + public Node getHere() { + return here; + } + + public Data dereference(XMLCryptoContext context) + throws URIReferenceException { + + if (context == null) { + throw new NullPointerException("context cannot be null"); + } + + /* + * If URIDereferencer is specified in context; use it, otherwise use + * built-in. + */ + URIDereferencer deref = context.getURIDereferencer(); + if (deref == null) { + deref = DOMURIDereferencer.INSTANCE; + } + + Data data = deref.dereference(this, context); + + // pass dereferenced data through Transforms + try { + for (int i = 0, size = transforms.size(); i < size; i++) { + Transform transform = (Transform) transforms.get(i); + data = ((DOMTransform) transform).transform(data, context); + } + } catch (Exception e) { + throw new URIReferenceException(e); + } + return data; + } + + public XMLStructure dereferenceAsXMLStructure(XMLCryptoContext context) + throws URIReferenceException { + + try { + ApacheData data = (ApacheData) dereference(context); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(new ByteArrayInputStream + (data.getXMLSignatureInput().getBytes())); + Element kiElem = doc.getDocumentElement(); + if (kiElem.getLocalName().equals("X509Data")) { + return new DOMX509Data(kiElem); + } else { + return null; // unsupported + } + } catch (Exception e) { + throw new URIReferenceException(e); + } + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof RetrievalMethod)) { + return false; + } + RetrievalMethod orm = (RetrievalMethod) obj; + + boolean typesEqual = (type == null ? orm.getType() == null : + type.equals(orm.getType())); + + return (uri.equals(orm.getURI()) && + transforms.equals(orm.getTransforms()) && typesEqual); + } +}