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 _CONNECTIVITY_OSUBCOMPONENT_HXX_
25 #define _CONNECTIVITY_OSUBCOMPONENT_HXX_
26 
27 #include <cppuhelper/weak.hxx>
28 #include <cppuhelper/interfacecontainer.h>
29 #include <com/sun/star/lang/DisposedException.hpp>
30 #include <cppuhelper/propshlp.hxx>
31 #include <osl/mutex.hxx>
32 #include <osl/diagnose.h>
33 
34 namespace cppu {
35 	class IPropertyArrayHelper;
36 }
37 
38 namespace com
39 {
40 	namespace sun
41 	{
42 		namespace star
43 		{
44 			namespace lang
45 			{
46 				class XComponent;
47 			}
48 		}
49 	}
50 }
51 namespace connectivity
52 {
53 
54 	namespace skeleton
55 	{
56 		void release(oslInterlockedCount& _refCount,
57 					 ::cppu::OBroadcastHelper& rBHelper,
58 					 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
59 					 ::com::sun::star::lang::XComponent* _pObject);
60 
61 		void checkDisposed(sal_Bool _bThrow) throw ( ::com::sun::star::lang::DisposedException );
62 		//************************************************************
63 		// OSubComponent
64 		//************************************************************
65 		template <class SELF, class WEAK> class OSubComponent
66 		{
67 		protected:
68 			// the parent must support the tunnel implementation
69 			::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xParent;
70 			SELF*	m_pDerivedImplementation;
71 
72 		public:
73 			OSubComponent(
74 					const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParent,
75 					SELF* _pDerivedImplementation)
76 				:m_xParent(_xParent)
77 				,m_pDerivedImplementation(_pDerivedImplementation)
78 			{
79 			}
80 
81 		protected:
82 			void dispose_ChildImpl()
83 			{
84 				::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
85 				m_xParent = NULL;
86 			}
87 			void relase_ChildImpl()
88 			{
89 				release(m_pDerivedImplementation->m_refCount,
90 										m_pDerivedImplementation->rBHelper,
91 										m_xParent,
92 										m_pDerivedImplementation);
93 
94 				m_pDerivedImplementation->WEAK::release();
95 			}
96 		};
97 
98 
99 		template <class TYPE>
100 		class OPropertyArrayUsageHelper
101 		{
102 		protected:
103 			static sal_Int32						s_nRefCount;
104 			static ::cppu::IPropertyArrayHelper*	s_pProps;
105 			static ::osl::Mutex						s_aMutex;
106 
107 		public:
108 			OPropertyArrayUsageHelper();
109 			virtual ~OPropertyArrayUsageHelper()
110 			{	// ARGHHHHHHH ..... would like to implement this in proparrhlp_impl.hxx (as we do with all other methods)
111 				// but SUNPRO 5 compiler (linker) doesn't like this
112 				::osl::MutexGuard aGuard(s_aMutex);
113 				OSL_ENSURE(s_nRefCount > 0, "OPropertyArrayUsageHelper::~OPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !");
114 				if (!--s_nRefCount)
115 				{
116 					delete s_pProps;
117 					s_pProps = NULL;
118 				}
119 			}
120 
121 			/** call this in the getInfoHelper method of your derived class. The method returns the array helper of the
122 				class, which is created if neccessary.
123 			*/
124 			::cppu::IPropertyArrayHelper*	getArrayHelper();
125 
126 		protected:
127 			/** used to implement the creation of the array helper which is shared amongst all instances of the class.
128 				This method needs to be implemented in derived classes.
129 				<BR>
130 				The method gets called with s_aMutex acquired.
131 				<BR>
132 				as long as IPropertyArrayHelper has no virtual destructor, the implementation of ~OPropertyArrayUsageHelper
133 				assumes that you created an ::cppu::OPropertyArrayHelper when deleting s_pProps.
134 				@return							an pointer to the newly created array helper. Must not be NULL.
135 			*/
136 			virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const = 0;
137 		};
138 
139 		template<class TYPE>
140 		sal_Int32						OPropertyArrayUsageHelper< TYPE >::s_nRefCount	= 0;
141 
142 		template<class TYPE>
143 		::cppu::IPropertyArrayHelper*	OPropertyArrayUsageHelper< TYPE >::s_pProps	= NULL;
144 
145 		template<class TYPE>
146 		::osl::Mutex					OPropertyArrayUsageHelper< TYPE >::s_aMutex;
147 
148 		//------------------------------------------------------------------
149 		template <class TYPE>
150 		OPropertyArrayUsageHelper<TYPE>::OPropertyArrayUsageHelper()
151 		{
152 			::osl::MutexGuard aGuard(s_aMutex);
153 			++s_nRefCount;
154 		}
155 
156 		//------------------------------------------------------------------
157 		template <class TYPE>
158 		::cppu::IPropertyArrayHelper* OPropertyArrayUsageHelper<TYPE>::getArrayHelper()
159 		{
160 			OSL_ENSURE(s_nRefCount, "OPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !");
161 			if (!s_pProps)
162 			{
163 				::osl::MutexGuard aGuard(s_aMutex);
164 				if (!s_pProps)
165 				{
166 					s_pProps = createArrayHelper();
167 					OSL_ENSURE(s_pProps, "OPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !");
168 				}
169 			}
170 			return s_pProps;
171 		}
172 
173 
174 
175 		class OBase_Mutex
176 		{
177 		public:
178 			::osl::Mutex m_aMutex;
179 		};
180 
181 		namespace internal
182 		{
183 			template <class T>
184 			void implCopySequence(const T* _pSource, T*& _pDest, sal_Int32 _nSourceLen)
185 			{
186 				for (sal_Int32 i=0; i<_nSourceLen; ++i, ++_pSource, ++_pDest)
187 					*_pDest = *_pSource;
188 			}
189 		}
190 		//-------------------------------------------------------------------------
191 		/// concat two sequences
192 		template <class T>
193 		::com::sun::star::uno::Sequence<T> concatSequences(const ::com::sun::star::uno::Sequence<T>& _rLeft, const ::com::sun::star::uno::Sequence<T>& _rRight)
194 		{
195 			sal_Int32 nLeft(_rLeft.getLength()), nRight(_rRight.getLength());
196 			const T* pLeft = _rLeft.getConstArray();
197 			const T* pRight = _rRight.getConstArray();
198 
199 			sal_Int32 nReturnLen(nLeft + nRight);
200 			::com::sun::star::uno::Sequence<T> aReturn(nReturnLen);
201 			T* pReturn = aReturn.getArray();
202 
203 			internal::implCopySequence(pLeft, pReturn, nLeft);
204 			internal::implCopySequence(pRight, pReturn, nRight);
205 
206 			return aReturn;
207 		}
208 
209 
210 #define DECLARE_SERVICE_INFO()	\
211 	virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException);	\
212     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);	\
213     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)	\
214 
215 #define IMPLEMENT_SERVICE_INFO(classname, implasciiname, serviceasciiname)	\
216 	::rtl::OUString SAL_CALL classname::getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException)	\
217 	{	\
218 		return ::rtl::OUString::createFromAscii(implasciiname);	\
219 	}	\
220     ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL classname::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)	\
221 	{	\
222 		::com::sun::star::uno::Sequence< ::rtl::OUString > aSupported(1);	\
223 		aSupported[0] = ::rtl::OUString::createFromAscii(serviceasciiname);	\
224 		return aSupported;	\
225 	}	\
226     sal_Bool SAL_CALL classname::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException)	\
227 	{	\
228 		Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());				\
229 		const ::rtl::OUString* pSupported = aSupported.getConstArray();					\
230 		const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();				\
231 		for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)	\
232 			;																			\
233 																						\
234 		return pSupported != pEnd;														\
235 	}	\
236 
237 
238 	}
239 }
240 #endif // _CONNECTIVITY_OSUBCOMPONENT_HXX_
241 
242