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 #ifndef _CONNECTIVITY_ADO_AOLEWRAP_HXX_
28 #define _CONNECTIVITY_ADO_AOLEWRAP_HXX_
29 
30 #include <osl/diagnose.h>
31 #include <osl/thread.h>
32 #include <map>
33 #include <vector>
34 #include "connectivity/StdTypeDefs.hxx"
35 
36 namespace rtl
37 {
38 	class OUString;
39 }
40 namespace connectivity
41 {
42 	namespace ado
43 	{
44 		class OLEVariant;
45 		class WpBase
46 		{
47 		protected:
48 			IDispatch* pIUnknown;
49 
50 			void setIDispatch(IDispatch* _pIUnknown);
51 		public:
52 			WpBase();
53 			WpBase(IDispatch* pInt);
54 			//inline
55 			WpBase& operator=(const WpBase& rhs);
56 			WpBase& operator=(IDispatch* rhs);
57 			WpBase(const WpBase& aWrapper);
58 			virtual ~WpBase();
59 			void clear();
60 
61 
62 			sal_Bool IsValid() const;
63 			operator IDispatch*();
64 
65 		};
66 		//////////////////////////////////////////////////////////////////////////
67 		//
68 		// Template-Klasse WpOLEBase<class T>
69 		// ==================================
70 		//
71         // Objekte dieser Klasse haelt einen Zeiger auf ein Interface vom Typ T.
72 		// Es gibt Konstruktoren und Zuweisungsoperator die sicherstellen, dass
73 		// AddRef() und Release() entsprechend den COM-Konventionen gerufen werden.
74 		// Ein Objekt kann auch keinen Zeiger halten (Nullzeiger), dann ergibt
75 		// der Aufruf von IsValid() FALSE.
76 		//
77 		// Um effizientes pass-by-value machen zu koennen, ist diese (ebenso wie die
78 		// abgeleiteten Klassen) eine ganz schmale Wrapper-Klasse unter Vermeidung
79 		// virtueller Methoden und mit Inlining.
80 
81 		//------------------------------------------------------------------------
82 		template<class T> class WpOLEBase : public WpBase
83 		{
84 		protected:
85 			T* pInterface;
86 
87 		public:
88 			WpOLEBase(T* pInt = NULL) : WpBase(pInt),pInterface(pInt){}
89 
90 
91 			//inline
92 			WpOLEBase<T>& operator=(const WpOLEBase<T>& rhs)
93 			{
94 				WpBase::operator=(rhs);
95 				pInterface = rhs.pInterface;
96 				return *this;
97 			};
98 
99 			WpOLEBase<T>& operator=(T* rhs)
100 			{
101 				WpBase::operator=(rhs);
102 				pInterface = rhs.pInterface;
103 				return *this;
104 			}
105 
106 			WpOLEBase(const WpOLEBase<T>& aWrapper)
107 			{
108 				operator=(aWrapper);
109 			}
110 
111 			virtual ~WpOLEBase()
112 			{
113 			}
114 
115 			operator T*() const { return static_cast<T*>(pInterface); }
116 			void setWithOutAddRef(T* _pInterface)
117 			{
118 				pInterface = _pInterface;
119 				WpBase::setIDispatch(_pInterface);
120 			}
121 		};
122 
123 
124 		//////////////////////////////////////////////////////////////////////////
125 		//
126 		// Template-Klasse WpOLECollection<class Ts, class T, class WrapT>
127 		// ===============================================================
128 		//
129 		// Diese Klasse, welche sich von WpOLEBase<Ts> ableitet, abstrahiert die
130 		// den DAO-Collections gemeinsamen Eigenschaften:
131 		//
132         // Sie werden ueber ein Interface Ts (etwa: DAOFields) angesprochen
133 		// und koennen ueber get_Item (hier:GetItem) Items des Typs T (genauer:
134 		// mit Interface T, etwa DAOField) herausgeben.
135 		//
136 		// Diese Wrapperklasse gibt aber nicht ein Interface T heraus,
137         // sondern ein Objekt der Klasse WrapT. Dieses muss eine Konstruktion
138 		// durch T zulassen, vorzugsweise ist es von WpOLEBase<T> abgeleitet.
139 		//
140 
141 		//------------------------------------------------------------------------
142 		template<class Ts, class T, class WrapT> class WpOLECollection : public WpOLEBase<Ts>
143 		{
144 		public:
145 			using WpOLEBase<Ts>::pInterface;
146 			using WpOLEBase<Ts>::IsValid;
147 			// Konstruktoren, operator=
148 			// diese rufen nur die Oberklasse
149 			WpOLECollection(Ts* pInt=NULL):WpOLEBase<Ts>(pInt){}
150 			WpOLECollection(const WpOLECollection& rhs){operator=(rhs);}
151 			inline WpOLECollection& operator=(const WpOLECollection& rhs)
152 				{WpOLEBase<Ts>::operator=(rhs); return *this;};
153 
154 			//////////////////////////////////////////////////////////////////////
155 
156 			inline void Refresh(){pInterface->Refresh();}
157 
158 			inline sal_Int32 GetItemCount()	const
159 			{
160 				sal_Int32 nCount = 0;
161 				return pInterface ? (SUCCEEDED(pInterface->get_Count(&nCount)) ? nCount : sal_Int32(0)) : sal_Int32(0);
162 			}
163 
164 			inline WrapT GetItem(sal_Int32 index) const
165 			{
166 				OSL_ENSURE(index >= 0 && index<GetItemCount(),"Wrong index for field!");
167 				T* pT = NULL;
168 				WrapT aRet(NULL);
169 				if(SUCCEEDED(pInterface->get_Item(OLEVariant(index), &pT)))
170 					aRet.setWithOutAddRef(pT);
171 				return aRet;
172 			}
173 
174 			inline WrapT GetItem(const OLEVariant& index) const
175 			{
176 				T* pT = NULL;
177 				WrapT aRet(NULL);
178 				if(SUCCEEDED(pInterface->get_Item(index, &pT)))
179 					aRet.setWithOutAddRef(pT);
180 				return aRet;
181 			}
182 
183 			inline WrapT GetItem(const ::rtl::OUString& sStr) const
184 			{
185 				WrapT aRet(NULL);
186 				T* pT = NULL;
187 				if (FAILED(pInterface->get_Item(OLEVariant(sStr), &pT)))
188 				{
189 #if OSL_DEBUG_LEVEL > 0
190 					::rtl::OString sTemp("Unknown Item: ");
191 					sTemp += ::rtl::OString(sStr.getStr(),sStr.getLength(),osl_getThreadTextEncoding());
192 					OSL_ENSURE(0,sTemp);
193 #endif
194 				}
195 				else
196 					aRet.setWithOutAddRef(pT);
197 				return aRet;
198 			}
199 			inline void fillElementNames(TStringVector& _rVector)
200 			{
201 				if(IsValid())
202 				{
203 					Refresh();
204 					sal_Int32 nCount = GetItemCount();
205 					_rVector.reserve(nCount);
206 					for(sal_Int32 i=0;i< nCount;++i)
207 					{
208 						WrapT aElement = GetItem(i);
209 						if(aElement.IsValid())
210 							_rVector.push_back(aElement.get_Name());
211 					}
212 				}
213 			}
214 		};
215 
216 		template<class Ts, class T, class WrapT> class WpOLEAppendCollection:
217 				public WpOLECollection<Ts,T,WrapT>
218 		{
219 
220 		public:
221 			// Konstruktoren, operator=
222 			// diese rufen nur die Oberklasse
223 			using WpOLEBase<Ts>::pInterface;
224 			WpOLEAppendCollection(Ts* pInt=NULL):WpOLECollection<Ts,T,WrapT>(pInt){}
225 			WpOLEAppendCollection(const WpOLEAppendCollection& rhs){ operator=(rhs); }
226 			inline WpOLEAppendCollection& operator=(const WpOLEAppendCollection& rhs)
227 				{WpOLEBase<Ts>::operator=(rhs); return *this;};
228 			//////////////////////////////////////////////////////////////////////
229 
230 			inline sal_Bool Append(const WrapT& aWrapT)
231 			{
232 				return SUCCEEDED(pInterface->Append(OLEVariant((T*)aWrapT)));
233 			};
234 
235 			inline sal_Bool Delete(const ::rtl::OUString& sName)
236 			{
237 				return SUCCEEDED(pInterface->Delete(OLEVariant(sName)));
238 			};
239 
240 
241 		};
242 	}
243 }
244 #endif // _CONNECTIVITY_ADO_AOLEWRAP_HXX_
245 
246