Reducing header overuse, non-inlining selected methods (CPPOST-35).
[shibboleth/cpp-xmltooling.git] / xmltooling / util / ParserPool.h
1 /*
2  *  Copyright 2001-2009 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 xmltooling/util/ParserPool.h
19  *
20  * A thread-safe pool of parsers that share characteristics.
21  */
22
23 #ifndef __xmltooling_pool_h__
24 #define __xmltooling_pool_h__
25
26 #include <xmltooling/unicode.h>
27
28 #include <map>
29 #include <stack>
30 #include <istream>
31 #include <xercesc/dom/DOM.hpp>
32 #include <xercesc/sax/InputSource.hpp>
33 #include <xercesc/util/BinInputStream.hpp>
34 #include <xercesc/util/SecurityManager.hpp>
35 #include <xercesc/util/XMLURL.hpp>
36
37 #ifndef XMLTOOLING_NO_XMLSEC
38 # include <xsec/framework/XSECDefs.hpp>
39 #endif
40
41 #if defined (_MSC_VER)
42     #pragma warning( push )
43     #pragma warning( disable : 4250 4251 )
44 #endif
45
46 namespace xmltooling {
47
48     class XMLTOOL_API Mutex;
49
50     /**
51      * A thread-safe pool of DOMBuilders that share characteristics.
52      */
53     class XMLTOOL_API ParserPool :
54 #ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
55         public xercesc::DOMLSResourceResolver
56 #else
57         public xercesc::DOMEntityResolver
58 #endif
59     {
60         MAKE_NONCOPYABLE(ParserPool);
61     public:
62         /**
63          * Constructs a new pool
64          *
65          * @param namespaceAware    indicates whether parsers should be namespace-aware or not
66          * @param schemaAware       indicates whether parsers should be schema-validating or not
67          */
68         ParserPool(bool namespaceAware=true, bool schemaAware=false);
69         ~ParserPool();
70
71         /**
72          * Creates a new document using a parser from this pool.
73          *
74          * @return new XML document
75          *
76          */
77         xercesc::DOMDocument* newDocument();
78
79         /**
80          * Parses a document using a pooled parser with the proper settings
81          *
82          * @param domsrc An input source containing the content to be parsed
83          * @return The DOM document resulting from the parse
84          * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML
85          */
86         xercesc::DOMDocument* parse(
87 #ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
88             xercesc::DOMLSInput& domsrc
89 #else
90             xercesc::DOMInputSource& domsrc
91 #endif
92             );
93
94         /**
95          * Parses a document using a pooled parser with the proper settings
96          *
97          * @param is An input stream containing the content to be parsed
98          * @return The DOM document resulting from the parse
99          * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML
100          */
101         xercesc::DOMDocument* parse(std::istream& is);
102
103         /**
104          * Load an OASIS catalog file to map schema namespace URIs to filenames.
105          *
106          * This does not provide real catalog support; only the &lt;uri&gt; element
107          * is supported to map from a namespace URI to a relative path or file:// URI.
108          *
109          * @param pathname  path to a catalog file
110          * @return true iff the catalog was successfully processed
111          */
112         bool loadCatalog(const XMLCh* pathname);
113
114         /**
115          * Load a schema explicitly from a local file.
116          *
117          * Note that "successful processing" does not imply that the schema is valid,
118          * only that a reference to it was successfully registered with the pool.
119          *
120          * @param nsURI     XML namespace to load
121          * @param pathname  path to schema file
122          * @return true iff the schema was successfully processed
123          */
124         bool loadSchema(const XMLCh* nsURI, const XMLCh* pathname);
125
126         /**
127          * Supplies all external entities (primarily schemas) to the parser
128          */
129 #ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
130         xercesc::DOMLSInput* resolveResource(
131             const XMLCh *const resourceType,
132             const XMLCh *const namespaceUri,
133             const XMLCh *const publicId,
134             const XMLCh *const systemId,
135             const XMLCh *const baseURI
136             );
137 #else
138         xercesc::DOMInputSource* resolveEntity(
139             const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI
140             );
141 #endif
142
143     private:
144 #ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
145         xercesc::DOMLSParser* createBuilder();
146         xercesc::DOMLSParser* checkoutBuilder();
147         void checkinBuilder(xercesc::DOMLSParser* builder);
148 #else
149         xercesc::DOMBuilder* createBuilder();
150         xercesc::DOMBuilder* checkoutBuilder();
151         void checkinBuilder(xercesc::DOMBuilder* builder);
152 #endif
153
154         xstring m_schemaLocations;
155         std::map<xstring,xstring> m_schemaLocMap;
156
157         bool m_namespaceAware,m_schemaAware;
158 #ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
159         std::stack<xercesc::DOMLSParser*> m_pool;
160 #else
161         std::stack<xercesc::DOMBuilder*> m_pool;
162 #endif
163         Mutex* m_lock;
164         xercesc::SecurityManager* m_security;
165     };
166
167     /**
168      * A parser source that wraps a C++ input stream
169      */
170     class XMLTOOL_API StreamInputSource : public xercesc::InputSource
171     {
172     MAKE_NONCOPYABLE(StreamInputSource);
173     public:
174         /**
175          * Constructs an input source around an input stream reference.
176          *
177          * @param is        reference to an input stream
178          * @param systemId  optional system identifier to attach to the stream
179          */
180         StreamInputSource(std::istream& is, const char* systemId=NULL);
181         /// @cond off
182         xercesc::BinInputStream* makeStream() const;
183         /// @endcond
184
185         /**
186          * A Xerces input stream that wraps a C++ input stream
187          */
188         class XMLTOOL_API StreamBinInputStream : public xercesc::BinInputStream
189         {
190         public:
191             /**
192              * Constructs a Xerces input stream around a C++ input stream reference.
193              *
194              * @param is            reference to an input stream
195              */
196             StreamBinInputStream(std::istream& is);
197             /// @cond off
198 #ifdef XMLTOOLING_XERCESC_64BITSAFE
199             XMLFilePos curPos() const;
200             const XMLCh* getContentType() const;
201 #else
202             unsigned int curPos() const;
203 #endif
204             xsecsize_t readBytes(XMLByte* const toFill, const xsecsize_t maxToRead);
205             /// @endcond
206         private:
207             std::istream& m_is;
208             xsecsize_t m_pos;
209         };
210
211     private:
212         std::istream& m_is;
213     };
214
215     /**
216      * A URL-based parser source that supports a more advanced input stream.
217      */
218     class XMLTOOL_API URLInputSource : public xercesc::InputSource
219     {
220     MAKE_NONCOPYABLE(URLInputSource);
221     public:
222         /**
223          * Constructor.
224          *
225          * @param url       source of input
226          * @param systemId  optional system identifier to attach to the source
227          */
228         URLInputSource(const XMLCh* url, const char* systemId=NULL);
229
230         /**
231          * Constructor taking a DOM element supporting the following content:
232          *
233          * <dl>
234          *  <dt>uri | url</dt>
235          *  <dd>identifies the remote resource</dd>
236          *  <dt>verifyHost</dt>
237          *  <dd>true iff name of host should be matched against TLS/SSL certificate</dd>
238          *  <dt>TransportOption elements, like so:</dt>
239          *  <dd>&lt;TransportOption provider="CURL" option="150"&gt;0&lt;/TransportOption&gt;</dd>
240          * </dl>
241          *
242          * @param e         DOM to supply configuration
243          * @param systemId  optional system identifier to attach to the source
244          */
245         URLInputSource(const xercesc::DOMElement* e, const char* systemId=NULL);
246
247         /// @cond off
248         virtual xercesc::BinInputStream* makeStream() const;
249         /// @endcond
250
251     private:
252 #ifdef XMLTOOLING_LITE
253         xercesc::XMLURL m_url;
254 #else
255         xmltooling::auto_ptr_char m_url;
256         const xercesc::DOMElement* m_root;
257 #endif
258     };
259 };
260
261 #if defined (_MSC_VER)
262     #pragma warning( pop )
263 #endif
264
265 #endif /* __xmltooling_pool_h__ */