diff options
author | Frank Schönheit <fs@openoffice.org> | 2001-11-07 13:28:21 +0000 |
---|---|---|
committer | Frank Schönheit <fs@openoffice.org> | 2001-11-07 13:28:21 +0000 |
commit | 923c89d40b568872e9449a84baf7d3d10fd7274a (patch) | |
tree | 65ddfc7d6f64aa36555950e257e5bf4f76c765a2 /svtools | |
parent | 8d296bc0bd9c7b5f999a37472a94e16de6098d54 (diff) |
initial checkin - helper class for caching the state of OOo's template folders
Diffstat (limited to 'svtools')
-rw-r--r-- | svtools/source/misc/templatefoldercache.cxx | 885 |
1 files changed, 885 insertions, 0 deletions
diff --git a/svtools/source/misc/templatefoldercache.cxx b/svtools/source/misc/templatefoldercache.cxx new file mode 100644 index 000000000000..d3eb3e240dd2 --- /dev/null +++ b/svtools/source/misc/templatefoldercache.cxx @@ -0,0 +1,885 @@ +/************************************************************************* + * + * $RCSfile: templatefoldercache.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: fs $ $Date: 2001-11-07 14:28:21 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef SFX2_TEMPLATEFOLDERCACHE_HXX +#include "templatefoldercache.hxx" +#endif +#ifndef _UNTOOLS_UCBSTREAMHELPER_HXX +#include <unotools/ucbstreamhelper.hxx> +#endif +#ifndef _UNOTOOLS_LOCALFILEHELPER_HXX +#include <unotools/localfilehelper.hxx> +#endif +#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_ +#include <com/sun/star/sdbc/XResultSet.hpp> +#endif +#ifndef _COM_SUN_STAR_UCB_XDYNAMICRESULTSET_HPP_ +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#endif +#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ +#include <com/sun/star/sdbc/XRow.hpp> +#endif +#ifndef _UCBHELPER_CONTENT_HXX +#include <ucbhelper/content.hxx> +#endif +#ifndef _VOS_REF_HXX_ +#include <vos/ref.hxx> +#endif +#ifndef _VOS_REFERNCE_HXX_ +#include <vos/refernce.hxx> +#endif +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX +#include <svtools/pathoptions.hxx> +#endif + +#include <vector> +#include <list> +#include <functional> +#include <algorithm> + +//......................................................................... +namespace sfx2 +{ +//......................................................................... + + using namespace ::utl; + using namespace ::com::sun::star; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::ucb; + using namespace ::com::sun::star::uno; + + //===================================================================== + //= helpers + //===================================================================== + //--------------------------------------------------------------------- + SvStream& operator << ( SvStream& _rStorage, const util::DateTime& _rDate ) + { + _rStorage << _rDate.HundredthSeconds; + _rStorage << _rDate.Seconds; + _rStorage << _rDate.Minutes; + _rStorage << _rDate.Hours; + _rStorage << _rDate.Day; + _rStorage << _rDate.Month; + _rStorage << _rDate.Year; + + return _rStorage; + } + + //--------------------------------------------------------------------- + SvStream& operator >> ( SvStream& _rStorage, util::DateTime& _rDate ) + { + _rStorage >> _rDate.HundredthSeconds; + _rStorage >> _rDate.Seconds; + _rStorage >> _rDate.Minutes; + _rStorage >> _rDate.Hours; + _rStorage >> _rDate.Day; + _rStorage >> _rDate.Month; + _rStorage >> _rDate.Year; + + return _rStorage; + } + + //--------------------------------------------------------------------- + sal_Bool operator == ( const util::DateTime& _rLHS, const util::DateTime& _rRHS ) + { + return _rLHS.HundredthSeconds == _rRHS.HundredthSeconds + && _rLHS.Seconds == _rRHS.Seconds + && _rLHS.Minutes == _rRHS.Minutes + && _rLHS.Hours == _rRHS.Hours + && _rLHS.Day == _rRHS.Day + && _rLHS.Month == _rRHS.Month + && _rLHS.Year == _rRHS.Year; + } + + //--------------------------------------------------------------------- + sal_Bool operator != ( const util::DateTime& _rLHS, const util::DateTime& _rRHS ) + { + return !( _rLHS == _rRHS ); + } + + //===================================================================== + //= TemplateContent + //===================================================================== + struct TemplateContent; + typedef ::std::vector< ::vos::ORef< TemplateContent > > TemplateFolderContent; + typedef TemplateFolderContent::const_iterator FolderIterator; + + /** a struct describing one content in one of the template dirs (or at least it's relevant aspects) + */ + struct TemplateContent : public ::vos::OReference + { + public: + + private: + INetURLObject m_aURL; + String m_sLocalName; // redundant - last segment of m_aURL + util::DateTime m_aLastModified; // date of last modification as reported by UCP + TemplateFolderContent m_aSubContents; // sorted (by name) list of the children + + private: + inline void implResetDate( ) + { + m_aLastModified.HundredthSeconds = m_aLastModified.Seconds = m_aLastModified.Minutes = m_aLastModified.Hours = 0; + m_aLastModified.Day = m_aLastModified.Month = m_aLastModified.Year = 0; + } + + private: + ~TemplateContent(); + + public: + TemplateContent(); + TemplateContent( const INetURLObject& _rURL ); + TemplateContent( const INetURLObject& _rURL, const util::DateTime& _rLastModified ); + + // attribute access + inline String getName( ) const { return m_sLocalName; } + inline String getURL( ) const { return m_aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ); } + inline void setModDate( const util::DateTime& _rDate ) { m_aLastModified = _rDate; } + inline const util::DateTime& getModDate( ) const { return m_aLastModified; } + + inline TemplateFolderContent& getSubContents() { return m_aSubContents; } + inline const TemplateFolderContent& getSubContents() const { return m_aSubContents; } + + inline FolderIterator begin() const { return m_aSubContents.begin(); } + inline FolderIterator end() const { return m_aSubContents.end(); } + inline TemplateFolderContent::size_type + size() const { return m_aSubContents.size(); } + + inline void push_back( const ::vos::ORef< TemplateContent >& _rxNewElement ) + { m_aSubContents.push_back( _rxNewElement ); } + }; + + //--------------------------------------------------------------------- + DBG_NAME( TemplateContent ) + + //--------------------------------------------------------------------- + TemplateContent::TemplateContent() + { + DBG_CTOR( TemplateContent, NULL ); + implResetDate(); + } + + //--------------------------------------------------------------------- + TemplateContent::TemplateContent( const INetURLObject& _rURL ) + :m_aURL( _rURL ) + { + DBG_CTOR( TemplateContent, NULL ); + DBG_ASSERT( INET_PROT_NOT_VALID != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" ); + m_sLocalName = m_aURL.getName(); + implResetDate(); + } + + //--------------------------------------------------------------------- + TemplateContent::TemplateContent( const INetURLObject& _rURL, const util::DateTime& _rLastModified ) + :m_aURL( _rURL ) + ,m_aLastModified( _rLastModified ) + { + DBG_CTOR( TemplateContent, NULL ); + DBG_ASSERT( INET_PROT_NOT_VALID != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" ); + m_sLocalName = m_aURL.getName(); + } + + //--------------------------------------------------------------------- + TemplateContent::~TemplateContent() + { + DBG_DTOR( TemplateContent, NULL ); + } + + //===================================================================== + //= stl helpers + //===================================================================== + //--------------------------------------------------------------------- + /// compares two TemplateContent by URL + struct TemplateContentURLLess + :public ::std::binary_function < ::vos::ORef< TemplateContent > + , ::vos::ORef< TemplateContent > + , bool + > + { + bool operator() ( const ::vos::ORef< TemplateContent >& _rxLHS, const ::vos::ORef< TemplateContent >& _rxRHS ) const + { + return _rxLHS->getURL() < _rxRHS->getURL() + ? true + : false; + } + }; + + //--------------------------------------------------------------------- + /// sorts the sib contents of a TemplateFolderContent + struct SubContentSort : public ::std::unary_function< ::vos::ORef< TemplateContent >, void > + { + void operator() ( TemplateFolderContent& _rFolder ) const + { + // sort the directory by name + ::std::sort( + _rFolder.begin(), + _rFolder.end(), + TemplateContentURLLess() + ); + + // sort the sub directories by name + ::std::for_each( + _rFolder.begin(), + _rFolder.end(), + *this + ); + } + + void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const + { + if ( _rxContent.isValid() && _rxContent->size() ) + { + operator()( _rxContent->getSubContents() ); + } + } + }; + //--------------------------------------------------------------------- + /** does a deep compare of two template contents + */ + struct TemplateContentEqual + :public ::std::binary_function < ::vos::ORef< TemplateContent > + , ::vos::ORef< TemplateContent > + , bool + > + { + //................................................................. + bool operator() ( const ::vos::ORef< TemplateContent >& _rLHS, const ::vos::ORef< TemplateContent >& _rRHS ) + { + if ( !_rLHS.isValid() || !_rRHS.isValid() ) + { + DBG_ERROR( "TemplateContentEqual::operator(): invalid contents!" ); + return true; + // this is not strictly true, in case only one is invalid - but this is a heavy error anyway + } + + if ( _rLHS->getURL() != _rRHS->getURL() ) + return false; + + if ( _rLHS->getModDate() != _rRHS->getModDate() ) + return false; + + if ( _rLHS->getSubContents().size() != _rRHS->getSubContents().size() ) + return false; + + if ( _rLHS->getSubContents().size() ) + { // there are children + // -> compare them + std::pair< FolderIterator, FolderIterator > aFirstDifferent = ::std::mismatch( + _rLHS->getSubContents().begin(), + _rLHS->getSubContents().end(), + _rRHS->getSubContents().begin(), + *this + ); + if ( aFirstDifferent.first != _rLHS->getSubContents().end() ) + return false;// the sub contents differ + } + + return true; + } + }; + + //--------------------------------------------------------------------- + /// base class for functors which act an an SvStream + struct StorageHelper + { + protected: + SvStream& m_rStorage; + StorageHelper( SvStream& _rStorage ) : m_rStorage( _rStorage ) { } + }; + + //--------------------------------------------------------------------- + /// functor which allows storing a string + struct StoreString + :public ::std::unary_function< String, void > + ,public StorageHelper + { + StoreString( SvStream& _rStorage ) : StorageHelper( _rStorage ) { } + + void operator() ( const String& _rString ) const + { + m_rStorage.WriteByteString( _rString ); + } + }; + + //--------------------------------------------------------------------- + /// functor which stores the local name of a TemplateContent + struct StoreLocalContentName + :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > + ,public StoreString + { + StoreLocalContentName( SvStream& _rStorage ) : StoreString( _rStorage ) { } + + void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const + { + // use the base class operator with the local name of the content + StoreString::operator() ( _rxContent->getName() ); + } + }; + + //--------------------------------------------------------------------- + struct StoreContentURL + :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > + ,public StoreString + { + StoreContentURL( SvStream& _rStorage ) : StoreString( _rStorage ) { } + + void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const + { + // use the base class operator with the local name of the content + StoreString::operator() ( _rxContent->getURL() ); + } + }; + + //--------------------------------------------------------------------- + /// functor which stores the complete content of a TemplateContent + struct StoreFolderContent + :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > + ,public StorageHelper + { + public: + StoreFolderContent( SvStream& _rStorage ) : StorageHelper( _rStorage ) { } + + //................................................................. + void operator() ( const TemplateContent& _rContent ) const + { + // store the info about this content + m_rStorage << _rContent.getModDate(); + + // store the info about the children + // the number + m_rStorage << (sal_Int32)_rContent.size(); + // their (local!) names + ::std::for_each( + _rContent.getSubContents().begin(), + _rContent.getSubContents().end(), + StoreLocalContentName( m_rStorage ) + ); + // their content + ::std::for_each( + _rContent.getSubContents().begin(), + _rContent.getSubContents().end(), + *this + ); + } + + //................................................................. + void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const + { + if ( _rxContent.isValid() ) + { + operator()( *_rxContent ); + } + } + }; + + //--------------------------------------------------------------------- + /// functor which reads a complete TemplateContent instance + struct ReadFolderContent + :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > + ,public StorageHelper + { + ReadFolderContent( SvStream& _rStorage ) : StorageHelper( _rStorage ) { } + + //................................................................. + void operator() ( TemplateContent& _rContent ) const + { + // store the info about this content + util::DateTime aModDate; + m_rStorage >> aModDate; + _rContent.setModDate( aModDate ); + + // store the info about the children + // the number + sal_Int32 nChildren = 0; + m_rStorage >> nChildren; + TemplateFolderContent& rChildren = _rContent.getSubContents(); + rChildren.resize( 0 ); + rChildren.reserve( nChildren ); + // initialize them with their (local) names + while ( nChildren-- ) + { + String sLocalName; + m_rStorage.ReadByteString( sLocalName ); + INetURLObject aChildURL( _rContent.getURL() ); + aChildURL.Append( sLocalName ); + rChildren.push_back( new TemplateContent( aChildURL ) ); + } + + // their content + ::std::for_each( + _rContent.getSubContents().begin(), + _rContent.getSubContents().end(), + *this + ); + } + + //................................................................. + void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const + { + if ( _rxContent.isValid() ) + { + operator()( *_rxContent ); + } + } + }; + + //===================================================================== + //= TemplateFolderCacheImpl + //===================================================================== + class TemplateFolderCacheImpl + { + private: + TemplateFolderContent m_aPreviousState; // the current state of the template dirs (as found on the HD) + TemplateFolderContent m_aCurrentState; // the previous state of the template dirs (as found in the cache file) + + SvStream* m_pCacheStream; + sal_Bool m_bNeedsUpdate : 1; + sal_Bool m_bKnowState : 1; + sal_Bool m_bValidCurrentState : 1; + + public: + TemplateFolderCacheImpl( ); + ~TemplateFolderCacheImpl( ); + + sal_Bool needsUpdate(); + void storeState(); + + private: + void initTemplDirs( ::std::vector< String >& _rRootDirs ); + sal_Bool openCacheStream( sal_Bool _bForRead ); + void closeCacheStream( ); + + /// read the state of the dirs from the cache file + sal_Bool readPreviousState(); + /// read the current state of the dirs + sal_Bool readCurrentState(); + + String implParseSmart( const String& _rPath ); + + sal_Bool implReadFolder( const ::vos::ORef< TemplateContent >& _rxRoot ); + + static String getCacheFileName(); + static sal_Int32 getMagicNumber(); + static void normalize( TemplateFolderContent& _rState ); + + // @return <TRUE/> if the states equal + static sal_Bool equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS ); + }; + + //--------------------------------------------------------------------- + TemplateFolderCacheImpl::TemplateFolderCacheImpl( ) + :m_pCacheStream ( NULL ) + ,m_bNeedsUpdate ( sal_True ) + ,m_bKnowState ( sal_False ) + ,m_bValidCurrentState ( sal_False ) + { + } + + //--------------------------------------------------------------------- + TemplateFolderCacheImpl::~TemplateFolderCacheImpl( ) + { + closeCacheStream( ); + } + + //--------------------------------------------------------------------- + sal_Int32 TemplateFolderCacheImpl::getMagicNumber() + { + sal_Int32 nMagic = 0; + ( nMagic += (sal_Int8)'T' ) <<= 4; + ( nMagic += (sal_Int8)'D' ) <<= 4; + ( nMagic += (sal_Int8)'S' ) <<= 4; + ( nMagic += (sal_Int8)'C' ) <<= 0; + return nMagic; + } + + //--------------------------------------------------------------------- + String TemplateFolderCacheImpl::getCacheFileName() + { + return String::CreateFromAscii( ".templdir.cache" ); + } + + + //--------------------------------------------------------------------- + void TemplateFolderCacheImpl::normalize( TemplateFolderContent& _rState ) + { + SubContentSort()( _rState ); + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCacheImpl::equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS ) + { + if ( _rLHS.size() != _rRHS.size() ) + return sal_False; + + // as both arrays are sorted (by definition - this is a precondition of this method) + // we can simply go from the front to the back and compare the single elements + + std::pair< FolderIterator, FolderIterator > aFirstDifferent = ::std::mismatch( + _rLHS.begin(), + _rLHS.end(), + _rRHS.begin(), + TemplateContentEqual() + ); + + return aFirstDifferent.first == _rLHS.end(); + } + + //--------------------------------------------------------------------- + void TemplateFolderCacheImpl::storeState() + { + DBG_ASSERT( m_bValidCurrentState, "TemplateFolderCacheImpl::storeState: no valid current state!" ); + if ( m_bValidCurrentState && openCacheStream( sal_False ) ) + { + *m_pCacheStream << getMagicNumber(); + + // store the template root folders + // the size + *m_pCacheStream << (sal_Int32)m_aCurrentState.size(); + // the complete URLs + ::std::for_each( + m_aCurrentState.begin(), + m_aCurrentState.end(), + StoreContentURL( *m_pCacheStream ) + ); + + // the contents + ::std::for_each( + m_aCurrentState.begin(), + m_aCurrentState.end(), + StoreFolderContent( *m_pCacheStream ) + ); + } + } + + //--------------------------------------------------------------------- + String TemplateFolderCacheImpl::implParseSmart( const String& _rPath ) + { + INetURLObject aParser; + aParser.SetSmartProtocol( INET_PROT_FILE ); + aParser.SetURL( _rPath, INetURLObject::WAS_ENCODED ); + if ( INET_PROT_NOT_VALID == aParser.GetProtocol() ) + { + String sURL; + LocalFileHelper::ConvertPhysicalNameToURL( _rPath, sURL ); + aParser.SetURL( sURL, INetURLObject::WAS_ENCODED ); + } + return aParser.GetMainURL( INetURLObject::DECODE_TO_IURI ); + } + + //--------------------------------------------------------------------- + void TemplateFolderCacheImpl::closeCacheStream( ) + { + DELETEZ( m_pCacheStream ); + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCacheImpl::implReadFolder( const ::vos::ORef< TemplateContent >& _rxRoot ) + { + try + { + // create a content for the current folder root + Reference< XResultSet > xResultSet; + Sequence< ::rtl::OUString > aContentProperties( 4); + aContentProperties[0] = ::rtl::OUString::createFromAscii( "Title" ); + aContentProperties[1] = ::rtl::OUString::createFromAscii( "DateModified" ); + aContentProperties[2] = ::rtl::OUString::createFromAscii( "DateCreated" ); + aContentProperties[3] = ::rtl::OUString::createFromAscii( "IsFolder" ); + + // get the set of sub contents in the folder + try + { + Reference< XDynamicResultSet > xDynResultSet; + + ::ucb::Content aTemplateRoot( _rxRoot->getURL(), Reference< XCommandEnvironment >() ); + xDynResultSet = aTemplateRoot.createDynamicCursor( aContentProperties, ::ucb::INCLUDE_FOLDERS_AND_DOCUMENTS ); + if ( xDynResultSet.is() ) + xResultSet = xDynResultSet->getStaticResultSet(); + } + catch( CommandAbortedException& ) + { + DBG_ERRORFILE( "TemplateFolderCacheImpl::implReadFolder: caught a CommandAbortedException!" ); + return sal_False; + } + catch( ::com::sun::star::uno::Exception& e ) + { + e; // make compiler happy + } + + // collect the infos about the sub contents + if ( xResultSet.is() ) + { + Reference< XRow > xRow( xResultSet, UNO_QUERY ); + while ( xResultSet->next() ) + { + INetURLObject aSubContentURL( _rxRoot->getURL() ); + aSubContentURL.Append( xRow->getString( 1 ) ); + // a new content instance + ::vos::ORef< TemplateContent > xChild = new TemplateContent( aSubContentURL ); + + // the modified date + xChild->setModDate( xRow->getTimestamp( 2 ) ); // date modified + if ( xRow->wasNull() ) + xChild->setModDate( xRow->getTimestamp( 3 ) ); // fallback: date created + + // push back this content + _rxRoot->push_back( xChild ); + + // is it a folder? + if ( xRow->getBoolean( 4 ) && !xRow->wasNull() ) + { // yes -> step down + FolderIterator aNextLevelRoot = _rxRoot->end(); + --aNextLevelRoot; + implReadFolder( *aNextLevelRoot ); + } + } + } + } + catch( const Exception& ) + { + DBG_ERROR( "TemplateFolderCacheImpl::implReadFolder: caught an exception!" ); + return sal_False; + } + return sal_True; + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCacheImpl::readCurrentState() + { + // reset + m_bValidCurrentState = sal_False; + m_aCurrentState.swap( TemplateFolderContent() ); + + // the template directories from the config + String aDirs = SvtPathOptions().GetTemplatePath(); + sal_uInt16 nDirs = aDirs.GetTokenCount( ';' ); + + m_aCurrentState.reserve( nDirs ); + // loop through all the root-level template folders + for ( sal_uInt16 i=0; i<nDirs; ++i) + { + // create a new entry + m_aCurrentState.push_back( new TemplateContent( INetURLObject( aDirs.GetToken( i, ';' ) ) ) ); + TemplateFolderContent::iterator aCurrentRoot = m_aCurrentState.end(); + --aCurrentRoot; + + if ( !implReadFolder( *aCurrentRoot ) ) + return sal_False; + } + + // normalize the array (which basically means "sort it") + normalize( m_aCurrentState ); + + m_bValidCurrentState = sal_True; + return m_bValidCurrentState; + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCacheImpl::readPreviousState() + { + DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::readPreviousState: not to be called without stream!" ); + + // reset + m_aPreviousState.swap( TemplateFolderContent() ); + + // check the magic number + sal_Int32 nMagic = 0; + *m_pCacheStream >> nMagic; + DBG_ASSERT( getMagicNumber() == nMagic, "TemplateFolderCacheImpl::readPreviousState: invalid cache file!" ); + if ( getMagicNumber() != nMagic ) + return sal_False; + + // the root directories + // their number + sal_Int32 nRootDirectories = 0; + *m_pCacheStream >> nRootDirectories; + // init empty TemplateContens with the URLs + m_aPreviousState.reserve( nRootDirectories ); + while ( nRootDirectories-- ) + { + String sURL; + m_pCacheStream->ReadByteString( sURL ); + m_aPreviousState.push_back( new TemplateContent( sURL ) ); + } + + // read the contents of the root folders + ::std::for_each( + m_aPreviousState.begin(), + m_aPreviousState.end(), + ReadFolderContent( *m_pCacheStream ) + ); + + DBG_ASSERT( !m_pCacheStream->GetErrorCode(), "TemplateFolderCacheImpl::readPreviousState: unknown error during reading the state cache!" ); + + // normalize the array (which basically means "sort it") + normalize( m_aPreviousState ); + + return sal_True; + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCacheImpl::openCacheStream( sal_Bool _bForRead ) + { + // close any old stream instance + closeCacheStream( ); + + // get the storage directory + String sStorageURL = implParseSmart( SvtPathOptions().GetStoragePath() ); + INetURLObject aStorageURL( sStorageURL ); + if ( INET_PROT_NOT_VALID == aStorageURL.GetProtocol() ) + { + DBG_ERROR( "TemplateFolderCacheImpl::openCacheStream: invalid storage path!" ); + return sal_False; + } + + // append our name + aStorageURL.Append( getCacheFileName() ); + + // open the stream + m_pCacheStream = UcbStreamHelper::CreateStream( aStorageURL.GetMainURL( INetURLObject::DECODE_TO_IURI ), + _bForRead ? STREAM_READ | STREAM_NOCREATE : STREAM_WRITE | STREAM_TRUNC ); + DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::openCacheStream: could not open/create the cache stream!" ); + if ( m_pCacheStream && m_pCacheStream->GetErrorCode() ) + { + DELETEZ( m_pCacheStream ); + } + + if ( m_pCacheStream ) + m_pCacheStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); + + return NULL != m_pCacheStream; + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCacheImpl::needsUpdate() + { + if ( m_bKnowState ) + return m_bNeedsUpdate; + + m_bNeedsUpdate = sal_True; + m_bKnowState = sal_True; + + if ( readCurrentState() ) + { + // open the stream which contains the cached state of the directories + if ( openCacheStream( sal_True ) ) + { // opening the stream succeeded + if ( readPreviousState() ) + { + m_bNeedsUpdate = !equalStates( m_aPreviousState, m_aCurrentState ); + } + else + { + closeCacheStream(); + } + } + } + return m_bNeedsUpdate; + } + + //--------------------------------------------------------------------- + void TemplateFolderCacheImpl::initTemplDirs( ::std::vector< String >& _rRootDirs ) + { + } + + //===================================================================== + //= TemplateFolderCache + //===================================================================== + //--------------------------------------------------------------------- + TemplateFolderCache::TemplateFolderCache( ) + :m_pImpl( new TemplateFolderCacheImpl ) + { + } + + //--------------------------------------------------------------------- + TemplateFolderCache::~TemplateFolderCache( ) + { + DELETEZ( m_pImpl ); + } + + //--------------------------------------------------------------------- + sal_Bool TemplateFolderCache::needsUpdate() + { + return m_pImpl->needsUpdate(); + } + + //--------------------------------------------------------------------- + void TemplateFolderCache::storeState() + { + m_pImpl->storeState(); + } + +//......................................................................... +} // namespace sfx2 +//......................................................................... + +/************************************************************************* + * history: + * $Log: not supported by cvs2svn $ + * + * Revision 1.0 07.11.01 12:40:25 fs + ************************************************************************/ + |