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