1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: templatefoldercache.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include "templatefoldercache.hxx"
34 #include <unotools/ucbstreamhelper.hxx>
35 #include <unotools/localfilehelper.hxx>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/sdbc/XResultSet.hpp>
38 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
39 #include <com/sun/star/sdbc/XRow.hpp>
40 #include <com/sun/star/ucb/XContentAccess.hpp>
41 #include <com/sun/star/uno/XComponentContext.hpp>
42 #include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
43 #include <ucbhelper/content.hxx>
44 #include <vos/ref.hxx>
45 #include <vos/refernce.hxx>
46 #include <tools/urlobj.hxx>
47 #include <tools/debug.hxx>
48 #include <svtools/pathoptions.hxx>
50 #include "comphelper/processfactory.hxx"
57 //.........................................................................
60 //.........................................................................
62 using namespace ::utl
;
63 using namespace ::com::sun::star
;
64 using namespace ::com::sun::star::sdbc
;
65 using namespace ::com::sun::star::ucb
;
66 using namespace ::com::sun::star::uno
;
68 //=====================================================================
70 //=====================================================================
71 //---------------------------------------------------------------------
72 SvStream
& operator << ( SvStream
& _rStorage
, const util::DateTime
& _rDate
)
74 _rStorage
<< _rDate
.HundredthSeconds
;
75 _rStorage
<< _rDate
.Seconds
;
76 _rStorage
<< _rDate
.Minutes
;
77 _rStorage
<< _rDate
.Hours
;
78 _rStorage
<< _rDate
.Day
;
79 _rStorage
<< _rDate
.Month
;
80 _rStorage
<< _rDate
.Year
;
85 //---------------------------------------------------------------------
86 SvStream
& operator >> ( SvStream
& _rStorage
, util::DateTime
& _rDate
)
88 _rStorage
>> _rDate
.HundredthSeconds
;
89 _rStorage
>> _rDate
.Seconds
;
90 _rStorage
>> _rDate
.Minutes
;
91 _rStorage
>> _rDate
.Hours
;
92 _rStorage
>> _rDate
.Day
;
93 _rStorage
>> _rDate
.Month
;
94 _rStorage
>> _rDate
.Year
;
99 //---------------------------------------------------------------------
100 sal_Bool
operator == ( const util::DateTime
& _rLHS
, const util::DateTime
& _rRHS
)
102 return _rLHS
.HundredthSeconds
== _rRHS
.HundredthSeconds
103 && _rLHS
.Seconds
== _rRHS
.Seconds
104 && _rLHS
.Minutes
== _rRHS
.Minutes
105 && _rLHS
.Hours
== _rRHS
.Hours
106 && _rLHS
.Day
== _rRHS
.Day
107 && _rLHS
.Month
== _rRHS
.Month
108 && _rLHS
.Year
== _rRHS
.Year
;
111 //---------------------------------------------------------------------
112 sal_Bool
operator != ( const util::DateTime
& _rLHS
, const util::DateTime
& _rRHS
)
114 return !( _rLHS
== _rRHS
);
117 //=====================================================================
119 //=====================================================================
120 struct TemplateContent
;
121 typedef ::std::vector
< ::vos::ORef
< TemplateContent
> > TemplateFolderContent
;
122 typedef TemplateFolderContent::const_iterator ConstFolderIterator
;
123 typedef TemplateFolderContent::iterator FolderIterator
;
125 /** a struct describing one content in one of the template dirs (or at least it's relevant aspects)
127 struct TemplateContent
: public ::vos::OReference
132 INetURLObject m_aURL
;
133 String m_sLocalName
; // redundant - last segment of m_aURL
134 util::DateTime m_aLastModified
; // date of last modification as reported by UCP
135 TemplateFolderContent m_aSubContents
; // sorted (by name) list of the children
138 inline void implResetDate( )
140 m_aLastModified
.HundredthSeconds
= m_aLastModified
.Seconds
= m_aLastModified
.Minutes
= m_aLastModified
.Hours
= 0;
141 m_aLastModified
.Day
= m_aLastModified
.Month
= m_aLastModified
.Year
= 0;
149 TemplateContent( const INetURLObject
& _rURL
);
150 TemplateContent( const INetURLObject
& _rURL
, const util::DateTime
& _rLastModified
);
153 inline String
getName( ) const { return m_sLocalName
; }
154 inline String
getURL( ) const { return m_aURL
.GetMainURL( INetURLObject::DECODE_TO_IURI
); }
155 inline void setModDate( const util::DateTime
& _rDate
) { m_aLastModified
= _rDate
; }
156 inline const util::DateTime
& getModDate( ) const { return m_aLastModified
; }
158 inline TemplateFolderContent
& getSubContents() { return m_aSubContents
; }
159 inline const TemplateFolderContent
& getSubContents() const { return m_aSubContents
; }
161 inline ConstFolderIterator
begin() const { return m_aSubContents
.begin(); }
162 inline ConstFolderIterator
end() const { return m_aSubContents
.end(); }
163 inline TemplateFolderContent::size_type
164 size() const { return m_aSubContents
.size(); }
166 inline void push_back( const ::vos::ORef
< TemplateContent
>& _rxNewElement
)
167 { m_aSubContents
.push_back( _rxNewElement
); }
170 //---------------------------------------------------------------------
171 DBG_NAME( TemplateContent
)
173 //---------------------------------------------------------------------
174 TemplateContent::TemplateContent()
176 DBG_CTOR( TemplateContent
, NULL
);
180 //---------------------------------------------------------------------
181 TemplateContent::TemplateContent( const INetURLObject
& _rURL
)
184 DBG_CTOR( TemplateContent
, NULL
);
185 DBG_ASSERT( INET_PROT_NOT_VALID
!= m_aURL
.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" );
186 m_sLocalName
= m_aURL
.getName();
190 //---------------------------------------------------------------------
191 TemplateContent::TemplateContent( const INetURLObject
& _rURL
, const util::DateTime
& _rLastModified
)
193 ,m_aLastModified( _rLastModified
)
195 DBG_CTOR( TemplateContent
, NULL
);
196 DBG_ASSERT( INET_PROT_NOT_VALID
!= m_aURL
.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" );
197 m_sLocalName
= m_aURL
.getName();
200 //---------------------------------------------------------------------
201 TemplateContent::~TemplateContent()
203 DBG_DTOR( TemplateContent
, NULL
);
206 //=====================================================================
208 //=====================================================================
209 //---------------------------------------------------------------------
210 /// compares two TemplateContent by URL
211 struct TemplateContentURLLess
212 :public ::std::binary_function
< ::vos::ORef
< TemplateContent
>
213 , ::vos::ORef
< TemplateContent
>
217 bool operator() ( const ::vos::ORef
< TemplateContent
>& _rxLHS
, const ::vos::ORef
< TemplateContent
>& _rxRHS
) const
219 return _rxLHS
->getURL() < _rxRHS
->getURL()
225 //---------------------------------------------------------------------
226 /// sorts the sib contents of a TemplateFolderContent
227 struct SubContentSort
: public ::std::unary_function
< ::vos::ORef
< TemplateContent
>, void >
229 void operator() ( TemplateFolderContent
& _rFolder
) const
231 // sort the directory by name
235 TemplateContentURLLess()
238 // sort the sub directories by name
246 void operator() ( const ::vos::ORef
< TemplateContent
>& _rxContent
) const
248 if ( _rxContent
.isValid() && _rxContent
->size() )
250 operator()( _rxContent
->getSubContents() );
254 //---------------------------------------------------------------------
255 /** does a deep compare of two template contents
257 struct TemplateContentEqual
258 :public ::std::binary_function
< ::vos::ORef
< TemplateContent
>
259 , ::vos::ORef
< TemplateContent
>
263 //.................................................................
264 bool operator() (const ::vos::ORef
< TemplateContent
>& _rLHS
, const ::vos::ORef
< TemplateContent
>& _rRHS
)
266 if ( !_rLHS
.isValid() || !_rRHS
.isValid() )
268 DBG_ERROR( "TemplateContentEqual::operator(): invalid contents!" );
270 // this is not strictly true, in case only one is invalid - but this is a heavy error anyway
273 if ( _rLHS
->getURL() != _rRHS
->getURL() )
276 if ( _rLHS
->getModDate() != _rRHS
->getModDate() )
279 if ( _rLHS
->getSubContents().size() != _rRHS
->getSubContents().size() )
282 if ( _rLHS
->getSubContents().size() )
283 { // there are children
285 ::std::pair
< FolderIterator
, FolderIterator
> aFirstDifferent
= ::std::mismatch(
286 _rLHS
->getSubContents().begin(),
287 _rLHS
->getSubContents().end(),
288 _rRHS
->getSubContents().begin(),
291 if ( aFirstDifferent
.first
!= _rLHS
->getSubContents().end() )
292 return false;// the sub contents differ
299 //---------------------------------------------------------------------
300 /// base class for functors which act an an SvStream
304 SvStream
& m_rStorage
;
305 StorageHelper( SvStream
& _rStorage
) : m_rStorage( _rStorage
) { }
308 //---------------------------------------------------------------------
309 /// functor which allows storing a string
311 :public ::std::unary_function
< String
, void >
312 ,public StorageHelper
314 StoreString( SvStream
& _rStorage
) : StorageHelper( _rStorage
) { }
316 void operator() ( const String
& _rString
) const
318 m_rStorage
.WriteByteString( _rString
);
322 //---------------------------------------------------------------------
323 /// functor which stores the local name of a TemplateContent
324 struct StoreLocalContentName
325 :public ::std::unary_function
< ::vos::ORef
< TemplateContent
>, void >
328 StoreLocalContentName( SvStream
& _rStorage
) : StoreString( _rStorage
) { }
330 void operator() ( const ::vos::ORef
< TemplateContent
>& _rxContent
) const
332 DBG_ERRORFILE( "This method must not be used, the whole URL must be stored!" );
334 // use the base class operator with the local name of the content
335 StoreString::operator() ( _rxContent
->getName() );
339 //---------------------------------------------------------------------
340 struct StoreContentURL
341 :public ::std::unary_function
< ::vos::ORef
< TemplateContent
>, void >
344 uno::Reference
< util::XOfficeInstallationDirectories
> m_xOfficeInstDirs
;
346 StoreContentURL( SvStream
& _rStorage
,
347 const uno::Reference
<
348 util::XOfficeInstallationDirectories
> &
350 : StoreString( _rStorage
), m_xOfficeInstDirs( xOfficeInstDirs
) { }
352 void operator() ( const ::vos::ORef
< TemplateContent
>& _rxContent
) const
354 // use the base class operator with the local name of the content
355 String sURL
= _rxContent
->getURL();
356 // #116281# Keep office installtion relocatable. Never store
357 // any direct references to office installation directory.
358 sURL
= m_xOfficeInstDirs
->makeRelocatableURL( sURL
);
359 StoreString::operator() ( sURL
);
363 //---------------------------------------------------------------------
364 /// functor which stores the complete content of a TemplateContent
365 struct StoreFolderContent
366 :public ::std::unary_function
< ::vos::ORef
< TemplateContent
>, void >
367 ,public StorageHelper
369 uno::Reference
< util::XOfficeInstallationDirectories
> m_xOfficeInstDirs
;
372 StoreFolderContent( SvStream
& _rStorage
,
373 const uno::Reference
<
374 util::XOfficeInstallationDirectories
> &
376 : StorageHelper( _rStorage
), m_xOfficeInstDirs( xOfficeInstDirs
) { }
378 //.................................................................
379 void operator() ( const TemplateContent
& _rContent
) const
381 // store the info about this content
382 m_rStorage
<< _rContent
.getModDate();
384 // store the info about the children
386 m_rStorage
<< (sal_Int32
)_rContent
.size();
387 // their URLs ( the local name is not enough, since URL might be not a hierarchical one, "expand:" for example )
389 _rContent
.getSubContents().begin(),
390 _rContent
.getSubContents().end(),
391 StoreContentURL( m_rStorage
, m_xOfficeInstDirs
)
395 _rContent
.getSubContents().begin(),
396 _rContent
.getSubContents().end(),
401 //.................................................................
402 void operator() ( const ::vos::ORef
< TemplateContent
>& _rxContent
) const
404 if ( _rxContent
.isValid() )
406 operator()( *_rxContent
);
411 //---------------------------------------------------------------------
412 /// functor which reads a complete TemplateContent instance
413 struct ReadFolderContent
414 :public ::std::unary_function
< ::vos::ORef
< TemplateContent
>, void >
415 ,public StorageHelper
417 uno::Reference
< util::XOfficeInstallationDirectories
> m_xOfficeInstDirs
;
419 ReadFolderContent( SvStream
& _rStorage
,
420 const uno::Reference
<
421 util::XOfficeInstallationDirectories
> &
423 : StorageHelper( _rStorage
), m_xOfficeInstDirs( xOfficeInstDirs
) { }
425 //.................................................................
426 void operator() ( TemplateContent
& _rContent
) const
428 // store the info about this content
429 util::DateTime aModDate
;
430 m_rStorage
>> aModDate
;
431 _rContent
.setModDate( aModDate
);
433 // store the info about the children
435 sal_Int32 nChildren
= 0;
436 m_rStorage
>> nChildren
;
437 TemplateFolderContent
& rChildren
= _rContent
.getSubContents();
438 rChildren
.resize( 0 );
439 rChildren
.reserve( nChildren
);
440 // initialize them with their (local) names
441 while ( nChildren
-- )
444 m_rStorage
.ReadByteString( sURL
);
445 sURL
= m_xOfficeInstDirs
->makeAbsoluteURL( sURL
);
446 INetURLObject
aChildURL( sURL
);
447 rChildren
.push_back( new TemplateContent( aChildURL
) );
452 _rContent
.getSubContents().begin(),
453 _rContent
.getSubContents().end(),
458 //.................................................................
459 void operator() ( const ::vos::ORef
< TemplateContent
>& _rxContent
) const
461 if ( _rxContent
.isValid() )
463 operator()( *_rxContent
);
468 //=====================================================================
469 //= TemplateFolderCacheImpl
470 //=====================================================================
471 class TemplateFolderCacheImpl
474 TemplateFolderContent m_aPreviousState
; // the current state of the template dirs (as found on the HD)
475 TemplateFolderContent m_aCurrentState
; // the previous state of the template dirs (as found in the cache file)
478 // will be lazy inited; never access directly; use getOfficeInstDirs().
479 uno::Reference
< util::XOfficeInstallationDirectories
> m_xOfficeInstDirs
;
481 SvStream
* m_pCacheStream
;
482 sal_Bool m_bNeedsUpdate
: 1;
483 sal_Bool m_bKnowState
: 1;
484 sal_Bool m_bValidCurrentState
: 1;
485 sal_Bool m_bAutoStoreState
: 1;
488 TemplateFolderCacheImpl( sal_Bool _bAutoStoreState
);
489 ~TemplateFolderCacheImpl( );
491 sal_Bool
needsUpdate( sal_Bool _bForceCheck
);
492 void storeState( sal_Bool _bForceRetrieval
);
495 void initTemplDirs( ::std::vector
< String
>& _rRootDirs
);
496 sal_Bool
openCacheStream( sal_Bool _bForRead
);
497 void closeCacheStream( );
499 /// read the state of the dirs from the cache file
500 sal_Bool
readPreviousState();
501 /// read the current state of the dirs
502 sal_Bool
readCurrentState();
504 String
implParseSmart( const String
& _rPath
);
506 sal_Bool
implReadFolder( const ::vos::ORef
< TemplateContent
>& _rxRoot
);
508 static String
getCacheFileName();
509 static sal_Int32
getMagicNumber();
510 static void normalize( TemplateFolderContent
& _rState
);
512 // @return <TRUE/> if the states equal
513 static sal_Bool
equalStates( const TemplateFolderContent
& _rLHS
, const TemplateFolderContent
& _rRHS
);
515 // late initialize m_xOfficeInstDirs
516 uno::Reference
< util::XOfficeInstallationDirectories
> getOfficeInstDirs();
519 //---------------------------------------------------------------------
520 TemplateFolderCacheImpl::TemplateFolderCacheImpl( sal_Bool _bAutoStoreState
)
521 :m_pCacheStream ( NULL
)
522 ,m_bNeedsUpdate ( sal_True
)
523 ,m_bKnowState ( sal_False
)
524 ,m_bValidCurrentState ( sal_False
)
525 ,m_bAutoStoreState ( _bAutoStoreState
)
529 //---------------------------------------------------------------------
530 TemplateFolderCacheImpl::~TemplateFolderCacheImpl( )
532 // store the current state if possible and required
533 if ( m_bValidCurrentState
&& m_bAutoStoreState
)
534 storeState( sal_False
);
539 //---------------------------------------------------------------------
540 sal_Int32
TemplateFolderCacheImpl::getMagicNumber()
542 sal_Int32 nMagic
= 0;
543 ( nMagic
+= (sal_Int8
)'T' ) <<= 4;
544 ( nMagic
+= (sal_Int8
)'D' ) <<= 4;
545 ( nMagic
+= (sal_Int8
)'S' ) <<= 4;
546 ( nMagic
+= (sal_Int8
)'C' ) <<= 0;
550 //---------------------------------------------------------------------
551 String
TemplateFolderCacheImpl::getCacheFileName()
553 return String::CreateFromAscii( ".templdir.cache" );
557 //---------------------------------------------------------------------
558 void TemplateFolderCacheImpl::normalize( TemplateFolderContent
& _rState
)
560 SubContentSort()( _rState
);
563 //---------------------------------------------------------------------
564 sal_Bool
TemplateFolderCacheImpl::equalStates( const TemplateFolderContent
& _rLHS
, const TemplateFolderContent
& _rRHS
)
566 if ( _rLHS
.size() != _rRHS
.size() )
569 // as both arrays are sorted (by definition - this is a precondition of this method)
570 // we can simply go from the front to the back and compare the single elements
572 ::std::pair
< ConstFolderIterator
, ConstFolderIterator
> aFirstDifferent
= ::std::mismatch(
576 TemplateContentEqual()
579 return aFirstDifferent
.first
== _rLHS
.end();
582 //---------------------------------------------------------------------
583 void TemplateFolderCacheImpl::storeState( sal_Bool _bForceRetrieval
)
585 if ( !m_bValidCurrentState
|| _bForceRetrieval
)
588 if ( m_bValidCurrentState
&& openCacheStream( sal_False
) )
590 *m_pCacheStream
<< getMagicNumber();
592 // store the template root folders
594 *m_pCacheStream
<< (sal_Int32
)m_aCurrentState
.size();
597 m_aCurrentState
.begin(),
598 m_aCurrentState
.end(),
599 StoreContentURL( *m_pCacheStream
, getOfficeInstDirs() )
604 m_aCurrentState
.begin(),
605 m_aCurrentState
.end(),
606 StoreFolderContent( *m_pCacheStream
, getOfficeInstDirs() )
611 //---------------------------------------------------------------------
612 String
TemplateFolderCacheImpl::implParseSmart( const String
& _rPath
)
614 INetURLObject aParser
;
615 aParser
.SetSmartProtocol( INET_PROT_FILE
);
616 aParser
.SetURL( _rPath
, INetURLObject::WAS_ENCODED
);
617 if ( INET_PROT_NOT_VALID
== aParser
.GetProtocol() )
620 LocalFileHelper::ConvertPhysicalNameToURL( _rPath
, sURL
);
621 aParser
.SetURL( sURL
, INetURLObject::WAS_ENCODED
);
623 return aParser
.GetMainURL( INetURLObject::DECODE_TO_IURI
);
626 //---------------------------------------------------------------------
627 void TemplateFolderCacheImpl::closeCacheStream( )
629 DELETEZ( m_pCacheStream
);
632 //---------------------------------------------------------------------
633 sal_Bool
TemplateFolderCacheImpl::implReadFolder( const ::vos::ORef
< TemplateContent
>& _rxRoot
)
637 // create a content for the current folder root
638 Reference
< XResultSet
> xResultSet
;
639 Sequence
< ::rtl::OUString
> aContentProperties( 4);
640 aContentProperties
[0] = ::rtl::OUString::createFromAscii( "Title" );
641 aContentProperties
[1] = ::rtl::OUString::createFromAscii( "DateModified" );
642 aContentProperties
[2] = ::rtl::OUString::createFromAscii( "DateCreated" );
643 aContentProperties
[3] = ::rtl::OUString::createFromAscii( "IsFolder" );
645 // get the set of sub contents in the folder
648 Reference
< XDynamicResultSet
> xDynResultSet
;
650 ::ucbhelper::Content
aTemplateRoot( _rxRoot
->getURL(), Reference
< XCommandEnvironment
>() );
651 xDynResultSet
= aTemplateRoot
.createDynamicCursor( aContentProperties
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
652 if ( xDynResultSet
.is() )
653 xResultSet
= xDynResultSet
->getStaticResultSet();
655 catch( CommandAbortedException
& )
657 DBG_ERRORFILE( "TemplateFolderCacheImpl::implReadFolder: caught a CommandAbortedException!" );
660 catch( ::com::sun::star::uno::Exception
& )
664 // collect the infos about the sub contents
665 if ( xResultSet
.is() )
667 Reference
< XRow
> xRow( xResultSet
, UNO_QUERY_THROW
);
668 Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY_THROW
);
670 while ( xResultSet
->next() )
672 INetURLObject
aSubContentURL( xContentAccess
->queryContentIdentifierString() );
674 // a new content instance
675 ::vos::ORef
< TemplateContent
> xChild
= new TemplateContent( aSubContentURL
);
678 xChild
->setModDate( xRow
->getTimestamp( 2 ) ); // date modified
679 if ( xRow
->wasNull() )
680 xChild
->setModDate( xRow
->getTimestamp( 3 ) ); // fallback: date created
682 // push back this content
683 _rxRoot
->push_back( xChild
);
686 if ( xRow
->getBoolean( 4 ) && !xRow
->wasNull() )
687 { // yes -> step down
688 ConstFolderIterator aNextLevelRoot
= _rxRoot
->end();
690 implReadFolder( *aNextLevelRoot
);
695 catch( const Exception
& )
697 DBG_ERROR( "TemplateFolderCacheImpl::implReadFolder: caught an exception!" );
703 //---------------------------------------------------------------------
704 sal_Bool
TemplateFolderCacheImpl::readCurrentState()
707 m_bValidCurrentState
= sal_False
;
708 TemplateFolderContent aTemplateFolderContent
;
709 m_aCurrentState
.swap( aTemplateFolderContent
);
711 // the template directories from the config
712 String aDirs
= SvtPathOptions().GetTemplatePath();
713 sal_uInt16 nDirs
= aDirs
.GetTokenCount( ';' );
715 m_aCurrentState
.reserve( nDirs
);
716 // loop through all the root-level template folders
717 for ( sal_uInt16 i
=0; i
<nDirs
; ++i
)
719 // create a new entry
720 m_aCurrentState
.push_back( new TemplateContent( INetURLObject( aDirs
.GetToken( i
, ';' ) ) ) );
721 TemplateFolderContent::iterator aCurrentRoot
= m_aCurrentState
.end();
724 if ( !implReadFolder( *aCurrentRoot
) )
728 // normalize the array (which basically means "sort it")
729 normalize( m_aCurrentState
);
731 m_bValidCurrentState
= sal_True
;
732 return m_bValidCurrentState
;
735 //---------------------------------------------------------------------
736 sal_Bool
TemplateFolderCacheImpl::readPreviousState()
738 DBG_ASSERT( m_pCacheStream
, "TemplateFolderCacheImpl::readPreviousState: not to be called without stream!" );
741 TemplateFolderContent aTemplateFolderContent
;
742 m_aPreviousState
.swap( aTemplateFolderContent
);
744 // check the magic number
745 sal_Int32 nMagic
= 0;
746 *m_pCacheStream
>> nMagic
;
747 DBG_ASSERT( getMagicNumber() == nMagic
, "TemplateFolderCacheImpl::readPreviousState: invalid cache file!" );
748 if ( getMagicNumber() != nMagic
)
751 // the root directories
753 sal_Int32 nRootDirectories
= 0;
754 *m_pCacheStream
>> nRootDirectories
;
755 // init empty TemplateContens with the URLs
756 m_aPreviousState
.reserve( nRootDirectories
);
757 while ( nRootDirectories
-- )
760 m_pCacheStream
->ReadByteString( sURL
);
761 // #116281# Keep office installtion relocatable. Never store
762 // any direct references to office installation directory.
763 sURL
= getOfficeInstDirs()->makeAbsoluteURL( sURL
);
764 m_aPreviousState
.push_back(
765 new TemplateContent( INetURLObject(sURL
) ) );
768 // read the contents of the root folders
770 m_aPreviousState
.begin(),
771 m_aPreviousState
.end(),
772 ReadFolderContent( *m_pCacheStream
, getOfficeInstDirs() )
775 DBG_ASSERT( !m_pCacheStream
->GetErrorCode(), "TemplateFolderCacheImpl::readPreviousState: unknown error during reading the state cache!" );
777 // normalize the array (which basically means "sort it")
778 normalize( m_aPreviousState
);
783 //---------------------------------------------------------------------
784 sal_Bool
TemplateFolderCacheImpl::openCacheStream( sal_Bool _bForRead
)
786 // close any old stream instance
789 // get the storage directory
790 String sStorageURL
= implParseSmart( SvtPathOptions().GetStoragePath() );
791 INetURLObject
aStorageURL( sStorageURL
);
792 if ( INET_PROT_NOT_VALID
== aStorageURL
.GetProtocol() )
794 DBG_ERROR( "TemplateFolderCacheImpl::openCacheStream: invalid storage path!" );
799 aStorageURL
.Append( getCacheFileName() );
802 m_pCacheStream
= UcbStreamHelper::CreateStream( aStorageURL
.GetMainURL( INetURLObject::DECODE_TO_IURI
),
803 _bForRead
? STREAM_READ
| STREAM_NOCREATE
: STREAM_WRITE
| STREAM_TRUNC
);
804 DBG_ASSERT( m_pCacheStream
, "TemplateFolderCacheImpl::openCacheStream: could not open/create the cache stream!" );
805 if ( m_pCacheStream
&& m_pCacheStream
->GetErrorCode() )
807 DELETEZ( m_pCacheStream
);
810 if ( m_pCacheStream
)
811 m_pCacheStream
->SetStreamCharSet( RTL_TEXTENCODING_UTF8
);
813 return NULL
!= m_pCacheStream
;
816 //---------------------------------------------------------------------
817 sal_Bool
TemplateFolderCacheImpl::needsUpdate( sal_Bool _bForceCheck
)
819 if ( m_bKnowState
&& !_bForceCheck
)
820 return m_bNeedsUpdate
;
822 m_bNeedsUpdate
= sal_True
;
823 m_bKnowState
= sal_True
;
825 if ( readCurrentState() )
827 // open the stream which contains the cached state of the directories
828 if ( openCacheStream( sal_True
) )
829 { // opening the stream succeeded
830 if ( readPreviousState() )
832 m_bNeedsUpdate
= !equalStates( m_aPreviousState
, m_aCurrentState
);
840 return m_bNeedsUpdate
;
843 //---------------------------------------------------------------------
844 void TemplateFolderCacheImpl::initTemplDirs( ::std::vector
< String
>& )
848 //---------------------------------------------------------------------
849 uno::Reference
< util::XOfficeInstallationDirectories
>
850 TemplateFolderCacheImpl::getOfficeInstDirs()
852 if ( !m_xOfficeInstDirs
.is() )
854 osl::MutexGuard
aGuard( m_aMutex
);
855 if ( !m_xOfficeInstDirs
.is() )
858 uno::Reference
< lang::XMultiServiceFactory
> xSMgr
859 = comphelper::getProcessServiceFactory();
860 OSL_ENSURE( xSMgr
.is(), "No service manager!" );
862 uno::Reference
< beans::XPropertySet
> xPropSet(
863 xSMgr
, uno::UNO_QUERY
);
866 uno::Reference
< uno::XComponentContext
> xCtx
;
867 xPropSet
->getPropertyValue(
869 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
872 OSL_ENSURE( xCtx
.is(),
873 "Unable to obtain component context from service manager!" );
877 xCtx
->getValueByName(
878 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
879 "/singletons/com.sun.star.util.theOfficeInstallationDirectories" ) ) )
880 >>= m_xOfficeInstDirs
;
883 OSL_ENSURE( m_xOfficeInstDirs
.is(),
884 "Unable to obtain office directories singleton!" );
889 return m_xOfficeInstDirs
;
892 //=====================================================================
893 //= TemplateFolderCache
894 //=====================================================================
895 //---------------------------------------------------------------------
896 TemplateFolderCache::TemplateFolderCache( sal_Bool _bAutoStoreState
)
897 :m_pImpl( new TemplateFolderCacheImpl( _bAutoStoreState
) )
901 //---------------------------------------------------------------------
902 TemplateFolderCache::~TemplateFolderCache( )
907 //---------------------------------------------------------------------
908 sal_Bool
TemplateFolderCache::needsUpdate( sal_Bool _bForceCheck
)
910 return m_pImpl
->needsUpdate( _bForceCheck
);
913 //---------------------------------------------------------------------
914 void TemplateFolderCache::storeState( sal_Bool _bForceRetrieval
)
916 m_pImpl
->storeState( _bForceRetrieval
);
919 //.........................................................................
921 //.........................................................................