diff options
Diffstat (limited to 'framework/source/classes/protocolhandlercache.cxx')
-rw-r--r-- | framework/source/classes/protocolhandlercache.cxx | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/framework/source/classes/protocolhandlercache.cxx b/framework/source/classes/protocolhandlercache.cxx new file mode 100644 index 000000000000..266100ce4f43 --- /dev/null +++ b/framework/source/classes/protocolhandlercache.cxx @@ -0,0 +1,361 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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 neccessary 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 automaticly + 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 neccessary 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 automaticly 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 |