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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sot.hxx"
26
27 #define _SOT_FACTORY_CXX
28 #define SOT_STRING_LIST
29
30 #include <sot/factory.hxx>
31 #include <tools/debug.hxx>
32 #include <tools/string.hxx>
33 #include <sot/object.hxx>
34 #include <sot/sotdata.hxx>
35 #include <sot/clsids.hxx>
36 #include <rtl/instance.hxx>
37 #include <com/sun/star/datatransfer/DataFlavor.hpp>
38
39 /************** class SotData_Impl *********************************************/
40 /*************************************************************************
41 |* SotData_Impl::SotData_Impl
42 |*
43 |* Beschreibung
44 *************************************************************************/
SotData_Impl()45 SotData_Impl::SotData_Impl()
46 : nSvObjCount( 0 )
47 , pObjectList( NULL )
48 , pFactoryList( NULL )
49 , pSotObjectFactory( NULL )
50 , pSotStorageStreamFactory( NULL )
51 , pSotStorageFactory( NULL )
52 , pDataFlavorList( NULL )
53 {
54 }
55 /*************************************************************************
56 |* SOTDATA()
57 |*
58 |* Beschreibung
59 *************************************************************************/
60 namespace { struct ImplData : public rtl::Static<SotData_Impl, ImplData> {}; }
SOTDATA()61 SotData_Impl * SOTDATA()
62 {
63 return &ImplData::get();
64 }
65
66 /*************************************************************************
67 |* SotFactory::DeInit()
68 |*
69 |* Beschreibung
70 *************************************************************************/
DeInit()71 void SotFactory::DeInit()
72 {
73 SotData_Impl * pSotData = SOTDATA();
74
75 if( pSotData->nSvObjCount )
76 {
77 #ifdef DBG_UTIL
78 ByteString aStr( "Objects alive: " );
79 aStr.Append( ByteString::CreateFromInt32( pSotData->nSvObjCount ) );
80 DBG_WARNING( aStr.GetBuffer() );
81
82 /*
83 SotObjectList *pObjList = pSotData->pObjectList;
84
85 if( pObjList )
86 {
87 SotObject * p = pObjList->First();
88 while( p )
89 {
90 String aStr( "Factory: " );
91 aStr += p->GetSvFactory()->GetClassName();
92 aStr += " Count: ";
93 aStr += p->GetRefCount();
94 DBG_TRACE( "\tReferences:" );
95 p->TestObjRef( sal_False );
96 #ifdef TEST_INVARIANT
97 DBG_TRACE( "\tInvariant:" );
98 p->TestInvariant( sal_True );
99 #endif
100 p = pObjList->Next();
101 }
102 }
103 */
104 #endif
105 return;
106 }
107
108 // Muss von hinten nach vorne zerstoert werden. Das ist die umgekehrte
109 // Reihenfolge der Erzeugung
110 SotFactoryList* pFactoryList = pSotData->pFactoryList;
111 if( pFactoryList )
112 {
113 SotFactory * pFact = pFactoryList->Last();
114 while( NULL != (pFact = pFactoryList->Remove()) )
115 {
116 delete pFact;
117 pFact = pFactoryList->Last();
118 }
119 delete pFactoryList;
120 pSotData->pFactoryList = NULL;
121 }
122
123 delete pSotData->pObjectList;
124 pSotData->pObjectList = NULL;
125 if( pSotData->pDataFlavorList )
126 {
127
128 for( sal_uLong i = 0, nMax = pSotData->pDataFlavorList->Count(); i < nMax; i++ )
129 delete (::com::sun::star::datatransfer::DataFlavor*) pSotData->pDataFlavorList->GetObject( i );
130 delete pSotData->pDataFlavorList;
131 pSotData->pDataFlavorList = NULL;
132 }
133 //delete pSOTDATA();
134 //SOTDATA() = NULL;
135 }
136
137
138 /************** class SotFactory *****************************************/
139 /*************************************************************************
140 |* SotFactory::SotFactory()
141 |*
142 |* Beschreibung
143 *************************************************************************/
144 TYPEINIT0(SotFactory);
145
SotFactory(const SvGlobalName & rName,const String & rClassName,CreateInstanceType pCreateFuncP)146 SotFactory::SotFactory( const SvGlobalName & rName,
147 const String & rClassName,
148 CreateInstanceType pCreateFuncP )
149 : SvGlobalName ( rName )
150 , nSuperCount ( 0 )
151 , pSuperClasses ( NULL )
152 , pCreateFunc ( pCreateFuncP )
153 , aClassName ( rClassName )
154 {
155 #ifdef DBG_UTIL
156 SvGlobalName aEmptyName;
157 if( aEmptyName != *this )
158 { // wegen Sfx-BasicFactories
159 DBG_ASSERT( aEmptyName != *this, "create factory without SvGlobalName" );
160 if( Find( *this ) )
161 {
162 /*
163 String aStr( GetClassName() );
164 aStr += ", UniqueName: ";
165 aStr += GetHexName();
166 aStr += ", create factories with the same unique name";
167 DBG_ERROR( aStr );
168 */
169 DBG_ERROR( "create factories with the same unique name" );
170 }
171 }
172 #endif
173 SotData_Impl * pSotData = SOTDATA();
174 if( !pSotData->pFactoryList )
175 pSotData->pFactoryList = new SotFactoryList();
176 // muss nach hinten, wegen Reihenfolge beim zerstoeren
177 pSotData->pFactoryList->Insert( this, LIST_APPEND );
178 }
179
180
181 //=========================================================================
~SotFactory()182 SotFactory::~SotFactory()
183 {
184 delete [] pSuperClasses;
185 }
186
187
188 /*************************************************************************
189 |* SotFactory::
190 |*
191 |* Beschreibung Zugriffsmethoden auf SotData_Impl-Daten
192 *************************************************************************/
GetSvObjectCount()193 sal_uInt32 SotFactory::GetSvObjectCount()
194 {
195 return SOTDATA()->nSvObjCount;
196 }
197
198
GetFactoryList()199 const SotFactoryList * SotFactory::GetFactoryList()
200 {
201 return SOTDATA()->pFactoryList;
202 }
203
204 /*************************************************************************
205 |* SotFactory::Find()
206 |*
207 |* Beschreibung
208 *************************************************************************/
Find(const SvGlobalName & rFactName)209 const SotFactory* SotFactory::Find( const SvGlobalName & rFactName )
210 {
211 SvGlobalName aEmpty;
212 SotData_Impl * pSotData = SOTDATA();
213 if( rFactName != aEmpty && pSotData->pFactoryList )
214 {
215 SotFactory * pFact = pSotData->pFactoryList->First();
216 while( pFact )
217 {
218 if( *pFact == rFactName )
219 return pFact;
220 pFact = pSotData->pFactoryList->Next();
221 }
222 }
223
224 return 0;
225 }
226
227 /*************************************************************************
228 |* SotFactory::PutSuperClass()
229 |*
230 |* Beschreibung
231 *************************************************************************/
PutSuperClass(const SotFactory * pFact)232 void SotFactory::PutSuperClass( const SotFactory * pFact )
233 {
234 nSuperCount++;
235 if( !pSuperClasses )
236 pSuperClasses = new const SotFactory * [ nSuperCount ];
237 else
238 {
239 const SotFactory ** pTmp = new const SotFactory * [ nSuperCount ];
240 memcpy( (void *)pTmp, (void *)pSuperClasses,
241 sizeof( void * ) * (nSuperCount -1) );
242 delete [] pSuperClasses;
243 pSuperClasses = pTmp;
244 }
245 pSuperClasses[ nSuperCount -1 ] = pFact;
246 }
247
248
249 /*************************************************************************
250 |* SotFactory::IncSvObjectCount()
251 |*
252 |* Beschreibung
253 *************************************************************************/
IncSvObjectCount(SotObject * pObj)254 void SotFactory::IncSvObjectCount( SotObject * pObj )
255 {
256 SotData_Impl * pSotData = SOTDATA();
257 pSotData->nSvObjCount++;
258 if( !pSotData->pObjectList )
259 pSotData->pObjectList = new SotObjectList();
260 if( pObj )
261 pSotData->pObjectList->Insert( pObj );
262 }
263
264
265 /*************************************************************************
266 |* SotFactory::DecSvObjectCount()
267 |*
268 |* Beschreibung
269 *************************************************************************/
DecSvObjectCount(SotObject * pObj)270 void SotFactory::DecSvObjectCount( SotObject * pObj )
271 {
272 SotData_Impl * pSotData = SOTDATA();
273 pSotData->nSvObjCount--;
274 if( pObj )
275 pSotData->pObjectList->Remove( pObj );
276 if( !pSotData->nSvObjCount )
277 {
278 //keine internen und externen Referenzen mehr
279 }
280 }
281
282
283 /*************************************************************************
284 |* SotFactory::TestInvariant()
285 |*
286 |* Beschreibung
287 *************************************************************************/
TestInvariant()288 void SotFactory::TestInvariant()
289 {
290 #ifdef TEST_INVARIANT
291 SotData_Impl * pSotData = SOTDATA();
292 if( pSotData->pObjectList )
293 {
294 sal_uLong nCount = pSotData->pObjectList->Count();
295 for( sal_uLong i = 0; i < nCount ; i++ )
296 {
297 pSotData->pObjectList->GetObject( i )->TestInvariant( sal_False );
298 }
299 }
300 #endif
301 }
302
303 /*************************************************************************
304 |* SotFactory::CreateInstance()
305 |*
306 |* Beschreibung
307 *************************************************************************/
CreateInstance(SotObject ** ppObj) const308 void * SotFactory::CreateInstance( SotObject ** ppObj ) const
309 {
310 DBG_ASSERT( pCreateFunc, "SotFactory::CreateInstance: pCreateFunc == 0" );
311 return pCreateFunc( ppObj );
312 }
313
314 //=========================================================================
CastAndAddRef(SotObject * pObj) const315 void * SotFactory::CastAndAddRef
316 (
317 SotObject * pObj /* Das Objekt von dem der Typ gepr"uft wird. */
318 ) const
319 /* [Beschreibung]
320
321 Ist eine Optimierung, damit die Ref-Klassen k"urzer implementiert
322 werden k"onnen. pObj wird auf den Typ der Factory gecastet.
323 In c++ (wenn es immer erlaubt w"are) w"urde der void * wie im
324 Beispiel gebildet.
325 Factory der Klasse SvPersist.
326 void * p = (void *)(SvPersist *)pObj;
327
328 [R"uckgabewert]
329
330 void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
331 der Factory.
332 Ansonsten wird pObj zuerst auf den Typ der Factory
333 gecastet und dann auf void *.
334
335 [Querverweise]
336
337 <SotObject::CastAndAddRef>
338 */
339 {
340 return pObj ? pObj->CastAndAddRef( this ) : NULL;
341 }
342
343 /*************************************************************************
344 |* SotFactory::Is()
345 |*
346 |* Beschreibung
347 *************************************************************************/
Is(const SotFactory * pSuperCl) const348 sal_Bool SotFactory::Is( const SotFactory * pSuperCl ) const
349 {
350 if( this == pSuperCl )
351 return sal_True;
352
353 for( sal_uInt16 i = 0; i < nSuperCount; i++ )
354 {
355 if( pSuperClasses[ i ]->Is( pSuperCl ) )
356 return sal_True;
357 }
358 return sal_False;
359 }
360
361
362
363
364