1 /*
2  * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 /*
26  * $Id: DOMCryptoContext.java,v 1.3 2005/05/09 18:33:26 mullan Exp $
27  */
28 package javax.xml.crypto.dom;
29 
30 import javax.xml.crypto.KeySelector;
31 import javax.xml.crypto.URIDereferencer;
32 import javax.xml.crypto.XMLCryptoContext;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.Map;
37 import org.w3c.dom.Element;
38 
39 /**
40  * This class provides a DOM-specific implementation of the
41  * {@link XMLCryptoContext} interface. It also includes additional
42  * methods that are specific to a DOM-based implementation for registering
43  * and retrieving elements that contain attributes of type ID.
44  *
45  * @author Sean Mullan
46  * @author JSR 105 Expert Group
47  * @since 1.6
48  */
49 public class DOMCryptoContext implements XMLCryptoContext {
50 
51     private HashMap<String,String> nsMap = new HashMap<>();
52     private HashMap<String,Element> idMap = new HashMap<>();
53     private HashMap<Object,Object> objMap = new HashMap<>();
54     private String baseURI;
55     private KeySelector ks;
56     private URIDereferencer dereferencer;
57     private HashMap<String,Object> propMap = new HashMap<>();
58     private String defaultPrefix;
59 
60     /**
61      * Default constructor. (For invocation by subclass constructors).
62      */
DOMCryptoContext()63     protected DOMCryptoContext() {}
64 
65     /**
66      * This implementation uses an internal {@link HashMap} to get the prefix
67      * that the specified URI maps to. It returns the <code>defaultPrefix</code>
68      * if it maps to <code>null</code>.
69      *
70      * @throws NullPointerException {@inheritDoc}
71      */
getNamespacePrefix(String namespaceURI, String defaultPrefix)72     public String getNamespacePrefix(String namespaceURI,
73         String defaultPrefix) {
74         if (namespaceURI == null) {
75             throw new NullPointerException("namespaceURI cannot be null");
76         }
77         String prefix = nsMap.get(namespaceURI);
78         return (prefix != null ? prefix : defaultPrefix);
79     }
80 
81     /**
82      * This implementation uses an internal {@link HashMap} to map the URI
83      * to the specified prefix.
84      *
85      * @throws NullPointerException {@inheritDoc}
86      */
putNamespacePrefix(String namespaceURI, String prefix)87     public String putNamespacePrefix(String namespaceURI, String prefix) {
88         if (namespaceURI == null) {
89             throw new NullPointerException("namespaceURI is null");
90         }
91         return nsMap.put(namespaceURI, prefix);
92     }
93 
getDefaultNamespacePrefix()94     public String getDefaultNamespacePrefix() {
95         return defaultPrefix;
96     }
97 
setDefaultNamespacePrefix(String defaultPrefix)98     public void setDefaultNamespacePrefix(String defaultPrefix) {
99         this.defaultPrefix = defaultPrefix;
100     }
101 
getBaseURI()102     public String getBaseURI() {
103         return baseURI;
104     }
105 
106     /**
107      * @throws IllegalArgumentException {@inheritDoc}
108      */
setBaseURI(String baseURI)109     public void setBaseURI(String baseURI) {
110         if (baseURI != null) {
111             java.net.URI.create(baseURI);
112         }
113         this.baseURI = baseURI;
114     }
115 
getURIDereferencer()116     public URIDereferencer getURIDereferencer() {
117         return dereferencer;
118     }
119 
setURIDereferencer(URIDereferencer dereferencer)120     public void setURIDereferencer(URIDereferencer dereferencer) {
121         this.dereferencer = dereferencer;
122     }
123 
124     /**
125      * This implementation uses an internal {@link HashMap} to get the object
126      * that the specified name maps to.
127      *
128      * @throws NullPointerException {@inheritDoc}
129      */
getProperty(String name)130     public Object getProperty(String name) {
131         if (name == null) {
132             throw new NullPointerException("name is null");
133         }
134         return propMap.get(name);
135     }
136 
137     /**
138      * This implementation uses an internal {@link HashMap} to map the name
139      * to the specified object.
140      *
141      * @throws NullPointerException {@inheritDoc}
142      */
setProperty(String name, Object value)143     public Object setProperty(String name, Object value) {
144         if (name == null) {
145             throw new NullPointerException("name is null");
146         }
147         return propMap.put(name, value);
148     }
149 
getKeySelector()150     public KeySelector getKeySelector() {
151         return ks;
152     }
153 
setKeySelector(KeySelector ks)154     public void setKeySelector(KeySelector ks) {
155         this.ks = ks;
156     }
157 
158     /**
159      * Returns the <code>Element</code> with the specified ID attribute value.
160      *
161      * <p>This implementation uses an internal {@link HashMap} to get the
162      * element that the specified attribute value maps to.
163      *
164      * @param idValue the value of the ID
165      * @return the <code>Element</code> with the specified ID attribute value,
166      *    or <code>null</code> if none.
167      * @throws NullPointerException if <code>idValue</code> is <code>null</code>
168      * @see #setIdAttributeNS
169      */
getElementById(String idValue)170     public Element getElementById(String idValue) {
171         if (idValue == null) {
172             throw new NullPointerException("idValue is null");
173         }
174         return idMap.get(idValue);
175     }
176 
177     /**
178      * Registers the element's attribute specified by the namespace URI and
179      * local name to be of type ID. The attribute must have a non-empty value.
180      *
181      * <p>This implementation uses an internal {@link HashMap} to map the
182      * attribute's value to the specified element.
183      *
184      * @param element the element
185      * @param namespaceURI the namespace URI of the attribute (specify
186      *    <code>null</code> if not applicable)
187      * @param localName the local name of the attribute
188      * @throws IllegalArgumentException if <code>localName</code> is not an
189      *    attribute of the specified element or it does not contain a specific
190      *    value
191      * @throws NullPointerException if <code>element</code> or
192      *    <code>localName</code> is <code>null</code>
193      * @see #getElementById
194      */
setIdAttributeNS(Element element, String namespaceURI, String localName)195     public void setIdAttributeNS(Element element, String namespaceURI,
196         String localName) {
197         if (element == null) {
198             throw new NullPointerException("element is null");
199         }
200         if (localName == null) {
201             throw new NullPointerException("localName is null");
202         }
203         String idValue = element.getAttributeNS(namespaceURI, localName);
204         if (idValue == null || idValue.length() == 0) {
205             throw new IllegalArgumentException(localName + " is not an " +
206                 "attribute");
207         }
208         idMap.put(idValue, element);
209     }
210 
211     /**
212      * Returns a read-only iterator over the set of Id/Element mappings of
213      * this <code>DOMCryptoContext</code>. Attempts to modify the set via the
214      * {@link Iterator#remove} method throw an
215      * <code>UnsupportedOperationException</code>. The mappings are returned
216      * in no particular order. Each element in the iteration is represented as a
217      * {@link java.util.Map.Entry}. If the <code>DOMCryptoContext</code> is
218      * modified while an iteration is in progress, the results of the
219      * iteration are undefined.
220      *
221      * @return a read-only iterator over the set of mappings
222      */
iterator()223     public Iterator<Map.Entry<String, Element>> iterator() {
224         return Collections.unmodifiableMap(idMap).entrySet().iterator();
225     }
226 
227     /**
228      * This implementation uses an internal {@link HashMap} to get the object
229      * that the specified key maps to.
230      */
get(Object key)231     public Object get(Object key) {
232         return objMap.get(key);
233     }
234 
235     /**
236      * This implementation uses an internal {@link HashMap} to map the key
237      * to the specified object.
238      *
239      * @throws IllegalArgumentException {@inheritDoc}
240      */
put(Object key, Object value)241     public Object put(Object key, Object value) {
242         return objMap.put(key, value);
243     }
244 }
245