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: SchemaGrammar.cpp 883376 2009-11-23 15:45:23Z borisk $
20  */
21 
22 // ---------------------------------------------------------------------------
23 //  Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/validators/schema/SchemaGrammar.hpp>
26 #include <xercesc/validators/schema/ComplexTypeInfo.hpp>
27 #include <xercesc/validators/schema/SchemaSymbols.hpp>
28 #include <xercesc/validators/schema/XercesGroupInfo.hpp>
29 #include <xercesc/validators/schema/XercesAttGroupInfo.hpp>
30 #include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp>
31 #include <xercesc/util/OutOfMemoryException.hpp>
32 #include <xercesc/framework/psvi/XSAnnotation.hpp>
33 
34 #include <xercesc/internal/XTemplateSerializer.hpp>
35 #include <xercesc/internal/ValidationContextImpl.hpp>
36 
37 XERCES_CPP_NAMESPACE_BEGIN
38 
39 typedef JanitorMemFunCall<SchemaGrammar>    CleanupType;
40 
41 // ---------------------------------------------------------------------------
42 //  SchemaGrammar: Constructors and Destructor
43 // ---------------------------------------------------------------------------
SchemaGrammar(MemoryManager * const manager)44 SchemaGrammar::SchemaGrammar(MemoryManager* const manager) :
45     fTargetNamespace(0)
46     , fElemDeclPool(0)
47     , fElemNonDeclPool(0)
48     , fGroupElemDeclPool(0)
49     , fNotationDeclPool(0)
50     , fAttributeDeclRegistry(0)
51     , fComplexTypeRegistry(0)
52     , fGroupInfoRegistry(0)
53     , fAttGroupInfoRegistry(0)
54     , fValidSubstitutionGroups(0)
55     , fValidationContext(0)
56     , fMemoryManager(manager)
57     , fGramDesc(0)
58     , fAnnotations(0)
59     , fValidated(false)
60     , fDatatypeRegistry(manager)
61     , fScopeCount (0)
62     , fAnonTypeCount (0)
63 {
64     CleanupType cleanup(this, &SchemaGrammar::cleanUp);
65 
66     //
67     //  Init all the pool members.
68     //
69     //  <TBD> Investigate what the optimum values would be for the various
70     //  pools.
71     //
72     fElemDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(109, true, 128, fMemoryManager);
73 
74     try {
75         // should not be necessary now that grammars, once built,
76         // are read-only
77         // fElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
78         fGroupElemDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(109, false, 128, fMemoryManager);
79         fNotationDeclPool = new (fMemoryManager) NameIdPool<XMLNotationDecl>(109, 128, fMemoryManager);
80         fValidationContext = new (fMemoryManager) ValidationContextImpl(fMemoryManager);
81 
82         //REVISIT: use grammarPool to create
83         fGramDesc = new (fMemoryManager) XMLSchemaDescriptionImpl(XMLUni::fgXMLNSURIName, fMemoryManager);
84 
85         // Create annotation table
86         fAnnotations = new (fMemoryManager) RefHashTableOf<XSAnnotation, PtrHasher>
87         (
88             29, true, fMemoryManager
89         );
90 
91         //
92         //  Call our own reset method. This lets us have the pool setup stuff
93         //  done in just one place (because this stame setup stuff has to be
94         //  done every time we are reset.)
95         //
96         reset();
97     }
98     catch(const OutOfMemoryException&)
99     {
100         cleanup.release();
101 
102         throw;
103     }
104 
105     cleanup.release();
106 }
107 
~SchemaGrammar()108 SchemaGrammar::~SchemaGrammar()
109 {
110     cleanUp();
111 }
112 
113 
114 // -----------------------------------------------------------------------
115 //  Virtual methods
116 // -----------------------------------------------------------------------
findOrAddElemDecl(const unsigned int uriId,const XMLCh * const baseName,const XMLCh * const prefixName,const XMLCh * const qName,unsigned int scope,bool & wasAdded)117 XMLElementDecl* SchemaGrammar::findOrAddElemDecl (const   unsigned int    uriId
118         , const XMLCh* const    baseName
119         , const XMLCh* const    prefixName
120         , const XMLCh* const    qName
121         , unsigned int          scope
122         ,       bool&           wasAdded )
123 {
124     // See it it exists
125     SchemaElementDecl* retVal = (SchemaElementDecl*) getElemDecl(uriId, baseName, qName, scope);
126 
127     // if not, then add this in
128     if (!retVal)
129     {
130         retVal = new (fMemoryManager) SchemaElementDecl
131         (
132             prefixName
133             , baseName
134             , uriId
135             , SchemaElementDecl::Any
136             , Grammar::TOP_LEVEL_SCOPE
137             , fMemoryManager
138         );
139         if(!fElemNonDeclPool)
140             fElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
141         const XMLSize_t elemId = fElemNonDeclPool->put((void*)retVal->getBaseName(), uriId, scope, retVal);
142         retVal->setId(elemId);
143         wasAdded = true;
144     }
145      else
146     {
147         wasAdded = false;
148     }
149     return retVal;
150 }
151 
putElemDecl(const unsigned int uriId,const XMLCh * const baseName,const XMLCh * const prefixName,const XMLCh * const,unsigned int scope,const bool notDeclared)152 XMLElementDecl* SchemaGrammar::putElemDecl (const   unsigned int    uriId
153         , const XMLCh* const    baseName
154         , const XMLCh* const    prefixName
155         , const XMLCh* const
156         , unsigned int          scope
157         , const bool            notDeclared)
158 {
159     SchemaElementDecl* retVal = new (fMemoryManager) SchemaElementDecl
160     (
161         prefixName
162         , baseName
163         , uriId
164         , SchemaElementDecl::Any
165         , Grammar::TOP_LEVEL_SCOPE
166         , fMemoryManager
167     );
168     if(notDeclared)
169     {
170         if(!fElemNonDeclPool)
171             fElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
172         retVal->setId(fElemNonDeclPool->put((void*)retVal->getBaseName(), uriId, scope, retVal));
173     } else
174     {
175         retVal->setId(fElemDeclPool->put((void*)retVal->getBaseName(), uriId, scope, retVal));
176     }
177     return retVal;
178 }
179 
reset()180 void SchemaGrammar::reset()
181 {
182     //
183     //  We need to reset all of the pools.
184     //
185     fElemDeclPool->removeAll();
186     if(fElemNonDeclPool)
187         fElemNonDeclPool->removeAll();
188     fGroupElemDeclPool->removeAll();
189     fNotationDeclPool->removeAll();
190     fAnnotations->removeAll();
191     fValidated = false;
192 }
193 
194 
cleanUp()195 void SchemaGrammar::cleanUp()
196 {
197     delete fElemDeclPool;
198     if(fElemNonDeclPool)
199         delete fElemNonDeclPool;
200     delete fGroupElemDeclPool;
201     delete fNotationDeclPool;
202     fMemoryManager->deallocate(fTargetNamespace);//delete [] fTargetNamespace;
203     delete fAttributeDeclRegistry;
204     delete fComplexTypeRegistry;
205     delete fGroupInfoRegistry;
206     delete fAttGroupInfoRegistry;
207     delete fValidSubstitutionGroups;
208     delete fValidationContext;
209     delete fGramDesc;
210     delete fAnnotations;
211 }
212 
setGrammarDescription(XMLGrammarDescription * gramDesc)213 void SchemaGrammar::setGrammarDescription(XMLGrammarDescription* gramDesc)
214 {
215     if ((!gramDesc) ||
216         (gramDesc->getGrammarType() != Grammar::SchemaGrammarType))
217         return;
218 
219     if (fGramDesc)
220         delete fGramDesc;
221 
222     //adopt the grammar Description
223     fGramDesc = (XMLSchemaDescription*) gramDesc;
224 }
225 
226 // ---------------------------------------------------------------------------
227 //  SchemaGrammar: Helper methods
228 // ---------------------------------------------------------------------------
putAnnotation(void * key,XSAnnotation * const annotation)229 void SchemaGrammar::putAnnotation(void* key, XSAnnotation* const annotation)
230 {
231     fAnnotations->put(key, annotation);
232 }
233 
addAnnotation(XSAnnotation * const annotation)234 void SchemaGrammar::addAnnotation(XSAnnotation* const annotation)
235 {
236     XSAnnotation* lAnnot = fAnnotations->get(this);
237 
238     if (lAnnot)
239         lAnnot->setNext(annotation);
240     else
241         fAnnotations->put(this, annotation);
242 }
243 
244 /***
245  * Support for Serialization/De-serialization
246  ***/
247 
IMPL_XSERIALIZABLE_TOCREATE(SchemaGrammar)248 IMPL_XSERIALIZABLE_TOCREATE(SchemaGrammar)
249 
250 void SchemaGrammar::serialize(XSerializeEngine& serEng)
251 {
252 
253     /***
254      * don't serialize ValidationContext* fValidationContext;
255      *                                    fElemNonDeclPool
256      ***/
257 
258     Grammar::serialize(serEng);
259 
260     if (serEng.isStoring())
261     {
262         //serialize DatatypeValidatorFactory first
263         fDatatypeRegistry.serialize(serEng);
264 
265         /***
266          *
267          * Serialize RefHash3KeysIdPool<SchemaElementDecl>* fElemDeclPool;
268          * Serialize RefHash3KeysIdPool<SchemaElementDecl>* fGroupElemDeclPool;
269          *
270         ***/
271         XTemplateSerializer::storeObject(fElemDeclPool, serEng);
272         XTemplateSerializer::storeObject(fGroupElemDeclPool, serEng);
273 
274         /***
275          * Serialize NameIdPool<XMLNotationDecl>*           fNotationDeclPool;
276          ***/
277         XTemplateSerializer::storeObject(fNotationDeclPool, serEng);
278 
279         /***
280          *
281          * Serialize RefHashTableOf<XMLAttDef>*             fAttributeDeclRegistry;
282          * Serialize RefHashTableOf<ComplexTypeInfo>*       fComplexTypeRegistry;
283          * Serialize RefHashTableOf<XercesGroupInfo>*       fGroupInfoRegistry;
284          * Serialize RefHashTableOf<XercesAttGroupInfo>*    fAttGroupInfoRegistry;
285          * Serialize RefHashTableOf<XMLRefInfo>*            fIDRefList;
286          *
287          ***/
288 
289         XTemplateSerializer::storeObject(fAttributeDeclRegistry, serEng);
290         XTemplateSerializer::storeObject(fComplexTypeRegistry, serEng);
291         XTemplateSerializer::storeObject(fGroupInfoRegistry, serEng);
292         XTemplateSerializer::storeObject(fAttGroupInfoRegistry, serEng);
293 
294         /***
295          * Serialize RefHash2KeysTableOf<ElemVector>*       fValidSubstitutionGroups;
296          ***/
297         XTemplateSerializer::storeObject(fValidSubstitutionGroups, serEng);
298 
299         /***
300          * Serialize RefHashTableOf<XSAnnotation>*       fAnnotations;
301          ***/
302         XTemplateSerializer::storeObject(fAnnotations, serEng);
303 
304         serEng.writeString(fTargetNamespace);
305         serEng<<fValidated;
306 
307         /***
308          * serialize() method shall be used to store object
309          * which has been created in ctor
310          ***/
311         fGramDesc->serialize(serEng);
312 
313     }
314     else
315     {
316         fDatatypeRegistry.serialize(serEng);
317 
318         /***
319          *
320          * Deserialize RefHash3KeysIdPool<SchemaElementDecl>* fElemDeclPool;
321          * Deserialize RefHash3KeysIdPool<SchemaElementDecl>* fGroupElemDeclPool;
322          *
323         ***/
324         XTemplateSerializer::loadObject(&fElemDeclPool, 109, true, 128, serEng);
325         XTemplateSerializer::loadObject(&fGroupElemDeclPool, 109, true, 128, serEng);
326 
327         /***
328          * Deserialize NameIdPool<XMLNotationDecl>*           fNotationDeclPool;
329          ***/
330         XTemplateSerializer::loadObject(&fNotationDeclPool, 109, 128, serEng);
331 
332         /***
333          *
334          * Deserialize RefHashTableOf<XMLAttDef>*             fAttributeDeclRegistry;
335          * Deserialize RefHashTableOf<ComplexTypeInfo>*       fComplexTypeRegistry;
336          * Deserialize RefHashTableOf<XercesGroupInfo>*       fGroupInfoRegistry;
337          * Deserialize RefHashTableOf<XercesAttGroupInfo>*    fAttGroupInfoRegistry;
338          * Deserialize RefHashTableOf<XMLRefInfo>*            fIDRefList;
339          *
340          ***/
341 
342         XTemplateSerializer::loadObject(&fAttributeDeclRegistry, 29, true, serEng);
343         XTemplateSerializer::loadObject(&fComplexTypeRegistry, 29, true, serEng);
344         XTemplateSerializer::loadObject(&fGroupInfoRegistry, 13, true, serEng);
345         XTemplateSerializer::loadObject(&fAttGroupInfoRegistry, 13, true, serEng);
346 
347         /***
348          * Deserialize RefHash2KeysTableOf<ElemVector>*       fValidSubstitutionGroups;
349          ***/
350         XTemplateSerializer::loadObject(&fValidSubstitutionGroups, 29, true, serEng);
351 
352         /***
353          * Deserialize RefHashTableOf<XSAnnotation>*       fAnnotations;
354          ***/
355         XTemplateSerializer::loadObject(&fAnnotations, 29, true, serEng);
356 
357         serEng.readString(fTargetNamespace);
358         serEng>>fValidated;
359 
360         /***
361          * serialize() method shall be used to load object
362          * which has been created in ctor
363          ***/
364         fGramDesc->serialize(serEng);
365 
366     }
367 }
368 
369 XERCES_CPP_NAMESPACE_END
370