GME
13
|
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