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 _UCBHELPER_CONTENTHELPER_HXX
25 #define _UCBHELPER_CONTENTHELPER_HXX
26 
27 #include <com/sun/star/beans/XPropertyContainer.hpp>
28 #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
29 #include <com/sun/star/ucb/XCommandProcessor.hpp>
30 #include <com/sun/star/ucb/XContent.hpp>
31 #include <com/sun/star/beans/XPropertySetInfoChangeNotifier.hpp>
32 #include <com/sun/star/ucb/XCommandInfoChangeNotifier.hpp>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/lang/XTypeProvider.hpp>
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
38 #include <com/sun/star/ucb/CommandAbortedException.hpp>
39 #include <cppuhelper/weak.hxx>
40 
41 #include "osl/mutex.hxx"
42 #include "rtl/ref.hxx"
43 #include <ucbhelper/macros.hxx>
44 #include "ucbhelper/ucbhelperdllapi.h"
45 
46 namespace com { namespace sun { namespace star { namespace ucb {
47 	struct CommandInfo;
48 	class XCommandEnvironment;
49 	class XCommandInfo;
50 	class XPersistentPropertySet;
51 } } } }
52 
53 namespace com { namespace sun { namespace star { namespace beans {
54 	struct Property;
55 	class XPropertySetInfo;
56 } } } }
57 
58 namespace ucbhelper_impl { struct ContentImplHelper_Impl; }
59 
60 namespace ucbhelper
61 {
62 
63 //=========================================================================
64 
65 class ContentProviderImplHelper;
66 
67 /**
68   * This is an abstract base class for implementations of the service
69   * com.sun.star.ucb.Content. Implementations derived from this class are
70   * objects provided by implementations derived from
71   * class ucb::ContentProviderImplHelper.
72   *
73   * Features of the base class implementation:
74   * - standard interfaces ( XInterface, XTypeProvider, XServiceInfo )
75   *	- all required interfaces for service com::sun::star::ucb::Content
76   * - all required listener containers
77   *   ( XComponent, XPropertiesChangeNotifier, XPropertySetInfoChangeNotifier,
78   *     XCommandInfoChangeNotifier )
79   *	- XPropertyContainer implementation ( persistence is implemented using
80   *   service com.sun.star.ucb.Store )
81   * - complete XPropertySetInfo implementation ( including Additioanl Core
82   *   Properties supplied via XPropertyContainer interface )
83   *   -> protected method: getPropertySetInfo
84   *	- complete XCommandInfo implementation
85   *    -> protected method: getCommandInfo
86   */
87 class UCBHELPER_DLLPUBLIC ContentImplHelper :
88 				public cppu::OWeakObject,
89 				public com::sun::star::lang::XTypeProvider,
90 				public com::sun::star::lang::XServiceInfo,
91 				public com::sun::star::lang::XComponent,
92 				public com::sun::star::ucb::XContent,
93 				public com::sun::star::ucb::XCommandProcessor,
94 				public com::sun::star::beans::XPropertiesChangeNotifier,
95 				public com::sun::star::beans::XPropertyContainer,
96 				public com::sun::star::beans::XPropertySetInfoChangeNotifier,
97 				public com::sun::star::ucb::XCommandInfoChangeNotifier,
98 				public com::sun::star::container::XChild
99 {
100 	friend class PropertySetInfo;
101 	friend class CommandProcessorInfo;
102 
103 	ucbhelper_impl::ContentImplHelper_Impl* m_pImpl;
104 
105 protected:
106 	osl::Mutex						 m_aMutex;
107 	com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
108 									 m_xSMgr;
109 	com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >
110 									 m_xIdentifier;
111 	rtl::Reference< ContentProviderImplHelper >
112 									 m_xProvider;
113 	sal_uInt32						 m_nCommandId;
114 
115 private:
116 	/**
117 	  * Your implementation of this method must return a sequence containing
118 	  * the meta data of the properties supported by the content.
119 	  * Note: If you wish to provide your own implementation of the interface
120 	  * XPropertyContainer ( completely override addContent and removeContent
121 	  * implementation of this base class in this case ), you can supply the
122 	  * meta data for your Additional Core Properties here to get a fully
123 	  * featured getPropertySetInfo method ( see below ).
124 	  *
125 	  * @param xEnv is an environment to use for example, for interactions.
126 	  * @return a sequence containing the property meta data.
127 	  */
128 	UCBHELPER_DLLPRIVATE
129     virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
130 	getProperties( const com::sun::star::uno::Reference<
131 					com::sun::star::ucb::XCommandEnvironment > & xEnv ) = 0;
132 
133 	/**
134 	  * Your implementation of this method must return a sequence containing
135 	  * the meta data of the commands supported by the content.
136 	  *
137 	  * @param xEnv is an environment to use for example, for interactions.
138 	  * @return a sequence containing the command meta data.
139 	  */
140 	UCBHELPER_DLLPRIVATE
141     virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
142 	getCommands( const com::sun::star::uno::Reference<
143 					com::sun::star::ucb::XCommandEnvironment > & xEnv ) = 0;
144 
145 	/**
146 	  * The implementation of this method shall return the URL of the parent
147 	  * of your content.
148 	  *
149 	  * @return the URL of the parent content or an empty string.
150 	  *         Note that not all contents must have one parent. There may
151 	  *         be contents with no parent. In that case an empty string must
152 	  *         be returned. If your content has more than one parent you may
153 	  *         return the URL of one "preferred" parent or an empty string.
154 	  */
155     UCBHELPER_DLLPRIVATE virtual ::rtl::OUString getParentURL() = 0;
156 
157 protected:
158 	/**
159 	  *	This method returns complete meta data for the properties ( including
160 	  * Additional Core Properties supplied via XPropertyContainer interface )
161 	  * supported by the content. To implement the required command
162 	  * "getPropertySetInfo" simply return the return value of this method.
163 	  *
164 	  * @param xEnv is an environment to use for example, for interactions.
165 	  * @param bCache indicates, whether the implemetation should use
166 	  *        cached data, if exist.
167 	  * @return an XPropertySetInfo implementation object containing meta data
168 	  *         for the properties supported by this content.
169 	  */
170     com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >
171 	getPropertySetInfo( const com::sun::star::uno::Reference<
172 							com::sun::star::ucb::XCommandEnvironment > & xEnv,
173 						sal_Bool bCache = sal_True );
174 
175 	/**
176 	  *	This method returns complete meta data for the commands supported by
177 	  * the content. To implement the required command "getCommandInfo" simply
178 	  * return the return value of this method.
179 	  *
180 	  * @param xEnv is an environment to use for example, for interactions.
181 	  * @param bCache indicates, whether the implemetation should use
182 	  *        cached data, if exist.
183 	  * @return an XCommandInfo implementation object containing meta data
184 	  *         for the commands supported by this content.
185 	  */
186     com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo >
187 	getCommandInfo( const com::sun::star::uno::Reference<
188 							com::sun::star::ucb::XCommandEnvironment > & xEnv,
189 					sal_Bool bCache = sal_True );
190 
191 	/**
192 	  * This method can be used to propagate changes of property values.
193 	  *
194 	  * @param evt is a sequence of property change events.
195 	  */
196 	void notifyPropertiesChange(
197 		const com::sun::star::uno::Sequence<
198 				com::sun::star::beans::PropertyChangeEvent >& evt ) const;
199 
200 	/**
201 	  * This method can be used to propagate changes of the propertyset
202 	  * info of your content (i.e. this happens if a new property is added
203 	  * to your content via its XPropertyContainer interface). This base class
204 	  * automatically generates events when the propertyset info changes. If
205 	  * you provide your own implementations of addproperty and removeProperty,
206 	  * then you must call "notifyPropertySetInfoChange" by yourself.
207 	  *
208 	  * @param evt is a sequence of property change events.
209 	  */
210 	void notifyPropertySetInfoChange(
211 		const com::sun::star::beans::PropertySetInfoChangeEvent& evt ) const;
212 
213 	/**
214 	  * This method can be used to propagate changes of the command info of
215 	  * your content. This can happen at any time if there shall be a new
216 	  * command available at a content or a currently present command shall no
217 	  * longer be present. (i.e. only if the content count of a trash can
218 	  * object is greater then zero, there will be available a  command
219 	  * "emptyTrash". If there are no objects in the trash can, this command
220 	  * won't be available.
221 	  *
222 	  * @param evt is a sequence of command info change events.
223 	  */
224 	void notifyCommandInfoChange(
225 			const com::sun::star::ucb::CommandInfoChangeEvent& evt ) const;
226 
227 	/**
228 	  * This method can be used to propagate content events.
229 	  *
230 	  * @param evt is a sequence of content events.
231 	  */
232 	void notifyContentEvent(
233 			const com::sun::star::ucb::ContentEvent& evt ) const;
234 
235 	/**
236 	  *	Use this method to announce the insertion of this content at
237 	  *	the end of your implementation of the command "insert". The
238 	  * implementation of is method propagates a ContentEvent( INSERTED ).
239 	  */
240 	void inserted();
241 
242 	/**
243 	  *	Use this method to announce the destruction of this content at
244 	  *	the end of your implementation of the command "delete". The
245 	  * implementation of is method propagates a ContentEvent( DELETED )
246 	  * and a ContentEvent( REMOVED ) at the parent of the deleted content,
247 	  * if a parent exists.
248 	  */
249 	void deleted();
250 
251 	/**
252 	  *	Use this method to change the identity of a content. The implementation
253 	  * of this method will replace the content identifier of the content and
254 	  * propagate the appropriate ContentEvent( EXCHANGED ).
255 	  *
256 	  * @param  rNewId is the new content identifier for the contant.
257 	  * @return a success indicator.
258 	  */
259 	sal_Bool exchange( const com::sun::star::uno::Reference<
260 						com::sun::star::ucb::XContentIdentifier >& rNewId );
261 
262 	/**
263 	  *	Use this method to get access to the Additional Core Properties of
264 	  *	the content ( added using content's XPropertyContainer interface ).
265 	  * If you supply your own XPropertyContainer implementation, this method
266 	  * will always return an empty propertyset.
267 	  *
268 	  * @param  bCreate indicates whether a new propertyset shall be created
269 	  *         if it does not exist.
270 	  * @return the implementation of the service
271 	  *         com.sun.star.ucb.PersistentPropertySet.
272 	  */
273 	com::sun::star::uno::Reference<
274         com::sun::star::ucb::XPersistentPropertySet >
275 	getAdditionalPropertySet( sal_Bool bCreate );
276 
277 	/**
278 	  *	This method renames the propertyset containing the Additional Core
279 	  * Properties of the content.
280 	  *
281 	  * @param  rOldKey is the old key of the propertyset.
282 	  * @param  rNewKey is the new key for the propertyset.
283 	  * @param  bRecursive is a flag indicating whether propertysets for
284 	  *         children described by rOldKey shall be renamed too.
285 	  * @return True, if the operation succeeded - False, otherwise.
286 	  */
287 	sal_Bool renameAdditionalPropertySet( const ::rtl::OUString& rOldKey,
288 										  const ::rtl::OUString& rNewKey,
289 										  sal_Bool bRecursive );
290 
291 	/**
292 	  *	This method copies the propertyset containing the Additional Core
293 	  * Properties of the content.
294 	  *
295 	  * @param  rSourceKey is the key of the source propertyset.
296 	  * @param  rTargetKey is the key of the target propertyset.
297 	  * @param  bRecursive is a flag indicating whether propertysets for
298 	  *         children described by rSourceKey shall be copied too.
299 	  * @return True, if the operation succeeded - False, otherwise.
300 	  */
301 	sal_Bool copyAdditionalPropertySet( const ::rtl::OUString& rSourceKey,
302 										const ::rtl::OUString& rTargetKey,
303 										sal_Bool bRecursive );
304 
305 	/**
306 	  *	This method removes the propertyset containing the Additional Core
307 	  * Properties of the content.
308 	  *
309 	  * @param  bRecursive is a flag indicating whether propertysets for
310 	  *         children described by rOldKey shall be removed too.
311 	  * @return True, if the operation succeeded - False, otherwise.
312 	  */
313 	sal_Bool removeAdditionalPropertySet( sal_Bool bRecursive );
314 
315 public:
316 	/**
317 	  * Constructor.
318 	  *
319 	  * Note that the implementation of this ctor registers itself at its
320 	  * content provider. The provider implementation inserts the content
321 	  * in a hash map. So it easyly can be found and reused when the provider
322 	  * is asked for a content.
323 	  *
324 	  * @param rxSMgr is a Service Manager.
325 	  * @param rxProvider is the provider for the content.
326 	  * @param Identifier is the content identifier for the content.
327 	  */
328 	ContentImplHelper(
329 			const com::sun::star::uno::Reference<
330 				com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
331 			const rtl::Reference< ContentProviderImplHelper >& rxProvider,
332 			const com::sun::star::uno::Reference<
333 				com::sun::star::ucb::XContentIdentifier >& Identifier );
334 
335 	/**
336 	  * Destructor.
337 	  *
338 	  * Note that the implementation of this dtor deregisters itself from its
339 	  * content provider. The provider implementation removes the content
340 	  * from a hash map.
341 	  */
342 	virtual ~ContentImplHelper();
343 
344 	// XInterface
345 	XINTERFACE_DECL()
346 
347 	// XTypeProvider
348 	XTYPEPROVIDER_DECL()
349 
350     // XServiceInfo
351     virtual ::rtl::OUString SAL_CALL
352 	getImplementationName()
353 		throw( ::com::sun::star::uno::RuntimeException ) = 0;
354     virtual sal_Bool SAL_CALL
355 	supportsService( const ::rtl::OUString& ServiceName )
356 		throw( ::com::sun::star::uno::RuntimeException );
357     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
358 	getSupportedServiceNames()
359 		throw( ::com::sun::star::uno::RuntimeException ) = 0;
360 
361 	// XComponent
362     virtual void SAL_CALL
363 	dispose()
364 		throw( com::sun::star::uno::RuntimeException );
365     virtual void SAL_CALL
366 	addEventListener( const com::sun::star::uno::Reference<
367 						com::sun::star::lang::XEventListener >& Listener )
368 		throw( com::sun::star::uno::RuntimeException );
369     virtual void SAL_CALL
370 	removeEventListener( const com::sun::star::uno::Reference<
371 							com::sun::star::lang::XEventListener >& Listener )
372 		throw( com::sun::star::uno::RuntimeException );
373 
374 	// XContent
375     virtual com::sun::star::uno::Reference<
376 				com::sun::star::ucb::XContentIdentifier > SAL_CALL
377 	getIdentifier()
378 		throw( com::sun::star::uno::RuntimeException );
379     virtual rtl::OUString SAL_CALL
380 	getContentType()
381 		throw( com::sun::star::uno::RuntimeException ) = 0;
382     virtual void SAL_CALL
383 	addContentEventListener(
384 		const com::sun::star::uno::Reference<
385 			com::sun::star::ucb::XContentEventListener >& Listener )
386 		throw( com::sun::star::uno::RuntimeException );
387     virtual void SAL_CALL
388 	removeContentEventListener(
389 		const com::sun::star::uno::Reference<
390 			com::sun::star::ucb::XContentEventListener >& Listener )
391 		throw( com::sun::star::uno::RuntimeException );
392 
393 	// XCommandProcessor
394     virtual sal_Int32 SAL_CALL
395 	createCommandIdentifier()
396 		throw( com::sun::star::uno::RuntimeException );
397     virtual com::sun::star::uno::Any SAL_CALL
398 	execute( const com::sun::star::ucb::Command& aCommand,
399 			 sal_Int32 CommandId,
400 			 const com::sun::star::uno::Reference<
401 			 	com::sun::star::ucb::XCommandEnvironment >& Environment )
402     	throw( com::sun::star::uno::Exception,
403 			   com::sun::star::ucb::CommandAbortedException,
404 			   com::sun::star::uno::RuntimeException ) = 0;
405     virtual void SAL_CALL
406 	abort( sal_Int32 CommandId )
407 		throw( com::sun::star::uno::RuntimeException ) = 0;
408 
409 	// XPropertiesChangeNotifier
410     virtual void SAL_CALL
411 	addPropertiesChangeListener(
412 		const com::sun::star::uno::Sequence< rtl::OUString >& PropertyNames,
413 	 	const com::sun::star::uno::Reference<
414 			com::sun::star::beans::XPropertiesChangeListener >& Listener )
415 		throw( com::sun::star::uno::RuntimeException );
416     virtual void SAL_CALL
417 	removePropertiesChangeListener(
418 		const com::sun::star::uno::Sequence< rtl::OUString >& PropertyNames,
419 		const com::sun::star::uno::Reference<
420 			com::sun::star::beans::XPropertiesChangeListener >& Listener )
421 		throw( com::sun::star::uno::RuntimeException );
422 
423 	// XCommandInfoChangeNotifier
424     virtual void SAL_CALL
425 	addCommandInfoChangeListener(
426 		const com::sun::star::uno::Reference<
427 			com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
428 		throw( com::sun::star::uno::RuntimeException );
429     virtual void SAL_CALL
430 	removeCommandInfoChangeListener(
431 		const com::sun::star::uno::Reference<
432 			::com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
433 		throw( com::sun::star::uno::RuntimeException );
434 
435 	// XPropertyContainer
436 
437 	/**
438 	  * This method adds a property to the content according to the interface
439 	  * specification. The properties will be stored using the service
440 	  * com.sun.star.ucb.Store.
441 	  *
442 	  * Note: You may provide your own implementation of this method, for
443 	  * instance, if your data source supports adding/removing of properties.
444 	  * Don't forget to return the meta data for these properties in your
445 	  * implementation of getPropertyInfoTable.
446 	  */
447 	virtual void SAL_CALL
448 	addProperty( const rtl::OUString& Name,
449 				 sal_Int16 Attributes,
450 				 const com::sun::star::uno::Any& DefaultValue )
451 		throw( com::sun::star::beans::PropertyExistException,
452 			   com::sun::star::beans::IllegalTypeException,
453 			   com::sun::star::lang::IllegalArgumentException,
454 			   com::sun::star::uno::RuntimeException );
455 
456 	/**
457 	  * This method removes a property from the content according to the
458 	  * interface specification. The properties will be stored using the
459 	  * service com.sun.star.ucb.Store.
460 	  *
461 	  * Note: You may provide your own implementation of this method, for
462 	  * instance, if your data source supports adding/removing of properties.
463 	  * Don't forget to return the meta data for these properties in your
464 	  * implementation of getPropertyInfoTable.
465 	  */
466     virtual void SAL_CALL
467 	removeProperty( const rtl::OUString& Name )
468 		throw( com::sun::star::beans::UnknownPropertyException,
469 			   com::sun::star::beans::NotRemoveableException,
470 			   com::sun::star::uno::RuntimeException );
471 
472 	// XPropertySetInfoChangeNotifier
473     virtual void SAL_CALL
474 	addPropertySetInfoChangeListener(
475 		const com::sun::star::uno::Reference<
476 			com::sun::star::beans::XPropertySetInfoChangeListener >& Listener )
477 		throw( com::sun::star::uno::RuntimeException );
478     virtual void SAL_CALL
479 	removePropertySetInfoChangeListener(
480 		const com::sun::star::uno::Reference<
481 			com::sun::star::beans::XPropertySetInfoChangeListener >& Listener )
482 		throw( com::sun::star::uno::RuntimeException );
483 
484 	// XChild
485 
486 	/**
487 	  * This method returns the content representing the parent of a content,
488 	  * if such a parent exists. The implementation of this method uses your
489 	  * implementation of getParentURL.
490 	  */
491     virtual com::sun::star::uno::Reference<
492 				com::sun::star::uno::XInterface > SAL_CALL
493 	getParent()
494 		throw( com::sun::star::uno::RuntimeException );
495 
496 	/**
497 	  * The implementation of this method always throws a NoSupportException.
498 	  */
499     virtual void SAL_CALL
500 	setParent( const com::sun::star::uno::Reference<
501 						com::sun::star::uno::XInterface >& Parent )
502 		throw( com::sun::star::lang::NoSupportException,
503 			   com::sun::star::uno::RuntimeException );
504 
505 	//////////////////////////////////////////////////////////////////////
506 	// Non-interface methods.
507 	//////////////////////////////////////////////////////////////////////
508 
509 	/**
510 	  * This method returns the provider of the content.
511 	  *
512 	  * @return the provider of the content.
513 	  */
getProvider() const514 	const rtl::Reference< ContentProviderImplHelper >& getProvider() const
515 	{ return m_xProvider; }
516 };
517 
518 } // namespace ucbhelper
519 
520 #endif /* !_UCBHELPER_CONTENTHELPER_HXX */
521