1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 #include <com/sun/star/container/XNameContainer.hpp>
27 #include <com/sun/star/container/XContainer.hpp>
28 #include <com/sun/star/embed/ElementModes.hpp>
29 #include <com/sun/star/embed/XTransactedObject.hpp>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <vcl/svapp.hxx>
32 #include <vos/mutex.hxx>
33 #include <tools/errinf.hxx>
34 #include <osl/mutex.hxx>
35 #include <vos/diagnose.hxx>
36 #include <rtl/uri.hxx>
37 #include <rtl/strbuf.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/anytostring.hxx>
40
41 #include "namecont.hxx"
42 #include <basic/basicmanagerrepository.hxx>
43 #include <tools/diagnose_ex.h>
44 #include <tools/urlobj.hxx>
45 #include <unotools/streamwrap.hxx>
46 #include <unotools/pathoptions.hxx>
47 #include <svtools/sfxecode.hxx>
48 #include <svtools/ehdl.hxx>
49 #include <basic/basmgr.hxx>
50 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
51 #include <com/sun/star/xml/sax/XParser.hpp>
52 #include <com/sun/star/xml/sax/InputSource.hpp>
53 #include <com/sun/star/io/XOutputStream.hpp>
54 #include <com/sun/star/io/XInputStream.hpp>
55 #include <com/sun/star/io/XActiveDataSource.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
57 #include <com/sun/star/uno/DeploymentException.hpp>
58 #include <com/sun/star/lang/DisposedException.hpp>
59 #include <com/sun/star/script/LibraryNotLoadedException.hpp>
60 #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
61 #include <com/sun/star/deployment/ExtensionManager.hpp>
62 #include <comphelper/storagehelper.hxx>
63 #include <cppuhelper/exc_hlp.hxx>
64 #include <basic/sbmod.hxx>
65
66 namespace basic
67 {
68
69 using namespace com::sun::star::document;
70 using namespace com::sun::star::container;
71 using namespace com::sun::star::uno;
72 using namespace com::sun::star::lang;
73 using namespace com::sun::star::io;
74 using namespace com::sun::star::ucb;
75 using namespace com::sun::star::script;
76 using namespace com::sun::star::beans;
77 using namespace com::sun::star::xml::sax;
78 using namespace com::sun::star::util;
79 using namespace com::sun::star::task;
80 using namespace com::sun::star::embed;
81 using namespace com::sun::star::frame;
82 using namespace com::sun::star::deployment;
83 using namespace com::sun::star;
84 using namespace cppu;
85 using namespace rtl;
86 using namespace osl;
87
88 using com::sun::star::uno::Reference;
89
90 // #i34411: Flag for error handling during migration
91 static bool GbMigrationSuppressErrors = false;
92
93 //============================================================================
94 // Implementation class NameContainer
95
96 // Methods XElementAccess
getElementType()97 Type NameContainer::getElementType()
98 {
99 return mType;
100 }
101
hasElements()102 sal_Bool NameContainer::hasElements()
103 {
104 sal_Bool bRet = (mnElementCount > 0);
105 return bRet;
106 }
107
108 // Methods XNameAccess
getByName(const OUString & aName)109 Any NameContainer::getByName( const OUString& aName )
110 {
111 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
112 if( aIt == mHashMap.end() )
113 {
114 throw NoSuchElementException();
115 }
116 sal_Int32 iHashResult = (*aIt).second;
117 Any aRetAny = mValues.getConstArray()[ iHashResult ];
118 return aRetAny;
119 }
120
getElementNames()121 Sequence< OUString > NameContainer::getElementNames()
122 {
123 return mNames;
124 }
125
hasByName(const OUString & aName)126 sal_Bool NameContainer::hasByName( const OUString& aName )
127 {
128 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
129 sal_Bool bRet = ( aIt != mHashMap.end() );
130 return bRet;
131 }
132
133
134 // Methods XNameReplace
replaceByName(const OUString & aName,const Any & aElement)135 void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
136 {
137 Type aAnyType = aElement.getValueType();
138 if( mType != aAnyType )
139 throw IllegalArgumentException();
140
141 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
142 if( aIt == mHashMap.end() )
143 {
144 throw NoSuchElementException();
145 }
146 sal_Int32 iHashResult = (*aIt).second;
147 Any aOldElement = mValues.getConstArray()[ iHashResult ];
148 mValues.getArray()[ iHashResult ] = aElement;
149
150
151 // Fire event
152 if( maContainerListeners.getLength() > 0 )
153 {
154 ContainerEvent aEvent;
155 aEvent.Source = mpxEventSource;
156 aEvent.Accessor <<= aName;
157 aEvent.Element = aElement;
158 aEvent.ReplacedElement = aOldElement;
159 maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent );
160 }
161
162 /* After the container event has been fired (one listener will update the
163 core Basic manager), fire change event. Listeners can rely that the
164 Basic source code of the core Basic manager is up-to-date. */
165 if( maChangesListeners.getLength() > 0 )
166 {
167 ChangesEvent aEvent;
168 aEvent.Source = mpxEventSource;
169 aEvent.Base <<= aEvent.Source;
170 aEvent.Changes.realloc( 1 );
171 aEvent.Changes[ 0 ].Accessor <<= aName;
172 aEvent.Changes[ 0 ].Element <<= aElement;
173 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
174 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
175 }
176 }
177
178
179 // Methods XNameContainer
insertByName(const OUString & aName,const Any & aElement)180 void NameContainer::insertByName( const OUString& aName, const Any& aElement )
181 {
182 Type aAnyType = aElement.getValueType();
183 if( mType != aAnyType )
184 throw IllegalArgumentException();
185
186 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
187 if( aIt != mHashMap.end() )
188 {
189 throw ElementExistException();
190 }
191
192 sal_Int32 nCount = mNames.getLength();
193 mNames.realloc( nCount + 1 );
194 mValues.realloc( nCount + 1 );
195 mNames.getArray()[ nCount ] = aName;
196 mValues.getArray()[ nCount ] = aElement;
197
198 mHashMap[ aName ] = nCount;
199 mnElementCount++;
200
201 // Fire event
202 if( maContainerListeners.getLength() > 0 )
203 {
204 ContainerEvent aEvent;
205 aEvent.Source = mpxEventSource;
206 aEvent.Accessor <<= aName;
207 aEvent.Element = aElement;
208 maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
209 }
210
211 /* After the container event has been fired (one listener will update the
212 core Basic manager), fire change event. Listeners can rely that the
213 Basic source code of the core Basic manager is up-to-date. */
214 if( maChangesListeners.getLength() > 0 )
215 {
216 ChangesEvent aEvent;
217 aEvent.Source = mpxEventSource;
218 aEvent.Base <<= aEvent.Source;
219 aEvent.Changes.realloc( 1 );
220 aEvent.Changes[ 0 ].Accessor <<= aName;
221 aEvent.Changes[ 0 ].Element <<= aElement;
222 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
223 }
224 }
225
removeByName(const OUString & aName)226 void NameContainer::removeByName( const OUString& aName )
227 {
228 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
229 if( aIt == mHashMap.end() )
230 {
231 throw NoSuchElementException();
232 }
233
234 sal_Int32 iHashResult = (*aIt).second;
235 Any aOldElement = mValues.getConstArray()[ iHashResult ];
236 mHashMap.erase( aIt );
237 sal_Int32 iLast = mNames.getLength() - 1;
238 if( iLast != iHashResult )
239 {
240 OUString* pNames = mNames.getArray();
241 Any* pValues = mValues.getArray();
242 pNames[ iHashResult ] = pNames[ iLast ];
243 pValues[ iHashResult ] = pValues[ iLast ];
244 mHashMap[ pNames[ iHashResult ] ] = iHashResult;
245 }
246 mNames.realloc( iLast );
247 mValues.realloc( iLast );
248 mnElementCount--;
249
250 // Fire event
251 if( maContainerListeners.getLength() > 0 )
252 {
253 ContainerEvent aEvent;
254 aEvent.Source = mpxEventSource;
255 aEvent.Accessor <<= aName;
256 aEvent.Element = aOldElement;
257 maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
258 }
259
260 /* After the container event has been fired (one listener will update the
261 core Basic manager), fire change event. Listeners can rely that the
262 Basic source code of the core Basic manager is up-to-date. */
263 if( maChangesListeners.getLength() > 0 )
264 {
265 ChangesEvent aEvent;
266 aEvent.Source = mpxEventSource;
267 aEvent.Base <<= aEvent.Source;
268 aEvent.Changes.realloc( 1 );
269 aEvent.Changes[ 0 ].Accessor <<= aName;
270 // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
271 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
272 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
273 }
274 }
275
276
277 // Methods XContainer
addContainerListener(const Reference<XContainerListener> & xListener)278 void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
279 {
280 if( !xListener.is() )
281 throw RuntimeException();
282 Reference< XInterface > xIface( xListener, UNO_QUERY );
283 maContainerListeners.addInterface( xIface );
284 }
285
removeContainerListener(const Reference<XContainerListener> & xListener)286 void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
287 {
288 if( !xListener.is() )
289 throw RuntimeException();
290 Reference< XInterface > xIface( xListener, UNO_QUERY );
291 maContainerListeners.removeInterface( xIface );
292 }
293
294 // Methods XChangesNotifier
addChangesListener(const Reference<XChangesListener> & xListener)295 void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener )
296 {
297 if( !xListener.is() )
298 throw RuntimeException();
299 Reference< XInterface > xIface( xListener, UNO_QUERY );
300 maChangesListeners.addInterface( xIface );
301 }
302
removeChangesListener(const Reference<XChangesListener> & xListener)303 void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener )
304 {
305 if( !xListener.is() )
306 throw RuntimeException();
307 Reference< XInterface > xIface( xListener, UNO_QUERY );
308 maChangesListeners.removeInterface( xIface );
309 }
310
311 //============================================================================
312 // ModifiableHelper
313
setModified(sal_Bool _bModified)314 void ModifiableHelper::setModified( sal_Bool _bModified )
315 {
316 if ( _bModified == mbModified )
317 return;
318 mbModified = _bModified;
319
320 if ( m_aModifyListeners.getLength() == 0 )
321 return;
322
323 EventObject aModifyEvent( m_rEventSource );
324 m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
325 }
326
327 //============================================================================
328
VBAScriptListenerContainer(::osl::Mutex & rMutex)329 VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex& rMutex ) :
330 VBAScriptListenerContainer_BASE( rMutex )
331 {
332 }
333
implTypedNotify(const Reference<vba::XVBAScriptListener> & rxListener,const vba::VBAScriptEvent & rEvent)334 bool VBAScriptListenerContainer::implTypedNotify( const Reference< vba::XVBAScriptListener >& rxListener, const vba::VBAScriptEvent& rEvent )
335 {
336 rxListener->notifyVBAScriptEvent( rEvent );
337 return true; // notify all other listeners too
338 }
339
340 //============================================================================
341
342 // Implementation class SfxLibraryContainer
DBG_NAME(SfxLibraryContainer)343 DBG_NAME( SfxLibraryContainer )
344
345 // Ctor
346 SfxLibraryContainer::SfxLibraryContainer( void )
347 : SfxLibraryContainer_BASE( maMutex )
348
349 , maVBAScriptListeners( maMutex )
350 , mnRunningVBAScripts( 0 )
351 , mbVBACompat( sal_False )
352 , maModifiable( *this, maMutex )
353 , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
354 , mbOldInfoFormat( sal_False )
355 , mbOasis2OOoFormat( sal_False )
356 , mpBasMgr( NULL )
357 , mbOwnBasMgr( sal_False )
358 {
359 DBG_CTOR( SfxLibraryContainer, NULL );
360
361 mxMSF = comphelper::getProcessServiceFactory();
362 if( !mxMSF.is() )
363 {
364 OSL_ENSURE( 0, "### couldn't get ProcessServiceFactory\n" );
365 }
366
367 mxSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
368 ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
369 if( !mxSFI.is() )
370 {
371 OSL_ENSURE( 0, "### couldn't create SimpleFileAccess component\n" );
372 }
373
374 mxStringSubstitution = Reference< XStringSubstitution >( mxMSF->createInstance
375 ( OUString::createFromAscii( "com.sun.star.util.PathSubstitution" ) ), UNO_QUERY );
376 if( !mxStringSubstitution.is() )
377 {
378 OSL_ENSURE( 0, "### couldn't create PathSubstitution component\n" );
379 }
380 }
381
~SfxLibraryContainer()382 SfxLibraryContainer::~SfxLibraryContainer()
383 {
384 if( mbOwnBasMgr )
385 BasicManager::LegacyDeleteBasicManager( mpBasMgr );
386 DBG_DTOR( SfxLibraryContainer, NULL );
387 }
388
checkDisposed() const389 void SfxLibraryContainer::checkDisposed() const
390 {
391 if ( isDisposed() )
392 throw DisposedException( ::rtl::OUString(), *const_cast< SfxLibraryContainer* >( this ) );
393 }
394
enterMethod()395 void SfxLibraryContainer::enterMethod()
396 {
397 maMutex.acquire();
398 checkDisposed();
399 }
400
leaveMethod()401 void SfxLibraryContainer::leaveMethod()
402 {
403 maMutex.release();
404 }
405
getBasicManager(void)406 BasicManager* SfxLibraryContainer::getBasicManager( void )
407 {
408 if ( mpBasMgr )
409 return mpBasMgr;
410
411 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
412 OSL_ENSURE( xDocument.is(), "SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager without document!" );
413 if ( xDocument.is() )
414 mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );
415
416 return mpBasMgr;
417 }
418
419 // Methods XStorageBasedLibraryContainer
getRootStorage()420 Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage()
421 {
422 LibraryContainerMethodGuard aGuard( *this );
423 return mxStorage;
424 }
425
setRootStorage(const Reference<XStorage> & _rxRootStorage)426 void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage )
427 {
428 LibraryContainerMethodGuard aGuard( *this );
429 if ( !_rxRootStorage.is() )
430 throw IllegalArgumentException();
431
432 mxStorage = _rxRootStorage;
433 onNewRootStorage();
434 }
435
storeLibrariesToStorage(const Reference<XStorage> & _rxRootStorage)436 void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage )
437 {
438 LibraryContainerMethodGuard aGuard( *this );
439 if ( !_rxRootStorage.is() )
440 throw IllegalArgumentException();
441
442 try
443 {
444 storeLibraries_Impl( _rxRootStorage, sal_True );
445 }
446 catch( const Exception& )
447 {
448 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
449 }
450 }
451
452
453 // Methods XModifiable
isModified()454 sal_Bool SfxLibraryContainer::isModified()
455 {
456 LibraryContainerMethodGuard aGuard( *this );
457 if ( maModifiable.isModified() )
458 return sal_True;
459
460 // the library container is not modified, go through the libraries and check whether they are modified
461 Sequence< OUString > aNames = maNameContainer.getElementNames();
462 const OUString* pNames = aNames.getConstArray();
463 sal_Int32 nNameCount = aNames.getLength();
464
465 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
466 {
467 OUString aName = pNames[ i ];
468 SfxLibrary* pImplLib = getImplLib( aName );
469 if( pImplLib->isModified() )
470 {
471 if ( aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ) ) )
472 {
473 // this is a workaround that has to be implemented because
474 // empty standard library should stay marked as modified
475 // but should not be treated as modified while it is empty
476 if ( pImplLib->hasElements() )
477 return sal_True;
478 }
479 else
480 return sal_True;
481 }
482 }
483
484 return sal_False;
485 }
486
setModified(sal_Bool _bModified)487 void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified )
488 {
489 LibraryContainerMethodGuard aGuard( *this );
490 maModifiable.setModified( _bModified );
491 }
492
addModifyListener(const Reference<XModifyListener> & _rxListener)493 void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener )
494 {
495 LibraryContainerMethodGuard aGuard( *this );
496 maModifiable.addModifyListener( _rxListener );
497 }
498
removeModifyListener(const Reference<XModifyListener> & _rxListener)499 void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener )
500 {
501 LibraryContainerMethodGuard aGuard( *this );
502 maModifiable.removeModifyListener( _rxListener );
503 }
504
505 // Methods XPersistentLibraryContainer
getRootLocation()506 Any SAL_CALL SfxLibraryContainer::getRootLocation()
507 {
508 LibraryContainerMethodGuard aGuard( *this );
509 return makeAny( getRootStorage() );
510 }
511
getContainerLocationName()512 ::rtl::OUString SAL_CALL SfxLibraryContainer::getContainerLocationName()
513 {
514 LibraryContainerMethodGuard aGuard( *this );
515 return maLibrariesDir;
516 }
517
storeLibraries()518 void SAL_CALL SfxLibraryContainer::storeLibraries( )
519 {
520 LibraryContainerMethodGuard aGuard( *this );
521 try
522 {
523 storeLibraries_Impl( mxStorage, mxStorage.is() );
524 // we need to store *all* libraries if and only if we are based on a storage:
525 // in this case, storeLibraries_Impl will remove the source storage, after loading
526 // all libraries, so we need to force them to be stored, again
527 }
528 catch( const Exception& )
529 {
530 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
531 }
532 }
533
checkAndCopyFileImpl(const INetURLObject & rSourceFolderInetObj,const INetURLObject & rTargetFolderInetObj,const OUString & rCheckFileName,const OUString & rCheckExtension,Reference<XSimpleFileAccess> xSFI)534 static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
535 const INetURLObject& rTargetFolderInetObj,
536 const OUString& rCheckFileName,
537 const OUString& rCheckExtension,
538 Reference< XSimpleFileAccess > xSFI )
539 {
540 INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
541 aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
542 sal_True, INetURLObject::ENCODE_ALL );
543 aTargetFolderInetObj.setExtension( rCheckExtension );
544 OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
545 if( !xSFI->exists( aTargetFile ) )
546 {
547 INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
548 aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
549 sal_True, INetURLObject::ENCODE_ALL );
550 aSourceFolderInetObj.setExtension( rCheckExtension );
551 OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
552 xSFI->copy( aSourceFile, aTargetFile );
553 }
554 }
555
createVariableURL(OUString & rStr,const OUString & rLibName,const OUString & rInfoFileName,bool bUser)556 static void createVariableURL( OUString& rStr, const OUString& rLibName,
557 const OUString& rInfoFileName, bool bUser )
558 {
559 if( bUser )
560 rStr = OUString::createFromAscii( "$(USER)/basic/" );
561 else
562 rStr = OUString::createFromAscii( "$(INST)/share/basic/" );
563
564 rStr += rLibName;
565 rStr += OUString::createFromAscii( "/" );
566 rStr += rInfoFileName;
567 rStr += OUString::createFromAscii( ".xlb/" );
568 }
569
init(const OUString & rInitialDocumentURL,const uno::Reference<embed::XStorage> & rxInitialStorage)570 sal_Bool SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
571 {
572 // this might be called from within the ctor, and the impl_init might (indirectly) create
573 // an UNO reference to ourself.
574 // Ensure that we're not destroyed while we're in here
575 osl_incrementInterlockedCount( &m_refCount );
576 sal_Bool bSuccess = init_Impl( rInitialDocumentURL, rxInitialStorage );
577 osl_decrementInterlockedCount( &m_refCount );
578
579 return bSuccess;
580 }
581
init_Impl(const OUString & rInitialDocumentURL,const uno::Reference<embed::XStorage> & rxInitialStorage)582 sal_Bool SfxLibraryContainer::init_Impl(
583 const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
584 {
585 uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
586
587 maInitialDocumentURL = rInitialDocumentURL;
588 maInfoFileName = OUString::createFromAscii( getInfoFileName() );
589 maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
590 maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
591 maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );
592
593 meInitMode = DEFAULT;
594 INetURLObject aInitUrlInetObj( maInitialDocumentURL );
595 OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
596 if( !aInitFileName.isEmpty() )
597 {
598 // We need a BasicManager to avoid problems
599 StarBASIC* pBas = new StarBASIC();
600 mpBasMgr = new BasicManager( pBas );
601 mbOwnBasMgr = sal_True;
602
603 OUString aExtension = aInitUrlInetObj.getExtension();
604 if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
605 {
606 meInitMode = CONTAINER_INIT_FILE;
607 INetURLObject aLibPathInetObj( aInitUrlInetObj );
608 aLibPathInetObj.removeSegment();
609 maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
610 }
611 else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
612 {
613 meInitMode = LIBRARY_INIT_FILE;
614 uno::Reference< embed::XStorage > xDummyStor;
615 ::xmlscript::LibDescriptor aLibDesc;
616 sal_Bool bReadIndexFile = implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
617 return bReadIndexFile;
618 }
619 else
620 {
621 // Decide between old and new document
622 sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
623 if ( bOldStorage )
624 {
625 meInitMode = OLD_BASIC_STORAGE;
626 importFromOldStorage( aInitFileName );
627 return sal_True;
628 }
629 else
630 {
631 meInitMode = OFFICE_DOCUMENT;
632 try
633 {
634 xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
635 }
636 catch ( uno::Exception& )
637 {
638 // TODO: error handling
639 }
640 }
641 }
642 }
643 else
644 {
645 // Default paths
646 maLibraryPath = SvtPathOptions().GetBasicPath();
647 }
648
649 Reference< XParser > xParser( mxMSF->createInstance(
650 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
651 if( !xParser.is() )
652 {
653 OSL_ENSURE( 0, "### couldn't create sax parser component\n" );
654 return sal_False;
655 }
656
657 uno::Reference< io::XInputStream > xInput;
658
659 mxStorage = xStorage;
660 sal_Bool bStorage = mxStorage.is();
661
662
663 // #110009: Scope to force the StorageRefs to be destructed and
664 // so the streams to be closed before the preload operation
665 {
666 // #110009
667
668 uno::Reference< embed::XStorage > xLibrariesStor;
669 String aFileName;
670
671 int nPassCount = 1;
672 if( !bStorage && meInitMode == DEFAULT )
673 nPassCount = 2;
674 for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
675 {
676 if( bStorage )
677 {
678 OSL_ENSURE( meInitMode == DEFAULT || meInitMode == OFFICE_DOCUMENT,
679 "### Wrong InitMode for document\n" );
680 try
681 {
682 uno::Reference< io::XStream > xStream;
683 xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
684 //if ( !xLibrariesStor.is() )
685 // TODO: the method must either return a storage or throw an exception
686 //throw uno::RuntimeException();
687
688 if ( xLibrariesStor.is() )
689 {
690 aFileName = maInfoFileName;
691 aFileName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
692
693 try
694 {
695 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
696 }
697 catch( uno::Exception& )
698 {}
699
700 if( !xStream.is() )
701 {
702 mbOldInfoFormat = true;
703
704 // Check old version
705 aFileName = maOldInfoFileName;
706 aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
707
708 try
709 {
710 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
711 }
712 catch( uno::Exception& )
713 {}
714
715 if( !xStream.is() )
716 {
717 // Check for EA2 document version with wrong extensions
718 aFileName = maOldInfoFileName;
719 aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xli") );
720 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
721 }
722 }
723 }
724
725 if ( xStream.is() )
726 xInput = xStream->getInputStream();
727 }
728 catch( uno::Exception& )
729 {
730 // TODO: error handling?
731 }
732 }
733 else
734 {
735 INetURLObject* pLibInfoInetObj = NULL;
736 if( meInitMode == CONTAINER_INIT_FILE )
737 {
738 aFileName = aInitFileName;
739 }
740 else
741 {
742 if( nPass == 1 )
743 pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(0) );
744 else
745 pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(1) );
746 pLibInfoInetObj->insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
747 pLibInfoInetObj->setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
748 aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
749 }
750
751 try
752 {
753 xInput = mxSFI->openFileRead( aFileName );
754 }
755 catch( Exception& )
756 {
757 xInput.clear();
758 if( nPass == 0 )
759 {
760 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
761 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
762 ErrorHandler::HandleError( nErrorCode );
763 }
764 }
765
766 // Old variant?
767 if( !xInput.is() && nPass == 0 )
768 {
769 INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
770 aLibInfoInetObj.insertName( maOldInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
771 aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xli") ) );
772 aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
773
774 try
775 {
776 xInput = mxSFI->openFileRead( aFileName );
777 mbOldInfoFormat = true;
778 }
779 catch( Exception& )
780 {
781 xInput.clear();
782 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
783 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
784 ErrorHandler::HandleError( nErrorCode );
785 }
786 }
787
788 delete pLibInfoInetObj;
789 }
790
791 if( xInput.is() )
792 {
793 InputSource source;
794 source.aInputStream = xInput;
795 source.sSystemId = aFileName;
796
797 // start parsing
798 ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();
799
800 try
801 {
802 xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
803 xParser->parseStream( source );
804 }
805 catch ( xml::sax::SAXException& e )
806 {
807 (void) e; // avoid warning
808 OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
809 return sal_False;
810 }
811 catch ( io::IOException& e )
812 {
813 (void) e; // avoid warning
814 OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
815 return sal_False;
816 }
817
818 sal_Int32 nLibCount = pLibArray->mnLibCount;
819 for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
820 {
821 ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
822
823 // Check storage URL
824 OUString aStorageURL = rLib.aStorageURL;
825 if( !bStorage && aStorageURL.isEmpty() && nPass == 0 )
826 {
827 String aLibraryPath;
828 if( meInitMode == CONTAINER_INIT_FILE )
829 aLibraryPath = maLibraryPath;
830 else
831 aLibraryPath = String(maLibraryPath).GetToken(1);
832 INetURLObject aInetObj( aLibraryPath );
833
834 aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
835 sal_True, INetURLObject::ENCODE_ALL );
836 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
837 if( mxSFI->isFolder( aLibDirPath ) )
838 {
839 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
840 maModifiable.setModified( sal_True );
841 }
842 else if( rLib.bLink )
843 {
844 // Check "share" path
845 INetURLObject aShareInetObj( String(maLibraryPath).GetToken(0) );
846 aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
847 sal_True, INetURLObject::ENCODE_ALL );
848 OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
849 if( mxSFI->isFolder( aShareLibDirPath ) )
850 {
851 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
852 maModifiable.setModified( sal_True );
853 }
854 else
855 {
856 // #i25537: Ignore lib if library folder does not really exist
857 continue;
858 }
859 }
860 }
861
862 OUString aLibName = rLib.aName;
863
864 // If the same library name is used by the shared and the
865 // user lib container index files the user file wins
866 if( nPass == 1 && hasByName( aLibName ) )
867 continue;
868
869 SfxLibrary* pImplLib;
870 if( rLib.bLink )
871 {
872 Reference< XNameAccess > xLib =
873 createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
874 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
875 }
876 else
877 {
878 Reference< XNameContainer > xLib = createLibrary( aLibName );
879 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
880 pImplLib->mbLoaded = sal_False;
881 pImplLib->mbReadOnly = rLib.bReadOnly;
882 if( !bStorage )
883 checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
884 pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
885 }
886 maModifiable.setModified( sal_False );
887
888 // Read library info files
889 if( !mbOldInfoFormat )
890 {
891 uno::Reference< embed::XStorage > xLibraryStor;
892 if( !pImplLib->mbInitialised && bStorage )
893 {
894 try {
895 xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
896 embed::ElementModes::READ );
897 }
898 catch( uno::Exception& )
899 {
900 #if OSL_DEBUG_LEVEL > 0
901 Any aError( ::cppu::getCaughtException() );
902 ::rtl::OStringBuffer aMessage;
903 aMessage.append( "couldn't open sub storage for library '" );
904 aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
905 aMessage.append( "'.\n\nException:" );
906 aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
907 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
908 #endif
909 }
910 }
911
912 // Link is already initialised in createLibraryLink()
913 if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
914 {
915 OUString aIndexFileName;
916 sal_Bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
917 if( bLoaded && aLibName != rLib.aName )
918 {
919 OSL_ENSURE( 0, "Different library names in library"
920 " container and library info files!\n" );
921 }
922 if( GbMigrationSuppressErrors && !bLoaded )
923 removeLibrary( aLibName );
924 }
925 }
926 else if( !bStorage )
927 {
928 // Write new index file immediately because otherwise
929 // the library elements will be lost when storing into
930 // the new info format
931 uno::Reference< embed::XStorage > xTmpStorage;
932 implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
933 }
934
935 implImportLibDescriptor( pImplLib, rLib );
936
937 if( nPass == 1 )
938 {
939 pImplLib->mbSharedIndexFile = sal_True;
940 pImplLib->mbReadOnly = sal_True;
941 }
942 }
943
944 // Keep flag for documents to force writing the new index files
945 if( !bStorage )
946 mbOldInfoFormat = sal_False;
947
948 delete pLibArray;
949 }
950 // Only in the first pass it's an error when no index file is found
951 else if( nPass == 0 )
952 {
953 return sal_False;
954 }
955 }
956
957 // #110009: END Scope to force the StorageRefs to be destructed
958 }
959 // #110009
960
961 if( !bStorage && meInitMode == DEFAULT )
962 {
963 try
964 {
965 implScanExtensions();
966 }
967 catch( uno::Exception& )
968 {
969 // TODO: error handling?
970 OSL_ASSERT( "Cannot access extensions!" );
971 }
972 }
973
974 // #110009 Preload?
975 {
976 Sequence< OUString > aNames = maNameContainer.getElementNames();
977 const OUString* pNames = aNames.getConstArray();
978 sal_Int32 nNameCount = aNames.getLength();
979 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
980 {
981 OUString aName = pNames[ i ];
982 SfxLibrary* pImplLib = getImplLib( aName );
983 if( pImplLib->mbPreload )
984 loadLibrary( aName );
985 }
986 }
987
988 // #118803# upgrade installation 7.0 -> 8.0
989 if( meInitMode == DEFAULT )
990 {
991 INetURLObject aUserBasicInetObj( String(maLibraryPath).GetToken(1) );
992 OUString aStandardStr( RTL_CONSTASCII_USTRINGPARAM("Standard") );
993
994 static char strPrevFolderName_1[] = "__basic_80";
995 static char strPrevFolderName_2[] = "__basic_80_2";
996 INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
997 aPrevUserBasicInetObj_1.removeSegment();
998 INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
999 aPrevUserBasicInetObj_1.Append( strPrevFolderName_1 );
1000 aPrevUserBasicInetObj_2.Append( strPrevFolderName_2 );
1001
1002 // #i93163
1003 bool bCleanUp = false;
1004 try
1005 {
1006 INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
1007 String aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1008 bool bSecondTime = false;
1009 if( mxSFI->isFolder( aPrevFolder ) )
1010 {
1011 // #110101 Check if Standard folder exists and is complete
1012 INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
1013 aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1014 sal_True, INetURLObject::ENCODE_ALL );
1015 INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
1016 aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1017 sal_True, INetURLObject::ENCODE_ALL );
1018 OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1019 if( mxSFI->isFolder( aPrevStandardFolder ) )
1020 {
1021 OUString aXlbExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1022 OUString aCheckFileName;
1023
1024 // Check if script.xlb exists
1025 aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("script") );
1026 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1027 aPrevUserBasicStandardInetObj,
1028 aCheckFileName, aXlbExtension, mxSFI );
1029
1030 // Check if dialog.xlb exists
1031 aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("dialog") );
1032 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1033 aPrevUserBasicStandardInetObj,
1034 aCheckFileName, aXlbExtension, mxSFI );
1035
1036 // Check if module1.xba exists
1037 OUString aXbaExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xba") ) );
1038 aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("Module1") );
1039 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1040 aPrevUserBasicStandardInetObj,
1041 aCheckFileName, aXbaExtension, mxSFI );
1042 }
1043 else
1044 {
1045 String aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1046 mxSFI->copy( aStandardFolder, aPrevStandardFolder );
1047 }
1048
1049 String aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1050 mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
1051 }
1052 else
1053 {
1054 bSecondTime = true;
1055 aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
1056 aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1057 }
1058 if( mxSFI->isFolder( aPrevFolder ) )
1059 {
1060 SfxLibraryContainer* pPrevCont = createInstanceImpl();
1061 Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
1062
1063 // Rename previous basic folder to make storage URLs correct during initialisation
1064 String aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1065 INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
1066 aUserBasicTmpInetObj.removeSegment();
1067 aUserBasicTmpInetObj.Append( "__basic_tmp" );
1068 String aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
1069
1070 mxSFI->move( aFolderUserBasic, aFolderTmp );
1071 try
1072 {
1073 mxSFI->move( aPrevFolder, aFolderUserBasic );
1074 }
1075 catch( Exception& )
1076 {
1077 // Move back user/basic folder
1078 try
1079 {
1080 mxSFI->kill( aFolderUserBasic );
1081 }
1082 catch( Exception& )
1083 {}
1084 mxSFI->move( aFolderTmp, aFolderUserBasic );
1085 throw;
1086 }
1087
1088 INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
1089 aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT,
1090 sal_True, INetURLObject::ENCODE_ALL );
1091 aPrevUserBasicLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
1092 OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
1093 Sequence<Any> aInitSeq( 1 );
1094 aInitSeq.getArray()[0] <<= aLibInfoFileName;
1095 GbMigrationSuppressErrors = true;
1096 pPrevCont->initialize( aInitSeq );
1097 GbMigrationSuppressErrors = false;
1098
1099 // Rename folders back
1100 mxSFI->move( aFolderUserBasic, aPrevFolder );
1101 mxSFI->move( aFolderTmp, aFolderUserBasic );
1102
1103 OUString aUserSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
1104 OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
1105 OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
1106 OUString aInstSearchStr = OUString::createFromAscii( "$(INST)" );
1107
1108 Sequence< OUString > aNames = pPrevCont->getElementNames();
1109 const OUString* pNames = aNames.getConstArray();
1110 sal_Int32 nNameCount = aNames.getLength();
1111
1112 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1113 {
1114 OUString aLibName = pNames[ i ];
1115 if( hasByName( aLibName ) )
1116 {
1117 if( aLibName == aStandardStr )
1118 {
1119 SfxLibrary* pImplLib = getImplLib( aStandardStr );
1120 INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
1121 String aStandardFolder = pImplLib->maStorageURL;
1122 mxSFI->kill( aStandardFolder );
1123 }
1124 else
1125 {
1126 continue;
1127 }
1128 }
1129
1130 SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
1131 if( pImplLib->mbLink )
1132 {
1133 OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
1134 bool bCreateLink = true;
1135 if( aStorageURL.indexOf( aUserSearchStr ) != -1 ||
1136 aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
1137 aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
1138 aStorageURL.indexOf( aInstSearchStr ) != -1 )
1139 {
1140 bCreateLink = false;
1141 }
1142 if( bCreateLink )
1143 createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
1144 }
1145 else
1146 {
1147 // Move folder if not already done
1148 INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
1149 aUserBasicLibFolderInetObj.Append( aLibName );
1150 String aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1151
1152 INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
1153 aPrevUserBasicLibFolderInetObj.Append( aLibName );
1154 String aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1155
1156 if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
1157 mxSFI->move( aPrevLibFolder, aLibFolder );
1158
1159 if( aLibName == aStandardStr )
1160 maNameContainer.removeByName( aLibName );
1161
1162 // Create library
1163 Reference< XNameContainer > xLib = createLibrary( aLibName );
1164 SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
1165 pNewLib->mbLoaded = false;
1166 pNewLib->implSetModified( sal_False );
1167 checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
1168 pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
1169
1170 uno::Reference< embed::XStorage > xDummyStor;
1171 ::xmlscript::LibDescriptor aLibDesc;
1172 /*sal_Bool bReadIndexFile =*/ implLoadLibraryIndexFile
1173 ( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
1174 implImportLibDescriptor( pNewLib, aLibDesc );
1175 }
1176 }
1177 mxSFI->kill( aPrevFolder );
1178 }
1179 }
1180 catch( Exception& )
1181 {
1182 bCleanUp = true;
1183 }
1184
1185 // #i93163
1186 if( bCleanUp )
1187 {
1188 DBG_ERROR( "Upgrade of Basic installation failed somehow" );
1189
1190 static char strErrorSavFolderName[] = "__basic_80_err";
1191 INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
1192 aPrevUserBasicInetObj_Err.removeSegment();
1193 aPrevUserBasicInetObj_Err.Append( strErrorSavFolderName );
1194 String aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );
1195
1196 bool bSaved = false;
1197 try
1198 {
1199 String aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
1200 if( mxSFI->isFolder( aPrevFolder_1 ) )
1201 {
1202 mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
1203 bSaved = true;
1204 }
1205 }
1206 catch( Exception& )
1207 {}
1208 try
1209 {
1210 String aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1211 if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
1212 mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
1213 else
1214 mxSFI->kill( aPrevFolder_2 );
1215 }
1216 catch( Exception& )
1217 {}
1218 }
1219 }
1220
1221 return sal_True;
1222 }
1223
implScanExtensions(void)1224 void SfxLibraryContainer::implScanExtensions( void )
1225 {
1226 ScriptExtensionIterator aScriptIt;
1227 rtl::OUString aLibURL;
1228
1229 bool bPureDialogLib = false;
1230 while( (aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).isEmpty() == false )
1231 {
1232 if( bPureDialogLib && maInfoFileName.equalsAscii( "script" ) )
1233 continue;
1234
1235 // Extract lib name
1236 sal_Int32 nLen = aLibURL.getLength();
1237 sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
1238 sal_Int32 nReduceCopy = 0;
1239 if( indexLastSlash == nLen - 1 )
1240 {
1241 nReduceCopy = 1;
1242 indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
1243 }
1244
1245 OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
1246
1247 // If a library of the same exists the existing library wins
1248 if( hasByName( aLibName ) )
1249 continue;
1250
1251 // Add index file to URL
1252 OUString aIndexFileURL = aLibURL;
1253 if( nReduceCopy == 0 )
1254 aIndexFileURL += OUString::createFromAscii( "/" );
1255 aIndexFileURL += maInfoFileName;
1256 aIndexFileURL += OUString::createFromAscii( ".xlb" );
1257
1258 // Create link
1259 const bool bReadOnly = false;
1260 Reference< XNameAccess > xLib =
1261 createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
1262 }
1263 }
1264
1265 // Handle maLibInfoFileURL and maStorageURL correctly
checkStorageURL(const OUString & aSourceURL,OUString & aLibInfoFileURL,OUString & aStorageURL,OUString & aUnexpandedStorageURL)1266 void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
1267 OUString& aLibInfoFileURL, OUString& aStorageURL, OUString& aUnexpandedStorageURL )
1268 {
1269 OUString aExpandedSourceURL = expand_url( aSourceURL );
1270 if( aExpandedSourceURL != aSourceURL )
1271 aUnexpandedStorageURL = aSourceURL;
1272
1273 INetURLObject aInetObj( aExpandedSourceURL );
1274 OUString aExtension = aInetObj.getExtension();
1275 if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
1276 {
1277 // URL to xlb file
1278 aLibInfoFileURL = aExpandedSourceURL;
1279 aInetObj.removeSegment();
1280 aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1281 }
1282 else
1283 {
1284 // URL to library folder
1285 aStorageURL = aExpandedSourceURL;
1286 aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1287 aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1288 aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1289 }
1290 }
1291
getImplLib(const String & rLibraryName)1292 SfxLibrary* SfxLibraryContainer::getImplLib( const String& rLibraryName )
1293 {
1294 Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
1295 Reference< XNameAccess > xNameAccess;
1296 aLibAny >>= xNameAccess;
1297 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
1298 return pImplLib;
1299 }
1300
1301
1302 // Storing with password encryption
1303
1304 // Empty implementation, avoids unnecessary implementation in dlgcont.cxx
implStorePasswordLibrary(SfxLibrary *,const OUString &,const uno::Reference<embed::XStorage> &,const uno::Reference<task::XInteractionHandler> &)1305 sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
1306 SfxLibrary*,
1307 const OUString&,
1308 const uno::Reference< embed::XStorage >&, const uno::Reference< task::XInteractionHandler >& )
1309 {
1310 return sal_False;
1311 }
1312
implStorePasswordLibrary(SfxLibrary *,const::rtl::OUString &,const::com::sun::star::uno::Reference<::com::sun::star::embed::XStorage> &,const::rtl::OUString &,const Reference<XSimpleFileAccess>,const uno::Reference<task::XInteractionHandler> &)1313 sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
1314 SfxLibrary* /*pLib*/,
1315 const ::rtl::OUString& /*aName*/,
1316 const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
1317 const ::rtl::OUString& /*aTargetURL*/,
1318 const Reference< XSimpleFileAccess > /*xToUseSFI*/,
1319 const uno::Reference< task::XInteractionHandler >& )
1320 {
1321 return sal_False;
1322 }
1323
implLoadPasswordLibrary(SfxLibrary *,const OUString &,sal_Bool)1324 sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
1325 SfxLibrary* /*pLib*/,
1326 const OUString& /*Name*/,
1327 sal_Bool /*bVerifyPasswordOnly*/ )
1328 {
1329 return sal_True;
1330 }
1331
1332
1333
1334 #define EXPAND_PROTOCOL "vnd.sun.star.expand"
1335 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
1336
createAppLibraryFolder(SfxLibrary * pLib,const OUString & aName)1337 OUString SfxLibraryContainer::createAppLibraryFolder
1338 ( SfxLibrary* pLib, const OUString& aName )
1339 {
1340 OUString aLibDirPath = pLib->maStorageURL;
1341 if( aLibDirPath.isEmpty() )
1342 {
1343 INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
1344 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1345 checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
1346 pLib->maStorageURL, pLib->maUnexpandedStorageURL );
1347 aLibDirPath = pLib->maStorageURL;
1348 }
1349
1350 if( !mxSFI->isFolder( aLibDirPath ) )
1351 {
1352 try
1353 {
1354 mxSFI->createFolder( aLibDirPath );
1355 }
1356 catch( Exception& )
1357 {}
1358 }
1359
1360 return aLibDirPath;
1361 }
1362
1363 // Storing
implStoreLibrary(SfxLibrary * pLib,const OUString & aName,const uno::Reference<embed::XStorage> & xStorage)1364 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1365 const OUString& aName, const uno::Reference< embed::XStorage >& xStorage )
1366 {
1367 OUString aDummyLocation;
1368 Reference< XSimpleFileAccess > xDummySFA;
1369 Reference< XInteractionHandler > xDummyHandler;
1370 implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
1371 }
1372
1373 // New variant for library export
implStoreLibrary(SfxLibrary * pLib,const OUString & aName,const uno::Reference<embed::XStorage> & xStorage,const::rtl::OUString & aTargetURL,Reference<XSimpleFileAccess> xToUseSFI,const Reference<XInteractionHandler> & xHandler)1374 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1375 const OUString& aName, const uno::Reference< embed::XStorage >& xStorage,
1376 const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI,
1377 const Reference< XInteractionHandler >& xHandler )
1378 {
1379 sal_Bool bLink = pLib->mbLink;
1380 sal_Bool bStorage = xStorage.is() && !bLink;
1381
1382 Sequence< OUString > aElementNames = pLib->getElementNames();
1383 sal_Int32 nNameCount = aElementNames.getLength();
1384 const OUString* pNames = aElementNames.getConstArray();
1385
1386 if( bStorage )
1387 {
1388 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1389 {
1390 OUString aElementName = pNames[ i ];
1391
1392 OUString aStreamName = aElementName;
1393 aStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
1394
1395 /*Any aElement = pLib->getByName( aElementName );*/
1396 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1397 {
1398 #if OSL_DEBUG_LEVEL > 0
1399 ::rtl::OStringBuffer aMessage;
1400 aMessage.append( "invalid library element '" );
1401 aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
1402 aMessage.append( "'." );
1403 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
1404 #endif
1405 continue;
1406 }
1407 try {
1408 uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
1409 aStreamName,
1410 embed::ElementModes::READWRITE );
1411 //if ( !xElementStream.is() )
1412 // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1413
1414 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
1415 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
1416
1417 uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1418 OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
1419 //if ( !xProps.is() ) //TODO
1420 // throw uno::RuntimeException();
1421
1422 if ( xProps.is() )
1423 {
1424 xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
1425
1426 // #87671 Allow encryption
1427 //REMOVE aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
1428 aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
1429 xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
1430
1431 Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
1432 Reference< XNameContainer > xLib( pLib );
1433 writeLibraryElement( xLib, aElementName, xOutput );
1434 // writeLibraryElement closes the stream
1435 // xOutput->closeOutput();
1436 }
1437 }
1438 catch( uno::Exception& )
1439 {
1440 OSL_ENSURE( sal_False, "Problem during storing of library!\n" );
1441 // TODO: error handling?
1442 }
1443 }
1444
1445 pLib->storeResourcesToStorage( xStorage );
1446 }
1447 else
1448 {
1449 // Export?
1450 bool bExport = aTargetURL.getLength();
1451 try
1452 {
1453 Reference< XSimpleFileAccess > xSFI = mxSFI;
1454 if( xToUseSFI.is() )
1455 xSFI = xToUseSFI;
1456
1457 OUString aLibDirPath;
1458 if( bExport )
1459 {
1460 INetURLObject aInetObj( aTargetURL );
1461 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1462 aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1463
1464 if( !xSFI->isFolder( aLibDirPath ) )
1465 xSFI->createFolder( aLibDirPath );
1466
1467 pLib->storeResourcesToURL( aLibDirPath, xHandler );
1468 }
1469 else
1470 {
1471 aLibDirPath = createAppLibraryFolder( pLib, aName );
1472 pLib->storeResources();
1473 }
1474
1475 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1476 {
1477 OUString aElementName = pNames[ i ];
1478
1479 INetURLObject aElementInetObj( aLibDirPath );
1480 aElementInetObj.insertName( aElementName, sal_False,
1481 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1482 aElementInetObj.setExtension( maLibElementFileExtension );
1483 String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
1484
1485 /*Any aElement = pLib->getByName( aElementName );*/
1486 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1487 {
1488 #if OSL_DEBUG_LEVEL > 0
1489 ::rtl::OStringBuffer aMessage;
1490 aMessage.append( "invalid library element '" );
1491 aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
1492 aMessage.append( "'." );
1493 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
1494 #endif
1495 continue;
1496 }
1497
1498 // TODO: Check modified
1499 try
1500 {
1501 if( xSFI->exists( aElementPath ) )
1502 xSFI->kill( aElementPath );
1503 Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
1504 Reference< XNameContainer > xLib( pLib );
1505 writeLibraryElement( xLib, aElementName, xOutput );
1506 xOutput->closeOutput();
1507 }
1508 catch( Exception& )
1509 {
1510 if( bExport )
1511 throw;
1512
1513 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
1514 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1515 ErrorHandler::HandleError( nErrorCode );
1516 }
1517 }
1518 }
1519 catch( Exception& )
1520 {
1521 if( bExport )
1522 throw;
1523 }
1524 }
1525 }
1526
implStoreLibraryIndexFile(SfxLibrary * pLib,const::xmlscript::LibDescriptor & rLib,const uno::Reference<embed::XStorage> & xStorage)1527 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1528 const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage )
1529 {
1530 OUString aDummyLocation;
1531 Reference< XSimpleFileAccess > xDummySFA;
1532 implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
1533 }
1534
1535 // New variant for library export
implStoreLibraryIndexFile(SfxLibrary * pLib,const::xmlscript::LibDescriptor & rLib,const uno::Reference<embed::XStorage> & xStorage,const::rtl::OUString & aTargetURL,Reference<XSimpleFileAccess> xToUseSFI)1536 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1537 const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage,
1538 const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI )
1539 {
1540 // Create sax writer
1541 Reference< XExtendedDocumentHandler > xHandler(
1542 mxMSF->createInstance(
1543 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
1544 if( !xHandler.is() )
1545 {
1546 OSL_ENSURE( 0, "### couldn't create sax-writer component\n" );
1547 return;
1548 }
1549
1550 sal_Bool bLink = pLib->mbLink;
1551 sal_Bool bStorage = xStorage.is() && !bLink;
1552
1553 // Write info file
1554 uno::Reference< io::XOutputStream > xOut;
1555 uno::Reference< io::XStream > xInfoStream;
1556 if( bStorage )
1557 {
1558 OUString aStreamName( maInfoFileName );
1559 aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
1560
1561 try {
1562 xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
1563 OSL_ENSURE( xInfoStream.is(), "No stream!\n" );
1564 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
1565 //if ( !xProps.is() )
1566 // throw uno::RuntimeException(); // TODO
1567
1568 if ( xProps.is() )
1569 {
1570 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
1571 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
1572 xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
1573
1574 // #87671 Allow encryption
1575 //REMOVE aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
1576 aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
1577 xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
1578
1579 xOut = xInfoStream->getOutputStream();
1580 }
1581 }
1582 catch( uno::Exception& )
1583 {
1584 OSL_ENSURE( sal_False, "Problem during storing of library index file!\n" );
1585 // TODO: error handling?
1586 }
1587 }
1588 else
1589 {
1590 // Export?
1591 bool bExport = aTargetURL.getLength();
1592 Reference< XSimpleFileAccess > xSFI = mxSFI;
1593 if( xToUseSFI.is() )
1594 xSFI = xToUseSFI;
1595
1596 OUString aLibInfoPath;
1597 if( bExport )
1598 {
1599 INetURLObject aInetObj( aTargetURL );
1600 aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1601 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1602 if( !xSFI->isFolder( aLibDirPath ) )
1603 xSFI->createFolder( aLibDirPath );
1604
1605 aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1606 aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1607 aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1608 }
1609 else
1610 {
1611 createAppLibraryFolder( pLib, rLib.aName );
1612 aLibInfoPath = pLib->maLibInfoFileURL;
1613 }
1614
1615 try
1616 {
1617 if( xSFI->exists( aLibInfoPath ) )
1618 xSFI->kill( aLibInfoPath );
1619 xOut = xSFI->openFileWrite( aLibInfoPath );
1620 }
1621 catch( Exception& )
1622 {
1623 if( bExport )
1624 throw;
1625
1626 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
1627 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1628 ErrorHandler::HandleError( nErrorCode );
1629 }
1630 }
1631 if( !xOut.is() )
1632 {
1633 OSL_ENSURE( 0, "### couldn't open output stream\n" );
1634 return;
1635 }
1636
1637 Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
1638 xSource->setOutputStream( xOut );
1639
1640 xmlscript::exportLibrary( xHandler, rLib );
1641 }
1642
1643
implLoadLibraryIndexFile(SfxLibrary * pLib,::xmlscript::LibDescriptor & rLib,const uno::Reference<embed::XStorage> & xStorage,const OUString & aIndexFileName)1644 sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib,
1645 ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, const OUString& aIndexFileName )
1646 {
1647 Reference< XParser > xParser( mxMSF->createInstance(
1648 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
1649 if( !xParser.is() )
1650 {
1651 OSL_ENSURE( 0, "### couldn't create sax parser component\n" );
1652 return sal_False;
1653 }
1654
1655 sal_Bool bLink = sal_False;
1656 sal_Bool bStorage = sal_False;
1657 if( pLib )
1658 {
1659 bLink = pLib->mbLink;
1660 bStorage = xStorage.is() && !bLink;
1661 }
1662
1663 // Read info file
1664 uno::Reference< io::XInputStream > xInput;
1665 String aLibInfoPath;
1666 if( bStorage )
1667 {
1668 aLibInfoPath = maInfoFileName;
1669 aLibInfoPath += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
1670
1671 try {
1672 uno::Reference< io::XStream > xInfoStream =
1673 xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
1674 xInput = xInfoStream->getInputStream();
1675 }
1676 catch( uno::Exception& )
1677 {}
1678 }
1679 else
1680 {
1681 // Create Input stream
1682 //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1683
1684 if( pLib )
1685 {
1686 createAppLibraryFolder( pLib, rLib.aName );
1687 aLibInfoPath = pLib->maLibInfoFileURL;
1688 }
1689 else
1690 aLibInfoPath = aIndexFileName;
1691
1692 try
1693 {
1694 xInput = mxSFI->openFileRead( aLibInfoPath );
1695 }
1696 catch( Exception& )
1697 {
1698 xInput.clear();
1699 if( !GbMigrationSuppressErrors )
1700 {
1701 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1702 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1703 ErrorHandler::HandleError( nErrorCode );
1704 }
1705 }
1706 }
1707 if( !xInput.is() )
1708 {
1709 // OSL_ENSURE( 0, "### couldn't open input stream\n" );
1710 return sal_False;
1711 }
1712
1713 InputSource source;
1714 source.aInputStream = xInput;
1715 source.sSystemId = aLibInfoPath;
1716
1717 // start parsing
1718 try {
1719 xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
1720 xParser->parseStream( source );
1721 }
1722 catch( Exception& )
1723 {
1724 // throw WrappedTargetException( OUString::createFromAscii( "parsing error!\n" ),
1725 // Reference< XInterface >(),
1726 // makeAny( e ) );
1727 OSL_ENSURE( 0, "Parsing error\n" );
1728 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1729 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1730 ErrorHandler::HandleError( nErrorCode );
1731 return sal_False;
1732 }
1733
1734 if( !pLib )
1735 {
1736 Reference< XNameContainer > xLib = createLibrary( rLib.aName );
1737 pLib = static_cast< SfxLibrary* >( xLib.get() );
1738 pLib->mbLoaded = sal_False;
1739 rLib.aStorageURL = aIndexFileName;
1740 checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
1741 pLib->maUnexpandedStorageURL );
1742
1743 implImportLibDescriptor( pLib, rLib );
1744 }
1745
1746 return sal_True;
1747 }
1748
implImportLibDescriptor(SfxLibrary * pLib,::xmlscript::LibDescriptor & rLib)1749 void SfxLibraryContainer::implImportLibDescriptor
1750 ( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib )
1751 {
1752 if( !pLib->mbInitialised )
1753 {
1754 sal_Int32 nElementCount = rLib.aElementNames.getLength();
1755 const OUString* pElementNames = rLib.aElementNames.getConstArray();
1756 Any aDummyElement = createEmptyLibraryElement();
1757 for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
1758 {
1759 pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
1760 }
1761 pLib->mbPasswordProtected = rLib.bPasswordProtected;
1762 pLib->mbReadOnly = rLib.bReadOnly;
1763 pLib->mbPreload = rLib.bPreload;
1764 pLib->implSetModified( sal_False );
1765
1766 pLib->mbInitialised = sal_True;
1767 }
1768 }
1769
1770
1771 // Methods of new XLibraryStorage interface?
storeLibraries_Impl(const uno::Reference<embed::XStorage> & i_rStorage,sal_Bool bComplete)1772 void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage, sal_Bool bComplete )
1773 {
1774 const Sequence< OUString > aNames = maNameContainer.getElementNames();
1775 sal_Int32 nNameCount = aNames.getLength();
1776 const OUString* pName = aNames.getConstArray();
1777 const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
1778
1779 // Don't count libs from shared index file
1780 sal_Int32 nLibsToSave = nNameCount;
1781 for( ; pName != pNamesEnd; ++pName )
1782 {
1783 SfxLibrary* pImplLib = getImplLib( *pName );
1784 if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
1785 nLibsToSave--;
1786 }
1787 if( !nLibsToSave )
1788 return;
1789
1790 ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray( nLibsToSave );
1791
1792 // Write to storage?
1793 sal_Bool bStorage = i_rStorage.is();
1794 uno::Reference< embed::XStorage > xSourceLibrariesStor;
1795 uno::Reference< embed::XStorage > xTargetLibrariesStor;
1796 ::rtl::OUString sTempTargetStorName;
1797 const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
1798 if ( bStorage )
1799 {
1800 // Don't write if only empty standard lib exists
1801 if ( ( nNameCount == 1 ) && ( aNames[0].equalsAscii( "Standard" ) ) )
1802 {
1803 Any aLibAny = maNameContainer.getByName( aNames[0] );
1804 Reference< XNameAccess > xNameAccess;
1805 aLibAny >>= xNameAccess;
1806 if ( !xNameAccess->hasElements() ){
1807 delete pLibArray;
1808 return;
1809 }
1810 }
1811
1812 // create the empty target storage
1813 try
1814 {
1815 ::rtl::OUString sTargetLibrariesStoreName;
1816 if ( bInplaceStorage )
1817 {
1818 // create a temporary target storage
1819 const ::rtl::OUStringBuffer aTempTargetNameBase = maLibrariesDir + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_temp_" ) );
1820 sal_Int32 index = 0;
1821 do
1822 {
1823 ::rtl::OUStringBuffer aTempTargetName( aTempTargetNameBase );
1824 aTempTargetName.append( index++ );
1825
1826 sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
1827 if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1828 break;
1829 }
1830 while ( true );
1831 sTempTargetStorName = sTargetLibrariesStoreName;
1832 }
1833 else
1834 {
1835 sTargetLibrariesStoreName = maLibrariesDir;
1836 if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1837 i_rStorage->removeElement( sTargetLibrariesStoreName );
1838 }
1839
1840 xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
1841 }
1842 catch( const uno::Exception& )
1843 {
1844 DBG_UNHANDLED_EXCEPTION();
1845 return;
1846 }
1847
1848 // open the source storage which might be used to copy yet-unmodified libraries
1849 try
1850 {
1851 if ( mxStorage->hasByName( maLibrariesDir ) )
1852 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
1853 else if ( bInplaceStorage )
1854 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
1855 }
1856 catch( const uno::Exception& )
1857 {
1858 DBG_UNHANDLED_EXCEPTION();
1859 return;
1860 }
1861 }
1862
1863 int iArray = 0;
1864 pName = aNames.getConstArray();
1865 ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
1866 for( ; pName != pNamesEnd; ++pName )
1867 {
1868 SfxLibrary* pImplLib = getImplLib( *pName );
1869 if( pImplLib->mbSharedIndexFile )
1870 continue;
1871 const bool bExtensionLib = pImplLib->mbExtension;
1872 ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
1873 aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
1874 if( !bExtensionLib )
1875 iArray++;
1876 rLib.aName = *pName;
1877
1878 rLib.bLink = pImplLib->mbLink;
1879 if( !bStorage || pImplLib->mbLink )
1880 {
1881 rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
1882 pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
1883 }
1884 rLib.bReadOnly = pImplLib->mbReadOnly;
1885 rLib.bPreload = pImplLib->mbPreload;
1886 rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
1887 rLib.aElementNames = pImplLib->getElementNames();
1888
1889 if( pImplLib->implIsModified() || bComplete )
1890 {
1891 // Can we simply copy the storage?
1892 if( !mbOldInfoFormat && !pImplLib->implIsModified() && !mbOasis2OOoFormat && xSourceLibrariesStor.is() )
1893 {
1894 try
1895 {
1896 xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
1897 }
1898 catch( const uno::Exception& )
1899 {
1900 DBG_UNHANDLED_EXCEPTION();
1901 // TODO: error handling?
1902 }
1903 }
1904 else
1905 {
1906 uno::Reference< embed::XStorage > xLibraryStor;
1907 if( bStorage )
1908 {
1909 try
1910 {
1911 xLibraryStor = xTargetLibrariesStor->openStorageElement(
1912 rLib.aName,
1913 embed::ElementModes::READWRITE );
1914 }
1915 catch( uno::Exception& )
1916 {
1917 #if OSL_DEBUG_LEVEL > 0
1918 Any aError( ::cppu::getCaughtException() );
1919 ::rtl::OStringBuffer aMessage;
1920 aMessage.append( "couldn't create sub storage for library '" );
1921 aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
1922 aMessage.append( "'.\n\nException:" );
1923 aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
1924 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
1925 #endif
1926 return;
1927 }
1928 }
1929
1930 // Maybe lib is not loaded?!
1931 if( bComplete )
1932 loadLibrary( rLib.aName );
1933
1934 if( pImplLib->mbPasswordProtected )
1935 implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
1936 // TODO: Check return value
1937 else
1938 implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
1939
1940 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
1941 if( bStorage )
1942 {
1943 try
1944 {
1945 uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
1946 xTransact->commit();
1947 }
1948 catch( uno::Exception& )
1949 {
1950 DBG_UNHANDLED_EXCEPTION();
1951 // TODO: error handling
1952 }
1953 }
1954 }
1955
1956 maModifiable.setModified( sal_True );
1957 pImplLib->implSetModified( sal_False );
1958 }
1959
1960 // For container info ReadOnly refers to mbReadOnlyLink
1961 rLib.bReadOnly = pImplLib->mbReadOnlyLink;
1962 }
1963
1964 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
1965 // then we need to clean up the temporary storage we used for this
1966 if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
1967 {
1968 OSL_ENSURE( xSourceLibrariesStor.is(), "SfxLibrariesContainer::storeLibraries_impl: unexpected: we should have a source storage here!" );
1969 try
1970 {
1971 // for this, we first remove everything from the source storage, then copy the complete content
1972 // from the temporary target storage. From then on, what used to be the "source storage" becomes
1973 // the "targt storage" for all subsequent operations.
1974
1975 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
1976 // open references to it.)
1977
1978 if ( xSourceLibrariesStor.is() )
1979 {
1980 // remove
1981 const Sequence< ::rtl::OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
1982 for ( const ::rtl::OUString* pRemoveName = aRemoveNames.getConstArray();
1983 pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
1984 ++pRemoveName
1985 )
1986 {
1987 xSourceLibrariesStor->removeElement( *pRemoveName );
1988 }
1989
1990 // copy
1991 const Sequence< ::rtl::OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
1992 for ( const ::rtl::OUString* pCopyName = aCopyNames.getConstArray();
1993 pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
1994 ++pCopyName
1995 )
1996 {
1997 xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
1998 }
1999 }
2000
2001 // close and remove temp target
2002 xTargetLibrariesStor->dispose();
2003 i_rStorage->removeElement( sTempTargetStorName );
2004 xTargetLibrariesStor.clear();
2005 sTempTargetStorName = ::rtl::OUString();
2006
2007 // adjust target
2008 xTargetLibrariesStor = xSourceLibrariesStor;
2009 xSourceLibrariesStor.clear();
2010 }
2011 catch( const Exception& )
2012 {
2013 DBG_UNHANDLED_EXCEPTION();
2014 }
2015 }
2016
2017 if( !mbOldInfoFormat && !maModifiable.isModified() )
2018 return;
2019 maModifiable.setModified( sal_False );
2020 mbOldInfoFormat = sal_False;
2021
2022 // Write library container info
2023 // Create sax writer
2024 Reference< XExtendedDocumentHandler > xHandler(
2025 mxMSF->createInstance(
2026 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
2027 if( !xHandler.is() )
2028 {
2029 OSL_ENSURE( 0, "### couldn't create sax-writer component\n" );
2030 return;
2031 }
2032
2033 // Write info file
2034 uno::Reference< io::XOutputStream > xOut;
2035 uno::Reference< io::XStream > xInfoStream;
2036 if( bStorage )
2037 {
2038 OUString aStreamName( maInfoFileName );
2039 aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
2040
2041 try {
2042 xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2043 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
2044 OSL_ENSURE ( xProps.is(), "The stream must implement XPropertySet!\n" );
2045 if ( !xProps.is() )
2046 throw uno::RuntimeException();
2047
2048 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
2049 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
2050 xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
2051
2052 // #87671 Allow encryption
2053 aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("UseCommonStoragePasswordEncryption") );
2054 xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
2055
2056 xOut = xInfoStream->getOutputStream();
2057 }
2058 catch( uno::Exception& )
2059 {
2060 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2061 ErrorHandler::HandleError( nErrorCode );
2062 }
2063 }
2064 else
2065 {
2066 // Create Output stream
2067 INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
2068 aLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2069 aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
2070 String aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2071
2072 try
2073 {
2074 if( mxSFI->exists( aLibInfoPath ) )
2075 mxSFI->kill( aLibInfoPath );
2076 xOut = mxSFI->openFileWrite( aLibInfoPath );
2077 }
2078 catch( Exception& )
2079 {
2080 xOut.clear();
2081 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2082 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2083 ErrorHandler::HandleError( nErrorCode );
2084 }
2085
2086 }
2087 if( !xOut.is() )
2088 {
2089 OSL_ENSURE( 0, "### couldn't open output stream\n" );
2090 return;
2091 }
2092
2093 Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
2094 xSource->setOutputStream( xOut );
2095
2096 try
2097 {
2098 xmlscript::exportLibraryContainer( xHandler, pLibArray );
2099 if ( bStorage )
2100 {
2101 uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
2102 OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
2103 if ( !xTransact.is() )
2104 throw uno::RuntimeException();
2105
2106 xTransact->commit();
2107 }
2108 }
2109 catch( uno::Exception& )
2110 {
2111 OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
2112 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2113 ErrorHandler::HandleError( nErrorCode );
2114 }
2115
2116 delete pLibArray;
2117 }
2118
2119
2120 // Methods XElementAccess
getElementType()2121 Type SAL_CALL SfxLibraryContainer::getElementType()
2122 {
2123 LibraryContainerMethodGuard aGuard( *this );
2124 return maNameContainer.getElementType();
2125 }
2126
hasElements()2127 sal_Bool SfxLibraryContainer::hasElements()
2128 {
2129 LibraryContainerMethodGuard aGuard( *this );
2130 sal_Bool bRet = maNameContainer.hasElements();
2131 return bRet;
2132 }
2133
2134 // Methods XNameAccess
getByName(const OUString & aName)2135 Any SfxLibraryContainer::getByName( const OUString& aName )
2136 {
2137 LibraryContainerMethodGuard aGuard( *this );
2138 Any aRetAny = maNameContainer.getByName( aName ) ;
2139 return aRetAny;
2140 }
2141
getElementNames()2142 Sequence< OUString > SfxLibraryContainer::getElementNames()
2143 {
2144 LibraryContainerMethodGuard aGuard( *this );
2145 return maNameContainer.getElementNames();
2146 }
2147
hasByName(const OUString & aName)2148 sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
2149 {
2150 LibraryContainerMethodGuard aGuard( *this );
2151 return maNameContainer.hasByName( aName ) ;
2152 }
2153
2154 // Methods XLibraryContainer
createLibrary(const OUString & Name)2155 Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
2156 {
2157 LibraryContainerMethodGuard aGuard( *this );
2158 SfxLibrary* pNewLib = implCreateLibrary( Name );
2159 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2160
2161 createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2162
2163 Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
2164 Any aElement;
2165 aElement <<= xNameAccess;
2166 maNameContainer.insertByName( Name, aElement );
2167 maModifiable.setModified( sal_True );
2168 Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2169 return xRet;
2170 }
2171
createLibraryLink(const OUString & Name,const OUString & StorageURL,sal_Bool ReadOnly)2172 Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
2173 ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2174 {
2175 LibraryContainerMethodGuard aGuard( *this );
2176 // TODO: Check other reasons to force ReadOnly status
2177 //if( !ReadOnly )
2178 //{
2179 //}
2180
2181 OUString aLibInfoFileURL;
2182 OUString aLibDirURL;
2183 OUString aUnexpandedStorageURL;
2184 checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2185
2186
2187 SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2188 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2189 pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2190 pNewLib->maOrignialStorageURL = StorageURL;
2191
2192 OUString aInitFileName;
2193 uno::Reference< embed::XStorage > xDummyStor;
2194 ::xmlscript::LibDescriptor aLibDesc;
2195 /*sal_Bool bReadIndexFile = */implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
2196 implImportLibDescriptor( pNewLib, aLibDesc );
2197
2198 Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
2199 Any aElement;
2200 aElement <<= xRet;
2201 maNameContainer.insertByName( Name, aElement );
2202 maModifiable.setModified( sal_True );
2203
2204 OUString aUserSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
2205 OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
2206 OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
2207 if( StorageURL.indexOf( aUserSearchStr ) != -1 )
2208 {
2209 pNewLib->mbExtension = sal_True;
2210 }
2211 else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
2212 {
2213 pNewLib->mbExtension = sal_True;
2214 pNewLib->mbReadOnly = sal_True;
2215 }
2216
2217 return xRet;
2218 }
2219
removeLibrary(const OUString & Name)2220 void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2221 {
2222 LibraryContainerMethodGuard aGuard( *this );
2223 // Get and hold library before removing
2224 Any aLibAny = maNameContainer.getByName( Name ) ;
2225 Reference< XNameAccess > xNameAccess;
2226 aLibAny >>= xNameAccess;
2227 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2228 if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2229 throw IllegalArgumentException();
2230
2231 // Remove from container
2232 maNameContainer.removeByName( Name );
2233 maModifiable.setModified( sal_True );
2234
2235 // Delete library files, but not for linked libraries
2236 if( !pImplLib->mbLink )
2237 {
2238 if( mxStorage.is() )
2239 return;
2240 if( xNameAccess->hasElements() )
2241 {
2242 Sequence< OUString > aNames = pImplLib->getElementNames();
2243 sal_Int32 nNameCount = aNames.getLength();
2244 const OUString* pNames = aNames.getConstArray();
2245 for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2246 {
2247 pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
2248 }
2249 }
2250
2251 // Delete index file
2252 createAppLibraryFolder( pImplLib, Name );
2253 String aLibInfoPath = pImplLib->maLibInfoFileURL;
2254 try
2255 {
2256 if( mxSFI->exists( aLibInfoPath ) )
2257 mxSFI->kill( aLibInfoPath );
2258 }
2259 catch( Exception& ) {}
2260
2261 // Delete folder if empty
2262 INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
2263 aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
2264 sal_True, INetURLObject::ENCODE_ALL );
2265 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
2266
2267 try
2268 {
2269 if( mxSFI->isFolder( aLibDirPath ) )
2270 {
2271 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2272 sal_Int32 nCount = aContentSeq.getLength();
2273 if( !nCount )
2274 mxSFI->kill( aLibDirPath );
2275 }
2276 }
2277 catch( Exception& )
2278 {
2279 }
2280 }
2281 }
2282
isLibraryLoaded(const OUString & Name)2283 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2284 {
2285 LibraryContainerMethodGuard aGuard( *this );
2286 SfxLibrary* pImplLib = getImplLib( Name );
2287 sal_Bool bRet = pImplLib->mbLoaded;
2288 return bRet;
2289 }
2290
2291
loadLibrary(const OUString & Name)2292 void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2293 {
2294 LibraryContainerMethodGuard aGuard( *this );
2295 Any aLibAny = maNameContainer.getByName( Name ) ;
2296 Reference< XNameAccess > xNameAccess;
2297 aLibAny >>= xNameAccess;
2298 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2299
2300 sal_Bool bLoaded = pImplLib->mbLoaded;
2301 pImplLib->mbLoaded = sal_True;
2302 if( !bLoaded && xNameAccess->hasElements() )
2303 {
2304 if( pImplLib->mbPasswordProtected )
2305 {
2306 implLoadPasswordLibrary( pImplLib, Name );
2307 return;
2308 }
2309
2310 sal_Bool bLink = pImplLib->mbLink;
2311 sal_Bool bStorage = mxStorage.is() && !bLink;
2312
2313 uno::Reference< embed::XStorage > xLibrariesStor;
2314 uno::Reference< embed::XStorage > xLibraryStor;
2315 if( bStorage )
2316 {
2317 try {
2318 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2319 OSL_ENSURE( xLibrariesStor.is(), "The method must either throw exception or return a storage!\n" );
2320 if ( !xLibrariesStor.is() )
2321 throw uno::RuntimeException();
2322
2323 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2324 OSL_ENSURE( xLibraryStor.is(), "The method must either throw exception or return a storage!\n" );
2325 if ( !xLibrariesStor.is() )
2326 throw uno::RuntimeException();
2327 }
2328 catch( uno::Exception& )
2329 {
2330 #if OSL_DEBUG_LEVEL > 0
2331 Any aError( ::cppu::getCaughtException() );
2332 ::rtl::OStringBuffer aMessage;
2333 aMessage.append( "couldn't open sub storage for library '" );
2334 aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
2335 aMessage.append( "'.\n\nException:" );
2336 aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
2337 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
2338 #endif
2339 return;
2340 }
2341 }
2342
2343 Sequence< OUString > aNames = pImplLib->getElementNames();
2344 sal_Int32 nNameCount = aNames.getLength();
2345 const OUString* pNames = aNames.getConstArray();
2346 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2347 {
2348 OUString aElementName = pNames[ i ];
2349
2350 OUString aFile;
2351 uno::Reference< io::XInputStream > xInStream;
2352
2353 if( bStorage )
2354 {
2355 uno::Reference< io::XStream > xElementStream;
2356
2357 aFile = aElementName;
2358 aFile += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
2359
2360 try {
2361 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2362 } catch( uno::Exception& )
2363 {}
2364
2365 if( !xElementStream.is() )
2366 {
2367 // Check for EA2 document version with wrong extensions
2368 aFile = aElementName;
2369 aFile += String( RTL_CONSTASCII_USTRINGPARAM(".") );
2370 aFile += maLibElementFileExtension;
2371 try {
2372 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2373 } catch( uno::Exception& )
2374 {}
2375 }
2376
2377 if ( xElementStream.is() )
2378 xInStream = xElementStream->getInputStream();
2379
2380 if ( !xInStream.is() )
2381 {
2382 #if OSL_DEBUG_LEVEL > 0
2383 ::rtl::OStringBuffer aMessage;
2384 aMessage.append( "couldn't open library element stream - attempted to open library '" );
2385 aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
2386 aMessage.append( "'." );
2387 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
2388 #endif
2389 return;
2390 }
2391 }
2392 else
2393 {
2394 String aLibDirPath = pImplLib->maStorageURL;
2395 INetURLObject aElementInetObj( aLibDirPath );
2396 aElementInetObj.insertName( aElementName, sal_False,
2397 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2398 aElementInetObj.setExtension( maLibElementFileExtension );
2399 aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
2400 }
2401
2402 Reference< XNameContainer > xLib( pImplLib );
2403 Any aAny = importLibraryElement( xLib, aElementName,
2404 aFile, xInStream );
2405 if( pImplLib->hasByName( aElementName ) )
2406 {
2407 if( aAny.hasValue() )
2408 pImplLib->maNameContainer.replaceByName( aElementName, aAny );
2409 }
2410 else
2411 {
2412 pImplLib->maNameContainer.insertByName( aElementName, aAny );
2413 }
2414 }
2415
2416 pImplLib->implSetModified( sal_False );
2417 }
2418 }
2419
2420 // Methods XLibraryContainer2
isLibraryLink(const OUString & Name)2421 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2422 {
2423 LibraryContainerMethodGuard aGuard( *this );
2424 SfxLibrary* pImplLib = getImplLib( Name );
2425 sal_Bool bRet = pImplLib->mbLink;
2426 return bRet;
2427 }
2428
getLibraryLinkURL(const OUString & Name)2429 OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2430 {
2431 LibraryContainerMethodGuard aGuard( *this );
2432 SfxLibrary* pImplLib = getImplLib( Name );
2433 sal_Bool bLink = pImplLib->mbLink;
2434 if( !bLink )
2435 throw IllegalArgumentException();
2436 OUString aRetStr = pImplLib->maLibInfoFileURL;
2437 return aRetStr;
2438 }
2439
isLibraryReadOnly(const OUString & Name)2440 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2441 {
2442 LibraryContainerMethodGuard aGuard( *this );
2443 SfxLibrary* pImplLib = getImplLib( Name );
2444 sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2445 return bRet;
2446 }
2447
setLibraryReadOnly(const OUString & Name,sal_Bool bReadOnly)2448 void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2449 {
2450 LibraryContainerMethodGuard aGuard( *this );
2451 SfxLibrary* pImplLib = getImplLib( Name );
2452 if( pImplLib->mbLink )
2453 {
2454 if( pImplLib->mbReadOnlyLink != bReadOnly )
2455 {
2456 pImplLib->mbReadOnlyLink = bReadOnly;
2457 pImplLib->implSetModified( sal_True );
2458 maModifiable.setModified( sal_True );
2459 }
2460 }
2461 else
2462 {
2463 if( pImplLib->mbReadOnly != bReadOnly )
2464 {
2465 pImplLib->mbReadOnly = bReadOnly;
2466 pImplLib->implSetModified( sal_True );
2467 }
2468 }
2469 }
2470
renameLibrary(const OUString & Name,const OUString & NewName)2471 void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2472 {
2473 LibraryContainerMethodGuard aGuard( *this );
2474 if( maNameContainer.hasByName( NewName ) )
2475 throw ElementExistException();
2476
2477 // Get and hold library before removing
2478 Any aLibAny = maNameContainer.getByName( Name ) ;
2479
2480 // #i24094 Maybe lib is not loaded!
2481 Reference< XNameAccess > xNameAccess;
2482 aLibAny >>= xNameAccess;
2483 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2484 if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2485 return; // Lib with unverified password cannot be renamed
2486 loadLibrary( Name );
2487
2488 // Remove from container
2489 maNameContainer.removeByName( Name );
2490 maModifiable.setModified( sal_True );
2491
2492 // Rename library folder, but not for linked libraries
2493 bool bMovedSuccessful = true;
2494
2495 // Rename files
2496 sal_Bool bStorage = mxStorage.is();
2497 if( !bStorage && !pImplLib->mbLink )
2498 {
2499 bMovedSuccessful = false;
2500
2501 OUString aLibDirPath = pImplLib->maStorageURL;
2502
2503 INetURLObject aDestInetObj( String(maLibraryPath).GetToken(1) );
2504 aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
2505 sal_True, INetURLObject::ENCODE_ALL );
2506 OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
2507
2508 // Store new URL
2509 OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2510 checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2511 pImplLib->maUnexpandedStorageURL );
2512
2513 try
2514 {
2515 if( mxSFI->isFolder( aLibDirPath ) )
2516 {
2517 if( !mxSFI->isFolder( aDestDirPath ) )
2518 mxSFI->createFolder( aDestDirPath );
2519
2520 // Move index file
2521 try
2522 {
2523 if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2524 mxSFI->kill( pImplLib->maLibInfoFileURL );
2525 mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2526 }
2527 catch( Exception& )
2528 {
2529 }
2530
2531 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2532 sal_Int32 nNameCount = aElementNames.getLength();
2533 const OUString* pNames = aElementNames.getConstArray();
2534 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2535 {
2536 OUString aElementName = pNames[ i ];
2537
2538 INetURLObject aElementInetObj( aLibDirPath );
2539 aElementInetObj.insertName( aElementName, sal_False,
2540 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2541 aElementInetObj.setExtension( maLibElementFileExtension );
2542 String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2543
2544 INetURLObject aElementDestInetObj( aDestDirPath );
2545 aElementDestInetObj.insertName( aElementName, sal_False,
2546 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2547 aElementDestInetObj.setExtension( maLibElementFileExtension );
2548 String aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2549
2550 try
2551 {
2552 if( mxSFI->exists( aDestElementPath ) )
2553 mxSFI->kill( aDestElementPath );
2554 mxSFI->move( aElementPath, aDestElementPath );
2555 }
2556 catch( Exception& )
2557 {
2558 }
2559 }
2560 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2561
2562 // Delete folder if empty
2563 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2564 sal_Int32 nCount = aContentSeq.getLength();
2565 if( !nCount )
2566 {
2567 mxSFI->kill( aLibDirPath );
2568 }
2569
2570 bMovedSuccessful = true;
2571 pImplLib->implSetModified( sal_True );
2572 }
2573 }
2574 catch( Exception& )
2575 {
2576 // Restore old library
2577 maNameContainer.insertByName( Name, aLibAny ) ;
2578 }
2579 }
2580
2581 if( bStorage && !pImplLib->mbLink )
2582 pImplLib->implSetModified( sal_True );
2583
2584 if( bMovedSuccessful )
2585 maNameContainer.insertByName( NewName, aLibAny ) ;
2586
2587 }
2588
2589
2590 // Methods XInitialization
initialize(const Sequence<Any> & _rArguments)2591 void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2592 {
2593 LibraryContainerMethodGuard aGuard( *this );
2594 sal_Int32 nArgCount = _rArguments.getLength();
2595 if ( nArgCount == 1 )
2596 {
2597 OUString sInitialDocumentURL;
2598 Reference< XStorageBasedDocument > xDocument;
2599 if ( _rArguments[0] >>= sInitialDocumentURL )
2600 {
2601 initializeFromDocumentURL( sInitialDocumentURL );
2602 return;
2603 }
2604
2605 if ( _rArguments[0] >>= xDocument )
2606 {
2607 initializeFromDocument( xDocument );
2608 return;
2609 }
2610 }
2611
2612 throw IllegalArgumentException();
2613 }
2614
initializeFromDocumentURL(const::rtl::OUString & _rInitialDocumentURL)2615 void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const ::rtl::OUString& _rInitialDocumentURL )
2616 {
2617 init( _rInitialDocumentURL, NULL );
2618 }
2619
initializeFromDocument(const Reference<XStorageBasedDocument> & _rxDocument)2620 void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
2621 {
2622 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2623 Reference< XStorage > xDocStorage;
2624 try
2625 {
2626 Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2627 if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.OfficeDocument" ) ) ) )
2628 xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
2629
2630 Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2631 Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2632
2633 mxOwnerDocument = xDocument;
2634 startComponentListening( xDocComponent );
2635 }
2636 catch( const Exception& ) { }
2637
2638 if ( !xDocStorage.is() )
2639 throw IllegalArgumentException();
2640
2641 init( OUString(), xDocStorage );
2642 }
2643
2644 // OEventListenerAdapter
_disposing(const EventObject & _rSource)2645 void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2646 {
2647 #if OSL_DEBUG_LEVEL > 0
2648 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2649 OSL_ENSURE( ( xDocument == _rSource.Source ) && xDocument.is(), "SfxLibraryContainer::_disposing: where does this come from?" );
2650 #else
2651 (void)_rSource;
2652 #endif
2653 dispose();
2654 }
2655
2656 // OComponentHelper
disposing()2657 void SAL_CALL SfxLibraryContainer::disposing()
2658 {
2659 Reference< XModel > xModel = mxOwnerDocument;
2660 EventObject aEvent( xModel.get() );
2661 maVBAScriptListeners.disposing( aEvent );
2662 stopAllComponentListening();
2663 mxOwnerDocument = WeakReference< XModel >();
2664 }
2665
2666 // Methods XLibraryContainerPassword
isLibraryPasswordProtected(const OUString &)2667 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
2668 {
2669 LibraryContainerMethodGuard aGuard( *this );
2670 return sal_False;
2671 }
2672
isLibraryPasswordVerified(const OUString &)2673 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
2674 {
2675 LibraryContainerMethodGuard aGuard( *this );
2676 throw IllegalArgumentException();
2677 }
2678
verifyLibraryPassword(const OUString &,const OUString &)2679 sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword
2680 ( const OUString&, const OUString& )
2681 {
2682 LibraryContainerMethodGuard aGuard( *this );
2683 throw IllegalArgumentException();
2684 }
2685
changeLibraryPassword(const OUString &,const OUString &,const OUString &)2686 void SAL_CALL SfxLibraryContainer::changeLibraryPassword(
2687 const OUString&, const OUString&, const OUString& )
2688 {
2689 LibraryContainerMethodGuard aGuard( *this );
2690 throw IllegalArgumentException();
2691 }
2692
2693 // Methods XContainer
addContainerListener(const Reference<XContainerListener> & xListener)2694 void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
2695 {
2696 LibraryContainerMethodGuard aGuard( *this );
2697 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
2698 maNameContainer.addContainerListener( xListener );
2699 }
2700
removeContainerListener(const Reference<XContainerListener> & xListener)2701 void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
2702 {
2703 LibraryContainerMethodGuard aGuard( *this );
2704 maNameContainer.removeContainerListener( xListener );
2705 }
2706
2707 // Methods XLibraryContainerExport
exportLibrary(const OUString & Name,const OUString & URL,const Reference<XInteractionHandler> & Handler)2708 void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2709 const Reference< XInteractionHandler >& Handler )
2710 {
2711 LibraryContainerMethodGuard aGuard( *this );
2712 SfxLibrary* pImplLib = getImplLib( Name );
2713
2714 Reference< XSimpleFileAccess > xToUseSFI;
2715 if( Handler.is() )
2716 {
2717 xToUseSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
2718 ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
2719 if( xToUseSFI.is() )
2720 xToUseSFI->setInteractionHandler( Handler );
2721 }
2722
2723 // Maybe lib is not loaded?!
2724 loadLibrary( Name );
2725
2726 uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
2727 if( pImplLib->mbPasswordProtected )
2728 implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2729 else
2730 implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2731
2732 ::xmlscript::LibDescriptor aLibDesc;
2733 aLibDesc.aName = Name;
2734 aLibDesc.bLink = false; // Link status gets lost?
2735 aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2736 aLibDesc.bPreload = false; // Preload status gets lost?
2737 aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2738 aLibDesc.aElementNames = pImplLib->getElementNames();
2739
2740 implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2741 }
2742
expand_url(const OUString & url)2743 OUString SfxLibraryContainer::expand_url( const OUString& url )
2744 {
2745 if (0 == url.compareToAscii( RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ))
2746 {
2747 if( !mxMacroExpander.is() )
2748 {
2749 Reference< XPropertySet > xProps( mxMSF, UNO_QUERY );
2750 OSL_ASSERT( xProps.is() );
2751 if( xProps.is() )
2752 {
2753 Reference< XComponentContext > xContext;
2754 xProps->getPropertyValue(
2755 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
2756 OSL_ASSERT( xContext.is() );
2757 if( xContext.is() )
2758 {
2759 Reference< util::XMacroExpander > xExpander;
2760 xContext->getValueByName(
2761 OUSTR("/singletons/com.sun.star.util.theMacroExpander") ) >>= xExpander;
2762 if(! xExpander.is())
2763 {
2764 throw uno::DeploymentException(
2765 OUSTR("no macro expander singleton available!"), Reference< XInterface >() );
2766 }
2767 MutexGuard guard( Mutex::getGlobalMutex() );
2768 if( !mxMacroExpander.is() )
2769 {
2770 mxMacroExpander = xExpander;
2771 }
2772 }
2773 }
2774 }
2775
2776 if( !mxMacroExpander.is() )
2777 return url;
2778
2779 // cut protocol
2780 OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
2781 // decode uric class chars
2782 macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
2783 // expand macro string
2784 OUString ret( mxMacroExpander->expandMacros( macro ) );
2785 return ret;
2786 }
2787 else if( mxStringSubstitution.is() )
2788 {
2789 OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2790 return ret;
2791 }
2792 else
2793 {
2794 return url;
2795 }
2796 }
2797
2798 //XLibraryContainer3
getOriginalLibraryLinkURL(const OUString & Name)2799 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2800 {
2801 LibraryContainerMethodGuard aGuard( *this );
2802 SfxLibrary* pImplLib = getImplLib( Name );
2803 sal_Bool bLink = pImplLib->mbLink;
2804 if( !bLink )
2805 throw IllegalArgumentException();
2806 OUString aRetStr = pImplLib->maOrignialStorageURL;
2807 return aRetStr;
2808 }
2809
2810
2811 // XVBACompatibility
getVBACompatibilityMode()2812 ::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode()
2813 {
2814 return mbVBACompat;
2815 }
2816
setVBACompatibilityMode(::sal_Bool _vbacompatmodeon)2817 void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon )
2818 {
2819 /* The member variable mbVBACompat must be set first, the following call
2820 to getBasicManager() may call getVBACompatibilityMode() which returns
2821 this value. */
2822 mbVBACompat = _vbacompatmodeon;
2823 if( BasicManager* pBasMgr = getBasicManager() )
2824 {
2825 // get the standard library
2826 String aLibName = pBasMgr->GetName();
2827 if ( aLibName.Len() == 0 )
2828 aLibName = String( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2829
2830 if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2831 pBasic->SetVBAEnabled( _vbacompatmodeon );
2832
2833 /* If in VBA compatibility mode, force creation of the VBA Globals
2834 object. Each application will create an instance of its own
2835 implementation and store it in its Basic manager. Implementations
2836 will do all necessary additional initialization, such as
2837 registering the global "This***Doc" UNO constant, starting the
2838 document events processor etc.
2839 */
2840 if( mbVBACompat ) try
2841 {
2842 Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
2843 Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
2844 xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
2845 }
2846 catch( Exception& )
2847 {
2848 }
2849 }
2850 }
2851
getRunningVBAScripts()2852 sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts()
2853 {
2854 LibraryContainerMethodGuard aGuard( *this );
2855 return mnRunningVBAScripts;
2856 }
2857
addVBAScriptListener(const Reference<vba::XVBAScriptListener> & rxListener)2858 void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener )
2859 {
2860 maVBAScriptListeners.addTypedListener( rxListener );
2861 }
2862
removeVBAScriptListener(const Reference<vba::XVBAScriptListener> & rxListener)2863 void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener )
2864 {
2865 maVBAScriptListeners.removeTypedListener( rxListener );
2866 }
2867
broadcastVBAScriptEvent(sal_Int32 nIdentifier,const::rtl::OUString & rModuleName)2868 void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const ::rtl::OUString& rModuleName )
2869 {
2870 // own lock for accessing the number of running scripts
2871 enterMethod();
2872 switch( nIdentifier )
2873 {
2874 case vba::VBAScriptEventId::SCRIPT_STARTED:
2875 ++mnRunningVBAScripts;
2876 break;
2877 case vba::VBAScriptEventId::SCRIPT_STOPPED:
2878 --mnRunningVBAScripts;
2879 break;
2880 }
2881 leaveMethod();
2882
2883 Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref
2884 Reference< XInterface > xSender( xModel, UNO_QUERY_THROW );
2885 vba::VBAScriptEvent aEvent( xSender, nIdentifier, rModuleName );
2886 maVBAScriptListeners.notify( aEvent );
2887 }
2888
2889 // Methods XServiceInfo
supportsService(const::rtl::OUString & _rServiceName)2890 ::sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const ::rtl::OUString& _rServiceName )
2891 {
2892 LibraryContainerMethodGuard aGuard( *this );
2893 Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
2894 const OUString* pSupportedServices = aSupportedServices.getConstArray();
2895 for ( sal_Int32 i=0; i<aSupportedServices.getLength(); ++i, ++pSupportedServices )
2896 if ( *pSupportedServices == _rServiceName )
2897 return sal_True;
2898 return sal_False;
2899 }
2900
2901 //============================================================================
2902
2903 // Implementation class SfxLibrary
2904
2905 // Ctor
SfxLibrary(ModifiableHelper & _rModifiable,const Type & aType,const Reference<XMultiServiceFactory> & xMSF,const Reference<XSimpleFileAccess> & xSFI)2906 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
2907 const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI )
2908 : OComponentHelper( m_aMutex )
2909 , mxMSF( xMSF )
2910 , mxSFI( xSFI )
2911 , mrModifiable( _rModifiable )
2912 , maNameContainer( aType )
2913 , mbLoaded( sal_True )
2914 , mbIsModified( sal_True )
2915 , mbInitialised( sal_False )
2916 , mbLink( sal_False )
2917 , mbReadOnly( sal_False )
2918 , mbReadOnlyLink( sal_False )
2919 , mbPreload( sal_False )
2920 , mbPasswordProtected( sal_False )
2921 , mbPasswordVerified( sal_False )
2922 , mbDoc50Password( sal_False )
2923 , mbSharedIndexFile( sal_False )
2924 , mbExtension( sal_False )
2925 {
2926 }
2927
SfxLibrary(ModifiableHelper & _rModifiable,const Type & aType,const Reference<XMultiServiceFactory> & xMSF,const Reference<XSimpleFileAccess> & xSFI,const OUString & aLibInfoFileURL,const OUString & aStorageURL,sal_Bool ReadOnly)2928 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
2929 const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI,
2930 const OUString& aLibInfoFileURL, const OUString& aStorageURL, sal_Bool ReadOnly )
2931 : OComponentHelper( m_aMutex )
2932 , mxMSF( xMSF )
2933 , mxSFI( xSFI )
2934 , mrModifiable( _rModifiable )
2935 , maNameContainer( aType )
2936 , mbLoaded( sal_False )
2937 , mbIsModified( sal_True )
2938 , mbInitialised( sal_False )
2939 , maLibInfoFileURL( aLibInfoFileURL )
2940 , maStorageURL( aStorageURL )
2941 , mbLink( sal_True )
2942 , mbReadOnly( sal_False )
2943 , mbReadOnlyLink( ReadOnly )
2944 , mbPreload( sal_False )
2945 , mbPasswordProtected( sal_False )
2946 , mbPasswordVerified( sal_False )
2947 , mbDoc50Password( sal_False )
2948 , mbSharedIndexFile( sal_False )
2949 , mbExtension( sal_False )
2950 {
2951 }
2952
implSetModified(sal_Bool _bIsModified)2953 void SfxLibrary::implSetModified( sal_Bool _bIsModified )
2954 {
2955 if ( mbIsModified == _bIsModified )
2956 return;
2957 mbIsModified = _bIsModified;
2958 if ( mbIsModified )
2959 mrModifiable.setModified( sal_True );
2960 }
2961
2962 // Methods XInterface
queryInterface(const Type & rType)2963 Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
2964 {
2965 Any aRet;
2966
2967 /*
2968 if( mbReadOnly )
2969 {
2970 aRet = Any( ::cppu::queryInterface( rType,
2971 static_cast< XContainer * >( this ),
2972 static_cast< XNameAccess * >( this ) ) );
2973 }
2974 else
2975 {
2976 */
2977 aRet = Any( ::cppu::queryInterface( rType,
2978 static_cast< XContainer * >( this ),
2979 static_cast< XNameContainer * >( this ),
2980 static_cast< XNameAccess * >( this ),
2981 static_cast< XElementAccess * >( this ),
2982 static_cast< XChangesNotifier * >( this ) ) );
2983 //}
2984 if( !aRet.hasValue() )
2985 aRet = OComponentHelper::queryInterface( rType );
2986 return aRet;
2987 }
2988
2989 // Methods XElementAccess
getElementType()2990 Type SfxLibrary::getElementType()
2991 {
2992 return maNameContainer.getElementType();
2993 }
2994
hasElements()2995 sal_Bool SfxLibrary::hasElements()
2996 {
2997 sal_Bool bRet = maNameContainer.hasElements();
2998 return bRet;
2999 }
3000
3001 // Methods XNameAccess
getByName(const OUString & aName)3002 Any SfxLibrary::getByName( const OUString& aName )
3003 {
3004 impl_checkLoaded();
3005
3006 Any aRetAny = maNameContainer.getByName( aName ) ;
3007 return aRetAny;
3008 }
3009
getElementNames()3010 Sequence< OUString > SfxLibrary::getElementNames()
3011 {
3012 return maNameContainer.getElementNames();
3013 }
3014
hasByName(const OUString & aName)3015 sal_Bool SfxLibrary::hasByName( const OUString& aName )
3016 {
3017 sal_Bool bRet = maNameContainer.hasByName( aName );
3018 return bRet;
3019 }
3020
impl_checkReadOnly()3021 void SfxLibrary::impl_checkReadOnly()
3022 {
3023 if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3024 throw IllegalArgumentException(
3025 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Library is readonly." ) ),
3026 // TODO: resource
3027 *this, 0
3028 );
3029 }
3030
impl_checkLoaded()3031 void SfxLibrary::impl_checkLoaded()
3032 {
3033 if ( !mbLoaded )
3034 throw WrappedTargetException(
3035 ::rtl::OUString(),
3036 *this,
3037 makeAny( LibraryNotLoadedException(
3038 ::rtl::OUString(),
3039 *this
3040 ) )
3041 );
3042 }
3043
3044 // Methods XNameReplace
replaceByName(const OUString & aName,const Any & aElement)3045 void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3046 {
3047 impl_checkReadOnly();
3048 impl_checkLoaded();
3049
3050 OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::replaceByName: replacing element is invalid!" );
3051
3052 maNameContainer.replaceByName( aName, aElement );
3053 implSetModified( sal_True );
3054 }
3055
3056
3057 // Methods XNameContainer
insertByName(const OUString & aName,const Any & aElement)3058 void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3059 {
3060 impl_checkReadOnly();
3061 impl_checkLoaded();
3062
3063 OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::insertByName: to-be-inserted element is invalid!" );
3064
3065 maNameContainer.insertByName( aName, aElement );
3066 implSetModified( sal_True );
3067 }
3068
impl_removeWithoutChecks(const::rtl::OUString & _rElementName)3069 void SfxLibrary::impl_removeWithoutChecks( const ::rtl::OUString& _rElementName )
3070 {
3071 maNameContainer.removeByName( _rElementName );
3072 implSetModified( sal_True );
3073
3074 // Remove element file
3075 if( !maStorageURL.isEmpty() )
3076 {
3077 INetURLObject aElementInetObj( maStorageURL );
3078 aElementInetObj.insertName( _rElementName, sal_False,
3079 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
3080 aElementInetObj.setExtension( maLibElementFileExtension );
3081 OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
3082
3083 try
3084 {
3085 if( mxSFI->exists( aFile ) )
3086 mxSFI->kill( aFile );
3087 }
3088 catch( Exception& )
3089 {
3090 DBG_UNHANDLED_EXCEPTION();
3091 }
3092 }
3093 }
3094
removeByName(const OUString & Name)3095 void SfxLibrary::removeByName( const OUString& Name )
3096 {
3097 impl_checkReadOnly();
3098 impl_checkLoaded();
3099 impl_removeWithoutChecks( Name );
3100 }
3101
3102 // XTypeProvider
getTypes()3103 Sequence< Type > SfxLibrary::getTypes()
3104 {
3105 static OTypeCollection * s_pTypes_NameContainer = 0;
3106 {
3107 if( !s_pTypes_NameContainer )
3108 {
3109 MutexGuard aGuard( Mutex::getGlobalMutex() );
3110 if( !s_pTypes_NameContainer )
3111 {
3112 static OTypeCollection s_aTypes_NameContainer(
3113 ::getCppuType( (const Reference< XNameContainer > *)0 ),
3114 ::getCppuType( (const Reference< XContainer > *)0 ),
3115 ::getCppuType( (const Reference< XChangesNotifier > *)0 ),
3116 OComponentHelper::getTypes() );
3117 s_pTypes_NameContainer = &s_aTypes_NameContainer;
3118 }
3119 }
3120 return s_pTypes_NameContainer->getTypes();
3121 }
3122 }
3123
3124
getImplementationId()3125 Sequence< sal_Int8 > SfxLibrary::getImplementationId()
3126 {
3127 static OImplementationId * s_pId_NameContainer = 0;
3128 {
3129 if( !s_pId_NameContainer )
3130 {
3131 MutexGuard aGuard( Mutex::getGlobalMutex() );
3132 if( !s_pId_NameContainer )
3133 {
3134 static OImplementationId s_aId_NameContainer;
3135 s_pId_NameContainer = &s_aId_NameContainer;
3136 }
3137 }
3138 return s_pId_NameContainer->getImplementationId();
3139 }
3140 }
3141
3142 // Methods XContainer
addContainerListener(const Reference<XContainerListener> & xListener)3143 void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
3144 {
3145 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3146 maNameContainer.addContainerListener( xListener );
3147 }
3148
removeContainerListener(const Reference<XContainerListener> & xListener)3149 void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
3150 {
3151 maNameContainer.removeContainerListener( xListener );
3152 }
3153
3154 // Methods XChangesNotifier
addChangesListener(const Reference<XChangesListener> & xListener)3155 void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
3156 {
3157 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3158 maNameContainer.addChangesListener( xListener );
3159 }
3160
removeChangesListener(const Reference<XChangesListener> & xListener)3161 void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
3162 {
3163 maNameContainer.removeChangesListener( xListener );
3164 }
3165
3166 //============================================================================
3167 // Implementation class ScriptExtensionIterator
3168
3169 static rtl::OUString aBasicLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.basic-library" ) );
3170 static rtl::OUString aDialogLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.dialog-library" ) );
3171
ScriptExtensionIterator(void)3172 ScriptExtensionIterator::ScriptExtensionIterator( void )
3173 : m_eState( USER_EXTENSIONS )
3174 , m_bUserPackagesLoaded( false )
3175 , m_bSharedPackagesLoaded( false )
3176 , m_bBundledPackagesLoaded( false )
3177 , m_iUserPackage( 0 )
3178 , m_iSharedPackage( 0 )
3179 , m_iBundledPackage( 0 )
3180 , m_pScriptSubPackageIterator( NULL )
3181 {
3182 Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
3183 Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
3184 OSL_ASSERT( xProps.is() );
3185 if (xProps.is())
3186 {
3187 xProps->getPropertyValue(
3188 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext;
3189 OSL_ASSERT( m_xContext.is() );
3190 }
3191 if( !m_xContext.is() )
3192 {
3193 throw RuntimeException(
3194 ::rtl::OUString::createFromAscii( "ScriptExtensionIterator::init(), no XComponentContext" ),
3195 Reference< XInterface >() );
3196 }
3197 }
3198
nextBasicOrDialogLibrary(bool & rbPureDialogLib)3199 rtl::OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
3200 {
3201 rtl::OUString aRetLib;
3202
3203 while( aRetLib.isEmpty() && m_eState != END_REACHED )
3204 {
3205 switch( m_eState )
3206 {
3207 case USER_EXTENSIONS:
3208 {
3209 Reference< deployment::XPackage > xScriptPackage =
3210 implGetNextUserScriptPackage( rbPureDialogLib );
3211 if( !xScriptPackage.is() )
3212 break;
3213
3214 aRetLib = xScriptPackage->getURL();
3215 break;
3216 }
3217
3218 case SHARED_EXTENSIONS:
3219 {
3220 Reference< deployment::XPackage > xScriptPackage =
3221 implGetNextSharedScriptPackage( rbPureDialogLib );
3222 if( !xScriptPackage.is() )
3223 break;
3224
3225 aRetLib = xScriptPackage->getURL();
3226 break;
3227 }
3228 case BUNDLED_EXTENSIONS:
3229 {
3230 Reference< deployment::XPackage > xScriptPackage =
3231 implGetNextBundledScriptPackage( rbPureDialogLib );
3232 if( !xScriptPackage.is() )
3233 break;
3234
3235 aRetLib = xScriptPackage->getURL();
3236 break;
3237 }
3238 case END_REACHED:
3239 VOS_ENSURE( false, "ScriptExtensionIterator::nextBasicOrDialogLibrary(): Invalid case END_REACHED" );
3240 break;
3241 }
3242 }
3243
3244 return aRetLib;
3245 }
3246
ScriptSubPackageIterator(Reference<deployment::XPackage> xMainPackage)3247 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
3248 : m_xMainPackage( xMainPackage )
3249 , m_bIsValid( false )
3250 , m_bIsBundle( false )
3251 , m_nSubPkgCount( 0 )
3252 , m_iNextSubPkg( 0 )
3253 {
3254 Reference< deployment::XPackage > xScriptPackage;
3255 if( !m_xMainPackage.is() )
3256 return;
3257
3258 // Check if parent package is registered
3259 beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3260 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3261 bool bRegistered = false;
3262 if( option.IsPresent )
3263 {
3264 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3265 if( !reg.IsAmbiguous && reg.Value )
3266 bRegistered = true;
3267 }
3268 if( bRegistered )
3269 {
3270 m_bIsValid = true;
3271 if( m_xMainPackage->isBundle() )
3272 {
3273 m_bIsBundle = true;
3274 m_aSubPkgSeq = m_xMainPackage->getBundle
3275 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
3276 m_nSubPkgCount = m_aSubPkgSeq.getLength();
3277 }
3278 }
3279 }
3280
getNextScriptSubPackage(bool & rbPureDialogLib)3281 Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage
3282 ( bool& rbPureDialogLib )
3283 {
3284 rbPureDialogLib = false;
3285
3286 Reference< deployment::XPackage > xScriptPackage;
3287 if( !m_bIsValid )
3288 return xScriptPackage;
3289
3290 if( m_bIsBundle )
3291 {
3292 const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3293 sal_Int32 iPkg;
3294 for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3295 {
3296 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3297 xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3298 if( xScriptPackage.is() )
3299 break;
3300 }
3301 m_iNextSubPkg = iPkg + 1;
3302 }
3303 else
3304 {
3305 xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3306 m_bIsValid = false; // No more script packages
3307 }
3308
3309 return xScriptPackage;
3310 }
3311
implDetectScriptPackage(const Reference<deployment::XPackage> xPackage,bool & rbPureDialogLib)3312 Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage
3313 ( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
3314 {
3315 Reference< deployment::XPackage > xScriptPackage;
3316
3317 if( xPackage.is() )
3318 {
3319 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
3320 rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
3321 if( aMediaType.equals( aBasicLibMediaType ) )
3322 {
3323 xScriptPackage = xPackage;
3324 }
3325 else if( aMediaType.equals( aDialogLibMediaType ) )
3326 {
3327 rbPureDialogLib = true;
3328 xScriptPackage = xPackage;
3329 }
3330 }
3331
3332 return xScriptPackage;
3333 }
3334
implGetScriptPackageFromPackage(const Reference<deployment::XPackage> xPackage,bool & rbPureDialogLib)3335 Reference< deployment::XPackage > ScriptExtensionIterator::implGetScriptPackageFromPackage
3336 ( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
3337 {
3338 rbPureDialogLib = false;
3339
3340 Reference< deployment::XPackage > xScriptPackage;
3341 if( !xPackage.is() )
3342 return xScriptPackage;
3343
3344 // Check if parent package is registered
3345 beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
3346 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3347 bool bRegistered = false;
3348 if( option.IsPresent )
3349 {
3350 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3351 if( !reg.IsAmbiguous && reg.Value )
3352 bRegistered = true;
3353 }
3354 if( bRegistered )
3355 {
3356 if( xPackage->isBundle() )
3357 {
3358 Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
3359 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
3360 sal_Int32 nPkgCount = aPkgSeq.getLength();
3361 const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
3362 for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
3363 {
3364 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3365 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
3366 rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
3367 if( aMediaType.equals( aBasicLibMediaType ) )
3368 {
3369 xScriptPackage = xSubPkg;
3370 break;
3371 }
3372 else if( aMediaType.equals( aDialogLibMediaType ) )
3373 {
3374 rbPureDialogLib = true;
3375 xScriptPackage = xSubPkg;
3376 break;
3377 }
3378 }
3379 }
3380 else
3381 {
3382 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
3383 rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
3384 if( aMediaType.equals( aBasicLibMediaType ) )
3385 {
3386 xScriptPackage = xPackage;
3387 }
3388 else if( aMediaType.equals( aDialogLibMediaType ) )
3389 {
3390 rbPureDialogLib = true;
3391 xScriptPackage = xPackage;
3392 }
3393 }
3394 }
3395
3396 return xScriptPackage;
3397 }
3398
implGetNextUserScriptPackage(bool & rbPureDialogLib)3399 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage
3400 ( bool& rbPureDialogLib )
3401 {
3402 Reference< deployment::XPackage > xScriptPackage;
3403
3404 if( !m_bUserPackagesLoaded )
3405 {
3406 try
3407 {
3408 Reference< XExtensionManager > xManager =
3409 ExtensionManager::get( m_xContext );
3410 m_aUserPackagesSeq = xManager->getDeployedExtensions
3411 (rtl::OUString::createFromAscii("user"),
3412 Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
3413 }
3414 catch( com::sun::star::uno::DeploymentException& )
3415 {
3416 // Special Office installations may not contain deployment code
3417 m_eState = END_REACHED;
3418 return xScriptPackage;
3419 }
3420
3421 m_bUserPackagesLoaded = true;
3422 }
3423
3424 if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3425 {
3426 m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
3427 }
3428 else
3429 {
3430 if( m_pScriptSubPackageIterator == NULL )
3431 {
3432 const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3433 Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3434 VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextUserScriptPackage(): Invalid package" );
3435 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3436 }
3437
3438 if( m_pScriptSubPackageIterator != NULL )
3439 {
3440 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3441 if( !xScriptPackage.is() )
3442 {
3443 delete m_pScriptSubPackageIterator;
3444 m_pScriptSubPackageIterator = NULL;
3445 m_iUserPackage++;
3446 }
3447 }
3448 }
3449
3450 return xScriptPackage;
3451 }
3452
implGetNextSharedScriptPackage(bool & rbPureDialogLib)3453 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage
3454 ( bool& rbPureDialogLib )
3455 {
3456 Reference< deployment::XPackage > xScriptPackage;
3457
3458 if( !m_bSharedPackagesLoaded )
3459 {
3460 try
3461 {
3462 Reference< XExtensionManager > xSharedManager =
3463 ExtensionManager::get( m_xContext );
3464 m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions
3465 (rtl::OUString::createFromAscii("shared"),
3466 Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
3467 }
3468 catch( com::sun::star::uno::DeploymentException& )
3469 {
3470 // Special Office installations may not contain deployment code
3471 return xScriptPackage;
3472 }
3473
3474 m_bSharedPackagesLoaded = true;
3475 }
3476
3477 if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3478 {
3479 m_eState = BUNDLED_EXTENSIONS;
3480 }
3481 else
3482 {
3483 if( m_pScriptSubPackageIterator == NULL )
3484 {
3485 const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3486 Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3487 VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextSharedScriptPackage(): Invalid package" );
3488 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3489 }
3490
3491 if( m_pScriptSubPackageIterator != NULL )
3492 {
3493 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3494 if( !xScriptPackage.is() )
3495 {
3496 delete m_pScriptSubPackageIterator;
3497 m_pScriptSubPackageIterator = NULL;
3498 m_iSharedPackage++;
3499 }
3500 }
3501 }
3502
3503 return xScriptPackage;
3504 }
3505
implGetNextBundledScriptPackage(bool & rbPureDialogLib)3506 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage
3507 ( bool& rbPureDialogLib )
3508 {
3509 Reference< deployment::XPackage > xScriptPackage;
3510
3511 if( !m_bBundledPackagesLoaded )
3512 {
3513 try
3514 {
3515 Reference< XExtensionManager > xManager =
3516 ExtensionManager::get( m_xContext );
3517 m_aBundledPackagesSeq = xManager->getDeployedExtensions
3518 (rtl::OUString::createFromAscii("bundled"),
3519 Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
3520 }
3521 catch( com::sun::star::uno::DeploymentException& )
3522 {
3523 // Special Office installations may not contain deployment code
3524 return xScriptPackage;
3525 }
3526
3527 m_bBundledPackagesLoaded = true;
3528 }
3529
3530 if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3531 {
3532 m_eState = END_REACHED;
3533 }
3534 else
3535 {
3536 if( m_pScriptSubPackageIterator == NULL )
3537 {
3538 const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3539 Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3540 VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextBundledScriptPackage(): Invalid package" );
3541 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3542 }
3543
3544 if( m_pScriptSubPackageIterator != NULL )
3545 {
3546 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3547 if( !xScriptPackage.is() )
3548 {
3549 delete m_pScriptSubPackageIterator;
3550 m_pScriptSubPackageIterator = NULL;
3551 m_iBundledPackage++;
3552 }
3553 }
3554 }
3555
3556 return xScriptPackage;
3557 }
3558
3559 } // namespace basic
3560