1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * Copyright 2008 by Sun Microsystems, Inc.
5 *
6 * OpenOffice.org - a multi-platform office productivity suite
7 *
8 * $RCSfile: mysqlc_subcomponent.hxx,v $
9 *
10 * $Revision: 1.1.2.2 $
11 *
12 * This file is part of OpenOffice.org.
13 *
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
17 *
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org.  If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
28 ************************************************************************/
29 
30 #ifndef _CONNECTIVITY_OSUBCOMPONENT_HXX_
31 #define _CONNECTIVITY_OSUBCOMPONENT_HXX_
32 
33 #ifndef _CPPUHELPER_WEAK_HXX_
34 #include <cppuhelper/weak.hxx>
35 #endif
36 #ifndef _CPPUHELPER_INTERFACECONTAINER_H_
37 #include <cppuhelper/interfacecontainer.h>
38 #endif
39 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
40 #include <com/sun/star/lang/DisposedException.hpp>
41 #endif
42 #ifndef _CPPUHELPER_PROPSHLP_HXX
43 #include <cppuhelper/propshlp.hxx>
44 #endif
45 #ifndef _OSL_MUTEX_HXX_
46 #include <osl/mutex.hxx>
47 #endif
48 #ifndef _OSL_DIAGNOSE_H_
49 #include <osl/diagnose.h>
50 #endif
51 
52 namespace cppu {
53 	class IPropertyArrayHelper;
54 }
55 
56 namespace com
57 {
58 	namespace sun
59 	{
60 		namespace star
61 		{
62 			namespace lang
63 			{
64 				class XComponent;
65 			}
66 		}
67 	}
68 }
69 namespace connectivity
70 {
71 
72 	namespace mysqlc
73 	{
74 		void release(oslInterlockedCount& _refCount,
75 					 ::cppu::OBroadcastHelper& rBHelper,
76 					 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
77 					 ::com::sun::star::lang::XComponent* _pObject);
78 
79 		void checkDisposed(sal_Bool _bThrow) throw (::com::sun::star::lang::DisposedException);
80 		//************************************************************
81 		// OSubComponent
82 		//************************************************************
83 		template <class SELF, class WEAK> class OSubComponent
84 		{
85 		protected:
86 			// the parent must support the tunnel implementation
87 			::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xParent;
88 			SELF*	m_pDerivedImplementation;
89 
90 		public:
91 			OSubComponent(
92 					const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParent,
93 					SELF* _pDerivedImplementation)
94 				:m_xParent(_xParent)
95 				,m_pDerivedImplementation(_pDerivedImplementation)
96 			{
97 			}
98 
99 		protected:
100 			void dispose_ChildImpl()
101 			{
102 				::osl::MutexGuard aGuard(m_pDerivedImplementation->rBHelper.rMutex);
103 				m_xParent = NULL;
104 			}
105 			void relase_ChildImpl()
106 			{
107 				release(m_pDerivedImplementation->m_refCount,
108 										m_pDerivedImplementation->rBHelper,
109 										m_xParent,
110 										m_pDerivedImplementation);
111 
112 				m_pDerivedImplementation->WEAK::release();
113 			}
114 		};
115 
116 
117 		template <class TYPE>
118 		class OPropertyArrayUsageHelper
119 		{
120 		protected:
121 			static sal_Int32						s_nRefCount;
122 			static ::cppu::IPropertyArrayHelper*	s_pProps;
123 			static ::osl::Mutex						s_aMutex;
124 
125 		public:
126 			OPropertyArrayUsageHelper();
127 			virtual ~OPropertyArrayUsageHelper()
128 			{	// ARGHHHHHHH ..... would like to implement this in proparrhlp_impl.hxx (as we do with all other methods)
129 				// but SUNPRO 5 compiler (linker) doesn't like this
130 				::osl::MutexGuard aGuard(s_aMutex);
131 				OSL_ENSURE(s_nRefCount > 0, "OPropertyArrayUsageHelper::~OPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !");
132 				if (!--s_nRefCount)
133 				{
134 					delete s_pProps;
135 					s_pProps = NULL;
136 				}
137 			}
138 
139 			/** call this in the getInfoHelper method of your derived class. The method returns the array helper of the
140 				class, which is created if neccessary.
141 			*/
142 			::cppu::IPropertyArrayHelper*	getArrayHelper();
143 
144 		protected:
145 			/** used to implement the creation of the array helper which is shared amongst all instances of the class.
146 				This method needs to be implemented in derived classes.
147 				<BR>
148 				The method gets called with s_aMutex acquired.
149 				<BR>
150 				as long as IPropertyArrayHelper has no virtual destructor, the implementation of ~OPropertyArrayUsageHelper
151 				assumes that you created an ::cppu::OPropertyArrayHelper when deleting s_pProps.
152 				@return							an pointer to the newly created array helper. Must not be NULL.
153 			*/
154 			virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const = 0;
155 		};
156 
157 		template<class TYPE>
158 		sal_Int32						OPropertyArrayUsageHelper< TYPE >::s_nRefCount	= 0;
159 
160 		template<class TYPE>
161 		::cppu::IPropertyArrayHelper*	OPropertyArrayUsageHelper< TYPE >::s_pProps	= NULL;
162 
163 		template<class TYPE>
164 		::osl::Mutex					OPropertyArrayUsageHelper< TYPE >::s_aMutex;
165 
166 		//------------------------------------------------------------------
167 		template <class TYPE>
168 		OPropertyArrayUsageHelper<TYPE>::OPropertyArrayUsageHelper()
169 		{
170 			::osl::MutexGuard aGuard(s_aMutex);
171 			++s_nRefCount;
172 		}
173 
174 		//------------------------------------------------------------------
175 		template <class TYPE>
176 		::cppu::IPropertyArrayHelper* OPropertyArrayUsageHelper<TYPE>::getArrayHelper()
177 		{
178 			OSL_ENSURE(s_nRefCount, "OPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !");
179 			if (!s_pProps) {
180 				::osl::MutexGuard aGuard(s_aMutex);
181 				if (!s_pProps) {
182 					s_pProps = createArrayHelper();
183 					OSL_ENSURE(s_pProps, "OPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !");
184 				}
185 			}
186 			return s_pProps;
187 		}
188 
189 
190 		class OBase_Mutex
191 		{
192 		public:
193 			::osl::Mutex m_aMutex;
194 		};
195 
196 		namespace internal
197 		{
198 			template <class T>
199 			void implCopySequence(const T* _pSource, T*& _pDest, sal_Int32 _nSourceLen)
200 			{
201 				for (sal_Int32 i=0; i<_nSourceLen; ++i, ++_pSource, ++_pDest)
202 					*_pDest = *_pSource;
203 			}
204 		}
205 		//-------------------------------------------------------------------------
206 		/// concat two sequences
207 		template <class T>
208 		::com::sun::star::uno::Sequence<T> concatSequences(const ::com::sun::star::uno::Sequence<T>& _rLeft, const ::com::sun::star::uno::Sequence<T>& _rRight)
209 		{
210 			sal_Int32 nLeft(_rLeft.getLength()), nRight(_rRight.getLength());
211 			const T* pLeft = _rLeft.getConstArray();
212 			const T* pRight = _rRight.getConstArray();
213 
214 			sal_Int32 nReturnLen(nLeft + nRight);
215 			::com::sun::star::uno::Sequence<T> aReturn(nReturnLen);
216 			T* pReturn = aReturn.getArray();
217 
218 			internal::implCopySequence(pLeft, pReturn, nLeft);
219 			internal::implCopySequence(pRight, pReturn, nRight);
220 
221 			return aReturn;
222 		}
223 
224 
225 #define DECLARE_SERVICE_INFO()	\
226 	virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException);	\
227 	virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException);	\
228 	virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)	\
229 
230 #define IMPLEMENT_SERVICE_INFO(classname, implasciiname, serviceasciiname)	\
231 	::rtl::OUString SAL_CALL classname::getImplementationName() throw (::com::sun::star::uno::RuntimeException)	\
232 	{	\
233 		return ::rtl::OUString::createFromAscii(implasciiname);	\
234 	}	\
235 	::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL classname::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)	\
236 	{	\
237 		::com::sun::star::uno::Sequence< ::rtl::OUString > aSupported(1);	\
238 		aSupported[0] = ::rtl::OUString::createFromAscii(serviceasciiname);	\
239 		return aSupported;	\
240 	}	\
241 	sal_Bool SAL_CALL classname::supportsService(const ::rtl::OUString& _rServiceName) throw(::com::sun::star::uno::RuntimeException)	\
242 	{	\
243 		Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());				\
244 		const ::rtl::OUString* pSupported = aSupported.getConstArray();					\
245 		const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();				\
246 		for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)	\
247 			;																			\
248 		return pSupported != pEnd;														\
249 	}	\
250 
251 
252 	}
253 }
254 #endif // _CONNECTIVITY_OSUBCOMPONENT_HXX_
255 
256