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