Set xsi:type during object construction.
[shibboleth/cpp-xmltooling.git] / xmltooling / XMLObjectBuilder.h
1 /*
2  *  Copyright 2001-2006 Internet2
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 /**
18  * @file XMLObjectBuilder.h
19  * 
20  * Factory interface for XMLObjects 
21  */
22
23 #if !defined(__xmltooling_xmlobjbuilder_h__)
24 #define __xmltooling_xmlobjbuilder_h__
25
26 #include <map>
27 #include <xmltooling/QName.h>
28 #include <xmltooling/XMLObject.h>
29 #include <xmltooling/util/XMLHelper.h>
30
31 #if defined (_MSC_VER)
32     #pragma warning( push )
33     #pragma warning( disable : 4250 4251 )
34 #endif
35
36 namespace xmltooling {
37
38     /**
39      * A factory interface for obtaining XMLObjects.
40      * Subclasses MAY supply additional factory methods.
41      */
42     class XMLTOOL_API XMLObjectBuilder
43     {
44     MAKE_NONCOPYABLE(XMLObjectBuilder);
45     public:
46         virtual ~XMLObjectBuilder() {}
47         
48         /**
49          * Creates an empty XMLObject with a particular element name.
50          * The results are undefined if localName is NULL or empty.
51          * 
52          * @param nsURI         namespace URI for element
53          * @param localName     local name of element
54          * @param prefix        prefix of element name
55          * @param schemaType    xsi:type of the object
56          * @return the empty XMLObject
57          */
58         virtual XMLObject* buildObject(
59             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL
60             ) const=0;
61
62         /**
63          * Creates an empty XMLObject with a particular element name.
64          * 
65          * @param q     QName of element for object
66          * @return the empty XMLObject
67          */
68         XMLObject* buildFromQName(const QName& q) const {
69             return buildObject(q.getNamespaceURI(),q.getLocalPart(),q.getPrefix());
70         }
71
72         /**
73          * Creates an unmarshalled XMLObject from a DOM Element.
74          * 
75          * @param element       the unmarshalling source
76          * @param bindDocument  true iff the XMLObject should take ownership of the DOM Document
77          * @return the unmarshalled XMLObject
78          */
79         XMLObject* buildFromElement(DOMElement* element, bool bindDocument=false) const {
80             std::auto_ptr<XMLObject> ret(
81                 buildObject(element->getNamespaceURI(),element->getLocalName(),element->getPrefix(),XMLHelper::getXSIType(element))
82                 );
83             ret->unmarshall(element,bindDocument);
84             return ret.release();
85         }
86
87         /**
88          * Creates an unmarshalled XMLObject from the root of a DOM Document.
89          * 
90          * @param doc           the unmarshalling source
91          * @param bindDocument  true iff the XMLObject should take ownership of the DOM Document
92          * @return the unmarshalled XMLObject
93          */
94         XMLObject* buildFromDocument(DOMDocument* doc, bool bindDocument=true) const {
95             return buildFromElement(doc->getDocumentElement(),bindDocument);
96         }
97
98         /**
99          * Creates an empty XMLObject using the default build method, if a builder can be found.
100          * 
101          * @param key   the element key used to locate a builder
102          * @return  the empty object or NULL if no builder is available 
103          */
104         static XMLObject* buildOne(const QName& key) {
105             const XMLObjectBuilder* b=getBuilder(key);
106             if (b)
107                 return b->buildFromQName(key);
108             b=getDefaultBuilder();
109             return b ? b->buildFromQName(key) : NULL;
110         }
111
112         /**
113          * Creates an unmarshalled XMLObject using the default build method, if a builder can be found.
114          * 
115          * @param element       the unmarshalling source
116          * @param bindDocument  true iff the new XMLObject should take ownership of the DOM Document
117          * @return  the unmarshalled object or NULL if no builder is available 
118          */
119         static XMLObject* buildOneFromElement(DOMElement* element, bool bindDocument=false) {
120             const XMLObjectBuilder* b=getBuilder(element);
121             return b ? b->buildFromElement(element,bindDocument) : NULL;
122         }
123
124         /**
125          * Retrieves an XMLObjectBuilder using the key it was registered with.
126          * 
127          * @param key the key used to register the builder
128          * @return the builder or NULL
129          */
130         static const XMLObjectBuilder* getBuilder(const QName& key) {
131             std::map<QName,XMLObjectBuilder*>::const_iterator i=m_map.find(key);
132             return (i==m_map.end()) ? NULL : i->second;
133         }
134
135         /**
136          * Retrieves an XMLObjectBuilder for a given DOM element.
137          * If no match is found, the default builder is returned, if any.
138          * 
139          * @param element the element for which to locate a builder
140          * @return the builder or NULL
141          */
142         static const XMLObjectBuilder* getBuilder(const DOMElement* element);
143
144         /**
145          * Retrieves the default XMLObjectBuilder for DOM elements
146          * 
147          * @return the default builder or NULL
148          */
149         static const XMLObjectBuilder* getDefaultBuilder() {
150             return m_default;
151         }
152
153         /**
154          * Gets an immutable list of all the builders currently registered.
155          * 
156          * @return list of all the builders currently registered
157          */
158         static const std::map<QName,XMLObjectBuilder*>& getBuilders() {
159             return m_map;
160         }
161     
162         /**
163          * Registers a new builder for the given key.
164          * 
165          * @param builderKey the key used to retrieve this builder later
166          * @param builder the builder
167          */
168         static void registerBuilder(const QName& builderKey, XMLObjectBuilder* builder) {
169             deregisterBuilder(builderKey);
170             m_map[builderKey]=builder;
171         }
172
173         /**
174          * Registers a default builder
175          * 
176          * @param builder the default builder
177          */
178         static void registerDefaultBuilder(XMLObjectBuilder* builder) {
179             deregisterDefaultBuilder();
180             m_default=builder;
181         }
182
183         /**
184          * Deregisters a builder.
185          * 
186          * @param builderKey the key for the builder to be deregistered
187          */
188         static void deregisterBuilder(const QName& builderKey) {
189             delete getBuilder(builderKey);
190             m_map.erase(builderKey);
191         }
192
193         /**
194          * Deregisters default builder.
195          */
196         static void deregisterDefaultBuilder() {
197             delete m_default;
198             m_default=NULL;
199         }
200
201         /**
202          * Unregisters and destroys all registered builders. 
203          */
204         static void destroyBuilders();
205
206     protected:
207         XMLObjectBuilder() {}
208     
209     private:
210         static std::map<QName,XMLObjectBuilder*> m_map;
211         static XMLObjectBuilder* m_default;
212     };
213
214 };
215
216 #if defined (_MSC_VER)
217     #pragma warning( pop )
218 #endif
219
220 #endif /* __xmltooling_xmlobjbuilder_h__ */