| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_framework.hxx" |
| |
| /*TODO |
| - change "singleton" behaviour by using new helper ::comhelper::SingletonRef |
| - rename method exist() to existHandlerForURL() or similar one |
| - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?! |
| */ |
| |
| //_________________________________________________________________________________________________________________ |
| // my own includes |
| //_________________________________________________________________________________________________________________ |
| |
| #include <classes/protocolhandlercache.hxx> |
| #include <classes/converter.hxx> |
| #include <threadhelp/readguard.hxx> |
| #include <threadhelp/writeguard.hxx> |
| #include <threadhelp/lockhelper.hxx> |
| |
| //_________________________________________________________________________________________________________________ |
| // interface includes |
| //_________________________________________________________________________________________________________________ |
| |
| //_________________________________________________________________________________________________________________ |
| // other includes |
| //_________________________________________________________________________________________________________________ |
| #include <tools/wldcrd.hxx> |
| #include <unotools/configpathes.hxx> |
| #include <rtl/ustrbuf.hxx> |
| |
| //_________________________________________________________________________________________________________________ |
| // namespace |
| //_________________________________________________________________________________________________________________ |
| |
| namespace framework{ |
| |
| //_________________________________________________________________________________________________________________ |
| // non exported const |
| //_________________________________________________________________________________________________________________ |
| |
| //_________________________________________________________________________________________________________________ |
| // non exported definitions |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short overloaded index operator of hash map to support pattern key search |
| @descr All keys inside this hash map are URL pattern which points to an uno |
| implementation name of a protocol handler service which is registered |
| for this pattern. This operator makes it easy to find such registered |
| handler by using a full qualified URL and compare it with all pattern |
| keys. |
| |
| @param sURL |
| the full qualified URL which should match to a registered pattern |
| |
| @return An iterator which points to the found item inside the hash or PatternHash::end() |
| if no pattern match this given <var>sURL</var>. |
| |
| @modified 30.04.2002 09:52, as96863 |
| */ |
| PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL ) |
| { |
| PatternHash::iterator pItem = this->begin(); |
| while( pItem!=this->end() ) |
| { |
| WildCard aPattern(pItem->first); |
| if (aPattern.Matches(sURL)) |
| break; |
| ++pItem; |
| } |
| return pItem; |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short initialize static member of class HandlerCache |
| @descr We use a singleton pattern to implement this handler cache. |
| That means it use two static member list to hold all necessary informations |
| and a ref count mechanism to create/destroy it on demand. |
| |
| @modified 30.04.2002 11:13, as96863 |
| */ |
| HandlerHash* HandlerCache::m_pHandler = NULL; |
| PatternHash* HandlerCache::m_pPattern = NULL; |
| sal_Int32 HandlerCache::m_nRefCount = 0 ; |
| HandlerCFGAccess* HandlerCache::m_pConfig = NULL; |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short ctor of the cache of all registered protoco handler |
| @descr It tries to open the right configuration package automatically |
| and fill the internal structures. After that the cache can be |
| used for read access on this data and perform some search |
| operations on it. |
| |
| @modified 30.04.2002 10:02, as96863 |
| */ |
| HandlerCache::HandlerCache() |
| { |
| /* SAFE */{ |
| WriteGuard aGlobalLock( LockHelper::getGlobalLock() ); |
| |
| if (m_nRefCount==0) |
| { |
| m_pHandler = new HandlerHash(); |
| m_pPattern = new PatternHash(); |
| m_pConfig = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER); |
| m_pConfig->read(&m_pHandler,&m_pPattern); |
| m_pConfig->setCache(this); |
| } |
| |
| ++m_nRefCount; |
| /* SAFE */} |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short dtor of the cache |
| @descr It frees all used memory. In further implementations (may if we support write access too) |
| it's a good place to flush changes back to the configuration - but not needed yet. |
| |
| @modified 30.04.2002 09:54, as96863 |
| */ |
| HandlerCache::~HandlerCache() |
| { |
| /* SAFE */{ |
| WriteGuard aGlobalLock( LockHelper::getGlobalLock() ); |
| |
| if( m_nRefCount==1) |
| { |
| m_pConfig->setCache(NULL); |
| m_pHandler->free(); |
| m_pPattern->free(); |
| |
| delete m_pConfig; |
| delete m_pHandler; |
| delete m_pPattern; |
| m_pConfig = NULL; |
| m_pHandler= NULL; |
| m_pPattern= NULL; |
| } |
| |
| --m_nRefCount; |
| /* SAFE */} |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short dtor of the cache |
| @descr It frees all used memory. In further implementations (may if we support write access too) |
| it's a good place to flush changes back to the configuration - but not needed yet. |
| |
| @modified 30.04.2002 09:54, as96863 |
| */ |
| sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const |
| { |
| sal_Bool bFound = sal_False; |
| /* SAFE */{ |
| ReadGuard aReadLock( LockHelper::getGlobalLock() ); |
| PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL); |
| if (pItem!=m_pPattern->end()) |
| { |
| *pReturn = (*m_pHandler)[pItem->second]; |
| bFound = sal_True; |
| } |
| /* SAFE */} |
| return bFound; |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short search for a registered handler by using an URL struct |
| @descr We combine necessary parts of this struct to a valid URL string |
| and call our other search method ... |
| It's a helper for outside code. |
| |
| @modified 30.04.2002 09:54, as96863 |
| */ |
| sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const |
| { |
| return search( aURL.Complete, pReturn ); |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| sal_Bool HandlerCache::exists( const ::rtl::OUString& sURL ) const |
| { |
| sal_Bool bFound = sal_False; |
| /* SAFE */{ |
| ReadGuard aReadLock( LockHelper::getGlobalLock() ); |
| PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL); |
| bFound = pItem!=m_pPattern->end(); |
| /* SAFE */} |
| return bFound; |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern) |
| { |
| // SAFE -> |
| WriteGuard aWriteLock( LockHelper::getGlobalLock() ); |
| |
| HandlerHash* pOldHandler = m_pHandler; |
| PatternHash* pOldPattern = m_pPattern; |
| |
| m_pHandler = pHandler; |
| m_pPattern = pPattern; |
| |
| pOldHandler->free(); |
| pOldPattern->free(); |
| delete pOldHandler; |
| delete pOldPattern; |
| |
| aWriteLock.unlock(); |
| // <- SAFE |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short dtor of the config access class |
| @descr It opens the configuration package automatically by using base class mechanism. |
| After that "read()" method of this class should be called to use it. |
| |
| @param sPackage |
| specifies the package name of the configuration data which should be used |
| |
| @modified 30.04.2002 10:06, as96863 |
| */ |
| HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage ) |
| : ConfigItem( sPackage ) |
| { |
| css::uno::Sequence< ::rtl::OUString > lListenPathes(1); |
| lListenPathes[0] = SETNAME_HANDLER; |
| EnableNotification(lListenPathes); |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| |
| /** |
| @short use base class mechanism to fill given structures |
| @descr User use us as a wrapper between configuration api and his internal structures. |
| He give us some pointer to his member and we fill it. |
| |
| @param pHandler |
| pointer to a list of protocol handler infos |
| |
| @param pPattern |
| reverse map of handler pattern to her uno names |
| |
| @modified 30.04.2002 09:54, as96863 |
| */ |
| void HandlerCFGAccess::read( HandlerHash** ppHandler , |
| PatternHash** ppPattern ) |
| { |
| // list of all uno implementation names without encoding |
| css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH ); |
| sal_Int32 nSourceCount = lNames.getLength(); |
| sal_Int32 nTargetCount = nSourceCount; |
| // list of all full qualified path names of configuration entries |
| css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount ); |
| |
| // expand names to full path names |
| sal_Int32 nSource=0; |
| sal_Int32 nTarget=0; |
| for( nSource=0; nSource<nSourceCount; ++nSource ) |
| { |
| ::rtl::OUStringBuffer sPath( SETNAME_HANDLER ); |
| sPath.append(CFG_PATH_SEPERATOR); |
| sPath.append(lNames[nSource]); |
| sPath.append(CFG_PATH_SEPERATOR); |
| sPath.append(PROPERTY_PROTOCOLS); |
| |
| lFullNames[nTarget] = sPath.makeStringAndClear(); |
| ++nTarget; |
| } |
| |
| // get values at all |
| css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames ); |
| LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" ) |
| |
| // fill structures |
| nSource = 0; |
| for( nTarget=0; nTarget<nTargetCount; ++nTarget ) |
| { |
| // create it new for every loop to guarantee a real empty object! |
| ProtocolHandler aHandler; |
| aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]); |
| |
| // unpack all values of this handler |
| css::uno::Sequence< ::rtl::OUString > lTemp; |
| lValues[nTarget] >>= lTemp; |
| aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp); |
| |
| // register his pattern into the performance search hash |
| for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin(); |
| pItem!=aHandler.m_lProtocols.end() ; |
| ++pItem ) |
| { |
| (**ppPattern)[*pItem] = lNames[nSource]; |
| } |
| |
| // ï¿œnsert the handler info into the normal handler cache |
| (**ppHandler)[lNames[nSource]] = aHandler; |
| ++nSource; |
| } |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/) |
| { |
| HandlerHash* pHandler = new HandlerHash; |
| PatternHash* pPattern = new PatternHash; |
| |
| read(&pHandler, &pPattern); |
| if (m_pCache) |
| m_pCache->takeOver(pHandler, pPattern); |
| else |
| { |
| delete pHandler; |
| delete pPattern; |
| } |
| } |
| |
| void HandlerCFGAccess::Commit() |
| { |
| } |
| |
| } // namespace framework |