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