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.XMLObject;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30 * This thread-safe factory creates {@link org.opensaml.xml.io.Marshaller}s that can be used to convert
31 * {@link org.opensaml.xml.XMLObject}s into W3C DOM elements. Marshallers are stored and retrieved by a
32 * {@link javax.xml.namespace.QName} key. This key is either the XML Schema Type or element QName of the XML element the
33 * XMLObject is marshalled into.
34 */
35 public class MarshallerFactory {
36
37 /** Class logger. */
38 private final Logger log = LoggerFactory.getLogger(MarshallerFactory.class);
39
40 /** Map of marshallers to the elements they are for. */
41 private Map<QName, Marshaller> marshallers;
42
43 /**
44 * Constructor.
45 */
46 public MarshallerFactory() {
47 marshallers = new ConcurrentHashMap<QName, Marshaller>();
48 }
49
50 /**
51 * Gets the Marshaller for a particular element or null if no marshaller is registered for an element.
52 *
53 * @param key the key the marshaller was registered under
54 *
55 * @return the Marshaller or null
56 */
57 public Marshaller getMarshaller(QName key) {
58 if (key == null) {
59 return null;
60 }
61
62 return marshallers.get(key);
63 }
64
65 /**
66 * Retrieves the marshaller for the given XMLObject. The schema type, if present, is tried first as the key with the
67 * element QName used if no schema type is present or does not have a marshaller registered under it.
68 *
69 * @param xmlObject the XMLObject to retrieve the marshaller for
70 *
71 * @return the marshaller that can be used for the given XMLObject
72 */
73 public Marshaller getMarshaller(XMLObject xmlObject) {
74 Marshaller marshaller;
75
76 marshaller = getMarshaller(xmlObject.getSchemaType());
77
78 if (marshaller == null) {
79 marshaller = getMarshaller(xmlObject.getElementQName());
80 }
81
82 return marshaller;
83 }
84
85 /**
86 * Gets an immutable listing of all the Marshallers currently registered.
87 *
88 * @return a listing of all the Marshallers currently registered
89 */
90 public Map<QName, Marshaller> getMarshallers() {
91 return Collections.unmodifiableMap(marshallers);
92 }
93
94 /**
95 * Registers a Marshaller with this factory. If a Marshaller exist for the element name given it is replaced with
96 * the given marshaller.
97 *
98 * @param key the key the marshaller was registered under
99 * @param marshaller the Marshaller
100 */
101 public void registerMarshaller(QName key, Marshaller marshaller) {
102 log.debug("Registering marshaller, {}, for object type {}", marshaller.getClass().getName(), key);
103 if(key == null){
104 throw new IllegalArgumentException("Marshaller key may not be null");
105 }
106 marshallers.put(key, marshaller);
107 }
108
109 /**
110 * Deregisters the marshaller for the given element.
111 *
112 * @param key the key the marshaller was registered under
113 *
114 * @return the Marshaller previously registered or null
115 */
116 public Marshaller deregisterMarshaller(QName key) {
117 log.debug("Deregistering marshaller for object type {}", key);
118 if(key != null){
119 return marshallers.remove(key);
120 }
121
122 return null;
123 }
124 }