GME  13
RangeTokenMap.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: RangeTokenMap.cpp 678879 2008-07-22 20:05:05Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/util/regx/RangeTokenMap.hpp>
00026 #include <xercesc/util/regx/RangeToken.hpp>
00027 #include <xercesc/util/regx/RegxDefs.hpp>
00028 #include <xercesc/util/regx/TokenFactory.hpp>
00029 #include <xercesc/util/regx/XMLRangeFactory.hpp>
00030 #include <xercesc/util/regx/ASCIIRangeFactory.hpp>
00031 #include <xercesc/util/regx/UnicodeRangeFactory.hpp>
00032 #include <xercesc/util/regx/BlockRangeFactory.hpp>
00033 #include <xercesc/util/PlatformUtils.hpp>
00034 #include <xercesc/util/XMLExceptMsgs.hpp>
00035 #include <xercesc/util/StringPool.hpp>
00036 #include <xercesc/util/XMLInitializer.hpp>
00037 #include <xercesc/util/OutOfMemoryException.hpp>
00038 
00039 XERCES_CPP_NAMESPACE_BEGIN
00040 
00041 RangeTokenMap* RangeTokenMap::fInstance = 0;
00042 
00043 void XMLInitializer::initializeRangeTokenMap()
00044 {
00045     RangeTokenMap::fInstance = new RangeTokenMap(
00046       XMLPlatformUtils::fgMemoryManager);
00047 
00048     if (RangeTokenMap::fInstance)
00049       RangeTokenMap::fInstance->buildTokenRanges();
00050 }
00051 
00052 void XMLInitializer::terminateRangeTokenMap()
00053 {
00054     delete RangeTokenMap::fInstance;
00055     RangeTokenMap::fInstance = 0;
00056 }
00057 
00058 
00059 // ---------------------------------------------------------------------------
00060 //  RangeTokenElemMap: Constructors and Destructor
00061 // ---------------------------------------------------------------------------
00062 RangeTokenElemMap::RangeTokenElemMap(unsigned int categoryId) :
00063     fCategoryId(categoryId)
00064     , fRange(0)
00065     , fNRange(0)
00066 {
00067 
00068 }
00069 
00070 RangeTokenElemMap::~RangeTokenElemMap()
00071 {
00072 
00073 }
00074 
00075 // ---------------------------------------------------------------------------
00076 //  RangeTokenMap: Constructors and Destructor
00077 // ---------------------------------------------------------------------------
00078 
00079 typedef JanitorMemFunCall<RangeTokenMap>    CleanupType;
00080 
00081 RangeTokenMap::RangeTokenMap(MemoryManager* manager) :
00082     fTokenRegistry(0)
00083     , fRangeMap(0)
00084     , fCategories(0)
00085     , fTokenFactory(0)
00086     , fMutex(manager)
00087 {
00088     CleanupType cleanup(this, &RangeTokenMap::cleanUp);
00089 
00090     try {
00091         fTokenRegistry = new (manager) RefHashTableOf<RangeTokenElemMap>(109, manager);
00092         fRangeMap = new (manager) RefHashTableOf<RangeFactory>(29, manager);
00093         fCategories = new (manager) XMLStringPool(109, manager);
00094         fTokenFactory = new (manager) TokenFactory(manager);
00095         initializeRegistry();
00096     }
00097     catch(const OutOfMemoryException&)
00098     {
00099         cleanup.release();
00100 
00101         throw;
00102     }
00103 
00104     cleanup.release();
00105 }
00106 
00107 RangeTokenMap::~RangeTokenMap() {
00108 
00109     cleanUp();
00110 }
00111 
00112 // ---------------------------------------------------------------------------
00113 //  RangeTokenMap: Getter methods
00114 // ---------------------------------------------------------------------------
00115 RangeToken* RangeTokenMap::getRange(const XMLCh* const keyword,
00116                                     const bool complement) {
00117 
00118     if (!fTokenRegistry->containsKey(keyword))
00119         return 0;
00120 
00121     RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword);
00122     RangeToken* rangeTok = elemMap->getRangeToken(complement);
00123 
00124     if (!rangeTok)
00125     {
00126         XMLMutexLock lockInit(&fMutex);
00127 
00128         // make sure that it was not created while we were locked
00129         rangeTok = elemMap->getRangeToken(complement);
00130 
00131         if (!rangeTok)
00132         {
00133             unsigned int categId = elemMap->getCategoryId();
00134             const XMLCh* categName = fCategories->getValueForId(categId);
00135             RangeFactory* rangeFactory = fRangeMap->get(categName);
00136 
00137             if (rangeFactory)
00138             {
00139                 rangeFactory->buildRanges(this);
00140                 rangeTok = elemMap->getRangeToken(complement);
00141 
00142                 // see if we are complementing an existing range
00143                 if (!rangeTok && complement)
00144                 {
00145                     rangeTok = elemMap->getRangeToken();
00146                     if (rangeTok)
00147                     {
00148                         rangeTok = RangeToken::complementRanges(rangeTok, fTokenFactory, fTokenRegistry->getMemoryManager());
00149                         elemMap->setRangeToken(rangeTok , complement);
00150                     }
00151                 }
00152             }
00153         }
00154     }
00155 
00156     return rangeTok;
00157 }
00158 
00159 
00160 // ---------------------------------------------------------------------------
00161 //  RangeTokenMap: Putter methods
00162 // ---------------------------------------------------------------------------
00163 void RangeTokenMap::addCategory(const XMLCh* const categoryName) {
00164 
00165     fCategories->addOrFind(categoryName);
00166 }
00167 
00168 void RangeTokenMap::addRangeMap(const XMLCh* const categoryName,
00169                                 RangeFactory* const rangeFactory) {
00170 
00171     fRangeMap->put((void*)categoryName, rangeFactory);
00172 }
00173 
00174 void RangeTokenMap::addKeywordMap(const XMLCh* const keyword,
00175                                  const XMLCh* const categoryName) {
00176 
00177     unsigned int categId = fCategories->getId(categoryName);
00178 
00179     if (categId == 0) {
00180         ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Regex_InvalidCategoryName, categoryName, fTokenRegistry->getMemoryManager());
00181     }
00182 
00183     if (fTokenRegistry->containsKey(keyword)) {
00184 
00185         RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword);
00186 
00187         if (elemMap->getCategoryId() != categId)
00188             elemMap->setCategoryId(categId);
00189 
00190         return;
00191     }
00192 
00193     fTokenRegistry->put((void*) keyword, new RangeTokenElemMap(categId));
00194 }
00195 
00196 // ---------------------------------------------------------------------------
00197 //  RangeTokenMap: Setter methods
00198 // ---------------------------------------------------------------------------
00199 void RangeTokenMap::setRangeToken(const XMLCh* const keyword,
00200                                   RangeToken* const tok,const bool complement) {
00201 
00202     if (fTokenRegistry->containsKey(keyword)) {
00203         fTokenRegistry->get(keyword)->setRangeToken(tok, complement);
00204     }
00205     else {
00206         ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Regex_KeywordNotFound, keyword, fTokenRegistry->getMemoryManager());
00207     }
00208 }
00209 
00210 
00211 // ---------------------------------------------------------------------------
00212 //  RangeTokenMap: Initialization methods
00213 // ---------------------------------------------------------------------------
00214 void RangeTokenMap::initializeRegistry() {
00215 
00216     // Add categories
00217     fCategories->addOrFind(fgXMLCategory);
00218     fCategories->addOrFind(fgASCIICategory);
00219     fCategories->addOrFind(fgUnicodeCategory);
00220     fCategories->addOrFind(fgBlockCategory);
00221 
00222     // Add xml range factory
00223     RangeFactory* rangeFact = new XMLRangeFactory();
00224     fRangeMap->put((void*)fgXMLCategory, rangeFact);
00225     rangeFact->initializeKeywordMap(this);
00226 
00227     // Add ascii range factory
00228     rangeFact = new ASCIIRangeFactory();
00229     fRangeMap->put((void*)fgASCIICategory, rangeFact);
00230     rangeFact->initializeKeywordMap(this);
00231 
00232     // Add unicode range factory
00233     rangeFact = new UnicodeRangeFactory();
00234     fRangeMap->put((void*)fgUnicodeCategory, rangeFact);
00235     rangeFact->initializeKeywordMap(this);
00236 
00237     // Add block range factory
00238     rangeFact = new BlockRangeFactory();
00239     fRangeMap->put((void*)fgBlockCategory, rangeFact);
00240     rangeFact->initializeKeywordMap(this);
00241 }
00242 
00243 void RangeTokenMap::buildTokenRanges()
00244 {
00245     // Build ranges */
00246     RangeFactory* rangeFactory = fRangeMap->get(fgXMLCategory);
00247     rangeFactory->buildRanges(this);
00248 
00249     rangeFactory = fRangeMap->get(fgASCIICategory);
00250     rangeFactory->buildRanges(this);
00251 
00252     rangeFactory = fRangeMap->get(fgUnicodeCategory);
00253     rangeFactory->buildRanges(this);
00254 
00255     rangeFactory = fRangeMap->get(fgBlockCategory);
00256     rangeFactory->buildRanges(this);
00257 }
00258 
00259 // ---------------------------------------------------------------------------
00260 //  RangeTokenMap: Instance methods
00261 // ---------------------------------------------------------------------------
00262 RangeTokenMap* RangeTokenMap::instance()
00263 {
00264     return fInstance;
00265 }
00266 
00267 // ---------------------------------------------------------------------------
00268 //  RangeTokenMap: helper methods
00269 // ---------------------------------------------------------------------------
00270 void RangeTokenMap::cleanUp()
00271 {
00272     delete fTokenRegistry;
00273     fTokenRegistry = 0;
00274 
00275     delete fRangeMap;
00276     fRangeMap = 0;
00277 
00278     delete fCategories;
00279     fCategories = 0;
00280 
00281     delete fTokenFactory;
00282     fTokenFactory = 0;
00283 }
00284 
00285 XERCES_CPP_NAMESPACE_END
00286