1*6d739b60SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*6d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*6d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*6d739b60SAndrew Rist * distributed with this work for additional information 6*6d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*6d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*6d739b60SAndrew Rist * "License"); you may not use this file except in compliance 9*6d739b60SAndrew Rist * with the License. You may obtain a copy of the License at 10*6d739b60SAndrew Rist * 11*6d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*6d739b60SAndrew Rist * 13*6d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*6d739b60SAndrew Rist * software distributed under the License is distributed on an 15*6d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*6d739b60SAndrew Rist * KIND, either express or implied. See the License for the 17*6d739b60SAndrew Rist * specific language governing permissions and limitations 18*6d739b60SAndrew Rist * under the License. 19*6d739b60SAndrew Rist * 20*6d739b60SAndrew Rist *************************************************************/ 21*6d739b60SAndrew Rist 22*6d739b60SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_framework.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir /*TODO 28cdf0e10cSrcweir - change "singleton" behaviour by using new helper ::comhelper::SingletonRef 29cdf0e10cSrcweir - rename method exist() to existHandlerForURL() or similar one 30cdf0e10cSrcweir - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?! 31cdf0e10cSrcweir */ 32cdf0e10cSrcweir 33cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 34cdf0e10cSrcweir // my own includes 35cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 36cdf0e10cSrcweir 37cdf0e10cSrcweir #include <classes/protocolhandlercache.hxx> 38cdf0e10cSrcweir #include <classes/converter.hxx> 39cdf0e10cSrcweir #include <threadhelp/readguard.hxx> 40cdf0e10cSrcweir #include <threadhelp/writeguard.hxx> 41cdf0e10cSrcweir #include <threadhelp/lockhelper.hxx> 42cdf0e10cSrcweir 43cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 44cdf0e10cSrcweir // interface includes 45cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 46cdf0e10cSrcweir 47cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 48cdf0e10cSrcweir // other includes 49cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 50cdf0e10cSrcweir #include <tools/wldcrd.hxx> 51cdf0e10cSrcweir #include <unotools/configpathes.hxx> 52cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 53cdf0e10cSrcweir 54cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 55cdf0e10cSrcweir // namespace 56cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 57cdf0e10cSrcweir 58cdf0e10cSrcweir namespace framework{ 59cdf0e10cSrcweir 60cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 61cdf0e10cSrcweir // non exported const 62cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 63cdf0e10cSrcweir 64cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 65cdf0e10cSrcweir // non exported definitions 66cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 67cdf0e10cSrcweir 68cdf0e10cSrcweir /** 69cdf0e10cSrcweir @short overloaded index operator of hash map to support pattern key search 70cdf0e10cSrcweir @descr All keys inside this hash map are URL pattern which points to an uno 71cdf0e10cSrcweir implementation name of a protocol handler service which is registered 72cdf0e10cSrcweir for this pattern. This operator makes it easy to find such registered 73cdf0e10cSrcweir handler by using a full qualified URL and compare it with all pattern 74cdf0e10cSrcweir keys. 75cdf0e10cSrcweir 76cdf0e10cSrcweir @param sURL 77cdf0e10cSrcweir the full qualified URL which should match to a registered pattern 78cdf0e10cSrcweir 79cdf0e10cSrcweir @return An iterator which points to the found item inside the hash or PatternHash::end() 80cdf0e10cSrcweir if no pattern match this given <var>sURL</var>. 81cdf0e10cSrcweir 82cdf0e10cSrcweir @modified 30.04.2002 09:52, as96863 83cdf0e10cSrcweir */ 84cdf0e10cSrcweir PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir PatternHash::iterator pItem = this->begin(); 87cdf0e10cSrcweir while( pItem!=this->end() ) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir WildCard aPattern(pItem->first); 90cdf0e10cSrcweir if (aPattern.Matches(sURL)) 91cdf0e10cSrcweir break; 92cdf0e10cSrcweir ++pItem; 93cdf0e10cSrcweir } 94cdf0e10cSrcweir return pItem; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 98cdf0e10cSrcweir 99cdf0e10cSrcweir /** 100cdf0e10cSrcweir @short initialize static member of class HandlerCache 101cdf0e10cSrcweir @descr We use a singleton pattern to implement this handler cache. 102cdf0e10cSrcweir That means it use two static member list to hold all neccessary informations 103cdf0e10cSrcweir and a ref count mechanism to create/destroy it on demand. 104cdf0e10cSrcweir 105cdf0e10cSrcweir @modified 30.04.2002 11:13, as96863 106cdf0e10cSrcweir */ 107cdf0e10cSrcweir HandlerHash* HandlerCache::m_pHandler = NULL; 108cdf0e10cSrcweir PatternHash* HandlerCache::m_pPattern = NULL; 109cdf0e10cSrcweir sal_Int32 HandlerCache::m_nRefCount = 0 ; 110cdf0e10cSrcweir HandlerCFGAccess* HandlerCache::m_pConfig = NULL; 111cdf0e10cSrcweir 112cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 113cdf0e10cSrcweir 114cdf0e10cSrcweir /** 115cdf0e10cSrcweir @short ctor of the cache of all registered protoco handler 116cdf0e10cSrcweir @descr It tries to open the right configuration package automaticly 117cdf0e10cSrcweir and fill the internal structures. After that the cache can be 118cdf0e10cSrcweir used for read access on this data and perform some search 119cdf0e10cSrcweir operations on it. 120cdf0e10cSrcweir 121cdf0e10cSrcweir @modified 30.04.2002 10:02, as96863 122cdf0e10cSrcweir */ 123cdf0e10cSrcweir HandlerCache::HandlerCache() 124cdf0e10cSrcweir { 125cdf0e10cSrcweir /* SAFE */{ 126cdf0e10cSrcweir WriteGuard aGlobalLock( LockHelper::getGlobalLock() ); 127cdf0e10cSrcweir 128cdf0e10cSrcweir if (m_nRefCount==0) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir m_pHandler = new HandlerHash(); 131cdf0e10cSrcweir m_pPattern = new PatternHash(); 132cdf0e10cSrcweir m_pConfig = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER); 133cdf0e10cSrcweir m_pConfig->read(&m_pHandler,&m_pPattern); 134cdf0e10cSrcweir m_pConfig->setCache(this); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir ++m_nRefCount; 138cdf0e10cSrcweir /* SAFE */} 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 142cdf0e10cSrcweir 143cdf0e10cSrcweir /** 144cdf0e10cSrcweir @short dtor of the cache 145cdf0e10cSrcweir @descr It frees all used memory. In further implementations (may if we support write access too) 146cdf0e10cSrcweir it's a good place to flush changes back to the configuration - but not needed yet. 147cdf0e10cSrcweir 148cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863 149cdf0e10cSrcweir */ 150cdf0e10cSrcweir HandlerCache::~HandlerCache() 151cdf0e10cSrcweir { 152cdf0e10cSrcweir /* SAFE */{ 153cdf0e10cSrcweir WriteGuard aGlobalLock( LockHelper::getGlobalLock() ); 154cdf0e10cSrcweir 155cdf0e10cSrcweir if( m_nRefCount==1) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir m_pConfig->setCache(NULL); 158cdf0e10cSrcweir m_pHandler->free(); 159cdf0e10cSrcweir m_pPattern->free(); 160cdf0e10cSrcweir 161cdf0e10cSrcweir delete m_pConfig; 162cdf0e10cSrcweir delete m_pHandler; 163cdf0e10cSrcweir delete m_pPattern; 164cdf0e10cSrcweir m_pConfig = NULL; 165cdf0e10cSrcweir m_pHandler= NULL; 166cdf0e10cSrcweir m_pPattern= NULL; 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir --m_nRefCount; 170cdf0e10cSrcweir /* SAFE */} 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 174cdf0e10cSrcweir 175cdf0e10cSrcweir /** 176cdf0e10cSrcweir @short dtor of the cache 177cdf0e10cSrcweir @descr It frees all used memory. In further implementations (may if we support write access too) 178cdf0e10cSrcweir it's a good place to flush changes back to the configuration - but not needed yet. 179cdf0e10cSrcweir 180cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863 181cdf0e10cSrcweir */ 182cdf0e10cSrcweir sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const 183cdf0e10cSrcweir { 184cdf0e10cSrcweir sal_Bool bFound = sal_False; 185cdf0e10cSrcweir /* SAFE */{ 186cdf0e10cSrcweir ReadGuard aReadLock( LockHelper::getGlobalLock() ); 187cdf0e10cSrcweir PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL); 188cdf0e10cSrcweir if (pItem!=m_pPattern->end()) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir *pReturn = (*m_pHandler)[pItem->second]; 191cdf0e10cSrcweir bFound = sal_True; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir /* SAFE */} 194cdf0e10cSrcweir return bFound; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 198cdf0e10cSrcweir 199cdf0e10cSrcweir /** 200cdf0e10cSrcweir @short search for a registered handler by using an URL struct 201cdf0e10cSrcweir @descr We combine neccessary parts of this struct to a valid URL string 202cdf0e10cSrcweir and call our other search method ... 203cdf0e10cSrcweir It's a helper for outside code. 204cdf0e10cSrcweir 205cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863 206cdf0e10cSrcweir */ 207cdf0e10cSrcweir sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const 208cdf0e10cSrcweir { 209cdf0e10cSrcweir return search( aURL.Complete, pReturn ); 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 213cdf0e10cSrcweir 214cdf0e10cSrcweir sal_Bool HandlerCache::exists( const ::rtl::OUString& sURL ) const 215cdf0e10cSrcweir { 216cdf0e10cSrcweir sal_Bool bFound = sal_False; 217cdf0e10cSrcweir /* SAFE */{ 218cdf0e10cSrcweir ReadGuard aReadLock( LockHelper::getGlobalLock() ); 219cdf0e10cSrcweir PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL); 220cdf0e10cSrcweir bFound = pItem!=m_pPattern->end(); 221cdf0e10cSrcweir /* SAFE */} 222cdf0e10cSrcweir return bFound; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 226cdf0e10cSrcweir void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir // SAFE -> 229cdf0e10cSrcweir WriteGuard aWriteLock( LockHelper::getGlobalLock() ); 230cdf0e10cSrcweir 231cdf0e10cSrcweir HandlerHash* pOldHandler = m_pHandler; 232cdf0e10cSrcweir PatternHash* pOldPattern = m_pPattern; 233cdf0e10cSrcweir 234cdf0e10cSrcweir m_pHandler = pHandler; 235cdf0e10cSrcweir m_pPattern = pPattern; 236cdf0e10cSrcweir 237cdf0e10cSrcweir pOldHandler->free(); 238cdf0e10cSrcweir pOldPattern->free(); 239cdf0e10cSrcweir delete pOldHandler; 240cdf0e10cSrcweir delete pOldPattern; 241cdf0e10cSrcweir 242cdf0e10cSrcweir aWriteLock.unlock(); 243cdf0e10cSrcweir // <- SAFE 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 247cdf0e10cSrcweir 248cdf0e10cSrcweir /** 249cdf0e10cSrcweir @short dtor of the config access class 250cdf0e10cSrcweir @descr It opens the configuration package automaticly by using base class mechanism. 251cdf0e10cSrcweir After that "read()" method of this class should be called to use it. 252cdf0e10cSrcweir 253cdf0e10cSrcweir @param sPackage 254cdf0e10cSrcweir specifies the package name of the configuration data which should be used 255cdf0e10cSrcweir 256cdf0e10cSrcweir @modified 30.04.2002 10:06, as96863 257cdf0e10cSrcweir */ 258cdf0e10cSrcweir HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage ) 259cdf0e10cSrcweir : ConfigItem( sPackage ) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lListenPathes(1); 262cdf0e10cSrcweir lListenPathes[0] = SETNAME_HANDLER; 263cdf0e10cSrcweir EnableNotification(lListenPathes); 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 267cdf0e10cSrcweir 268cdf0e10cSrcweir /** 269cdf0e10cSrcweir @short use base class mechanism to fill given structures 270cdf0e10cSrcweir @descr User use us as a wrapper between configuration api and his internal structures. 271cdf0e10cSrcweir He give us some pointer to his member and we fill it. 272cdf0e10cSrcweir 273cdf0e10cSrcweir @param pHandler 274cdf0e10cSrcweir pointer to a list of protocol handler infos 275cdf0e10cSrcweir 276cdf0e10cSrcweir @param pPattern 277cdf0e10cSrcweir reverse map of handler pattern to her uno names 278cdf0e10cSrcweir 279cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863 280cdf0e10cSrcweir */ 281cdf0e10cSrcweir void HandlerCFGAccess::read( HandlerHash** ppHandler , 282cdf0e10cSrcweir PatternHash** ppPattern ) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir // list of all uno implementation names without encoding 285cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH ); 286cdf0e10cSrcweir sal_Int32 nSourceCount = lNames.getLength(); 287cdf0e10cSrcweir sal_Int32 nTargetCount = nSourceCount; 288cdf0e10cSrcweir // list of all full qualified path names of configuration entries 289cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount ); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // expand names to full path names 292cdf0e10cSrcweir sal_Int32 nSource=0; 293cdf0e10cSrcweir sal_Int32 nTarget=0; 294cdf0e10cSrcweir for( nSource=0; nSource<nSourceCount; ++nSource ) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir ::rtl::OUStringBuffer sPath( SETNAME_HANDLER ); 297cdf0e10cSrcweir sPath.append(CFG_PATH_SEPERATOR); 298cdf0e10cSrcweir sPath.append(lNames[nSource]); 299cdf0e10cSrcweir sPath.append(CFG_PATH_SEPERATOR); 300cdf0e10cSrcweir sPath.append(PROPERTY_PROTOCOLS); 301cdf0e10cSrcweir 302cdf0e10cSrcweir lFullNames[nTarget] = sPath.makeStringAndClear(); 303cdf0e10cSrcweir ++nTarget; 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir // get values at all 307cdf0e10cSrcweir css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames ); 308cdf0e10cSrcweir LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" ) 309cdf0e10cSrcweir 310cdf0e10cSrcweir // fill structures 311cdf0e10cSrcweir nSource = 0; 312cdf0e10cSrcweir for( nTarget=0; nTarget<nTargetCount; ++nTarget ) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir // create it new for every loop to guarantee a real empty object! 315cdf0e10cSrcweir ProtocolHandler aHandler; 316cdf0e10cSrcweir aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]); 317cdf0e10cSrcweir 318cdf0e10cSrcweir // unpack all values of this handler 319cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lTemp; 320cdf0e10cSrcweir lValues[nTarget] >>= lTemp; 321cdf0e10cSrcweir aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp); 322cdf0e10cSrcweir 323cdf0e10cSrcweir // register his pattern into the performance search hash 324cdf0e10cSrcweir for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin(); 325cdf0e10cSrcweir pItem!=aHandler.m_lProtocols.end() ; 326cdf0e10cSrcweir ++pItem ) 327cdf0e10cSrcweir { 328cdf0e10cSrcweir (**ppPattern)[*pItem] = lNames[nSource]; 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir // ï¿œnsert the handler info into the normal handler cache 332cdf0e10cSrcweir (**ppHandler)[lNames[nSource]] = aHandler; 333cdf0e10cSrcweir ++nSource; 334cdf0e10cSrcweir } 335cdf0e10cSrcweir } 336cdf0e10cSrcweir 337cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 338cdf0e10cSrcweir void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/) 339cdf0e10cSrcweir { 340cdf0e10cSrcweir HandlerHash* pHandler = new HandlerHash; 341cdf0e10cSrcweir PatternHash* pPattern = new PatternHash; 342cdf0e10cSrcweir 343cdf0e10cSrcweir read(&pHandler, &pPattern); 344cdf0e10cSrcweir if (m_pCache) 345cdf0e10cSrcweir m_pCache->takeOver(pHandler, pPattern); 346cdf0e10cSrcweir else 347cdf0e10cSrcweir { 348cdf0e10cSrcweir delete pHandler; 349cdf0e10cSrcweir delete pPattern; 350cdf0e10cSrcweir } 351cdf0e10cSrcweir } 352cdf0e10cSrcweir 353cdf0e10cSrcweir void HandlerCFGAccess::Commit() 354cdf0e10cSrcweir { 355cdf0e10cSrcweir } 356cdf0e10cSrcweir 357cdf0e10cSrcweir } // namespace framework 358