1*5900e8ecSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*5900e8ecSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*5900e8ecSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*5900e8ecSAndrew Rist * distributed with this work for additional information 6*5900e8ecSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*5900e8ecSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*5900e8ecSAndrew Rist * "License"); you may not use this file except in compliance 9*5900e8ecSAndrew Rist * with the License. You may obtain a copy of the License at 10*5900e8ecSAndrew Rist * 11*5900e8ecSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*5900e8ecSAndrew Rist * 13*5900e8ecSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*5900e8ecSAndrew Rist * software distributed under the License is distributed on an 15*5900e8ecSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*5900e8ecSAndrew Rist * KIND, either express or implied. See the License for the 17*5900e8ecSAndrew Rist * specific language governing permissions and limitations 18*5900e8ecSAndrew Rist * under the License. 19*5900e8ecSAndrew Rist * 20*5900e8ecSAndrew Rist *************************************************************/ 21*5900e8ecSAndrew Rist 22*5900e8ecSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svtools.hxx" 26cdf0e10cSrcweir #include <svtools/templatefoldercache.hxx> 27cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx> 28cdf0e10cSrcweir #include <unotools/localfilehelper.hxx> 29cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 30cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSet.hpp> 31cdf0e10cSrcweir #include <com/sun/star/ucb/XDynamicResultSet.hpp> 32cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp> 33cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp> 34cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp> 35cdf0e10cSrcweir #include <com/sun/star/util/XOfficeInstallationDirectories.hpp> 36cdf0e10cSrcweir #include <ucbhelper/content.hxx> 37cdf0e10cSrcweir #include <vos/ref.hxx> 38cdf0e10cSrcweir #include <vos/refernce.hxx> 39cdf0e10cSrcweir #include <tools/urlobj.hxx> 40cdf0e10cSrcweir #include <tools/debug.hxx> 41cdf0e10cSrcweir #include <unotools/pathoptions.hxx> 42cdf0e10cSrcweir 43cdf0e10cSrcweir #include "comphelper/processfactory.hxx" 44cdf0e10cSrcweir 45cdf0e10cSrcweir #include <vector> 46cdf0e10cSrcweir #include <list> 47cdf0e10cSrcweir #include <functional> 48cdf0e10cSrcweir #include <algorithm> 49cdf0e10cSrcweir 50cdf0e10cSrcweir //......................................................................... 51cdf0e10cSrcweir namespace svt 52cdf0e10cSrcweir { 53cdf0e10cSrcweir //......................................................................... 54cdf0e10cSrcweir 55cdf0e10cSrcweir using namespace ::utl; 56cdf0e10cSrcweir using namespace ::com::sun::star; 57cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 58cdf0e10cSrcweir using namespace ::com::sun::star::ucb; 59cdf0e10cSrcweir using namespace ::com::sun::star::uno; 60cdf0e10cSrcweir 61cdf0e10cSrcweir //===================================================================== 62cdf0e10cSrcweir //= helpers 63cdf0e10cSrcweir //===================================================================== 64cdf0e10cSrcweir //--------------------------------------------------------------------- operator <<(SvStream & _rStorage,const util::DateTime & _rDate)65cdf0e10cSrcweir SvStream& operator << ( SvStream& _rStorage, const util::DateTime& _rDate ) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir _rStorage << _rDate.HundredthSeconds; 68cdf0e10cSrcweir _rStorage << _rDate.Seconds; 69cdf0e10cSrcweir _rStorage << _rDate.Minutes; 70cdf0e10cSrcweir _rStorage << _rDate.Hours; 71cdf0e10cSrcweir _rStorage << _rDate.Day; 72cdf0e10cSrcweir _rStorage << _rDate.Month; 73cdf0e10cSrcweir _rStorage << _rDate.Year; 74cdf0e10cSrcweir 75cdf0e10cSrcweir return _rStorage; 76cdf0e10cSrcweir } 77cdf0e10cSrcweir 78cdf0e10cSrcweir //--------------------------------------------------------------------- operator >>(SvStream & _rStorage,util::DateTime & _rDate)79cdf0e10cSrcweir SvStream& operator >> ( SvStream& _rStorage, util::DateTime& _rDate ) 80cdf0e10cSrcweir { 81cdf0e10cSrcweir _rStorage >> _rDate.HundredthSeconds; 82cdf0e10cSrcweir _rStorage >> _rDate.Seconds; 83cdf0e10cSrcweir _rStorage >> _rDate.Minutes; 84cdf0e10cSrcweir _rStorage >> _rDate.Hours; 85cdf0e10cSrcweir _rStorage >> _rDate.Day; 86cdf0e10cSrcweir _rStorage >> _rDate.Month; 87cdf0e10cSrcweir _rStorage >> _rDate.Year; 88cdf0e10cSrcweir 89cdf0e10cSrcweir return _rStorage; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir //--------------------------------------------------------------------- operator ==(const util::DateTime & _rLHS,const util::DateTime & _rRHS)93cdf0e10cSrcweir sal_Bool operator == ( const util::DateTime& _rLHS, const util::DateTime& _rRHS ) 94cdf0e10cSrcweir { 95cdf0e10cSrcweir return _rLHS.HundredthSeconds == _rRHS.HundredthSeconds 96cdf0e10cSrcweir && _rLHS.Seconds == _rRHS.Seconds 97cdf0e10cSrcweir && _rLHS.Minutes == _rRHS.Minutes 98cdf0e10cSrcweir && _rLHS.Hours == _rRHS.Hours 99cdf0e10cSrcweir && _rLHS.Day == _rRHS.Day 100cdf0e10cSrcweir && _rLHS.Month == _rRHS.Month 101cdf0e10cSrcweir && _rLHS.Year == _rRHS.Year; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir //--------------------------------------------------------------------- operator !=(const util::DateTime & _rLHS,const util::DateTime & _rRHS)105cdf0e10cSrcweir sal_Bool operator != ( const util::DateTime& _rLHS, const util::DateTime& _rRHS ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return !( _rLHS == _rRHS ); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir //===================================================================== 111cdf0e10cSrcweir //= TemplateContent 112cdf0e10cSrcweir //===================================================================== 113cdf0e10cSrcweir struct TemplateContent; 114cdf0e10cSrcweir typedef ::std::vector< ::vos::ORef< TemplateContent > > TemplateFolderContent; 115cdf0e10cSrcweir typedef TemplateFolderContent::const_iterator ConstFolderIterator; 116cdf0e10cSrcweir typedef TemplateFolderContent::iterator FolderIterator; 117cdf0e10cSrcweir 118cdf0e10cSrcweir /** a struct describing one content in one of the template dirs (or at least it's relevant aspects) 119cdf0e10cSrcweir */ 120cdf0e10cSrcweir struct TemplateContent : public ::vos::OReference 121cdf0e10cSrcweir { 122cdf0e10cSrcweir public: 123cdf0e10cSrcweir 124cdf0e10cSrcweir private: 125cdf0e10cSrcweir INetURLObject m_aURL; 126cdf0e10cSrcweir String m_sLocalName; // redundant - last segment of m_aURL 127cdf0e10cSrcweir util::DateTime m_aLastModified; // date of last modification as reported by UCP 128cdf0e10cSrcweir TemplateFolderContent m_aSubContents; // sorted (by name) list of the children 129cdf0e10cSrcweir 130cdf0e10cSrcweir private: implResetDatesvt::TemplateContent131cdf0e10cSrcweir inline void implResetDate( ) 132cdf0e10cSrcweir { 133cdf0e10cSrcweir m_aLastModified.HundredthSeconds = m_aLastModified.Seconds = m_aLastModified.Minutes = m_aLastModified.Hours = 0; 134cdf0e10cSrcweir m_aLastModified.Day = m_aLastModified.Month = m_aLastModified.Year = 0; 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir private: 138cdf0e10cSrcweir ~TemplateContent(); 139cdf0e10cSrcweir 140cdf0e10cSrcweir public: 141cdf0e10cSrcweir TemplateContent(); 142cdf0e10cSrcweir TemplateContent( const INetURLObject& _rURL ); 143cdf0e10cSrcweir TemplateContent( const INetURLObject& _rURL, const util::DateTime& _rLastModified ); 144cdf0e10cSrcweir 145cdf0e10cSrcweir // attribute access getNamesvt::TemplateContent146cdf0e10cSrcweir inline String getName( ) const { return m_sLocalName; } getURLsvt::TemplateContent147cdf0e10cSrcweir inline String getURL( ) const { return m_aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ); } setModDatesvt::TemplateContent148cdf0e10cSrcweir inline void setModDate( const util::DateTime& _rDate ) { m_aLastModified = _rDate; } getModDatesvt::TemplateContent149cdf0e10cSrcweir inline const util::DateTime& getModDate( ) const { return m_aLastModified; } 150cdf0e10cSrcweir getSubContentssvt::TemplateContent151cdf0e10cSrcweir inline TemplateFolderContent& getSubContents() { return m_aSubContents; } getSubContentssvt::TemplateContent152cdf0e10cSrcweir inline const TemplateFolderContent& getSubContents() const { return m_aSubContents; } 153cdf0e10cSrcweir beginsvt::TemplateContent154cdf0e10cSrcweir inline ConstFolderIterator begin() const { return m_aSubContents.begin(); } endsvt::TemplateContent155cdf0e10cSrcweir inline ConstFolderIterator end() const { return m_aSubContents.end(); } 156cdf0e10cSrcweir inline TemplateFolderContent::size_type sizesvt::TemplateContent157cdf0e10cSrcweir size() const { return m_aSubContents.size(); } 158cdf0e10cSrcweir push_backsvt::TemplateContent159cdf0e10cSrcweir inline void push_back( const ::vos::ORef< TemplateContent >& _rxNewElement ) 160cdf0e10cSrcweir { m_aSubContents.push_back( _rxNewElement ); } 161cdf0e10cSrcweir }; 162cdf0e10cSrcweir 163cdf0e10cSrcweir //--------------------------------------------------------------------- DBG_NAME(TemplateContent)164cdf0e10cSrcweir DBG_NAME( TemplateContent ) 165cdf0e10cSrcweir 166cdf0e10cSrcweir //--------------------------------------------------------------------- 167cdf0e10cSrcweir TemplateContent::TemplateContent() 168cdf0e10cSrcweir { 169cdf0e10cSrcweir DBG_CTOR( TemplateContent, NULL ); 170cdf0e10cSrcweir implResetDate(); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir //--------------------------------------------------------------------- TemplateContent(const INetURLObject & _rURL)174cdf0e10cSrcweir TemplateContent::TemplateContent( const INetURLObject& _rURL ) 175cdf0e10cSrcweir :m_aURL( _rURL ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir DBG_CTOR( TemplateContent, NULL ); 178cdf0e10cSrcweir DBG_ASSERT( INET_PROT_NOT_VALID != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" ); 179cdf0e10cSrcweir m_sLocalName = m_aURL.getName(); 180cdf0e10cSrcweir implResetDate(); 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir //--------------------------------------------------------------------- TemplateContent(const INetURLObject & _rURL,const util::DateTime & _rLastModified)184cdf0e10cSrcweir TemplateContent::TemplateContent( const INetURLObject& _rURL, const util::DateTime& _rLastModified ) 185cdf0e10cSrcweir :m_aURL( _rURL ) 186cdf0e10cSrcweir ,m_aLastModified( _rLastModified ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir DBG_CTOR( TemplateContent, NULL ); 189cdf0e10cSrcweir DBG_ASSERT( INET_PROT_NOT_VALID != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" ); 190cdf0e10cSrcweir m_sLocalName = m_aURL.getName(); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir //--------------------------------------------------------------------- ~TemplateContent()194cdf0e10cSrcweir TemplateContent::~TemplateContent() 195cdf0e10cSrcweir { 196cdf0e10cSrcweir DBG_DTOR( TemplateContent, NULL ); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir 199cdf0e10cSrcweir //===================================================================== 200cdf0e10cSrcweir //= stl helpers 201cdf0e10cSrcweir //===================================================================== 202cdf0e10cSrcweir //--------------------------------------------------------------------- 203cdf0e10cSrcweir /// compares two TemplateContent by URL 204cdf0e10cSrcweir struct TemplateContentURLLess 205cdf0e10cSrcweir :public ::std::binary_function < ::vos::ORef< TemplateContent > 206cdf0e10cSrcweir , ::vos::ORef< TemplateContent > 207cdf0e10cSrcweir , bool 208cdf0e10cSrcweir > 209cdf0e10cSrcweir { operator ()svt::TemplateContentURLLess210cdf0e10cSrcweir bool operator() ( const ::vos::ORef< TemplateContent >& _rxLHS, const ::vos::ORef< TemplateContent >& _rxRHS ) const 211cdf0e10cSrcweir { 212cdf0e10cSrcweir return _rxLHS->getURL() < _rxRHS->getURL() 213cdf0e10cSrcweir ? true 214cdf0e10cSrcweir : false; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir }; 217cdf0e10cSrcweir 218cdf0e10cSrcweir //--------------------------------------------------------------------- 219cdf0e10cSrcweir /// sorts the sib contents of a TemplateFolderContent 220cdf0e10cSrcweir struct SubContentSort : public ::std::unary_function< ::vos::ORef< TemplateContent >, void > 221cdf0e10cSrcweir { operator ()svt::SubContentSort222cdf0e10cSrcweir void operator() ( TemplateFolderContent& _rFolder ) const 223cdf0e10cSrcweir { 224cdf0e10cSrcweir // sort the directory by name 225cdf0e10cSrcweir ::std::sort( 226cdf0e10cSrcweir _rFolder.begin(), 227cdf0e10cSrcweir _rFolder.end(), 228cdf0e10cSrcweir TemplateContentURLLess() 229cdf0e10cSrcweir ); 230cdf0e10cSrcweir 231cdf0e10cSrcweir // sort the sub directories by name 232cdf0e10cSrcweir ::std::for_each( 233cdf0e10cSrcweir _rFolder.begin(), 234cdf0e10cSrcweir _rFolder.end(), 235cdf0e10cSrcweir *this 236cdf0e10cSrcweir ); 237cdf0e10cSrcweir } 238cdf0e10cSrcweir operator ()svt::SubContentSort239cdf0e10cSrcweir void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const 240cdf0e10cSrcweir { 241cdf0e10cSrcweir if ( _rxContent.isValid() && _rxContent->size() ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir operator()( _rxContent->getSubContents() ); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir } 246cdf0e10cSrcweir }; 247cdf0e10cSrcweir //--------------------------------------------------------------------- 248cdf0e10cSrcweir /** does a deep compare of two template contents 249cdf0e10cSrcweir */ 250cdf0e10cSrcweir struct TemplateContentEqual 251cdf0e10cSrcweir :public ::std::binary_function < ::vos::ORef< TemplateContent > 252cdf0e10cSrcweir , ::vos::ORef< TemplateContent > 253cdf0e10cSrcweir , bool 254cdf0e10cSrcweir > 255cdf0e10cSrcweir { 256cdf0e10cSrcweir //................................................................. operator ()svt::TemplateContentEqual257cdf0e10cSrcweir bool operator() (const ::vos::ORef< TemplateContent >& _rLHS, const ::vos::ORef< TemplateContent >& _rRHS ) 258cdf0e10cSrcweir { 259cdf0e10cSrcweir if ( !_rLHS.isValid() || !_rRHS.isValid() ) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir DBG_ERROR( "TemplateContentEqual::operator(): invalid contents!" ); 262cdf0e10cSrcweir return true; 263cdf0e10cSrcweir // this is not strictly true, in case only one is invalid - but this is a heavy error anyway 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir if ( _rLHS->getURL() != _rRHS->getURL() ) 267cdf0e10cSrcweir return false; 268cdf0e10cSrcweir 269cdf0e10cSrcweir if ( _rLHS->getModDate() != _rRHS->getModDate() ) 270cdf0e10cSrcweir return false; 271cdf0e10cSrcweir 272cdf0e10cSrcweir if ( _rLHS->getSubContents().size() != _rRHS->getSubContents().size() ) 273cdf0e10cSrcweir return false; 274cdf0e10cSrcweir 275cdf0e10cSrcweir if ( _rLHS->getSubContents().size() ) 276cdf0e10cSrcweir { // there are children 277cdf0e10cSrcweir // -> compare them 278cdf0e10cSrcweir ::std::pair< FolderIterator, FolderIterator > aFirstDifferent = ::std::mismatch( 279cdf0e10cSrcweir _rLHS->getSubContents().begin(), 280cdf0e10cSrcweir _rLHS->getSubContents().end(), 281cdf0e10cSrcweir _rRHS->getSubContents().begin(), 282cdf0e10cSrcweir *this 283cdf0e10cSrcweir ); 284cdf0e10cSrcweir if ( aFirstDifferent.first != _rLHS->getSubContents().end() ) 285cdf0e10cSrcweir return false;// the sub contents differ 286cdf0e10cSrcweir } 287cdf0e10cSrcweir 288cdf0e10cSrcweir return true; 289cdf0e10cSrcweir } 290cdf0e10cSrcweir }; 291cdf0e10cSrcweir 292cdf0e10cSrcweir //--------------------------------------------------------------------- 293cdf0e10cSrcweir /// base class for functors which act an an SvStream 294cdf0e10cSrcweir struct StorageHelper 295cdf0e10cSrcweir { 296cdf0e10cSrcweir protected: 297cdf0e10cSrcweir SvStream& m_rStorage; StorageHelpersvt::StorageHelper298cdf0e10cSrcweir StorageHelper( SvStream& _rStorage ) : m_rStorage( _rStorage ) { } 299cdf0e10cSrcweir }; 300cdf0e10cSrcweir 301cdf0e10cSrcweir //--------------------------------------------------------------------- 302cdf0e10cSrcweir /// functor which allows storing a string 303cdf0e10cSrcweir struct StoreString 304cdf0e10cSrcweir :public ::std::unary_function< String, void > 305cdf0e10cSrcweir ,public StorageHelper 306cdf0e10cSrcweir { StoreStringsvt::StoreString307cdf0e10cSrcweir StoreString( SvStream& _rStorage ) : StorageHelper( _rStorage ) { } 308cdf0e10cSrcweir operator ()svt::StoreString309cdf0e10cSrcweir void operator() ( const String& _rString ) const 310cdf0e10cSrcweir { 311cdf0e10cSrcweir m_rStorage.WriteByteString( _rString ); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir }; 314cdf0e10cSrcweir 315cdf0e10cSrcweir //--------------------------------------------------------------------- 316cdf0e10cSrcweir /// functor which stores the local name of a TemplateContent 317cdf0e10cSrcweir struct StoreLocalContentName 318cdf0e10cSrcweir :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > 319cdf0e10cSrcweir ,public StoreString 320cdf0e10cSrcweir { StoreLocalContentNamesvt::StoreLocalContentName321cdf0e10cSrcweir StoreLocalContentName( SvStream& _rStorage ) : StoreString( _rStorage ) { } 322cdf0e10cSrcweir operator ()svt::StoreLocalContentName323cdf0e10cSrcweir void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const 324cdf0e10cSrcweir { 325cdf0e10cSrcweir DBG_ERRORFILE( "This method must not be used, the whole URL must be stored!" ); 326cdf0e10cSrcweir 327cdf0e10cSrcweir // use the base class operator with the local name of the content 328cdf0e10cSrcweir StoreString::operator() ( _rxContent->getName() ); 329cdf0e10cSrcweir } 330cdf0e10cSrcweir }; 331cdf0e10cSrcweir 332cdf0e10cSrcweir //--------------------------------------------------------------------- 333cdf0e10cSrcweir struct StoreContentURL 334cdf0e10cSrcweir :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > 335cdf0e10cSrcweir ,public StoreString 336cdf0e10cSrcweir { 337cdf0e10cSrcweir uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs; 338cdf0e10cSrcweir StoreContentURLsvt::StoreContentURL339cdf0e10cSrcweir StoreContentURL( SvStream& _rStorage, 340cdf0e10cSrcweir const uno::Reference< 341cdf0e10cSrcweir util::XOfficeInstallationDirectories > & 342cdf0e10cSrcweir xOfficeInstDirs ) 343cdf0e10cSrcweir : StoreString( _rStorage ), m_xOfficeInstDirs( xOfficeInstDirs ) { } 344cdf0e10cSrcweir operator ()svt::StoreContentURL345cdf0e10cSrcweir void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const 346cdf0e10cSrcweir { 347cdf0e10cSrcweir // use the base class operator with the local name of the content 348cdf0e10cSrcweir String sURL = _rxContent->getURL(); 349cdf0e10cSrcweir // #116281# Keep office installtion relocatable. Never store 350cdf0e10cSrcweir // any direct references to office installation directory. 351cdf0e10cSrcweir sURL = m_xOfficeInstDirs->makeRelocatableURL( sURL ); 352cdf0e10cSrcweir StoreString::operator() ( sURL ); 353cdf0e10cSrcweir } 354cdf0e10cSrcweir }; 355cdf0e10cSrcweir 356cdf0e10cSrcweir //--------------------------------------------------------------------- 357cdf0e10cSrcweir /// functor which stores the complete content of a TemplateContent 358cdf0e10cSrcweir struct StoreFolderContent 359cdf0e10cSrcweir :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > 360cdf0e10cSrcweir ,public StorageHelper 361cdf0e10cSrcweir { 362cdf0e10cSrcweir uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs; 363cdf0e10cSrcweir 364cdf0e10cSrcweir public: StoreFolderContentsvt::StoreFolderContent365cdf0e10cSrcweir StoreFolderContent( SvStream& _rStorage, 366cdf0e10cSrcweir const uno::Reference< 367cdf0e10cSrcweir util::XOfficeInstallationDirectories > & 368cdf0e10cSrcweir xOfficeInstDirs ) 369cdf0e10cSrcweir : StorageHelper( _rStorage ), m_xOfficeInstDirs( xOfficeInstDirs ) { } 370cdf0e10cSrcweir 371cdf0e10cSrcweir //................................................................. operator ()svt::StoreFolderContent372cdf0e10cSrcweir void operator() ( const TemplateContent& _rContent ) const 373cdf0e10cSrcweir { 374cdf0e10cSrcweir // store the info about this content 375cdf0e10cSrcweir m_rStorage << _rContent.getModDate(); 376cdf0e10cSrcweir 377cdf0e10cSrcweir // store the info about the children 378cdf0e10cSrcweir // the number 379cdf0e10cSrcweir m_rStorage << (sal_Int32)_rContent.size(); 380cdf0e10cSrcweir // their URLs ( the local name is not enough, since URL might be not a hierarchical one, "expand:" for example ) 381cdf0e10cSrcweir ::std::for_each( 382cdf0e10cSrcweir _rContent.getSubContents().begin(), 383cdf0e10cSrcweir _rContent.getSubContents().end(), 384cdf0e10cSrcweir StoreContentURL( m_rStorage, m_xOfficeInstDirs ) 385cdf0e10cSrcweir ); 386cdf0e10cSrcweir // their content 387cdf0e10cSrcweir ::std::for_each( 388cdf0e10cSrcweir _rContent.getSubContents().begin(), 389cdf0e10cSrcweir _rContent.getSubContents().end(), 390cdf0e10cSrcweir *this 391cdf0e10cSrcweir ); 392cdf0e10cSrcweir } 393cdf0e10cSrcweir 394cdf0e10cSrcweir //................................................................. operator ()svt::StoreFolderContent395cdf0e10cSrcweir void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const 396cdf0e10cSrcweir { 397cdf0e10cSrcweir if ( _rxContent.isValid() ) 398cdf0e10cSrcweir { 399cdf0e10cSrcweir operator()( *_rxContent ); 400cdf0e10cSrcweir } 401cdf0e10cSrcweir } 402cdf0e10cSrcweir }; 403cdf0e10cSrcweir 404cdf0e10cSrcweir //--------------------------------------------------------------------- 405cdf0e10cSrcweir /// functor which reads a complete TemplateContent instance 406cdf0e10cSrcweir struct ReadFolderContent 407cdf0e10cSrcweir :public ::std::unary_function< ::vos::ORef< TemplateContent >, void > 408cdf0e10cSrcweir ,public StorageHelper 409cdf0e10cSrcweir { 410cdf0e10cSrcweir uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs; 411cdf0e10cSrcweir ReadFolderContentsvt::ReadFolderContent412cdf0e10cSrcweir ReadFolderContent( SvStream& _rStorage, 413cdf0e10cSrcweir const uno::Reference< 414cdf0e10cSrcweir util::XOfficeInstallationDirectories > & 415cdf0e10cSrcweir xOfficeInstDirs ) 416cdf0e10cSrcweir : StorageHelper( _rStorage ), m_xOfficeInstDirs( xOfficeInstDirs ) { } 417cdf0e10cSrcweir 418cdf0e10cSrcweir //................................................................. operator ()svt::ReadFolderContent419cdf0e10cSrcweir void operator() ( TemplateContent& _rContent ) const 420cdf0e10cSrcweir { 421cdf0e10cSrcweir // store the info about this content 422cdf0e10cSrcweir util::DateTime aModDate; 423cdf0e10cSrcweir m_rStorage >> aModDate; 424cdf0e10cSrcweir _rContent.setModDate( aModDate ); 425cdf0e10cSrcweir 426cdf0e10cSrcweir // store the info about the children 427cdf0e10cSrcweir // the number 428cdf0e10cSrcweir sal_Int32 nChildren = 0; 429cdf0e10cSrcweir m_rStorage >> nChildren; 430cdf0e10cSrcweir TemplateFolderContent& rChildren = _rContent.getSubContents(); 431cdf0e10cSrcweir rChildren.resize( 0 ); 432cdf0e10cSrcweir rChildren.reserve( nChildren ); 433cdf0e10cSrcweir // initialize them with their (local) names 434cdf0e10cSrcweir while ( nChildren-- ) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir String sURL; 437cdf0e10cSrcweir m_rStorage.ReadByteString( sURL ); 438cdf0e10cSrcweir sURL = m_xOfficeInstDirs->makeAbsoluteURL( sURL ); 439cdf0e10cSrcweir INetURLObject aChildURL( sURL ); 440cdf0e10cSrcweir rChildren.push_back( new TemplateContent( aChildURL ) ); 441cdf0e10cSrcweir } 442cdf0e10cSrcweir 443cdf0e10cSrcweir // their content 444cdf0e10cSrcweir ::std::for_each( 445cdf0e10cSrcweir _rContent.getSubContents().begin(), 446cdf0e10cSrcweir _rContent.getSubContents().end(), 447cdf0e10cSrcweir *this 448cdf0e10cSrcweir ); 449cdf0e10cSrcweir } 450cdf0e10cSrcweir 451cdf0e10cSrcweir //................................................................. operator ()svt::ReadFolderContent452cdf0e10cSrcweir void operator() ( const ::vos::ORef< TemplateContent >& _rxContent ) const 453cdf0e10cSrcweir { 454cdf0e10cSrcweir if ( _rxContent.isValid() ) 455cdf0e10cSrcweir { 456cdf0e10cSrcweir operator()( *_rxContent ); 457cdf0e10cSrcweir } 458cdf0e10cSrcweir } 459cdf0e10cSrcweir }; 460cdf0e10cSrcweir 461cdf0e10cSrcweir //===================================================================== 462cdf0e10cSrcweir //= TemplateFolderCacheImpl 463cdf0e10cSrcweir //===================================================================== 464cdf0e10cSrcweir class TemplateFolderCacheImpl 465cdf0e10cSrcweir { 466cdf0e10cSrcweir private: 467cdf0e10cSrcweir TemplateFolderContent m_aPreviousState; // the current state of the template dirs (as found on the HD) 468cdf0e10cSrcweir TemplateFolderContent m_aCurrentState; // the previous state of the template dirs (as found in the cache file) 469cdf0e10cSrcweir 470cdf0e10cSrcweir osl::Mutex m_aMutex; 471cdf0e10cSrcweir // will be lazy inited; never access directly; use getOfficeInstDirs(). 472cdf0e10cSrcweir uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs; 473cdf0e10cSrcweir 474cdf0e10cSrcweir SvStream* m_pCacheStream; 475cdf0e10cSrcweir sal_Bool m_bNeedsUpdate : 1; 476cdf0e10cSrcweir sal_Bool m_bKnowState : 1; 477cdf0e10cSrcweir sal_Bool m_bValidCurrentState : 1; 478cdf0e10cSrcweir sal_Bool m_bAutoStoreState : 1; 479cdf0e10cSrcweir 480cdf0e10cSrcweir public: 481cdf0e10cSrcweir TemplateFolderCacheImpl( sal_Bool _bAutoStoreState ); 482cdf0e10cSrcweir ~TemplateFolderCacheImpl( ); 483cdf0e10cSrcweir 484cdf0e10cSrcweir sal_Bool needsUpdate( sal_Bool _bForceCheck ); 485cdf0e10cSrcweir void storeState( sal_Bool _bForceRetrieval ); 486cdf0e10cSrcweir 487cdf0e10cSrcweir private: 488cdf0e10cSrcweir void initTemplDirs( ::std::vector< String >& _rRootDirs ); 489cdf0e10cSrcweir sal_Bool openCacheStream( sal_Bool _bForRead ); 490cdf0e10cSrcweir void closeCacheStream( ); 491cdf0e10cSrcweir 492cdf0e10cSrcweir /// read the state of the dirs from the cache file 493cdf0e10cSrcweir sal_Bool readPreviousState(); 494cdf0e10cSrcweir /// read the current state of the dirs 495cdf0e10cSrcweir sal_Bool readCurrentState(); 496cdf0e10cSrcweir 497cdf0e10cSrcweir String implParseSmart( const String& _rPath ); 498cdf0e10cSrcweir 499cdf0e10cSrcweir sal_Bool implReadFolder( const ::vos::ORef< TemplateContent >& _rxRoot ); 500cdf0e10cSrcweir 501cdf0e10cSrcweir static String getCacheFileName(); 502cdf0e10cSrcweir static sal_Int32 getMagicNumber(); 503cdf0e10cSrcweir static void normalize( TemplateFolderContent& _rState ); 504cdf0e10cSrcweir 505cdf0e10cSrcweir // @return <TRUE/> if the states equal 506cdf0e10cSrcweir static sal_Bool equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS ); 507cdf0e10cSrcweir 508cdf0e10cSrcweir // late initialize m_xOfficeInstDirs 509cdf0e10cSrcweir uno::Reference< util::XOfficeInstallationDirectories > getOfficeInstDirs(); 510cdf0e10cSrcweir }; 511cdf0e10cSrcweir 512cdf0e10cSrcweir //--------------------------------------------------------------------- TemplateFolderCacheImpl(sal_Bool _bAutoStoreState)513cdf0e10cSrcweir TemplateFolderCacheImpl::TemplateFolderCacheImpl( sal_Bool _bAutoStoreState ) 514cdf0e10cSrcweir :m_pCacheStream ( NULL ) 515cdf0e10cSrcweir ,m_bNeedsUpdate ( sal_True ) 516cdf0e10cSrcweir ,m_bKnowState ( sal_False ) 517cdf0e10cSrcweir ,m_bValidCurrentState ( sal_False ) 518cdf0e10cSrcweir ,m_bAutoStoreState ( _bAutoStoreState ) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir //--------------------------------------------------------------------- ~TemplateFolderCacheImpl()523cdf0e10cSrcweir TemplateFolderCacheImpl::~TemplateFolderCacheImpl( ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir // store the current state if possible and required 526cdf0e10cSrcweir if ( m_bValidCurrentState && m_bAutoStoreState ) 527cdf0e10cSrcweir storeState( sal_False ); 528cdf0e10cSrcweir 529cdf0e10cSrcweir closeCacheStream( ); 530cdf0e10cSrcweir } 531cdf0e10cSrcweir 532cdf0e10cSrcweir //--------------------------------------------------------------------- getMagicNumber()533cdf0e10cSrcweir sal_Int32 TemplateFolderCacheImpl::getMagicNumber() 534cdf0e10cSrcweir { 535cdf0e10cSrcweir sal_Int32 nMagic = 0; 536cdf0e10cSrcweir ( nMagic += (sal_Int8)'T' ) <<= 4; 537cdf0e10cSrcweir ( nMagic += (sal_Int8)'D' ) <<= 4; 538cdf0e10cSrcweir ( nMagic += (sal_Int8)'S' ) <<= 4; 539cdf0e10cSrcweir ( nMagic += (sal_Int8)'C' ) <<= 0; 540cdf0e10cSrcweir return nMagic; 541cdf0e10cSrcweir } 542cdf0e10cSrcweir 543cdf0e10cSrcweir //--------------------------------------------------------------------- getCacheFileName()544cdf0e10cSrcweir String TemplateFolderCacheImpl::getCacheFileName() 545cdf0e10cSrcweir { 546cdf0e10cSrcweir return String::CreateFromAscii( ".templdir.cache" ); 547cdf0e10cSrcweir } 548cdf0e10cSrcweir 549cdf0e10cSrcweir 550cdf0e10cSrcweir //--------------------------------------------------------------------- normalize(TemplateFolderContent & _rState)551cdf0e10cSrcweir void TemplateFolderCacheImpl::normalize( TemplateFolderContent& _rState ) 552cdf0e10cSrcweir { 553cdf0e10cSrcweir SubContentSort()( _rState ); 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir //--------------------------------------------------------------------- equalStates(const TemplateFolderContent & _rLHS,const TemplateFolderContent & _rRHS)557cdf0e10cSrcweir sal_Bool TemplateFolderCacheImpl::equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS ) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir if ( _rLHS.size() != _rRHS.size() ) 560cdf0e10cSrcweir return sal_False; 561cdf0e10cSrcweir 562cdf0e10cSrcweir // as both arrays are sorted (by definition - this is a precondition of this method) 563cdf0e10cSrcweir // we can simply go from the front to the back and compare the single elements 564cdf0e10cSrcweir 565cdf0e10cSrcweir ::std::pair< ConstFolderIterator, ConstFolderIterator > aFirstDifferent = ::std::mismatch( 566cdf0e10cSrcweir _rLHS.begin(), 567cdf0e10cSrcweir _rLHS.end(), 568cdf0e10cSrcweir _rRHS.begin(), 569cdf0e10cSrcweir TemplateContentEqual() 570cdf0e10cSrcweir ); 571cdf0e10cSrcweir 572cdf0e10cSrcweir return aFirstDifferent.first == _rLHS.end(); 573cdf0e10cSrcweir } 574cdf0e10cSrcweir 575cdf0e10cSrcweir //--------------------------------------------------------------------- storeState(sal_Bool _bForceRetrieval)576cdf0e10cSrcweir void TemplateFolderCacheImpl::storeState( sal_Bool _bForceRetrieval ) 577cdf0e10cSrcweir { 578cdf0e10cSrcweir if ( !m_bValidCurrentState || _bForceRetrieval ) 579cdf0e10cSrcweir readCurrentState( ); 580cdf0e10cSrcweir 581cdf0e10cSrcweir if ( m_bValidCurrentState && openCacheStream( sal_False ) ) 582cdf0e10cSrcweir { 583cdf0e10cSrcweir *m_pCacheStream << getMagicNumber(); 584cdf0e10cSrcweir 585cdf0e10cSrcweir // store the template root folders 586cdf0e10cSrcweir // the size 587cdf0e10cSrcweir *m_pCacheStream << (sal_Int32)m_aCurrentState.size(); 588cdf0e10cSrcweir // the complete URLs 589cdf0e10cSrcweir ::std::for_each( 590cdf0e10cSrcweir m_aCurrentState.begin(), 591cdf0e10cSrcweir m_aCurrentState.end(), 592cdf0e10cSrcweir StoreContentURL( *m_pCacheStream, getOfficeInstDirs() ) 593cdf0e10cSrcweir ); 594cdf0e10cSrcweir 595cdf0e10cSrcweir // the contents 596cdf0e10cSrcweir ::std::for_each( 597cdf0e10cSrcweir m_aCurrentState.begin(), 598cdf0e10cSrcweir m_aCurrentState.end(), 599cdf0e10cSrcweir StoreFolderContent( *m_pCacheStream, getOfficeInstDirs() ) 600cdf0e10cSrcweir ); 601cdf0e10cSrcweir } 602cdf0e10cSrcweir } 603cdf0e10cSrcweir 604cdf0e10cSrcweir //--------------------------------------------------------------------- implParseSmart(const String & _rPath)605cdf0e10cSrcweir String TemplateFolderCacheImpl::implParseSmart( const String& _rPath ) 606cdf0e10cSrcweir { 607cdf0e10cSrcweir INetURLObject aParser; 608cdf0e10cSrcweir aParser.SetSmartProtocol( INET_PROT_FILE ); 609cdf0e10cSrcweir aParser.SetURL( _rPath, INetURLObject::WAS_ENCODED ); 610cdf0e10cSrcweir if ( INET_PROT_NOT_VALID == aParser.GetProtocol() ) 611cdf0e10cSrcweir { 612cdf0e10cSrcweir String sURL; 613cdf0e10cSrcweir LocalFileHelper::ConvertPhysicalNameToURL( _rPath, sURL ); 614cdf0e10cSrcweir aParser.SetURL( sURL, INetURLObject::WAS_ENCODED ); 615cdf0e10cSrcweir } 616cdf0e10cSrcweir return aParser.GetMainURL( INetURLObject::DECODE_TO_IURI ); 617cdf0e10cSrcweir } 618cdf0e10cSrcweir 619cdf0e10cSrcweir //--------------------------------------------------------------------- closeCacheStream()620cdf0e10cSrcweir void TemplateFolderCacheImpl::closeCacheStream( ) 621cdf0e10cSrcweir { 622cdf0e10cSrcweir DELETEZ( m_pCacheStream ); 623cdf0e10cSrcweir } 624cdf0e10cSrcweir 625cdf0e10cSrcweir //--------------------------------------------------------------------- implReadFolder(const::vos::ORef<TemplateContent> & _rxRoot)626cdf0e10cSrcweir sal_Bool TemplateFolderCacheImpl::implReadFolder( const ::vos::ORef< TemplateContent >& _rxRoot ) 627cdf0e10cSrcweir { 628cdf0e10cSrcweir try 629cdf0e10cSrcweir { 630cdf0e10cSrcweir // create a content for the current folder root 631cdf0e10cSrcweir Reference< XResultSet > xResultSet; 632cdf0e10cSrcweir Sequence< ::rtl::OUString > aContentProperties( 4); 633cdf0e10cSrcweir aContentProperties[0] = ::rtl::OUString::createFromAscii( "Title" ); 634cdf0e10cSrcweir aContentProperties[1] = ::rtl::OUString::createFromAscii( "DateModified" ); 635cdf0e10cSrcweir aContentProperties[2] = ::rtl::OUString::createFromAscii( "DateCreated" ); 636cdf0e10cSrcweir aContentProperties[3] = ::rtl::OUString::createFromAscii( "IsFolder" ); 637cdf0e10cSrcweir 638cdf0e10cSrcweir // get the set of sub contents in the folder 639cdf0e10cSrcweir try 640cdf0e10cSrcweir { 641cdf0e10cSrcweir Reference< XDynamicResultSet > xDynResultSet; 642cdf0e10cSrcweir 643cdf0e10cSrcweir ::ucbhelper::Content aTemplateRoot( _rxRoot->getURL(), Reference< XCommandEnvironment >() ); 644cdf0e10cSrcweir xDynResultSet = aTemplateRoot.createDynamicCursor( aContentProperties, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ); 645cdf0e10cSrcweir if ( xDynResultSet.is() ) 646cdf0e10cSrcweir xResultSet = xDynResultSet->getStaticResultSet(); 647cdf0e10cSrcweir } 648cdf0e10cSrcweir catch( CommandAbortedException& ) 649cdf0e10cSrcweir { 650cdf0e10cSrcweir DBG_ERRORFILE( "TemplateFolderCacheImpl::implReadFolder: caught a CommandAbortedException!" ); 651cdf0e10cSrcweir return sal_False; 652cdf0e10cSrcweir } 653cdf0e10cSrcweir catch( ::com::sun::star::uno::Exception& ) 654cdf0e10cSrcweir { 655cdf0e10cSrcweir } 656cdf0e10cSrcweir 657cdf0e10cSrcweir // collect the infos about the sub contents 658cdf0e10cSrcweir if ( xResultSet.is() ) 659cdf0e10cSrcweir { 660cdf0e10cSrcweir Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW ); 661cdf0e10cSrcweir Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW ); 662cdf0e10cSrcweir 663cdf0e10cSrcweir while ( xResultSet->next() ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir INetURLObject aSubContentURL( xContentAccess->queryContentIdentifierString() ); 666cdf0e10cSrcweir 667cdf0e10cSrcweir // a new content instance 668cdf0e10cSrcweir ::vos::ORef< TemplateContent > xChild = new TemplateContent( aSubContentURL ); 669cdf0e10cSrcweir 670cdf0e10cSrcweir // the modified date 671cdf0e10cSrcweir xChild->setModDate( xRow->getTimestamp( 2 ) ); // date modified 672cdf0e10cSrcweir if ( xRow->wasNull() ) 673cdf0e10cSrcweir xChild->setModDate( xRow->getTimestamp( 3 ) ); // fallback: date created 674cdf0e10cSrcweir 675cdf0e10cSrcweir // push back this content 676cdf0e10cSrcweir _rxRoot->push_back( xChild ); 677cdf0e10cSrcweir 678cdf0e10cSrcweir // is it a folder? 679cdf0e10cSrcweir if ( xRow->getBoolean( 4 ) && !xRow->wasNull() ) 680cdf0e10cSrcweir { // yes -> step down 681cdf0e10cSrcweir ConstFolderIterator aNextLevelRoot = _rxRoot->end(); 682cdf0e10cSrcweir --aNextLevelRoot; 683cdf0e10cSrcweir implReadFolder( *aNextLevelRoot ); 684cdf0e10cSrcweir } 685cdf0e10cSrcweir } 686cdf0e10cSrcweir } 687cdf0e10cSrcweir } 688cdf0e10cSrcweir catch( const Exception& ) 689cdf0e10cSrcweir { 690cdf0e10cSrcweir DBG_ERROR( "TemplateFolderCacheImpl::implReadFolder: caught an exception!" ); 691cdf0e10cSrcweir return sal_False; 692cdf0e10cSrcweir } 693cdf0e10cSrcweir return sal_True; 694cdf0e10cSrcweir } 695cdf0e10cSrcweir 696cdf0e10cSrcweir //--------------------------------------------------------------------- readCurrentState()697cdf0e10cSrcweir sal_Bool TemplateFolderCacheImpl::readCurrentState() 698cdf0e10cSrcweir { 699cdf0e10cSrcweir // reset 700cdf0e10cSrcweir m_bValidCurrentState = sal_False; 701cdf0e10cSrcweir TemplateFolderContent aTemplateFolderContent; 702cdf0e10cSrcweir m_aCurrentState.swap( aTemplateFolderContent ); 703cdf0e10cSrcweir 704cdf0e10cSrcweir // the template directories from the config 705cdf0e10cSrcweir const SvtPathOptions aPathOptions; 706cdf0e10cSrcweir String aDirs = aPathOptions.GetTemplatePath(); 707cdf0e10cSrcweir sal_uInt16 nDirs = aDirs.GetTokenCount( ';' ); 708cdf0e10cSrcweir 709cdf0e10cSrcweir m_aCurrentState.reserve( nDirs ); 710cdf0e10cSrcweir // loop through all the root-level template folders 711cdf0e10cSrcweir for ( sal_uInt16 i=0; i<nDirs; ++i) 712cdf0e10cSrcweir { 713cdf0e10cSrcweir String sTemplatePath( aDirs.GetToken( i, ';' ) ); 714cdf0e10cSrcweir sTemplatePath = aPathOptions.ExpandMacros( sTemplatePath ); 715cdf0e10cSrcweir // create a new entry 716cdf0e10cSrcweir m_aCurrentState.push_back( new TemplateContent( INetURLObject( sTemplatePath ) ) ); 717cdf0e10cSrcweir TemplateFolderContent::iterator aCurrentRoot = m_aCurrentState.end(); 718cdf0e10cSrcweir --aCurrentRoot; 719cdf0e10cSrcweir 720cdf0e10cSrcweir if ( !implReadFolder( *aCurrentRoot ) ) 721cdf0e10cSrcweir return sal_False; 722cdf0e10cSrcweir } 723cdf0e10cSrcweir 724cdf0e10cSrcweir // normalize the array (which basically means "sort it") 725cdf0e10cSrcweir normalize( m_aCurrentState ); 726cdf0e10cSrcweir 727cdf0e10cSrcweir m_bValidCurrentState = sal_True; 728cdf0e10cSrcweir return m_bValidCurrentState; 729cdf0e10cSrcweir } 730cdf0e10cSrcweir 731cdf0e10cSrcweir //--------------------------------------------------------------------- readPreviousState()732cdf0e10cSrcweir sal_Bool TemplateFolderCacheImpl::readPreviousState() 733cdf0e10cSrcweir { 734cdf0e10cSrcweir DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::readPreviousState: not to be called without stream!" ); 735cdf0e10cSrcweir 736cdf0e10cSrcweir // reset 737cdf0e10cSrcweir TemplateFolderContent aTemplateFolderContent; 738cdf0e10cSrcweir m_aPreviousState.swap( aTemplateFolderContent ); 739cdf0e10cSrcweir 740cdf0e10cSrcweir // check the magic number 741cdf0e10cSrcweir sal_Int32 nMagic = 0; 742cdf0e10cSrcweir *m_pCacheStream >> nMagic; 743cdf0e10cSrcweir DBG_ASSERT( getMagicNumber() == nMagic, "TemplateFolderCacheImpl::readPreviousState: invalid cache file!" ); 744cdf0e10cSrcweir if ( getMagicNumber() != nMagic ) 745cdf0e10cSrcweir return sal_False; 746cdf0e10cSrcweir 747cdf0e10cSrcweir // the root directories 748cdf0e10cSrcweir // their number 749cdf0e10cSrcweir sal_Int32 nRootDirectories = 0; 750cdf0e10cSrcweir *m_pCacheStream >> nRootDirectories; 751cdf0e10cSrcweir // init empty TemplateContens with the URLs 752cdf0e10cSrcweir m_aPreviousState.reserve( nRootDirectories ); 753cdf0e10cSrcweir while ( nRootDirectories-- ) 754cdf0e10cSrcweir { 755cdf0e10cSrcweir String sURL; 756cdf0e10cSrcweir m_pCacheStream->ReadByteString( sURL ); 757cdf0e10cSrcweir // #116281# Keep office installtion relocatable. Never store 758cdf0e10cSrcweir // any direct references to office installation directory. 759cdf0e10cSrcweir sURL = getOfficeInstDirs()->makeAbsoluteURL( sURL ); 760cdf0e10cSrcweir m_aPreviousState.push_back( 761cdf0e10cSrcweir new TemplateContent( INetURLObject(sURL) ) ); 762cdf0e10cSrcweir } 763cdf0e10cSrcweir 764cdf0e10cSrcweir // read the contents of the root folders 765cdf0e10cSrcweir ::std::for_each( 766cdf0e10cSrcweir m_aPreviousState.begin(), 767cdf0e10cSrcweir m_aPreviousState.end(), 768cdf0e10cSrcweir ReadFolderContent( *m_pCacheStream, getOfficeInstDirs() ) 769cdf0e10cSrcweir ); 770cdf0e10cSrcweir 771cdf0e10cSrcweir DBG_ASSERT( !m_pCacheStream->GetErrorCode(), "TemplateFolderCacheImpl::readPreviousState: unknown error during reading the state cache!" ); 772cdf0e10cSrcweir 773cdf0e10cSrcweir // normalize the array (which basically means "sort it") 774cdf0e10cSrcweir normalize( m_aPreviousState ); 775cdf0e10cSrcweir 776cdf0e10cSrcweir return sal_True; 777cdf0e10cSrcweir } 778cdf0e10cSrcweir 779cdf0e10cSrcweir //--------------------------------------------------------------------- openCacheStream(sal_Bool _bForRead)780cdf0e10cSrcweir sal_Bool TemplateFolderCacheImpl::openCacheStream( sal_Bool _bForRead ) 781cdf0e10cSrcweir { 782cdf0e10cSrcweir // close any old stream instance 783cdf0e10cSrcweir closeCacheStream( ); 784cdf0e10cSrcweir 785cdf0e10cSrcweir // get the storage directory 786cdf0e10cSrcweir String sStorageURL = implParseSmart( SvtPathOptions().GetStoragePath() ); 787cdf0e10cSrcweir INetURLObject aStorageURL( sStorageURL ); 788cdf0e10cSrcweir if ( INET_PROT_NOT_VALID == aStorageURL.GetProtocol() ) 789cdf0e10cSrcweir { 790cdf0e10cSrcweir DBG_ERROR( "TemplateFolderCacheImpl::openCacheStream: invalid storage path!" ); 791cdf0e10cSrcweir return sal_False; 792cdf0e10cSrcweir } 793cdf0e10cSrcweir 794cdf0e10cSrcweir // append our name 795cdf0e10cSrcweir aStorageURL.Append( getCacheFileName() ); 796cdf0e10cSrcweir 797cdf0e10cSrcweir // open the stream 798cdf0e10cSrcweir m_pCacheStream = UcbStreamHelper::CreateStream( aStorageURL.GetMainURL( INetURLObject::DECODE_TO_IURI ), 799cdf0e10cSrcweir _bForRead ? STREAM_READ | STREAM_NOCREATE : STREAM_WRITE | STREAM_TRUNC ); 800cdf0e10cSrcweir DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::openCacheStream: could not open/create the cache stream!" ); 801cdf0e10cSrcweir if ( m_pCacheStream && m_pCacheStream->GetErrorCode() ) 802cdf0e10cSrcweir { 803cdf0e10cSrcweir DELETEZ( m_pCacheStream ); 804cdf0e10cSrcweir } 805cdf0e10cSrcweir 806cdf0e10cSrcweir if ( m_pCacheStream ) 807cdf0e10cSrcweir m_pCacheStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); 808cdf0e10cSrcweir 809cdf0e10cSrcweir return NULL != m_pCacheStream; 810cdf0e10cSrcweir } 811cdf0e10cSrcweir 812cdf0e10cSrcweir //--------------------------------------------------------------------- needsUpdate(sal_Bool _bForceCheck)813cdf0e10cSrcweir sal_Bool TemplateFolderCacheImpl::needsUpdate( sal_Bool _bForceCheck ) 814cdf0e10cSrcweir { 815cdf0e10cSrcweir if ( m_bKnowState && !_bForceCheck ) 816cdf0e10cSrcweir return m_bNeedsUpdate; 817cdf0e10cSrcweir 818cdf0e10cSrcweir m_bNeedsUpdate = sal_True; 819cdf0e10cSrcweir m_bKnowState = sal_True; 820cdf0e10cSrcweir 821cdf0e10cSrcweir if ( readCurrentState() ) 822cdf0e10cSrcweir { 823cdf0e10cSrcweir // open the stream which contains the cached state of the directories 824cdf0e10cSrcweir if ( openCacheStream( sal_True ) ) 825cdf0e10cSrcweir { // opening the stream succeeded 826cdf0e10cSrcweir if ( readPreviousState() ) 827cdf0e10cSrcweir { 828cdf0e10cSrcweir m_bNeedsUpdate = !equalStates( m_aPreviousState, m_aCurrentState ); 829cdf0e10cSrcweir } 830cdf0e10cSrcweir else 831cdf0e10cSrcweir { 832cdf0e10cSrcweir closeCacheStream(); 833cdf0e10cSrcweir } 834cdf0e10cSrcweir } 835cdf0e10cSrcweir } 836cdf0e10cSrcweir return m_bNeedsUpdate; 837cdf0e10cSrcweir } 838cdf0e10cSrcweir 839cdf0e10cSrcweir //--------------------------------------------------------------------- initTemplDirs(::std::vector<String> &)840cdf0e10cSrcweir void TemplateFolderCacheImpl::initTemplDirs( ::std::vector< String >& ) 841cdf0e10cSrcweir { 842cdf0e10cSrcweir } 843cdf0e10cSrcweir 844cdf0e10cSrcweir //--------------------------------------------------------------------- 845cdf0e10cSrcweir uno::Reference< util::XOfficeInstallationDirectories > getOfficeInstDirs()846cdf0e10cSrcweir TemplateFolderCacheImpl::getOfficeInstDirs() 847cdf0e10cSrcweir { 848cdf0e10cSrcweir if ( !m_xOfficeInstDirs.is() ) 849cdf0e10cSrcweir { 850cdf0e10cSrcweir osl::MutexGuard aGuard( m_aMutex ); 851cdf0e10cSrcweir if ( !m_xOfficeInstDirs.is() ) 852cdf0e10cSrcweir { 853cdf0e10cSrcweir // @@@ This is bad! 854cdf0e10cSrcweir uno::Reference< lang::XMultiServiceFactory > xSMgr 855cdf0e10cSrcweir = comphelper::getProcessServiceFactory(); 856cdf0e10cSrcweir OSL_ENSURE( xSMgr.is(), "No service manager!" ); 857cdf0e10cSrcweir 858cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xPropSet( 859cdf0e10cSrcweir xSMgr, uno::UNO_QUERY ); 860cdf0e10cSrcweir if ( xPropSet.is() ) 861cdf0e10cSrcweir { 862cdf0e10cSrcweir uno::Reference< uno::XComponentContext > xCtx; 863cdf0e10cSrcweir xPropSet->getPropertyValue( 864cdf0e10cSrcweir rtl::OUString( 865cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) 866cdf0e10cSrcweir >>= xCtx; 867cdf0e10cSrcweir 868cdf0e10cSrcweir OSL_ENSURE( xCtx.is(), 869cdf0e10cSrcweir "Unable to obtain component context from service manager!" ); 870cdf0e10cSrcweir 871cdf0e10cSrcweir if ( xCtx.is() ) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir xCtx->getValueByName( 874cdf0e10cSrcweir rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 875cdf0e10cSrcweir "/singletons/com.sun.star.util.theOfficeInstallationDirectories" ) ) ) 876cdf0e10cSrcweir >>= m_xOfficeInstDirs; 877cdf0e10cSrcweir } 878cdf0e10cSrcweir 879cdf0e10cSrcweir OSL_ENSURE( m_xOfficeInstDirs.is(), 880cdf0e10cSrcweir "Unable to obtain office directories singleton!" ); 881cdf0e10cSrcweir 882cdf0e10cSrcweir } 883cdf0e10cSrcweir } 884cdf0e10cSrcweir } 885cdf0e10cSrcweir return m_xOfficeInstDirs; 886cdf0e10cSrcweir } 887cdf0e10cSrcweir 888cdf0e10cSrcweir //===================================================================== 889cdf0e10cSrcweir //= TemplateFolderCache 890cdf0e10cSrcweir //===================================================================== 891cdf0e10cSrcweir //--------------------------------------------------------------------- TemplateFolderCache(sal_Bool _bAutoStoreState)892cdf0e10cSrcweir TemplateFolderCache::TemplateFolderCache( sal_Bool _bAutoStoreState ) 893cdf0e10cSrcweir :m_pImpl( new TemplateFolderCacheImpl( _bAutoStoreState ) ) 894cdf0e10cSrcweir { 895cdf0e10cSrcweir } 896cdf0e10cSrcweir 897cdf0e10cSrcweir //--------------------------------------------------------------------- ~TemplateFolderCache()898cdf0e10cSrcweir TemplateFolderCache::~TemplateFolderCache( ) 899cdf0e10cSrcweir { 900cdf0e10cSrcweir DELETEZ( m_pImpl ); 901cdf0e10cSrcweir } 902cdf0e10cSrcweir 903cdf0e10cSrcweir //--------------------------------------------------------------------- needsUpdate(sal_Bool _bForceCheck)904cdf0e10cSrcweir sal_Bool TemplateFolderCache::needsUpdate( sal_Bool _bForceCheck ) 905cdf0e10cSrcweir { 906cdf0e10cSrcweir return m_pImpl->needsUpdate( _bForceCheck ); 907cdf0e10cSrcweir } 908cdf0e10cSrcweir 909cdf0e10cSrcweir //--------------------------------------------------------------------- storeState(sal_Bool _bForceRetrieval)910cdf0e10cSrcweir void TemplateFolderCache::storeState( sal_Bool _bForceRetrieval ) 911cdf0e10cSrcweir { 912cdf0e10cSrcweir m_pImpl->storeState( _bForceRetrieval ); 913cdf0e10cSrcweir } 914cdf0e10cSrcweir 915cdf0e10cSrcweir //......................................................................... 916cdf0e10cSrcweir } // namespace sfx2 917cdf0e10cSrcweir //......................................................................... 918cdf0e10cSrcweir 919