1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*
19  * $Id: XMLGrammarPoolImpl.hpp 671531 2008-06-25 12:38:28Z borisk $
20  */
21 
22 #if !defined(XERCESC_INCLUDE_GUARD_XMLGRAMMARPOOLIMPL_HPP)
23 #define XERCESC_INCLUDE_GUARD_XMLGRAMMARPOOLIMPL_HPP
24 
25 #include <xercesc/framework/XMLGrammarPool.hpp>
26 
27 XERCES_CPP_NAMESPACE_BEGIN
28 
29 class XMLSynchronizedStringPool;
30 
31 class XMLUTIL_EXPORT XMLGrammarPoolImpl : public XMLGrammarPool
32 {
33 public :
34     // -----------------------------------------------------------------------
35     /** @name constructor and destructor */
36     // -----------------------------------------------------------------------
37     //@{
38 
39     XMLGrammarPoolImpl(MemoryManager* const memMgr = XMLPlatformUtils::fgMemoryManager);
40 
41     ~XMLGrammarPoolImpl();
42     //@}
43 
44     // -----------------------------------------------------------------------
45     /** @name Implementation of Grammar Pool Interface */
46     // -----------------------------------------------------------------------
47     //@{
48 
49     /**
50       * cacheGrammar
51       *
52       * Provide the grammar pool with an opportunity
53       * to cache the given grammar.  If the pool does not choose to do so,
54       * it should return false; otherwise, it should return true, so that
55       * the caller knows whether the grammar has been adopted.
56       *
57       * @param gramToCache: the Grammar to be cached in the grammar pool
58       * @return true if the grammar pool has elected to cache the grammar (in which case
59       * it is assumed to have adopted it); false if it does not cache it
60 	  *
61       */
62     virtual bool           cacheGrammar(Grammar* const               gramToCache);
63 
64 
65     /**
66       * retrieveGrammar
67       *
68       * @param gramDesc: the Grammar Description used to search for grammar
69 	  *                  cached in the grammar pool
70 	  *
71       */
72     virtual Grammar*       retrieveGrammar(XMLGrammarDescription* const gramDesc);
73 
74 
75     /**
76       * orphanGrammar
77       *
78 	  * grammar removed from the grammar pool and owned by the caller
79       *
80       * @param nameSpaceKey: Key used to search for grammar in the grammar pool
81 	  *
82       */
83     virtual Grammar*       orphanGrammar(const XMLCh* const nameSpaceKey);
84 
85 
86     /**
87      * Get an enumeration of the cached Grammars in the Grammar pool
88      *
89      * @return enumeration of the cached Grammars in Grammar pool
90      */
91     virtual RefHashTableOfEnumerator<Grammar> getGrammarEnumerator() const;
92 
93     /**
94       * clear
95       *
96 	  * all grammars are removed from the grammar pool and deleted.
97       * @return true if the grammar pool was cleared. false if it did not.
98       */
99     virtual bool           clear();
100 
101     /**
102       * lockPool
103       *
104 	  * When this method is called by the application, the
105       * grammar pool should stop adding new grammars to the cache.
106       */
107     virtual void           lockPool();
108 
109     /**
110       * unlockPool
111       *
112 	  * After this method has been called, the grammar pool implementation
113       * should return to its default behaviour when cacheGrammars(...) is called.
114       *
115       * For PSVI support any previous XSModel that was produced will be deleted.
116       */
117     virtual void           unlockPool();
118 
119     //@}
120 
121     // -----------------------------------------------------------------------
122     /** @name  Implementation of Factory interface */
123     // -----------------------------------------------------------------------
124     //@{
125 
126     /**
127       * createDTDGrammar
128       *
129       */
130     virtual DTDGrammar*            createDTDGrammar();
131 
132     /**
133       * createSchemaGrammar
134       *
135       */
136     virtual SchemaGrammar*         createSchemaGrammar();
137 
138     /**
139       * createDTDDescription
140       *
141       */
142     virtual XMLDTDDescription*     createDTDDescription(const XMLCh* const systemId);
143     /**
144       * createSchemaDescription
145       *
146       */
147     virtual XMLSchemaDescription*  createSchemaDescription(const XMLCh* const targetNamespace);
148     //@}
149 
150     // -----------------------------------------------------------------------
151     /** @name  schema component model support */
152     // -----------------------------------------------------------------------
153     //@{
154 
155     /***
156       * Return an XSModel derived from the components of all SchemaGrammars
157       * in the grammar pool.  If the pool is locked, this should
158       * be a thread-safe operation.
159       *
160       * NOTE: The function should NEVER return NULL.  If there are no grammars in
161       *       the pool it should return an XSModel containing the Schema for Schema.
162       *
163       * Calling getXSModel() on an unlocked grammar pool may result in the
164       * creation of a new XSModel with the old XSModel being deleted.
165       * The bool parameter will indicate if the XSModel was changed.
166       *
167       * In this implementation, when the pool is not locked a new XSModel will be
168       * computed each this time the pool is called if the pool has changed (and the
169       * previous one will be destroyed at that time).  When the lockPool()
170       * method is called, an XSModel will be generated and returned whenever this method is called
171       * while the pool is in the locked state.  This will be destroyed if the unlockPool()
172       * operation is called.  The XSModel will not be serialized,
173       * but will be recreated if a deserialized pool is in the
174       * locked state.
175       *
176       */
177     virtual XSModel *getXSModel(bool& XSModelWasChanged);
178 
179     // @}
180     // -----------------------------------------------------------------------
181     /** @name  Getter */
182     // -----------------------------------------------------------------------
183     //@{
184 
185     /**
186       * Return an XMLStringPool for use by validation routines.
187       * Implementations should not create a string pool on each call to this
188       * method, but should maintain one string pool for all grammars
189       * for which this pool is responsible.
190       */
191     virtual XMLStringPool *getURIStringPool();
192 
193     // @}
194 
195     // -----------------------------------------------------------------------
196     // serialization and deserialization support
197     // -----------------------------------------------------------------------
198 
199     /***
200       *
201       * Multiple serializations
202       *
203       *    For multiple serializations, if the same file name is given, then the
204       *    last result will be in the file (overwriting mode), if different file
205       *    names are given, then there are multiple data stores for each serialization.
206       *
207       * Multiple deserializations
208       *
209       *    Not supported
210       *
211       * Versioning
212       *
213       *    Only binary data serialized with the current XercesC Version and
214       *    SerializationLevel is supported.
215       *
216       * Clean up
217       *
218       *    In the event of an exception thrown due to a corrupted data store during
219       *    deserialization, this implementation may not be able to clean up all resources
220       *    allocated, and therefore it is the client application's responsibility to
221       *    clean up those unreleased resources.
222       *
223       * Coupling of Grammars and StringPool
224       *
225       *    This implementation assumes that StringPool shall always be
226       *    serialized/deserialized together with the grammars. In the case that such a
227       *    coupling is not desired, client application can modify this behaviour by
228       *    either derivate from this imlementation and overwrite the serializeGrammars()
229       *    and/or deserializeGrammars() to decouple grammars and string pool, or
230       *    Once deserializeGrammars() is done, insert another StringPool through
231       *    setStringPool().
232       *
233       *    Client application shall be aware of the unpredicatable/undefined consequence
234       *    of this decoupling.
235       */
236 
237     virtual void     serializeGrammars(BinOutputStream* const);
238     virtual void     deserializeGrammars(BinInputStream* const);
239 
240 private:
241 
242     virtual void    createXSModel();
243 
244     void
245     cleanUp();
246 
247     // -----------------------------------------------------------------------
248     /** name  Unimplemented copy constructor and operator= */
249     // -----------------------------------------------------------------------
250     //@{
251     XMLGrammarPoolImpl(const XMLGrammarPoolImpl& );
252     XMLGrammarPoolImpl& operator=(const XMLGrammarPoolImpl& );
253     //@}
254 
255     // -----------------------------------------------------------------------
256     //
257     // fGrammarRegistry:
258     //
259 	//    container
260     // fStringPool
261     //    grammars need a string pool for URI -> int mappings
262     // fSynchronizedStringPool
263     //      When the grammar pool is locked, provide a string pool
264     //      that can be updated in a thread-safe manner.
265     // fLocked
266     //      whether the pool has been locked
267     //
268     // -----------------------------------------------------------------------
269     RefHashTableOf<Grammar>*            fGrammarRegistry;
270     XMLStringPool*                      fStringPool;
271     XMLSynchronizedStringPool*          fSynchronizedStringPool;
272     XSModel*                            fXSModel;
273     bool                                fLocked;
274     bool                                fXSModelIsValid;
275 };
276 
277 XERCES_CPP_NAMESPACE_END
278 
279 #endif
280