1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _DBA_CORE_DEFINITIONCONTAINER_HXX_ 25 #define _DBA_CORE_DEFINITIONCONTAINER_HXX_ 26 27 #ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_ 28 #include <cppuhelper/interfacecontainer.hxx> 29 #endif 30 #ifndef _CPPUHELPER_IMPLBASE7_HXX_ 31 #include <cppuhelper/implbase7.hxx> 32 #endif 33 #ifndef _COMPHELPER_STLTYPES_HXX_ 34 #include <comphelper/stl_types.hxx> 35 #endif 36 #ifndef _OSL_MUTEX_HXX_ 37 #include <osl/mutex.hxx> 38 #endif 39 #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ 40 #include <com/sun/star/container/XChild.hpp> 41 #endif 42 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ 43 #include <com/sun/star/container/XNameContainer.hpp> 44 #endif 45 #ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_ 46 #include <com/sun/star/container/XContainer.hpp> 47 #endif 48 #ifndef _COM_SUN_STAR_CONTAINER_XENUMERATIONACCESS_HPP_ 49 #include <com/sun/star/container/XEnumerationAccess.hpp> 50 #endif 51 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_ 52 #include <com/sun/star/container/XIndexAccess.hpp> 53 #endif 54 #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ 55 #include <com/sun/star/lang/XServiceInfo.hpp> 56 #endif 57 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ 58 #include <com/sun/star/lang/DisposedException.hpp> 59 #endif 60 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_ 61 #include <com/sun/star/beans/XPropertyChangeListener.hpp> 62 #endif 63 #ifndef _COM_SUN_STAR_BEANS_XVETOABLECHANGELISTENER_HPP_ 64 #include <com/sun/star/beans/XVetoableChangeListener.hpp> 65 #endif 66 #ifndef _COM_SUN_STAR_CONTAINER_XCONTAINERAPPROVEBROADCASTER_HPP_ 67 #include <com/sun/star/container/XContainerApproveBroadcaster.hpp> 68 #endif 69 #ifndef DBA_CONTENTHELPER_HXX 70 #include "ContentHelper.hxx" 71 #endif 72 #ifndef DBACCESS_CONTAINERAPPROVE_HXX 73 #include "containerapprove.hxx" 74 #endif 75 #ifndef _COMPHELPER_UNO3_HXX_ 76 #include <comphelper/uno3.hxx> 77 #endif 78 #ifndef _RTL_REF_HXX_ 79 #include <rtl/ref.hxx> 80 #endif 81 #ifndef _DBASHARED_APITOOLS_HXX_ 82 #include "apitools.hxx" 83 #endif 84 //........................................................................ 85 namespace dbaccess 86 { 87 //........................................................................ 88 89 class ODefinitionContainer_Impl : public OContentHelper_Impl 90 { 91 public: 92 typedef ::std::map< ::rtl::OUString, TContentPtr > NamedDefinitions; 93 typedef NamedDefinitions::iterator iterator; 94 typedef NamedDefinitions::const_iterator const_iterator; 95 96 private: 97 NamedDefinitions m_aDefinitions; 98 99 public: 100 inline size_t size() const { return m_aDefinitions.size(); } 101 102 inline const_iterator begin() const { return m_aDefinitions.begin(); } 103 inline const_iterator end() const { return m_aDefinitions.end(); } 104 105 inline const_iterator find( const ::rtl::OUString& _rName ) const { return m_aDefinitions.find( _rName ); } 106 const_iterator find( TContentPtr _pDefinition ) const; 107 108 inline void erase( const ::rtl::OUString& _rName ) { m_aDefinitions.erase( _rName ); } 109 void erase( TContentPtr _pDefinition ); 110 111 inline void insert( const ::rtl::OUString& _rName, TContentPtr _pDefinition ) 112 { 113 m_aDefinitions.insert( NamedDefinitions::value_type( _rName, _pDefinition ) ); 114 } 115 116 private: 117 iterator find( TContentPtr _pDefinition ); 118 // (for the moment, this is private. Make it public if needed. If really needed.) 119 }; 120 121 //========================================================================== 122 //= ODefinitionContainer - base class of collections of database definition 123 //= documents 124 //========================================================================== 125 typedef ::cppu::ImplHelper7 < ::com::sun::star::container::XIndexAccess 126 , ::com::sun::star::container::XNameContainer 127 , ::com::sun::star::container::XEnumerationAccess 128 , ::com::sun::star::container::XContainer 129 , ::com::sun::star::container::XContainerApproveBroadcaster 130 , ::com::sun::star::beans::XPropertyChangeListener 131 , ::com::sun::star::beans::XVetoableChangeListener 132 > ODefinitionContainer_Base; 133 134 class ODefinitionContainer 135 :public OContentHelper 136 ,public ODefinitionContainer_Base 137 { 138 protected: 139 DECLARE_STL_USTRINGACCESS_MAP(::com::sun::star::uno::WeakReference< ::com::sun::star::ucb::XContent >, Documents); 140 DECLARE_STL_VECTOR(Documents::iterator, DocumentsIndexAccess); 141 142 enum ContainerOperation 143 { 144 E_REPLACED, 145 E_REMOVED, 146 E_INSERTED 147 }; 148 149 enum ListenerType 150 { 151 ApproveListeners, 152 ContainerListemers 153 }; 154 155 private: 156 PContainerApprove m_pElementApproval; 157 158 protected: 159 // we can't just hold a vector of XContentRefs, as after initialization they're all empty 160 // cause we load them only on access 161 DocumentsIndexAccess m_aDocuments; // for a efficient index access 162 Documents m_aDocumentMap; // for a efficient name access 163 164 ::cppu::OInterfaceContainerHelper 165 m_aApproveListeners; 166 ::cppu::OInterfaceContainerHelper 167 m_aContainerListeners; 168 169 sal_Bool m_bInPropertyChange; 170 bool m_bCheckSlash; 171 172 protected: 173 /** Additionally to our own approvals which new elements must pass, derived classes 174 can specifiy an additional approval instance here. 175 176 Every time a new element is inserted into the container (or an element is replaced 177 with a new one), this new element must pass our own internal approval, plus the approval 178 given here. 179 */ 180 void setElementApproval( PContainerApprove _pElementApproval ) { m_pElementApproval = _pElementApproval; } 181 PContainerApprove getElementApproval() const { return m_pElementApproval; } 182 183 protected: 184 virtual ~ODefinitionContainer(); 185 186 inline const ODefinitionContainer_Impl& getDefinitions() const 187 { 188 return dynamic_cast< const ODefinitionContainer_Impl& >( *m_pImpl.get() ); 189 } 190 191 inline ODefinitionContainer_Impl& getDefinitions() 192 { 193 return dynamic_cast< ODefinitionContainer_Impl& >( *m_pImpl.get() ); 194 } 195 public: 196 /** constructs the container. 197 */ 198 ODefinitionContainer( 199 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB 200 , const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParentContainer 201 , const TContentPtr& _pImpl 202 , bool _bCheckSlash = true 203 ); 204 205 // ::com::sun::star::uno::XInterface 206 DECLARE_XINTERFACE( ) 207 // com::sun::star::lang::XTypeProvider 208 DECLARE_TYPEPROVIDER( ); 209 210 // ::com::sun::star::lang::XServiceInfo 211 virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); 212 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); 213 214 // ::com::sun::star::container::XElementAccess 215 virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw(::com::sun::star::uno::RuntimeException); 216 virtual sal_Bool SAL_CALL hasElements( ) throw(::com::sun::star::uno::RuntimeException); 217 218 // ::com::sun::star::container::XEnumerationAccess 219 virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration( ) throw(::com::sun::star::uno::RuntimeException); 220 221 // ::com::sun::star::container::XIndexAccess 222 virtual sal_Int32 SAL_CALL getCount( ) throw(::com::sun::star::uno::RuntimeException); 223 virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 _nIndex ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 224 225 // ::com::sun::star::container::XNameContainer 226 virtual void SAL_CALL insertByName( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 227 virtual void SAL_CALL removeByName( const ::rtl::OUString& _rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 228 229 // ::com::sun::star::container::XNameReplace 230 virtual void SAL_CALL replaceByName( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 231 232 // ::com::sun::star::container::XNameAccess 233 virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 234 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw(::com::sun::star::uno::RuntimeException); 235 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException); 236 237 // ::com::sun::star::container::XContainer 238 virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); 239 virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); 240 241 // XContainerApproveBroadcaster 242 virtual void SAL_CALL addContainerApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerApproveListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); 243 virtual void SAL_CALL removeContainerApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerApproveListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); 244 245 // ::com::sun::star::lang::XEventListener 246 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); 247 248 // XPropertyChangeListener 249 virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException); 250 // XVetoableChangeListener 251 virtual void SAL_CALL vetoableChange( const ::com::sun::star::beans::PropertyChangeEvent& aEvent ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException); 252 253 protected: 254 // helper 255 virtual void SAL_CALL disposing(); 256 257 /** create a object from it's persistent data within the configuration. To be overwritten by derived classes. 258 @param _rName the name the object has within the container 259 @return the newly created object or an empty reference if somthing went wrong 260 */ 261 virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > createObject( 262 const ::rtl::OUString& _rName) = 0; 263 264 /** get the object specified by the given name. If desired, the object will be read if not already done so.<BR> 265 @param _rName the object name 266 @param _bReadIfNeccessary if sal_True, the object will be created if necessary 267 @return the property set interface of the object. Usually the return value is not NULL, but 268 if so, then the object could not be read from the configuration 269 @throws NoSuchElementException if there is no object with the given name. 270 @see createObject 271 */ 272 virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > 273 implGetByName(const ::rtl::OUString& _rName, sal_Bool _bCreateIfNecessary) throw (::com::sun::star::container::NoSuchElementException); 274 275 /** quickly checks if there already is an element with a given name. No access to the configuration occures, i.e. 276 if there is such an object which is not already loaded, it won't be loaded now. 277 @param _rName the object name to check 278 @return sal_True if there already exists such an object 279 */ 280 virtual sal_Bool checkExistence(const ::rtl::OUString& _rName); 281 282 /** append a new object to the container. No plausibility checks are done, e.g. if the object is non-NULL or 283 if the name is already used by another object or anything like this. This method is for derived classes 284 which may support different methods to create and/or append objects, and don't want to deal with the 285 internal structures of this class.<BR> 286 The old component will not be disposed, this is the callers responsibility, too. 287 @param _rName the name of the new object 288 @param _rxNewObject the new object (not surprising, is it ?) 289 @see createConfigKey 290 @see implReplace 291 @see implRemove 292 */ 293 void implAppend( 294 const ::rtl::OUString& _rName, 295 const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& _rxNewObject 296 ); 297 298 /** remove all references to an object from the container. No plausibility checks are done, e.g. whether 299 or not there exists an object with the given name. This is the responsibility of the caller.<BR> 300 Additionally the node for the given object will be removed from the registry (including all sub nodes).<BR> 301 The old component will not be disposed, this is the callers responsibility, too. 302 @param _rName the objects name 303 @see implReplace 304 @see implAppend 305 */ 306 void implRemove(const ::rtl::OUString& _rName); 307 308 /** remove a object in the container. No plausibility checks are done, e.g. whether 309 or not there exists an object with the given name or the object is non-NULL. This is the responsibility of the caller.<BR> 310 Additionally all object-related informations within the registry will be deleted. The new object config node, 311 where the caller may want to store the new objects information, is returned.<BR> 312 The old component will not be disposed, this is the callers responsibility, too. 313 @param _rName the objects name 314 @param _rxNewObject the new object 315 @param _rNewObjectNode the configuration node where the new object may be stored 316 @see implAppend 317 @see implRemove 318 */ 319 void implReplace( 320 const ::rtl::OUString& _rName, 321 const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& _rxNewObject 322 ); 323 324 /** notifies our container/approve listeners 325 */ 326 void notifyByName( 327 ::osl::ResettableMutexGuard& _rGuard, 328 const ::rtl::OUString& _rName, 329 const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& _xNewElement, 330 const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& xOldElement, 331 ContainerOperation _eOperation, 332 ListenerType _eType 333 ); 334 335 inline SAL_CALL operator ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > () const 336 { 337 return const_cast< XContainer* >( static_cast< const XContainer* >( this ) ); 338 } 339 340 private: 341 void addObjectListener(const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& _xNewObject); 342 void removeObjectListener(const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& _xNewObject); 343 344 /** approve that the object given may be inserted into the container. Should be overloaded by derived classes, 345 the default implementation just checks the object to be non-void. 346 347 @throws IllegalArgumentException 348 if the name or the object are invalid 349 @throws ElementExistException 350 if the object already exists in the container, or another object with the same name 351 already exists 352 @throws WrappedTargetException 353 if another error occures which prevents insertion of the object into the container 354 */ 355 void approveNewObject( 356 const ::rtl::OUString& _sName, 357 const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >& _rxObject 358 ) const; 359 360 inline bool impl_haveAnyListeners_nothrow() const 361 { 362 return ( m_aContainerListeners.getLength() > 0 ) || ( m_aApproveListeners.getLength() > 0 ); 363 } 364 }; 365 366 //........................................................................ 367 } // namespace dbaccess 368 //........................................................................ 369 370 #endif // _DBA_CORE_DEFINITIONCONTAINER_HXX_ 371 372