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