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