GME  13
IdentityConstraintHandler.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  * 
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  * 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: IdentityConstraintHandler.cpp 803869 2009-08-13 12:56:21Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include "IdentityConstraintHandler.hpp"
00026 
00027 #include <xercesc/validators/schema/SchemaElementDecl.hpp>
00028 
00029 #include <xercesc/validators/schema/identity/FieldActivator.hpp>
00030 #include <xercesc/validators/schema/identity/ValueStore.hpp>
00031 #include <xercesc/validators/schema/identity/IC_Selector.hpp>
00032 
00033 #include <xercesc/util/OutOfMemoryException.hpp>
00034 
00035 XERCES_CPP_NAMESPACE_BEGIN
00036 
00037 typedef JanitorMemFunCall<IdentityConstraintHandler>    CleanupType;
00038 
00039 // ---------------------------------------------------------------------------
00040 //  IdentityConstraintHandler: Constructors and Destructor
00041 // ---------------------------------------------------------------------------
00042 IdentityConstraintHandler::IdentityConstraintHandler(XMLScanner*    const scanner
00043                      , MemoryManager* const manager)
00044 : fScanner(scanner)
00045 , fMemoryManager(manager)
00046 , fMatcherStack(0)
00047 , fValueStoreCache(0)
00048 , fFieldActivator(0)
00049 {
00050     CleanupType cleanup(this, &IdentityConstraintHandler::cleanUp);
00051 
00052     try {
00053 
00054         fMatcherStack    = new (fMemoryManager) XPathMatcherStack(fMemoryManager);
00055         fValueStoreCache = new (fMemoryManager) ValueStoreCache(fMemoryManager);
00056         fFieldActivator  = new (fMemoryManager) FieldActivator(fValueStoreCache, fMatcherStack, fMemoryManager);
00057 
00058         fValueStoreCache->setScanner(scanner);
00059     }
00060     catch(const OutOfMemoryException&)
00061     {
00062         cleanup.release();
00063 
00064         throw;
00065     }
00066 
00067     cleanup.release();
00068 }
00069 
00070 IdentityConstraintHandler::~IdentityConstraintHandler()
00071 {
00072     cleanUp();
00073 }
00074 
00075 // ---------------------------------------------------------------------------
00076 //  IdentityConstraintHandler:  methods
00077 // ---------------------------------------------------------------------------
00078 void IdentityConstraintHandler::deactivateContext(      SchemaElementDecl* const elem
00079                                                 , const XMLCh*             const content
00080                                                 , ValidationContext*       validationContext /*=0*/
00081                                                 , DatatypeValidator*       actualValidator /*=0*/)
00082 {
00083 
00084     XMLSize_t oldCount = fMatcherStack->getMatcherCount();
00085 
00086     if (oldCount || elem->getIdentityConstraintCount()) 
00087     {
00088 
00089         for (XMLSize_t i = oldCount; i > 0; i--) 
00090         {
00091             XPathMatcher* matcher = fMatcherStack->getMatcherAt(i-1);
00092             matcher->endElement(*(elem), content, validationContext, actualValidator);
00093         }
00094 
00095         if (fMatcherStack->size() > 0) 
00096         {
00097             fMatcherStack->popContext();
00098         }
00099 
00100         // handle everything *but* keyref's.
00101         XMLSize_t newCount = fMatcherStack->getMatcherCount();
00102 
00103         for (XMLSize_t j = oldCount; j > newCount; j--) 
00104         {
00105             XPathMatcher* matcher = fMatcherStack->getMatcherAt(j-1);
00106             IdentityConstraint* ic = matcher->getIdentityConstraint();
00107 
00108             if (ic  && (ic->getType() != IdentityConstraint::ICType_KEYREF))
00109                 fValueStoreCache->transplant(ic, matcher->getInitialDepth());
00110         }
00111 
00112         // now handle keyref's...
00113         for (XMLSize_t k = oldCount; k > newCount; k--)
00114         {
00115             XPathMatcher* matcher = fMatcherStack->getMatcherAt(k-1);
00116             IdentityConstraint* ic = matcher->getIdentityConstraint();
00117 
00118             if (ic && (ic->getType() == IdentityConstraint::ICType_KEYREF)) 
00119             {
00120                 ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
00121 
00122                 if (values) { // nothing to do if nothing matched!
00123                     values->endDocumentFragment(fValueStoreCache);
00124                 }
00125             }
00126         }
00127 
00128         fValueStoreCache->endElement();
00129 
00130     }
00131 }
00132 
00133 void IdentityConstraintHandler::activateIdentityConstraint
00134                      (      
00135                              SchemaElementDecl* const     elem
00136                      ,       int                          elemDepth
00137                      , const unsigned int                 uriId
00138                      , const XMLCh*                 const elemPrefix
00139                      , const RefVectorOf<XMLAttr>&        attrList
00140                      , const XMLSize_t                    attrCount
00141                      , ValidationContext*                 validationContext /*=0*/)
00142 {
00143 
00144     XMLSize_t count = elem->getIdentityConstraintCount();
00145 
00146     if (count || fMatcherStack->getMatcherCount()) 
00147     {
00148 
00149         fValueStoreCache->startElement();
00150         fMatcherStack->pushContext();
00151         fValueStoreCache->initValueStoresFor( elem, elemDepth);
00152 
00153         for (XMLSize_t i = 0; i < count; i++) 
00154         {
00155             activateSelectorFor(elem->getIdentityConstraintAt(i), elemDepth);
00156         }
00157 
00158         // call all active identity constraints
00159         count = fMatcherStack->getMatcherCount();
00160 
00161         for (XMLSize_t j = 0; j < count; j++) 
00162         {
00163             XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
00164             matcher->startElement(*elem, uriId, elemPrefix, attrList, attrCount, validationContext);
00165         }
00166     }
00167 }
00168 
00169 void IdentityConstraintHandler::activateSelectorFor(      IdentityConstraint* const ic
00170                                    , const int                       initialDepth) 
00171 {
00172 
00173     IC_Selector* selector = ic->getSelector();
00174 
00175     if (!selector)
00176         return;
00177 
00178     XPathMatcher* matcher = selector->createMatcher(fFieldActivator, initialDepth, fMemoryManager);
00179 
00180     fMatcherStack->addMatcher(matcher);
00181     matcher->startDocumentFragment();
00182 }
00183 
00184 // ---------------------------------------------------------------------------
00185 //  IdentityConstraintHandler:  Getter methods
00186 // ---------------------------------------------------------------------------
00187 
00188 // ---------------------------------------------------------------------------
00189 //  IdentityConstraintHandler: cleanUp methods
00190 // ---------------------------------------------------------------------------
00191 void IdentityConstraintHandler::cleanUp() 
00192 {
00193     if (fMatcherStack)
00194         delete fMatcherStack;
00195 
00196     if (fValueStoreCache)
00197         delete fValueStoreCache;
00198 
00199     if (fFieldActivator)
00200         delete fFieldActivator;
00201 
00202 }
00203 
00204 void IdentityConstraintHandler::reset()
00205 {
00206     fValueStoreCache->startDocument();
00207     fMatcherStack->clear();
00208 }
00209 
00210 XERCES_CPP_NAMESPACE_END
00211