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_ucbhelper.hxx"
26 /**************************************************************************
27 TODO
28 **************************************************************************
29
30 *************************************************************************/
31
32 #include <hash_map>
33 #include <com/sun/star/ucb/ContentAction.hpp>
34 #include <com/sun/star/ucb/CommandInfoChange.hpp>
35 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
38 #include <cppuhelper/interfacecontainer.hxx>
39
40 #include "osl/diagnose.h"
41 #include "osl/mutex.hxx"
42 #include "rtl/ref.hxx"
43 #include <ucbhelper/contentidentifier.hxx>
44 #include <ucbhelper/contenthelper.hxx>
45 #include <ucbhelper/providerhelper.hxx>
46 #include <ucbhelper/contentinfo.hxx>
47
48 using namespace com::sun::star;
49
50 namespace ucbhelper_impl
51 {
52
53 //=========================================================================
54 //
55 // class PropertyEventSequence.
56 //
57 //=========================================================================
58
59 class PropertyEventSequence
60 {
61 uno::Sequence< beans::PropertyChangeEvent > m_aSeq;
62 sal_uInt32 m_nPos;
63
64 public:
PropertyEventSequence(sal_uInt32 nSize)65 PropertyEventSequence( sal_uInt32 nSize )
66 : m_aSeq( nSize ), m_nPos( 0 ) {};
67
append(const beans::PropertyChangeEvent & rEvt)68 void append( const beans::PropertyChangeEvent& rEvt )
69 { m_aSeq.getArray()[ m_nPos ] = rEvt; ++m_nPos; }
70
getEvents()71 const uno::Sequence< beans::PropertyChangeEvent >& getEvents()
72 { m_aSeq.realloc( m_nPos ); return m_aSeq; }
73 };
74
75 //=========================================================================
76 //
77 // PropertiesEventListenerMap.
78 //
79 //=========================================================================
80
81 typedef void* XPropertiesChangeListenerPtr; // -> Compiler problems!
82
83 struct equalPtr
84 {
operator ()ucbhelper_impl::equalPtr85 bool operator()( const XPropertiesChangeListenerPtr& rp1,
86 const XPropertiesChangeListenerPtr& rp2 ) const
87 {
88 return ( rp1 == rp2 );
89 }
90 };
91
92 struct hashPtr
93 {
operator ()ucbhelper_impl::hashPtr94 size_t operator()( const XPropertiesChangeListenerPtr& rp ) const
95 {
96 return (size_t)rp;
97 }
98 };
99
100 typedef std::hash_map
101 <
102 XPropertiesChangeListenerPtr,
103 PropertyEventSequence*,
104 hashPtr,
105 equalPtr
106 >
107 PropertiesEventListenerMap;
108
109 //=========================================================================
110 //
111 // PropertyChangeListenerContainer.
112 //
113 //=========================================================================
114
115 struct equalStr
116 {
operator ()ucbhelper_impl::equalStr117 bool operator()( const rtl::OUString& s1, const rtl::OUString& s2 ) const
118 {
119 return !!( s1 == s2 );
120 }
121 };
122
123 struct hashStr
124 {
operator ()ucbhelper_impl::hashStr125 size_t operator()( const rtl::OUString& rName ) const
126 {
127 return rName.hashCode();
128 }
129 };
130
131 typedef cppu::OMultiTypeInterfaceContainerHelperVar
132 <
133 rtl::OUString,
134 hashStr,
135 equalStr
136 > PropertyChangeListeners;
137
138 //=========================================================================
139 //
140 // struct ContentImplHelper_Impl
141 //
142 //=========================================================================
143
144 struct ContentImplHelper_Impl
145 {
146 rtl::Reference< ::ucbhelper::PropertySetInfo > m_xPropSetInfo;
147 rtl::Reference< ::ucbhelper::CommandProcessorInfo > m_xCommandsInfo;
148 cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
149 cppu::OInterfaceContainerHelper* m_pContentEventListeners;
150 cppu::OInterfaceContainerHelper* m_pPropSetChangeListeners;
151 cppu::OInterfaceContainerHelper* m_pCommandChangeListeners;
152 PropertyChangeListeners* m_pPropertyChangeListeners;
153
ContentImplHelper_Implucbhelper_impl::ContentImplHelper_Impl154 ContentImplHelper_Impl()
155 : m_pDisposeEventListeners( 0 ),
156 m_pContentEventListeners( 0 ),
157 m_pPropSetChangeListeners( 0 ),
158 m_pCommandChangeListeners( 0 ),
159 m_pPropertyChangeListeners( 0 ) {}
160
~ContentImplHelper_Implucbhelper_impl::ContentImplHelper_Impl161 ~ContentImplHelper_Impl()
162 {
163 delete m_pDisposeEventListeners;
164 delete m_pContentEventListeners;
165 delete m_pPropSetChangeListeners;
166 delete m_pCommandChangeListeners;
167 delete m_pPropertyChangeListeners;
168 }
169 };
170
171 } // namespace ucbhelper_impl
172
173 using namespace ucbhelper_impl;
174
175 //=========================================================================
176 //=========================================================================
177 //
178 // ContentImplHelper Implementation.
179 //
180 //=========================================================================
181 //=========================================================================
182
183 namespace ucbhelper {
184
ContentImplHelper(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,const rtl::Reference<ContentProviderImplHelper> & rxProvider,const uno::Reference<com::sun::star::ucb::XContentIdentifier> & Identifier)185 ContentImplHelper::ContentImplHelper(
186 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
187 const rtl::Reference< ContentProviderImplHelper >& rxProvider,
188 const uno::Reference<
189 com::sun::star::ucb::XContentIdentifier >& Identifier )
190 : m_pImpl( new ContentImplHelper_Impl ),
191 m_xSMgr( rxSMgr ),
192 m_xIdentifier( Identifier ),
193 m_xProvider( rxProvider ),
194 m_nCommandId( 0 )
195 {
196 }
197
198 //=========================================================================
199 // virtual
~ContentImplHelper()200 ContentImplHelper::~ContentImplHelper()
201 {
202 delete m_pImpl;
203 }
204
205 //=========================================================================
206 //
207 // XInterface methods.
208 //
209 //=========================================================================
210
acquire()211 void SAL_CALL ContentImplHelper::acquire()
212 throw()
213 {
214 cppu::OWeakObject::acquire();
215 }
216
release()217 void SAL_CALL ContentImplHelper::release()
218 throw()
219 {
220 // #144882# - Call to OWeakObject::release may destroy m_xProvider.
221 // Prevent this.
222 rtl::Reference< ContentProviderImplHelper > xKeepProviderAlive(
223 m_xProvider );
224
225 {
226 osl::MutexGuard aGuard( m_xProvider->m_aMutex );
227 OWeakObject::release();
228 }
229 }
230
queryInterface(const uno::Type & rType)231 uno::Any SAL_CALL ContentImplHelper::queryInterface( const uno::Type & rType )
232 {
233 com::sun::star::uno::Any aRet = cppu::queryInterface( rType,
234 static_cast< lang::XTypeProvider * >(this),
235 static_cast< lang::XServiceInfo * >(this),
236 static_cast< lang::XComponent * >(this),
237 static_cast< com::sun::star::ucb::XContent * >(this),
238 static_cast< com::sun::star::ucb::XCommandProcessor * >(this),
239 static_cast< beans::XPropertiesChangeNotifier * >(this),
240 static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >(this),
241 static_cast< beans::XPropertyContainer * >(this),
242 static_cast< beans::XPropertySetInfoChangeNotifier * >(this),
243 static_cast< container::XChild * >(this));
244 return aRet.hasValue() ? aRet : cppu::OWeakObject::queryInterface( rType );
245 }
246
247 //=========================================================================
248 //
249 // XTypeProvider methods.
250 //
251 //=========================================================================
252
253 XTYPEPROVIDER_IMPL_10( ContentImplHelper,
254 lang::XTypeProvider,
255 lang::XServiceInfo,
256 lang::XComponent,
257 com::sun::star::ucb::XContent,
258 com::sun::star::ucb::XCommandProcessor,
259 beans::XPropertiesChangeNotifier,
260 com::sun::star::ucb::XCommandInfoChangeNotifier,
261 beans::XPropertyContainer,
262 beans::XPropertySetInfoChangeNotifier,
263 container::XChild );
264
265 //=========================================================================
266 //
267 // XServiceInfo methods.
268 //
269 //=========================================================================
270
271 // virtual
supportsService(const rtl::OUString & ServiceName)272 sal_Bool SAL_CALL ContentImplHelper::supportsService(
273 const rtl::OUString& ServiceName )
274 {
275 uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
276 const rtl::OUString* pArray = aSNL.getConstArray();
277 for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
278 {
279 if ( pArray[ i ] == ServiceName )
280 return sal_True;
281 }
282
283 return sal_False;
284 }
285
286 //=========================================================================
287 //
288 // XComponent methods.
289 //
290 //=========================================================================
291
292 // virtual
dispose()293 void SAL_CALL ContentImplHelper::dispose()
294 {
295 osl::MutexGuard aGuard( m_aMutex );
296
297 if ( m_pImpl->m_pDisposeEventListeners &&
298 m_pImpl->m_pDisposeEventListeners->getLength() )
299 {
300 lang::EventObject aEvt;
301 aEvt.Source = static_cast< lang::XComponent * >( this );
302 m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
303 }
304
305 if ( m_pImpl->m_pContentEventListeners &&
306 m_pImpl->m_pContentEventListeners->getLength() )
307 {
308 lang::EventObject aEvt;
309 aEvt.Source = static_cast< com::sun::star::ucb::XContent * >( this );
310 m_pImpl->m_pContentEventListeners->disposeAndClear( aEvt );
311 }
312
313 if ( m_pImpl->m_pPropSetChangeListeners &&
314 m_pImpl->m_pPropSetChangeListeners->getLength() )
315 {
316 lang::EventObject aEvt;
317 aEvt.Source
318 = static_cast< beans::XPropertySetInfoChangeNotifier * >( this );
319 m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
320 }
321
322 if ( m_pImpl->m_pCommandChangeListeners &&
323 m_pImpl->m_pCommandChangeListeners->getLength() )
324 {
325 lang::EventObject aEvt;
326 aEvt.Source = static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >( this );
327 m_pImpl->m_pCommandChangeListeners->disposeAndClear( aEvt );
328 }
329
330 if ( m_pImpl->m_pPropertyChangeListeners )
331 {
332 lang::EventObject aEvt;
333 aEvt.Source
334 = static_cast< beans::XPropertiesChangeNotifier * >( this );
335 m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
336 }
337 }
338
339 //=========================================================================
340 // virtual
addEventListener(const uno::Reference<lang::XEventListener> & Listener)341 void SAL_CALL ContentImplHelper::addEventListener(
342 const uno::Reference< lang::XEventListener >& Listener )
343 {
344 osl::MutexGuard aGuard( m_aMutex );
345
346 if ( !m_pImpl->m_pDisposeEventListeners )
347 m_pImpl->m_pDisposeEventListeners
348 = new cppu::OInterfaceContainerHelper( m_aMutex );
349
350 m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
351 }
352
353 //=========================================================================
354 // virtual
removeEventListener(const uno::Reference<lang::XEventListener> & Listener)355 void SAL_CALL ContentImplHelper::removeEventListener(
356 const uno::Reference< lang::XEventListener >& Listener )
357 {
358 osl::MutexGuard aGuard( m_aMutex );
359
360 if ( m_pImpl->m_pDisposeEventListeners )
361 m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
362 }
363
364 //=========================================================================
365 //
366 // XContent methods.
367 //
368 //=========================================================================
369
370 // virtual
371 uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL
getIdentifier()372 ContentImplHelper::getIdentifier()
373 {
374 return m_xIdentifier;
375 }
376
377 //=========================================================================
378 // virtual
addContentEventListener(const uno::Reference<com::sun::star::ucb::XContentEventListener> & Listener)379 void SAL_CALL ContentImplHelper::addContentEventListener(
380 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
381 {
382 osl::MutexGuard aGuard( m_aMutex );
383
384 if ( !m_pImpl->m_pContentEventListeners )
385 m_pImpl->m_pContentEventListeners
386 = new cppu::OInterfaceContainerHelper( m_aMutex );
387
388 m_pImpl->m_pContentEventListeners->addInterface( Listener );
389 }
390
391 //=========================================================================
392 // virtual
removeContentEventListener(const uno::Reference<com::sun::star::ucb::XContentEventListener> & Listener)393 void SAL_CALL ContentImplHelper::removeContentEventListener(
394 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
395 {
396 osl::MutexGuard aGuard( m_aMutex );
397
398 if ( m_pImpl->m_pContentEventListeners )
399 m_pImpl->m_pContentEventListeners->removeInterface( Listener );
400 }
401
402 //=========================================================================
403 //
404 // XCommandProcessor methods.
405 //
406 //=========================================================================
407
408 // virtual
createCommandIdentifier()409 sal_Int32 SAL_CALL ContentImplHelper::createCommandIdentifier()
410 {
411 osl::MutexGuard aGuard( m_aMutex );
412
413 // Just increase counter on every call to generate an identifier.
414 return ++m_nCommandId;
415 }
416
417 //=========================================================================
418 //
419 // XPropertiesChangeNotifier methods.
420 //
421 //=========================================================================
422
423 // virtual
addPropertiesChangeListener(const uno::Sequence<rtl::OUString> & PropertyNames,const uno::Reference<beans::XPropertiesChangeListener> & Listener)424 void SAL_CALL ContentImplHelper::addPropertiesChangeListener(
425 const uno::Sequence< rtl::OUString >& PropertyNames,
426 const uno::Reference< beans::XPropertiesChangeListener >& Listener )
427 {
428 osl::MutexGuard aGuard( m_aMutex );
429
430 if ( !m_pImpl->m_pPropertyChangeListeners )
431 m_pImpl->m_pPropertyChangeListeners
432 = new PropertyChangeListeners( m_aMutex );
433
434 sal_Int32 nCount = PropertyNames.getLength();
435 if ( !nCount )
436 {
437 // Note: An empty sequence means a listener for "all" properties.
438 m_pImpl->m_pPropertyChangeListeners->addInterface(
439 rtl::OUString(), Listener );
440 }
441 else
442 {
443 const rtl::OUString* pSeq = PropertyNames.getConstArray();
444
445 for ( sal_Int32 n = 0; n < nCount; ++n )
446 {
447 const rtl::OUString& rName = pSeq[ n ];
448 if ( rName.getLength() )
449 m_pImpl->m_pPropertyChangeListeners->addInterface(
450 rName, Listener );
451 }
452 }
453 }
454
455 //=========================================================================
456 // virtual
removePropertiesChangeListener(const uno::Sequence<rtl::OUString> & PropertyNames,const uno::Reference<beans::XPropertiesChangeListener> & Listener)457 void SAL_CALL ContentImplHelper::removePropertiesChangeListener(
458 const uno::Sequence< rtl::OUString >& PropertyNames,
459 const uno::Reference< beans::XPropertiesChangeListener >& Listener )
460 {
461 osl::MutexGuard aGuard( m_aMutex );
462
463 if ( !m_pImpl->m_pPropertyChangeListeners )
464 return;
465
466 sal_Int32 nCount = PropertyNames.getLength();
467 if ( !nCount )
468 {
469 // Note: An empty sequence means a listener for "all" properties.
470 m_pImpl->m_pPropertyChangeListeners->removeInterface(
471 rtl::OUString(), Listener );
472 }
473 else
474 {
475 const rtl::OUString* pSeq = PropertyNames.getConstArray();
476
477 for ( sal_Int32 n = 0; n < nCount; ++n )
478 {
479 const rtl::OUString& rName = pSeq[ n ];
480 if ( rName.getLength() )
481 m_pImpl->m_pPropertyChangeListeners->removeInterface(
482 rName, Listener );
483 }
484 }
485 }
486
487 //=========================================================================
488 //
489 // XCommandInfoChangeNotifier methods.
490 //
491 //=========================================================================
492
493 // virtual
addCommandInfoChangeListener(const uno::Reference<com::sun::star::ucb::XCommandInfoChangeListener> & Listener)494 void SAL_CALL ContentImplHelper::addCommandInfoChangeListener(
495 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
496 {
497 osl::MutexGuard aGuard( m_aMutex );
498
499 if ( !m_pImpl->m_pCommandChangeListeners )
500 m_pImpl->m_pCommandChangeListeners
501 = new cppu::OInterfaceContainerHelper( m_aMutex );
502
503 m_pImpl->m_pCommandChangeListeners->addInterface( Listener );
504 }
505
506 //=========================================================================
507 // virtual
removeCommandInfoChangeListener(const uno::Reference<com::sun::star::ucb::XCommandInfoChangeListener> & Listener)508 void SAL_CALL ContentImplHelper::removeCommandInfoChangeListener(
509 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
510 {
511 osl::MutexGuard aGuard( m_aMutex );
512
513 if ( m_pImpl->m_pCommandChangeListeners )
514 m_pImpl->m_pCommandChangeListeners->removeInterface( Listener );
515 }
516
517 //=========================================================================
518 //
519 // XPropertyContainer methods.
520 //
521 //=========================================================================
522
523 // virtual
addProperty(const rtl::OUString & Name,sal_Int16 Attributes,const uno::Any & DefaultValue)524 void SAL_CALL ContentImplHelper::addProperty(
525 const rtl::OUString& Name,
526 sal_Int16 Attributes,
527 const uno::Any& DefaultValue )
528 {
529 osl::MutexGuard aGuard( m_aMutex );
530
531 //////////////////////////////////////////////////////////////////////
532 // Make sure a property with the requested name does not already
533 // exist in dynamic and static(!) properties.
534 //////////////////////////////////////////////////////////////////////
535
536 // @@@ Need real command environment here, but where to get it from?
537 // XPropertyContainer interface should be replaced by
538 // XCommandProcessor commands!
539 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
540
541 if ( getPropertySetInfo( xEnv )->hasPropertyByName( Name ) )
542 {
543 // Property does already exist.
544 throw beans::PropertyExistException();
545 }
546
547 //////////////////////////////////////////////////////////////////////
548 // Add a new dynamic property.
549 //////////////////////////////////////////////////////////////////////
550
551 // Open/create persistent property set.
552 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet(
553 getAdditionalPropertySet( sal_True ) );
554
555 OSL_ENSURE( xSet.is(),
556 "ContentImplHelper::addProperty - No property set!" );
557
558 if ( xSet.is() )
559 {
560 uno::Reference< beans::XPropertyContainer > xContainer(
561 xSet, uno::UNO_QUERY );
562
563 OSL_ENSURE(
564 xContainer.is(),
565 "ContentImplHelper::addProperty - No property container!" );
566
567 if ( xContainer.is() )
568 {
569 // Property is always removeable.
570 Attributes |= beans::PropertyAttribute::REMOVEABLE;
571
572 try
573 {
574 xContainer->addProperty( Name, Attributes, DefaultValue );
575 }
576 catch ( beans::PropertyExistException const & )
577 {
578 OSL_ENSURE( sal_False,
579 "ContentImplHelper::addProperty - Exists!" );
580 throw;
581 }
582 catch ( beans::IllegalTypeException const & )
583 {
584 OSL_ENSURE( sal_False,
585 "ContentImplHelper::addProperty - Wrong Type!" );
586 throw;
587 }
588 catch ( lang::IllegalArgumentException const & )
589 {
590 OSL_ENSURE( sal_False,
591 "ContentImplHelper::addProperty - Illegal Arg!" );
592 throw;
593 }
594
595 // Success!
596
597 if ( m_pImpl->m_xPropSetInfo.is() )
598 {
599 // Info cached in propertyset info is invalid now!
600 m_pImpl->m_xPropSetInfo->reset();
601 }
602
603 // Notify propertyset info change listeners.
604 if ( m_pImpl->m_pPropSetChangeListeners &&
605 m_pImpl->m_pPropSetChangeListeners->getLength() )
606 {
607 beans::PropertySetInfoChangeEvent evt(
608 static_cast< cppu::OWeakObject * >( this ),
609 Name,
610 -1, // No handle available
611 beans::PropertySetInfoChange::PROPERTY_INSERTED );
612 notifyPropertySetInfoChange( evt );
613 }
614 }
615 }
616 }
617
618 //=========================================================================
619 // virtual
removeProperty(const rtl::OUString & Name)620 void SAL_CALL ContentImplHelper::removeProperty( const rtl::OUString& Name )
621 {
622 osl::MutexGuard aGuard( m_aMutex );
623
624 try
625 {
626 // @@@ Need real command environment here, but where to get it from?
627 // XPropertyContainer interface should be replaced by
628 // XCommandProcessor commands!
629 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
630
631 beans::Property aProp
632 = getPropertySetInfo( xEnv )->getPropertyByName( Name );
633
634 if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) )
635 {
636 // Not removeable!
637 throw beans::NotRemoveableException();
638 }
639 }
640 catch ( beans::UnknownPropertyException const & )
641 {
642 OSL_ENSURE( sal_False, "ContentImplHelper::removeProperty - Unknown!" );
643 throw;
644 }
645
646 //////////////////////////////////////////////////////////////////////
647 // Try to remove property from dynamic property set.
648 //////////////////////////////////////////////////////////////////////
649
650 // Open persistent property set, if exists.
651 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet(
652 getAdditionalPropertySet( sal_False ) );
653 if ( xSet.is() )
654 {
655 uno::Reference< beans::XPropertyContainer > xContainer(
656 xSet, uno::UNO_QUERY );
657
658 OSL_ENSURE(
659 xContainer.is(),
660 "ContentImplHelper::removeProperty - No property container!" );
661
662 if ( xContainer.is() )
663 {
664 try
665 {
666 xContainer->removeProperty( Name );
667 }
668 catch ( beans::UnknownPropertyException const & )
669 {
670 OSL_ENSURE( sal_False,
671 "ContentImplHelper::removeProperty - Unknown!" );
672 throw;
673 }
674 catch ( beans::NotRemoveableException const & )
675 {
676 OSL_ENSURE(
677 sal_False,
678 "ContentImplHelper::removeProperty - Unremoveable!" );
679 throw;
680 }
681
682 xContainer = 0;
683
684 // Success!
685
686 if ( xSet->getPropertySetInfo()->getProperties().getLength() == 0 )
687 {
688 // Remove empty propertyset from registry.
689 uno::Reference< com::sun::star::ucb::XPropertySetRegistry >
690 xReg = xSet->getRegistry();
691 if ( xReg.is() )
692 {
693 rtl::OUString aKey( xSet->getKey() );
694 xSet = 0;
695 xReg->removePropertySet( aKey );
696 }
697 }
698
699 if ( m_pImpl->m_xPropSetInfo.is() )
700 {
701 // Info cached in propertyset info is invalid now!
702 m_pImpl->m_xPropSetInfo->reset();
703 }
704
705 // Notify propertyset info change listeners.
706 if ( m_pImpl->m_pPropSetChangeListeners &&
707 m_pImpl->m_pPropSetChangeListeners->getLength() )
708 {
709 beans::PropertySetInfoChangeEvent evt(
710 static_cast< cppu::OWeakObject * >( this ),
711 Name,
712 -1, // No handle available
713 beans::PropertySetInfoChange::PROPERTY_REMOVED );
714 notifyPropertySetInfoChange( evt );
715 }
716 }
717 }
718 }
719
720 //=========================================================================
721 //
722 // XPropertySetInfoChangeNotifier methods.
723 //
724 //=========================================================================
725
726 // virtual
addPropertySetInfoChangeListener(const uno::Reference<beans::XPropertySetInfoChangeListener> & Listener)727 void SAL_CALL ContentImplHelper::addPropertySetInfoChangeListener(
728 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener )
729 {
730 osl::MutexGuard aGuard( m_aMutex );
731
732 if ( !m_pImpl->m_pPropSetChangeListeners )
733 m_pImpl->m_pPropSetChangeListeners
734 = new cppu::OInterfaceContainerHelper( m_aMutex );
735
736 m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
737 }
738
739 //=========================================================================
740 // virtual
removePropertySetInfoChangeListener(const uno::Reference<beans::XPropertySetInfoChangeListener> & Listener)741 void SAL_CALL ContentImplHelper::removePropertySetInfoChangeListener(
742 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener )
743 {
744 osl::MutexGuard aGuard( m_aMutex );
745
746 if ( m_pImpl->m_pPropSetChangeListeners )
747 m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
748 }
749
750 //=========================================================================
751 //
752 // XChild methods.
753 //
754 //=========================================================================
755
756 // virtual
getParent()757 uno::Reference< uno::XInterface > SAL_CALL ContentImplHelper::getParent()
758 {
759 uno::Reference< uno::XInterface > xParent;
760 rtl::OUString aURL = getParentURL();
761
762 if ( aURL.getLength() )
763 {
764 uno::Reference< com::sun::star::ucb::XContentIdentifier > xId(
765 new ContentIdentifier( m_xSMgr, aURL ) );
766 try
767 {
768 xParent.set( m_xProvider->queryContent( xId ) );
769 }
770 catch ( com::sun::star::ucb::IllegalIdentifierException const & )
771 {
772 }
773 }
774
775 return xParent;
776 }
777
778 //=========================================================================
779 // virtual
setParent(const uno::Reference<uno::XInterface> &)780 void SAL_CALL ContentImplHelper::setParent(
781 const uno::Reference< uno::XInterface >& )
782 {
783 throw lang::NoSupportException();
784 }
785
786 //=========================================================================
787 //
788 // Non-interface methods
789 //
790 //=========================================================================
791
792 uno::Reference< com::sun::star::ucb::XPersistentPropertySet >
getAdditionalPropertySet(sal_Bool bCreate)793 ContentImplHelper::getAdditionalPropertySet( sal_Bool bCreate )
794 {
795 // Get propertyset from provider.
796 return m_xProvider->getAdditionalPropertySet(
797 m_xIdentifier->getContentIdentifier(), bCreate );
798 }
799
800 //=========================================================================
renameAdditionalPropertySet(const rtl::OUString & rOldKey,const rtl::OUString & rNewKey,sal_Bool bRecursive)801 sal_Bool ContentImplHelper::renameAdditionalPropertySet(
802 const rtl::OUString& rOldKey,
803 const rtl::OUString& rNewKey,
804 sal_Bool bRecursive )
805 {
806 return m_xProvider->renameAdditionalPropertySet(
807 rOldKey, rNewKey, bRecursive );
808 }
809
810 //=========================================================================
copyAdditionalPropertySet(const rtl::OUString & rSourceKey,const rtl::OUString & rTargetKey,sal_Bool bRecursive)811 sal_Bool ContentImplHelper::copyAdditionalPropertySet(
812 const rtl::OUString& rSourceKey,
813 const rtl::OUString& rTargetKey,
814 sal_Bool bRecursive )
815 {
816 return m_xProvider->copyAdditionalPropertySet(
817 rSourceKey, rTargetKey, bRecursive );
818 }
819
820 //=========================================================================
removeAdditionalPropertySet(sal_Bool bRecursive)821 sal_Bool ContentImplHelper::removeAdditionalPropertySet( sal_Bool bRecursive )
822 {
823 return m_xProvider->removeAdditionalPropertySet(
824 m_xIdentifier->getContentIdentifier(), bRecursive );
825 }
826
827 //=========================================================================
notifyPropertiesChange(const uno::Sequence<beans::PropertyChangeEvent> & evt) const828 void ContentImplHelper::notifyPropertiesChange(
829 const uno::Sequence< beans::PropertyChangeEvent >& evt ) const
830 {
831 if ( !m_pImpl->m_pPropertyChangeListeners )
832 return;
833
834 sal_Int32 nCount = evt.getLength();
835 if ( nCount )
836 {
837 // First, notify listeners interested in changes of every property.
838 cppu::OInterfaceContainerHelper* pAllPropsContainer
839 = m_pImpl->m_pPropertyChangeListeners->getContainer(
840 rtl::OUString() );
841 if ( pAllPropsContainer )
842 {
843 cppu::OInterfaceIteratorHelper aIter( *pAllPropsContainer );
844 while ( aIter.hasMoreElements() )
845 {
846 // Propagate event.
847 uno::Reference< beans::XPropertiesChangeListener > xListener(
848 aIter.next(), uno::UNO_QUERY );
849 if ( xListener.is() )
850 xListener->propertiesChange( evt );
851 }
852 }
853
854 PropertiesEventListenerMap aListeners;
855
856 const beans::PropertyChangeEvent* pEvents = evt.getConstArray();
857
858 for ( sal_Int32 n = 0; n < nCount; ++n )
859 {
860 const beans::PropertyChangeEvent& rEvent = pEvents[ n ];
861 const rtl::OUString& rName = rEvent.PropertyName;
862
863 cppu::OInterfaceContainerHelper* pPropsContainer
864 = m_pImpl->m_pPropertyChangeListeners->getContainer( rName );
865 if ( pPropsContainer )
866 {
867 cppu::OInterfaceIteratorHelper aIter( *pPropsContainer );
868 while ( aIter.hasMoreElements() )
869 {
870 PropertyEventSequence* p = NULL;
871
872 beans::XPropertiesChangeListener* pListener =
873 static_cast< beans::XPropertiesChangeListener * >(
874 aIter.next() );
875 PropertiesEventListenerMap::iterator it =
876 aListeners.find( pListener );
877 if ( it == aListeners.end() )
878 {
879 // Not in map - create and insert new entry.
880 p = new PropertyEventSequence( nCount );
881 aListeners[ pListener ] = p;
882 }
883 else
884 p = (*it).second;
885
886 if ( p )
887 p->append( rEvent );
888 }
889 }
890 }
891
892 // Notify listeners.
893 PropertiesEventListenerMap::iterator it = aListeners.begin();
894 while ( !aListeners.empty() )
895 {
896 beans::XPropertiesChangeListener* pListener =
897 static_cast< beans::XPropertiesChangeListener * >( (*it).first );
898 PropertyEventSequence* pSeq = (*it).second;
899
900 // Remove current element.
901 aListeners.erase( it );
902
903 // Propagate event.
904 pListener->propertiesChange( pSeq->getEvents() );
905
906 delete pSeq;
907
908 it = aListeners.begin();
909 }
910 }
911 }
912
913 //=========================================================================
notifyPropertySetInfoChange(const beans::PropertySetInfoChangeEvent & evt) const914 void ContentImplHelper::notifyPropertySetInfoChange(
915 const beans::PropertySetInfoChangeEvent& evt ) const
916 {
917 if ( !m_pImpl->m_pPropSetChangeListeners )
918 return;
919
920 // Notify event listeners.
921 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pPropSetChangeListeners );
922 while ( aIter.hasMoreElements() )
923 {
924 // Propagate event.
925 uno::Reference< beans::XPropertySetInfoChangeListener >
926 xListener( aIter.next(), uno::UNO_QUERY );
927 if ( xListener.is() )
928 xListener->propertySetInfoChange( evt );
929 }
930 }
931
932 //=========================================================================
notifyCommandInfoChange(const com::sun::star::ucb::CommandInfoChangeEvent & evt) const933 void ContentImplHelper::notifyCommandInfoChange(
934 const com::sun::star::ucb::CommandInfoChangeEvent& evt ) const
935 {
936 if ( !m_pImpl->m_pCommandChangeListeners )
937 return;
938
939 // Notify event listeners.
940 cppu::OInterfaceIteratorHelper aIter(
941 *m_pImpl->m_pCommandChangeListeners );
942 while ( aIter.hasMoreElements() )
943 {
944 // Propagate event.
945 uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >
946 xListener( aIter.next(), uno::UNO_QUERY );
947 if ( xListener.is() )
948 xListener->commandInfoChange( evt );
949 }
950 }
951
952 //=========================================================================
notifyContentEvent(const com::sun::star::ucb::ContentEvent & evt) const953 void ContentImplHelper::notifyContentEvent(
954 const com::sun::star::ucb::ContentEvent& evt ) const
955 {
956 if ( !m_pImpl->m_pContentEventListeners )
957 return;
958
959 // Notify event listeners.
960 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pContentEventListeners );
961 while ( aIter.hasMoreElements() )
962 {
963 // Propagate event.
964 uno::Reference<
965 com::sun::star::ucb::XContentEventListener > xListener(
966 aIter.next(), uno::UNO_QUERY );
967 if ( xListener.is() )
968 xListener->contentEvent( evt );
969 }
970 }
971
972 //=========================================================================
inserted()973 void ContentImplHelper::inserted()
974 {
975 // Content is not yet registered at provider.
976 m_xProvider->registerNewContent( this );
977
978 // If the parent content is currently not instantiated, there can be
979 // no listeners interested in changes ;-)
980
981 rtl::Reference< ContentImplHelper > xParent
982 = m_xProvider->queryExistingContent( getParentURL() );
983
984 if ( xParent.is() )
985 {
986 com::sun::star::ucb::ContentEvent aEvt(
987 static_cast< cppu::OWeakObject * >( xParent.get() ), // Source
988 com::sun::star::ucb::ContentAction::INSERTED, // Action
989 this, // Content
990 xParent->getIdentifier() ); // Id
991 xParent->notifyContentEvent( aEvt );
992 }
993 }
994
995 //=========================================================================
deleted()996 void ContentImplHelper::deleted()
997 {
998 uno::Reference< com::sun::star::ucb::XContent > xThis = this;
999
1000 rtl::Reference< ContentImplHelper > xParent
1001 = m_xProvider->queryExistingContent( getParentURL() );
1002
1003 if ( xParent.is() )
1004 {
1005 // Let parent notify "REMOVED" event.
1006 com::sun::star::ucb::ContentEvent aEvt(
1007 static_cast< cppu::OWeakObject * >( xParent.get() ),
1008 com::sun::star::ucb::ContentAction::REMOVED,
1009 this,
1010 xParent->getIdentifier() );
1011 xParent->notifyContentEvent( aEvt );
1012 }
1013
1014 // Notify "DELETED" event.
1015 com::sun::star::ucb::ContentEvent aEvt1(
1016 static_cast< cppu::OWeakObject * >( this ),
1017 com::sun::star::ucb::ContentAction::DELETED,
1018 this,
1019 getIdentifier() );
1020 notifyContentEvent( aEvt1 );
1021
1022 m_xProvider->removeContent( this );
1023 }
1024
1025 //=========================================================================
exchange(const uno::Reference<com::sun::star::ucb::XContentIdentifier> & rNewId)1026 sal_Bool ContentImplHelper::exchange(
1027 const uno::Reference< com::sun::star::ucb::XContentIdentifier >& rNewId )
1028 {
1029 uno::Reference< com::sun::star::ucb::XContent > xThis = this;
1030
1031 osl::ClearableMutexGuard aGuard( m_aMutex );
1032
1033 rtl::Reference< ContentImplHelper > xContent
1034 = m_xProvider->queryExistingContent( rNewId );
1035 if ( xContent.is() )
1036 {
1037 // @@@
1038 // Big trouble. Another object with the new identity exists.
1039 // How shall I mutate to / merge with the other object?
1040 return sal_False;
1041 }
1042
1043 uno::Reference< com::sun::star::ucb::XContentIdentifier > xOldId
1044 = getIdentifier();
1045
1046 // Re-insert at provider.
1047 m_xProvider->removeContent( this );
1048 m_xIdentifier = rNewId;
1049 m_xProvider->registerNewContent( this );
1050
1051 aGuard.clear();
1052
1053 // Notify "EXCHANGED" event.
1054 com::sun::star::ucb::ContentEvent aEvt(
1055 static_cast< cppu::OWeakObject * >( this ),
1056 com::sun::star::ucb::ContentAction::EXCHANGED,
1057 this,
1058 xOldId );
1059 notifyContentEvent( aEvt );
1060 return sal_True;
1061 }
1062
1063 //=========================================================================
1064 uno::Reference< com::sun::star::ucb::XCommandInfo >
getCommandInfo(const uno::Reference<com::sun::star::ucb::XCommandEnvironment> & xEnv,sal_Bool bCache)1065 ContentImplHelper::getCommandInfo(
1066 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
1067 sal_Bool bCache )
1068 {
1069 osl::MutexGuard aGuard( m_aMutex );
1070
1071 if ( !m_pImpl->m_xCommandsInfo.is() )
1072 m_pImpl->m_xCommandsInfo
1073 = new CommandProcessorInfo( m_xSMgr, xEnv, this );
1074 else if ( !bCache )
1075 m_pImpl->m_xCommandsInfo->reset();
1076
1077 return uno::Reference< com::sun::star::ucb::XCommandInfo >(
1078 m_pImpl->m_xCommandsInfo.get() );
1079 }
1080
1081 //=========================================================================
1082 uno::Reference< beans::XPropertySetInfo >
getPropertySetInfo(const uno::Reference<com::sun::star::ucb::XCommandEnvironment> & xEnv,sal_Bool bCache)1083 ContentImplHelper::getPropertySetInfo(
1084 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
1085 sal_Bool bCache )
1086 {
1087 osl::MutexGuard aGuard( m_aMutex );
1088
1089 if ( !m_pImpl->m_xPropSetInfo.is() )
1090 m_pImpl->m_xPropSetInfo
1091 = new PropertySetInfo( m_xSMgr, xEnv, this );
1092 else if ( !bCache )
1093 m_pImpl->m_xPropSetInfo->reset();
1094
1095 return uno::Reference< beans::XPropertySetInfo >(
1096 m_pImpl->m_xPropSetInfo.get() );
1097 }
1098
1099 } // namespace ucbhelper
1100