1 /*
2 * Copyright [2006] [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;
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 * A factory for {@link org.opensaml.xml.XMLObjectBuilder}s. XMLObjectBuilders 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 * built XMLObject object represents.
34 */
35 public class XMLObjectBuilderFactory {
36
37 /** Class logger. */
38 private final Logger log = LoggerFactory.getLogger(XMLObjectBuilderFactory.class);
39
40 /** Registered builders. */
41 private Map<QName, XMLObjectBuilder> builders;
42
43 /** Constructor. */
44 public XMLObjectBuilderFactory() {
45 builders = new ConcurrentHashMap<QName, XMLObjectBuilder>();
46 }
47
48 /**
49 * Retrieves an {@link XMLObjectBuilder} using the key it was registered with.
50 *
51 * @param key the key used to register the builder
52 *
53 * @return the builder
54 */
55 public XMLObjectBuilder getBuilder(QName key) {
56 if(key == null){
57 return null;
58 }
59 return builders.get(key);
60 }
61
62 /**
63 * Retrieves the XMLObject builder for the given element. The schema type, if present, is tried first as the key
64 * with the element QName used if no schema type is present or does not have a builder registered under it.
65 *
66 * @param domElement the element to retrieve the builder for
67 *
68 * @return the builder for the XMLObject the given element can be unmarshalled into
69 */
70 public XMLObjectBuilder getBuilder(Element domElement) {
71 XMLObjectBuilder builder;
72
73 builder = getBuilder(XMLHelper.getXSIType(domElement));
74
75 if (builder == null) {
76 builder = getBuilder(XMLHelper.getNodeQName(domElement));
77 }
78
79 return builder;
80 }
81
82 /**
83 * Gets an immutable list of all the builders currently registered.
84 *
85 * @return list of all the builders currently registered
86 */
87 public Map<QName, XMLObjectBuilder> getBuilders() {
88 return Collections.unmodifiableMap(builders);
89 }
90
91 /**
92 * Registers a new builder for the given name.
93 *
94 * @param builderKey the key used to retrieve this builder later
95 * @param builder the builder
96 */
97 public void registerBuilder(QName builderKey, XMLObjectBuilder builder) {
98 log.debug("Registering builder, {} under key {}", builder.getClass().getName(), builderKey);
99 if(builderKey == null){
100 throw new IllegalArgumentException("Builder key may not be null");
101 }
102 builders.put(builderKey, builder);
103 }
104
105 /**
106 * Deregisters a builder.
107 *
108 * @param builderKey the key for the builder to be deregistered
109 *
110 * @return the builder that was registered for the given QName
111 */
112 public XMLObjectBuilder deregisterBuilder(QName builderKey) {
113 log.debug("Deregistering builder for object type {}", builderKey);
114 if(builderKey != null){
115 return builders.remove(builderKey);
116 }
117
118 return null;
119 }
120 }