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 throw( uno::RuntimeException )
233 {
234 com::sun::star::uno::Any aRet = cppu::queryInterface( rType,
235 static_cast< lang::XTypeProvider * >(this),
236 static_cast< lang::XServiceInfo * >(this),
237 static_cast< lang::XComponent * >(this),
238 static_cast< com::sun::star::ucb::XContent * >(this),
239 static_cast< com::sun::star::ucb::XCommandProcessor * >(this),
240 static_cast< beans::XPropertiesChangeNotifier * >(this),
241 static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >(this),
242 static_cast< beans::XPropertyContainer * >(this),
243 static_cast< beans::XPropertySetInfoChangeNotifier * >(this),
244 static_cast< container::XChild * >(this));
245 return aRet.hasValue() ? aRet : cppu::OWeakObject::queryInterface( rType );
246 }
247
248 //=========================================================================
249 //
250 // XTypeProvider methods.
251 //
252 //=========================================================================
253
254 XTYPEPROVIDER_IMPL_10( ContentImplHelper,
255 lang::XTypeProvider,
256 lang::XServiceInfo,
257 lang::XComponent,
258 com::sun::star::ucb::XContent,
259 com::sun::star::ucb::XCommandProcessor,
260 beans::XPropertiesChangeNotifier,
261 com::sun::star::ucb::XCommandInfoChangeNotifier,
262 beans::XPropertyContainer,
263 beans::XPropertySetInfoChangeNotifier,
264 container::XChild );
265
266 //=========================================================================
267 //
268 // XServiceInfo methods.
269 //
270 //=========================================================================
271
272 // virtual
supportsService(const rtl::OUString & ServiceName)273 sal_Bool SAL_CALL ContentImplHelper::supportsService(
274 const rtl::OUString& ServiceName )
275 throw( uno::RuntimeException )
276 {
277 uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
278 const rtl::OUString* pArray = aSNL.getConstArray();
279 for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
280 {
281 if ( pArray[ i ] == ServiceName )
282 return sal_True;
283 }
284
285 return sal_False;
286 }
287
288 //=========================================================================
289 //
290 // XComponent methods.
291 //
292 //=========================================================================
293
294 // virtual
dispose()295 void SAL_CALL ContentImplHelper::dispose()
296 throw( uno::RuntimeException )
297 {
298 osl::MutexGuard aGuard( m_aMutex );
299
300 if ( m_pImpl->m_pDisposeEventListeners &&
301 m_pImpl->m_pDisposeEventListeners->getLength() )
302 {
303 lang::EventObject aEvt;
304 aEvt.Source = static_cast< lang::XComponent * >( this );
305 m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
306 }
307
308 if ( m_pImpl->m_pContentEventListeners &&
309 m_pImpl->m_pContentEventListeners->getLength() )
310 {
311 lang::EventObject aEvt;
312 aEvt.Source = static_cast< com::sun::star::ucb::XContent * >( this );
313 m_pImpl->m_pContentEventListeners->disposeAndClear( aEvt );
314 }
315
316 if ( m_pImpl->m_pPropSetChangeListeners &&
317 m_pImpl->m_pPropSetChangeListeners->getLength() )
318 {
319 lang::EventObject aEvt;
320 aEvt.Source
321 = static_cast< beans::XPropertySetInfoChangeNotifier * >( this );
322 m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
323 }
324
325 if ( m_pImpl->m_pCommandChangeListeners &&
326 m_pImpl->m_pCommandChangeListeners->getLength() )
327 {
328 lang::EventObject aEvt;
329 aEvt.Source = static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >( this );
330 m_pImpl->m_pCommandChangeListeners->disposeAndClear( aEvt );
331 }
332
333 if ( m_pImpl->m_pPropertyChangeListeners )
334 {
335 lang::EventObject aEvt;
336 aEvt.Source
337 = static_cast< beans::XPropertiesChangeNotifier * >( this );
338 m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
339 }
340 }
341
342 //=========================================================================
343 // virtual
addEventListener(const uno::Reference<lang::XEventListener> & Listener)344 void SAL_CALL ContentImplHelper::addEventListener(
345 const uno::Reference< lang::XEventListener >& Listener )
346 throw( uno::RuntimeException )
347 {
348 osl::MutexGuard aGuard( m_aMutex );
349
350 if ( !m_pImpl->m_pDisposeEventListeners )
351 m_pImpl->m_pDisposeEventListeners
352 = new cppu::OInterfaceContainerHelper( m_aMutex );
353
354 m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
355 }
356
357 //=========================================================================
358 // virtual
removeEventListener(const uno::Reference<lang::XEventListener> & Listener)359 void SAL_CALL ContentImplHelper::removeEventListener(
360 const uno::Reference< lang::XEventListener >& Listener )
361 throw( uno::RuntimeException )
362 {
363 osl::MutexGuard aGuard( m_aMutex );
364
365 if ( m_pImpl->m_pDisposeEventListeners )
366 m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
367 }
368
369 //=========================================================================
370 //
371 // XContent methods.
372 //
373 //=========================================================================
374
375 // virtual
376 uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL
getIdentifier()377 ContentImplHelper::getIdentifier()
378 throw( uno::RuntimeException )
379 {
380 return m_xIdentifier;
381 }
382
383 //=========================================================================
384 // virtual
addContentEventListener(const uno::Reference<com::sun::star::ucb::XContentEventListener> & Listener)385 void SAL_CALL ContentImplHelper::addContentEventListener(
386 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
387 throw( uno::RuntimeException )
388 {
389 osl::MutexGuard aGuard( m_aMutex );
390
391 if ( !m_pImpl->m_pContentEventListeners )
392 m_pImpl->m_pContentEventListeners
393 = new cppu::OInterfaceContainerHelper( m_aMutex );
394
395 m_pImpl->m_pContentEventListeners->addInterface( Listener );
396 }
397
398 //=========================================================================
399 // virtual
removeContentEventListener(const uno::Reference<com::sun::star::ucb::XContentEventListener> & Listener)400 void SAL_CALL ContentImplHelper::removeContentEventListener(
401 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
402 throw( uno::RuntimeException )
403 {
404 osl::MutexGuard aGuard( m_aMutex );
405
406 if ( m_pImpl->m_pContentEventListeners )
407 m_pImpl->m_pContentEventListeners->removeInterface( Listener );
408 }
409
410 //=========================================================================
411 //
412 // XCommandProcessor methods.
413 //
414 //=========================================================================
415
416 // virtual
createCommandIdentifier()417 sal_Int32 SAL_CALL ContentImplHelper::createCommandIdentifier()
418 throw( uno::RuntimeException )
419 {
420 osl::MutexGuard aGuard( m_aMutex );
421
422 // Just increase counter on every call to generate an identifier.
423 return ++m_nCommandId;
424 }
425
426 //=========================================================================
427 //
428 // XPropertiesChangeNotifier methods.
429 //
430 //=========================================================================
431
432 // virtual
addPropertiesChangeListener(const uno::Sequence<rtl::OUString> & PropertyNames,const uno::Reference<beans::XPropertiesChangeListener> & Listener)433 void SAL_CALL ContentImplHelper::addPropertiesChangeListener(
434 const uno::Sequence< rtl::OUString >& PropertyNames,
435 const uno::Reference< beans::XPropertiesChangeListener >& Listener )
436 throw( uno::RuntimeException )
437 {
438 osl::MutexGuard aGuard( m_aMutex );
439
440 if ( !m_pImpl->m_pPropertyChangeListeners )
441 m_pImpl->m_pPropertyChangeListeners
442 = new PropertyChangeListeners( m_aMutex );
443
444 sal_Int32 nCount = PropertyNames.getLength();
445 if ( !nCount )
446 {
447 // Note: An empty sequence means a listener for "all" properties.
448 m_pImpl->m_pPropertyChangeListeners->addInterface(
449 rtl::OUString(), Listener );
450 }
451 else
452 {
453 const rtl::OUString* pSeq = PropertyNames.getConstArray();
454
455 for ( sal_Int32 n = 0; n < nCount; ++n )
456 {
457 const rtl::OUString& rName = pSeq[ n ];
458 if ( rName.getLength() )
459 m_pImpl->m_pPropertyChangeListeners->addInterface(
460 rName, Listener );
461 }
462 }
463 }
464
465 //=========================================================================
466 // virtual
removePropertiesChangeListener(const uno::Sequence<rtl::OUString> & PropertyNames,const uno::Reference<beans::XPropertiesChangeListener> & Listener)467 void SAL_CALL ContentImplHelper::removePropertiesChangeListener(
468 const uno::Sequence< rtl::OUString >& PropertyNames,
469 const uno::Reference< beans::XPropertiesChangeListener >& Listener )
470 throw( uno::RuntimeException )
471 {
472 osl::MutexGuard aGuard( m_aMutex );
473
474 if ( !m_pImpl->m_pPropertyChangeListeners )
475 return;
476
477 sal_Int32 nCount = PropertyNames.getLength();
478 if ( !nCount )
479 {
480 // Note: An empty sequence means a listener for "all" properties.
481 m_pImpl->m_pPropertyChangeListeners->removeInterface(
482 rtl::OUString(), Listener );
483 }
484 else
485 {
486 const rtl::OUString* pSeq = PropertyNames.getConstArray();
487
488 for ( sal_Int32 n = 0; n < nCount; ++n )
489 {
490 const rtl::OUString& rName = pSeq[ n ];
491 if ( rName.getLength() )
492 m_pImpl->m_pPropertyChangeListeners->removeInterface(
493 rName, Listener );
494 }
495 }
496 }
497
498 //=========================================================================
499 //
500 // XCommandInfoChangeNotifier methods.
501 //
502 //=========================================================================
503
504 // virtual
addCommandInfoChangeListener(const uno::Reference<com::sun::star::ucb::XCommandInfoChangeListener> & Listener)505 void SAL_CALL ContentImplHelper::addCommandInfoChangeListener(
506 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
507 throw( uno::RuntimeException )
508 {
509 osl::MutexGuard aGuard( m_aMutex );
510
511 if ( !m_pImpl->m_pCommandChangeListeners )
512 m_pImpl->m_pCommandChangeListeners
513 = new cppu::OInterfaceContainerHelper( m_aMutex );
514
515 m_pImpl->m_pCommandChangeListeners->addInterface( Listener );
516 }
517
518 //=========================================================================
519 // virtual
removeCommandInfoChangeListener(const uno::Reference<com::sun::star::ucb::XCommandInfoChangeListener> & Listener)520 void SAL_CALL ContentImplHelper::removeCommandInfoChangeListener(
521 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
522 throw( uno::RuntimeException )
523 {
524 osl::MutexGuard aGuard( m_aMutex );
525
526 if ( m_pImpl->m_pCommandChangeListeners )
527 m_pImpl->m_pCommandChangeListeners->removeInterface( Listener );
528 }
529
530 //=========================================================================
531 //
532 // XPropertyContainer methods.
533 //
534 //=========================================================================
535
536 // virtual
addProperty(const rtl::OUString & Name,sal_Int16 Attributes,const uno::Any & DefaultValue)537 void SAL_CALL ContentImplHelper::addProperty(
538 const rtl::OUString& Name,
539 sal_Int16 Attributes,
540 const uno::Any& DefaultValue )
541 throw( beans::PropertyExistException,
542 beans::IllegalTypeException,
543 lang::IllegalArgumentException,
544 uno::RuntimeException )
545 {
546 osl::MutexGuard aGuard( m_aMutex );
547
548 //////////////////////////////////////////////////////////////////////
549 // Make sure a property with the requested name does not already
550 // exist in dynamic and static(!) properties.
551 //////////////////////////////////////////////////////////////////////
552
553 // @@@ Need real command environment here, but where to get it from?
554 // XPropertyContainer interface should be replaced by
555 // XCommandProcessor commands!
556 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
557
558 if ( getPropertySetInfo( xEnv )->hasPropertyByName( Name ) )
559 {
560 // Property does already exist.
561 throw beans::PropertyExistException();
562 }
563
564 //////////////////////////////////////////////////////////////////////
565 // Add a new dynamic property.
566 //////////////////////////////////////////////////////////////////////
567
568 // Open/create persistent property set.
569 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet(
570 getAdditionalPropertySet( sal_True ) );
571
572 OSL_ENSURE( xSet.is(),
573 "ContentImplHelper::addProperty - No property set!" );
574
575 if ( xSet.is() )
576 {
577 uno::Reference< beans::XPropertyContainer > xContainer(
578 xSet, uno::UNO_QUERY );
579
580 OSL_ENSURE(
581 xContainer.is(),
582 "ContentImplHelper::addProperty - No property container!" );
583
584 if ( xContainer.is() )
585 {
586 // Property is always removeable.
587 Attributes |= beans::PropertyAttribute::REMOVEABLE;
588
589 try
590 {
591 xContainer->addProperty( Name, Attributes, DefaultValue );
592 }
593 catch ( beans::PropertyExistException const & )
594 {
595 OSL_ENSURE( sal_False,
596 "ContentImplHelper::addProperty - Exists!" );
597 throw;
598 }
599 catch ( beans::IllegalTypeException const & )
600 {
601 OSL_ENSURE( sal_False,
602 "ContentImplHelper::addProperty - Wrong Type!" );
603 throw;
604 }
605 catch ( lang::IllegalArgumentException const & )
606 {
607 OSL_ENSURE( sal_False,
608 "ContentImplHelper::addProperty - Illegal Arg!" );
609 throw;
610 }
611
612 // Success!
613
614 if ( m_pImpl->m_xPropSetInfo.is() )
615 {
616 // Info cached in propertyset info is invalid now!
617 m_pImpl->m_xPropSetInfo->reset();
618 }
619
620 // Notify propertyset info change listeners.
621 if ( m_pImpl->m_pPropSetChangeListeners &&
622 m_pImpl->m_pPropSetChangeListeners->getLength() )
623 {
624 beans::PropertySetInfoChangeEvent evt(
625 static_cast< cppu::OWeakObject * >( this ),
626 Name,
627 -1, // No handle available
628 beans::PropertySetInfoChange::PROPERTY_INSERTED );
629 notifyPropertySetInfoChange( evt );
630 }
631 }
632 }
633 }
634
635 //=========================================================================
636 // virtual
removeProperty(const rtl::OUString & Name)637 void SAL_CALL ContentImplHelper::removeProperty( const rtl::OUString& Name )
638 throw( beans::UnknownPropertyException,
639 beans::NotRemoveableException,
640 uno::RuntimeException )
641 {
642 osl::MutexGuard aGuard( m_aMutex );
643
644 try
645 {
646 // @@@ Need real command environment here, but where to get it from?
647 // XPropertyContainer interface should be replaced by
648 // XCommandProcessor commands!
649 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
650
651 beans::Property aProp
652 = getPropertySetInfo( xEnv )->getPropertyByName( Name );
653
654 if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) )
655 {
656 // Not removeable!
657 throw beans::NotRemoveableException();
658 }
659 }
660 catch ( beans::UnknownPropertyException const & )
661 {
662 OSL_ENSURE( sal_False, "ContentImplHelper::removeProperty - Unknown!" );
663 throw;
664 }
665
666 //////////////////////////////////////////////////////////////////////
667 // Try to remove property from dynamic property set.
668 //////////////////////////////////////////////////////////////////////
669
670 // Open persistent property set, if exists.
671 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet(
672 getAdditionalPropertySet( sal_False ) );
673 if ( xSet.is() )
674 {
675 uno::Reference< beans::XPropertyContainer > xContainer(
676 xSet, uno::UNO_QUERY );
677
678 OSL_ENSURE(
679 xContainer.is(),
680 "ContentImplHelper::removeProperty - No property container!" );
681
682 if ( xContainer.is() )
683 {
684 try
685 {
686 xContainer->removeProperty( Name );
687 }
688 catch ( beans::UnknownPropertyException const & )
689 {
690 OSL_ENSURE( sal_False,
691 "ContentImplHelper::removeProperty - Unknown!" );
692 throw;
693 }
694 catch ( beans::NotRemoveableException const & )
695 {
696 OSL_ENSURE(
697 sal_False,
698 "ContentImplHelper::removeProperty - Unremoveable!" );
699 throw;
700 }
701
702 xContainer = 0;
703
704 // Success!
705
706 if ( xSet->getPropertySetInfo()->getProperties().getLength() == 0 )
707 {
708 // Remove empty propertyset from registry.
709 uno::Reference< com::sun::star::ucb::XPropertySetRegistry >
710 xReg = xSet->getRegistry();
711 if ( xReg.is() )
712 {
713 rtl::OUString aKey( xSet->getKey() );
714 xSet = 0;
715 xReg->removePropertySet( aKey );
716 }
717 }
718
719 if ( m_pImpl->m_xPropSetInfo.is() )
720 {
721 // Info cached in propertyset info is invalid now!
722 m_pImpl->m_xPropSetInfo->reset();
723 }
724
725 // Notify propertyset info change listeners.
726 if ( m_pImpl->m_pPropSetChangeListeners &&
727 m_pImpl->m_pPropSetChangeListeners->getLength() )
728 {
729 beans::PropertySetInfoChangeEvent evt(
730 static_cast< cppu::OWeakObject * >( this ),
731 Name,
732 -1, // No handle available
733 beans::PropertySetInfoChange::PROPERTY_REMOVED );
734 notifyPropertySetInfoChange( evt );
735 }
736 }
737 }
738 }
739
740 //=========================================================================
741 //
742 // XPropertySetInfoChangeNotifier methods.
743 //
744 //=========================================================================
745
746 // virtual
addPropertySetInfoChangeListener(const uno::Reference<beans::XPropertySetInfoChangeListener> & Listener)747 void SAL_CALL ContentImplHelper::addPropertySetInfoChangeListener(
748 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener )
749 throw( uno::RuntimeException )
750 {
751 osl::MutexGuard aGuard( m_aMutex );
752
753 if ( !m_pImpl->m_pPropSetChangeListeners )
754 m_pImpl->m_pPropSetChangeListeners
755 = new cppu::OInterfaceContainerHelper( m_aMutex );
756
757 m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
758 }
759
760 //=========================================================================
761 // virtual
removePropertySetInfoChangeListener(const uno::Reference<beans::XPropertySetInfoChangeListener> & Listener)762 void SAL_CALL ContentImplHelper::removePropertySetInfoChangeListener(
763 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener )
764 throw( uno::RuntimeException )
765 {
766 osl::MutexGuard aGuard( m_aMutex );
767
768 if ( m_pImpl->m_pPropSetChangeListeners )
769 m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
770 }
771
772 //=========================================================================
773 //
774 // XChild methods.
775 //
776 //=========================================================================
777
778 // virtual
getParent()779 uno::Reference< uno::XInterface > SAL_CALL ContentImplHelper::getParent()
780 throw( uno::RuntimeException )
781 {
782 uno::Reference< uno::XInterface > xParent;
783 rtl::OUString aURL = getParentURL();
784
785 if ( aURL.getLength() )
786 {
787 uno::Reference< com::sun::star::ucb::XContentIdentifier > xId(
788 new ContentIdentifier( m_xSMgr, aURL ) );
789 try
790 {
791 xParent.set( m_xProvider->queryContent( xId ) );
792 }
793 catch ( com::sun::star::ucb::IllegalIdentifierException const & )
794 {
795 }
796 }
797
798 return xParent;
799 }
800
801 //=========================================================================
802 // virtual
setParent(const uno::Reference<uno::XInterface> &)803 void SAL_CALL ContentImplHelper::setParent(
804 const uno::Reference< uno::XInterface >& )
805 throw( lang::NoSupportException, uno::RuntimeException )
806 {
807 throw lang::NoSupportException();
808 }
809
810 //=========================================================================
811 //
812 // Non-interface methods
813 //
814 //=========================================================================
815
816 uno::Reference< com::sun::star::ucb::XPersistentPropertySet >
getAdditionalPropertySet(sal_Bool bCreate)817 ContentImplHelper::getAdditionalPropertySet( sal_Bool bCreate )
818 {
819 // Get propertyset from provider.
820 return m_xProvider->getAdditionalPropertySet(
821 m_xIdentifier->getContentIdentifier(), bCreate );
822 }
823
824 //=========================================================================
renameAdditionalPropertySet(const rtl::OUString & rOldKey,const rtl::OUString & rNewKey,sal_Bool bRecursive)825 sal_Bool ContentImplHelper::renameAdditionalPropertySet(
826 const rtl::OUString& rOldKey,
827 const rtl::OUString& rNewKey,
828 sal_Bool bRecursive )
829 {
830 return m_xProvider->renameAdditionalPropertySet(
831 rOldKey, rNewKey, bRecursive );
832 }
833
834 //=========================================================================
copyAdditionalPropertySet(const rtl::OUString & rSourceKey,const rtl::OUString & rTargetKey,sal_Bool bRecursive)835 sal_Bool ContentImplHelper::copyAdditionalPropertySet(
836 const rtl::OUString& rSourceKey,
837 const rtl::OUString& rTargetKey,
838 sal_Bool bRecursive )
839 {
840 return m_xProvider->copyAdditionalPropertySet(
841 rSourceKey, rTargetKey, bRecursive );
842 }
843
844 //=========================================================================
removeAdditionalPropertySet(sal_Bool bRecursive)845 sal_Bool ContentImplHelper::removeAdditionalPropertySet( sal_Bool bRecursive )
846 {
847 return m_xProvider->removeAdditionalPropertySet(
848 m_xIdentifier->getContentIdentifier(), bRecursive );
849 }
850
851 //=========================================================================
notifyPropertiesChange(const uno::Sequence<beans::PropertyChangeEvent> & evt) const852 void ContentImplHelper::notifyPropertiesChange(
853 const uno::Sequence< beans::PropertyChangeEvent >& evt ) const
854 {
855 if ( !m_pImpl->m_pPropertyChangeListeners )
856 return;
857
858 sal_Int32 nCount = evt.getLength();
859 if ( nCount )
860 {
861 // First, notify listeners interested in changes of every property.
862 cppu::OInterfaceContainerHelper* pAllPropsContainer
863 = m_pImpl->m_pPropertyChangeListeners->getContainer(
864 rtl::OUString() );
865 if ( pAllPropsContainer )
866 {
867 cppu::OInterfaceIteratorHelper aIter( *pAllPropsContainer );
868 while ( aIter.hasMoreElements() )
869 {
870 // Propagate event.
871 uno::Reference< beans::XPropertiesChangeListener > xListener(
872 aIter.next(), uno::UNO_QUERY );
873 if ( xListener.is() )
874 xListener->propertiesChange( evt );
875 }
876 }
877
878 PropertiesEventListenerMap aListeners;
879
880 const beans::PropertyChangeEvent* pEvents = evt.getConstArray();
881
882 for ( sal_Int32 n = 0; n < nCount; ++n )
883 {
884 const beans::PropertyChangeEvent& rEvent = pEvents[ n ];
885 const rtl::OUString& rName = rEvent.PropertyName;
886
887 cppu::OInterfaceContainerHelper* pPropsContainer
888 = m_pImpl->m_pPropertyChangeListeners->getContainer( rName );
889 if ( pPropsContainer )
890 {
891 cppu::OInterfaceIteratorHelper aIter( *pPropsContainer );
892 while ( aIter.hasMoreElements() )
893 {
894 PropertyEventSequence* p = NULL;
895
896 beans::XPropertiesChangeListener* pListener =
897 static_cast< beans::XPropertiesChangeListener * >(
898 aIter.next() );
899 PropertiesEventListenerMap::iterator it =
900 aListeners.find( pListener );
901 if ( it == aListeners.end() )
902 {
903 // Not in map - create and insert new entry.
904 p = new PropertyEventSequence( nCount );
905 aListeners[ pListener ] = p;
906 }
907 else
908 p = (*it).second;
909
910 if ( p )
911 p->append( rEvent );
912 }
913 }
914 }
915
916 // Notify listeners.
917 PropertiesEventListenerMap::iterator it = aListeners.begin();
918 while ( !aListeners.empty() )
919 {
920 beans::XPropertiesChangeListener* pListener =
921 static_cast< beans::XPropertiesChangeListener * >( (*it).first );
922 PropertyEventSequence* pSeq = (*it).second;
923
924 // Remove current element.
925 aListeners.erase( it );
926
927 // Propagate event.
928 pListener->propertiesChange( pSeq->getEvents() );
929
930 delete pSeq;
931
932 it = aListeners.begin();
933 }
934 }
935 }
936
937 //=========================================================================
notifyPropertySetInfoChange(const beans::PropertySetInfoChangeEvent & evt) const938 void ContentImplHelper::notifyPropertySetInfoChange(
939 const beans::PropertySetInfoChangeEvent& evt ) const
940 {
941 if ( !m_pImpl->m_pPropSetChangeListeners )
942 return;
943
944 // Notify event listeners.
945 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pPropSetChangeListeners );
946 while ( aIter.hasMoreElements() )
947 {
948 // Propagate event.
949 uno::Reference< beans::XPropertySetInfoChangeListener >
950 xListener( aIter.next(), uno::UNO_QUERY );
951 if ( xListener.is() )
952 xListener->propertySetInfoChange( evt );
953 }
954 }
955
956 //=========================================================================
notifyCommandInfoChange(const com::sun::star::ucb::CommandInfoChangeEvent & evt) const957 void ContentImplHelper::notifyCommandInfoChange(
958 const com::sun::star::ucb::CommandInfoChangeEvent& evt ) const
959 {
960 if ( !m_pImpl->m_pCommandChangeListeners )
961 return;
962
963 // Notify event listeners.
964 cppu::OInterfaceIteratorHelper aIter(
965 *m_pImpl->m_pCommandChangeListeners );
966 while ( aIter.hasMoreElements() )
967 {
968 // Propagate event.
969 uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >
970 xListener( aIter.next(), uno::UNO_QUERY );
971 if ( xListener.is() )
972 xListener->commandInfoChange( evt );
973 }
974 }
975
976 //=========================================================================
notifyContentEvent(const com::sun::star::ucb::ContentEvent & evt) const977 void ContentImplHelper::notifyContentEvent(
978 const com::sun::star::ucb::ContentEvent& evt ) const
979 {
980 if ( !m_pImpl->m_pContentEventListeners )
981 return;
982
983 // Notify event listeners.
984 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pContentEventListeners );
985 while ( aIter.hasMoreElements() )
986 {
987 // Propagate event.
988 uno::Reference<
989 com::sun::star::ucb::XContentEventListener > xListener(
990 aIter.next(), uno::UNO_QUERY );
991 if ( xListener.is() )
992 xListener->contentEvent( evt );
993 }
994 }
995
996 //=========================================================================
inserted()997 void ContentImplHelper::inserted()
998 {
999 // Content is not yet registered at provider.
1000 m_xProvider->registerNewContent( this );
1001
1002 // If the parent content is currently not instanciated, there can be
1003 // no listeners interested in changes ;-)
1004
1005 rtl::Reference< ContentImplHelper > xParent
1006 = m_xProvider->queryExistingContent( getParentURL() );
1007
1008 if ( xParent.is() )
1009 {
1010 com::sun::star::ucb::ContentEvent aEvt(
1011 static_cast< cppu::OWeakObject * >( xParent.get() ), // Source
1012 com::sun::star::ucb::ContentAction::INSERTED, // Action
1013 this, // Content
1014 xParent->getIdentifier() ); // Id
1015 xParent->notifyContentEvent( aEvt );
1016 }
1017 }
1018
1019 //=========================================================================
deleted()1020 void ContentImplHelper::deleted()
1021 {
1022 uno::Reference< com::sun::star::ucb::XContent > xThis = this;
1023
1024 rtl::Reference< ContentImplHelper > xParent
1025 = m_xProvider->queryExistingContent( getParentURL() );
1026
1027 if ( xParent.is() )
1028 {
1029 // Let parent notify "REMOVED" event.
1030 com::sun::star::ucb::ContentEvent aEvt(
1031 static_cast< cppu::OWeakObject * >( xParent.get() ),
1032 com::sun::star::ucb::ContentAction::REMOVED,
1033 this,
1034 xParent->getIdentifier() );
1035 xParent->notifyContentEvent( aEvt );
1036 }
1037
1038 // Notify "DELETED" event.
1039 com::sun::star::ucb::ContentEvent aEvt1(
1040 static_cast< cppu::OWeakObject * >( this ),
1041 com::sun::star::ucb::ContentAction::DELETED,
1042 this,
1043 getIdentifier() );
1044 notifyContentEvent( aEvt1 );
1045
1046 m_xProvider->removeContent( this );
1047 }
1048
1049 //=========================================================================
exchange(const uno::Reference<com::sun::star::ucb::XContentIdentifier> & rNewId)1050 sal_Bool ContentImplHelper::exchange(
1051 const uno::Reference< com::sun::star::ucb::XContentIdentifier >& rNewId )
1052 {
1053 uno::Reference< com::sun::star::ucb::XContent > xThis = this;
1054
1055 osl::ClearableMutexGuard aGuard( m_aMutex );
1056
1057 rtl::Reference< ContentImplHelper > xContent
1058 = m_xProvider->queryExistingContent( rNewId );
1059 if ( xContent.is() )
1060 {
1061 // @@@
1062 // Big trouble. Another object with the new identity exists.
1063 // How shall I mutate to / merge with the other object?
1064 return sal_False;
1065 }
1066
1067 uno::Reference< com::sun::star::ucb::XContentIdentifier > xOldId
1068 = getIdentifier();
1069
1070 // Re-insert at provider.
1071 m_xProvider->removeContent( this );
1072 m_xIdentifier = rNewId;
1073 m_xProvider->registerNewContent( this );
1074
1075 aGuard.clear();
1076
1077 // Notify "EXCHANGED" event.
1078 com::sun::star::ucb::ContentEvent aEvt(
1079 static_cast< cppu::OWeakObject * >( this ),
1080 com::sun::star::ucb::ContentAction::EXCHANGED,
1081 this,
1082 xOldId );
1083 notifyContentEvent( aEvt );
1084 return sal_True;
1085 }
1086
1087 //=========================================================================
1088 uno::Reference< com::sun::star::ucb::XCommandInfo >
getCommandInfo(const uno::Reference<com::sun::star::ucb::XCommandEnvironment> & xEnv,sal_Bool bCache)1089 ContentImplHelper::getCommandInfo(
1090 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
1091 sal_Bool bCache )
1092 {
1093 osl::MutexGuard aGuard( m_aMutex );
1094
1095 if ( !m_pImpl->m_xCommandsInfo.is() )
1096 m_pImpl->m_xCommandsInfo
1097 = new CommandProcessorInfo( m_xSMgr, xEnv, this );
1098 else if ( !bCache )
1099 m_pImpl->m_xCommandsInfo->reset();
1100
1101 return uno::Reference< com::sun::star::ucb::XCommandInfo >(
1102 m_pImpl->m_xCommandsInfo.get() );
1103 }
1104
1105 //=========================================================================
1106 uno::Reference< beans::XPropertySetInfo >
getPropertySetInfo(const uno::Reference<com::sun::star::ucb::XCommandEnvironment> & xEnv,sal_Bool bCache)1107 ContentImplHelper::getPropertySetInfo(
1108 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
1109 sal_Bool bCache )
1110 {
1111 osl::MutexGuard aGuard( m_aMutex );
1112
1113 if ( !m_pImpl->m_xPropSetInfo.is() )
1114 m_pImpl->m_xPropSetInfo
1115 = new PropertySetInfo( m_xSMgr, xEnv, this );
1116 else if ( !bCache )
1117 m_pImpl->m_xPropSetInfo->reset();
1118
1119 return uno::Reference< beans::XPropertySetInfo >(
1120 m_pImpl->m_xPropSetInfo.get() );
1121 }
1122
1123 } // namespace ucbhelper
1124