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