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 #ifndef COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX
24 #define COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX
25 
26 #include <cppuhelper/component.hxx>
27 #include <osl/mutex.hxx>
28 #include <cppuhelper/interfacecontainer.hxx>
29 #include <osl/diagnose.h>
30 #include <comphelper/stl_types.hxx>
31 #include <rtl/instance.hxx>
32 #include <cppuhelper/propshlp.hxx>
33 
34 namespace cppu { class IPropertyArrayHelper; }
35 
36 namespace comphelper
37 {
38 	//************************************************************
39 	//  OIdPropertyArrayUsageHelper
40 	//************************************************************
41 	template <typename TYPE> struct OIdPropertyArrayUsageHelperMutex
42         	: public rtl::Static< ::osl::Mutex, OIdPropertyArrayUsageHelperMutex<TYPE> > {};
43 
44 	typedef std::map< sal_Int32, ::cppu::IPropertyArrayHelper*, std::less< sal_Int32 > > OIdPropertyArrayMap;
45 	template <class TYPE>
46 	class OIdPropertyArrayUsageHelper
47 	{
48 	protected:
49 		static sal_Int32						s_nRefCount;
50 		static OIdPropertyArrayMap*				s_pMap;
51 
52 	public:
53 		OIdPropertyArrayUsageHelper();
~OIdPropertyArrayUsageHelper()54 		virtual ~OIdPropertyArrayUsageHelper()
55 		{
56 			::osl::MutexGuard aGuard(OIdPropertyArrayUsageHelperMutex<TYPE>::get());
57 			OSL_ENSURE(s_nRefCount > 0, "OIdPropertyArrayUsageHelper::~OIdPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !");
58 			if (!--s_nRefCount)
59 			{
60 				// delete the element
61 				for (OIdPropertyArrayMap::iterator i = s_pMap->begin(); i != s_pMap->end(); ++i)
62 					delete (*i).second;
63 				delete s_pMap;
64 				s_pMap = NULL;
65 			}
66 		}
67 
68 		/** call this in the getInfoHelper method of your derived class. The method returns the array helper of the
69 			class, which is created if necessary.
70 		*/
71 		::cppu::IPropertyArrayHelper* getArrayHelper(sal_Int32 nId);
72 
73 	protected:
74 		/** used to implement the creation of the array helper which is shared amongst all instances of the class.
75 			This method needs to be implemented in derived classes.
76 			<BR>
77 			The method gets called with Mutex acquired.
78 			<BR>
79 			as long as IPropertyArrayHelper has no virtual destructor, the implementation of ~OPropertyArrayUsageHelper
80 			assumes that you created an ::cppu::OPropertyArrayHelper when deleting s_pProps.
81 			@return							an pointer to the newly created array helper. Must not be NULL.
82 		*/
83 		virtual ::cppu::IPropertyArrayHelper* createArrayHelper(sal_Int32 nId) const = 0;
84 	};
85 
86 	//------------------------------------------------------------------
87 	template<class TYPE>
88 	sal_Int32						OIdPropertyArrayUsageHelper< TYPE >::s_nRefCount	= 0;
89 
90 	template<class TYPE>
91 	OIdPropertyArrayMap*			OIdPropertyArrayUsageHelper< TYPE >::s_pMap	= NULL;
92 
93 	//------------------------------------------------------------------
94 	template <class TYPE>
OIdPropertyArrayUsageHelper()95 	OIdPropertyArrayUsageHelper<TYPE>::OIdPropertyArrayUsageHelper()
96 	{
97 		::osl::MutexGuard aGuard(OIdPropertyArrayUsageHelperMutex<TYPE>::get());
98 		// create the map if necessary
99 		if (s_pMap == NULL)
100 			s_pMap = new OIdPropertyArrayMap();
101 		++s_nRefCount;
102 	}
103 
104 	//------------------------------------------------------------------
105 	template <class TYPE>
getArrayHelper(sal_Int32 nId)106 	::cppu::IPropertyArrayHelper* OIdPropertyArrayUsageHelper<TYPE>::getArrayHelper(sal_Int32 nId)
107 	{
108 		OSL_ENSURE(s_nRefCount, "OIdPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !");
109 		::osl::MutexGuard aGuard(OIdPropertyArrayUsageHelperMutex<TYPE>::get());
110 		// do we have the array already?
111 		if (! (*s_pMap)[nId] )
112 		{
113 			(*s_pMap)[nId] = createArrayHelper(nId);
114 			OSL_ENSURE((*s_pMap)[nId], "OIdPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !");
115 		}
116 		return (*s_pMap)[nId];
117 	}
118 }
119 #endif // COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX
120