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