1 /*
2 * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.opensaml.xml.io;
18
19 import java.util.Collections;
20 import java.util.Map;
21 import java.util.concurrent.ConcurrentHashMap;
22
23 import javax.xml.namespace.QName;
24
25 import org.opensaml.xml.util.XMLHelper;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.w3c.dom.Element;
29
30 /**
31 * This thread-safe factory creates {@link org.opensaml.xml.io.Unmarshaller}s that can be used to convert W3C DOM
32 * elements into {@link org.opensaml.xml.XMLObject}s. Unmarshallers are stored and retrieved by a
33 * {@link javax.xml.namespace.QName} key. This key is either the XML Schema Type or element QName of the XML element
34 * being unmarshalled.
35 */
36 public class UnmarshallerFactory {
37
38 /** Class logger. */
39 private final Logger log = LoggerFactory.getLogger(UnmarshallerFactory.class);
40
41 /** Map of unmarshallers to the elements they are for. */
42 private Map<QName, Unmarshaller> unmarshallers;
43
44 /**
45 * Constructor.
46 */
47 public UnmarshallerFactory() {
48 unmarshallers = new ConcurrentHashMap<QName, Unmarshaller>();
49 }
50
51 /**
52 * Gets the Unmarshaller for a particular element or null if no unmarshaller is registered for an element.
53 *
54 * @param key the key the unmarshaller was registered under
55 *
56 * @return the Unmarshaller
57 */
58 public Unmarshaller getUnmarshaller(QName key) {
59 if (key == null) {
60 return null;
61 }
62
63 return unmarshallers.get(key);
64 }
65
66 /**
67 * Retrieves the unmarshaller for the given element. The schema type, if present, is tried first as the key with the
68 * element QName used if no schema type is present or does not have a unmarshaller registered under it.
69 *
70 * @param domElement the element to retrieve the unmarshaller for
71 *
72 * @return the unmarshaller for the XMLObject the given element can be unmarshalled into
73 */
74 public Unmarshaller getUnmarshaller(Element domElement) {
75 Unmarshaller unmarshaller;
76
77 unmarshaller = getUnmarshaller(XMLHelper.getXSIType(domElement));
78
79 if (unmarshaller == null) {
80 unmarshaller = getUnmarshaller(XMLHelper.getNodeQName(domElement));
81 }
82
83 return unmarshaller;
84 }
85
86 /**
87 * Gets an immutable listing of all the Unarshallers currently registered.
88 *
89 * @return a listing of all the Unmarshallers currently registered
90 */
91 public Map<QName, Unmarshaller> getUnmarshallers() {
92 return Collections.unmodifiableMap(unmarshallers);
93 }
94
95 /**
96 * Registers an Unmarshaller with this factory. If an Unmarshaller exist for the Qname given it is replaced with the
97 * given unmarshaller.
98 *
99 * @param key the key the unmarshaller was registered under
100 * @param unmarshaller the Unmarshaller
101 */
102 public void registerUnmarshaller(QName key, Unmarshaller unmarshaller) {
103 log.debug("Registering unmarshaller, {}, for object type, {}", unmarshaller.getClass().getName(), key);
104 if (key == null) {
105 throw new IllegalArgumentException("Unmarshaller key may not be null");
106 }
107 unmarshallers.put(key, unmarshaller);
108 }
109
110 /**
111 * Deregisters the unmarshaller for the given element.
112 *
113 * @param key the key the unmarshaller was registered under
114 *
115 * @return the Unmarshaller previously registered or null
116 */
117 public Unmarshaller deregisterUnmarshaller(QName key) {
118 log.debug("Deregistering marshaller for object type {}", key);
119 if (key != null) {
120 return unmarshallers.remove(key);
121 }
122
123 return null;
124 }
125 }