jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java
changeset 2 90ce3da70b43
child 1337 e8d6cef36199
--- /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 <code>DOMRetrievalMethod</code> 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 <code>null</code>
+     *    or empty.
+     * @throws IllegalArgumentException if the format of <code>uri</code> is
+     *    invalid, as specified by Reference's URI attribute in the W3C
+     *    specification for XML-Signature Syntax and Processing
+     * @throws NullPointerException if <code>uriReference</code>
+     *    is <code>null</code>
+     * @throws ClassCastException if <code>transforms</code> 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 <code>DOMRetrievalMethod</code> 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);
+    }
+}