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