update dev300-m58
[ooovba.git] / sot / source / base / factory.cxx
blobba67e954f5af2040a31ea25cb81717f2a538cc88
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: factory.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
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.
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).
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.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sot.hxx"
34 #define _SOT_FACTORY_CXX
35 #define SOT_STRING_LIST
37 #include <sot/factory.hxx>
38 #include <tools/debug.hxx>
39 #include <tools/string.hxx>
40 #include <sot/object.hxx>
41 #include <sot/sotdata.hxx>
42 #include <clsids.hxx>
43 #include <rtl/instance.hxx>
44 #include <com/sun/star/datatransfer/DataFlavor.hpp>
46 /************** class SotData_Impl *********************************************/
47 /*************************************************************************
48 |* SotData_Impl::SotData_Impl
50 |* Beschreibung
51 *************************************************************************/
52 SotData_Impl::SotData_Impl()
53 : nSvObjCount( 0 )
54 , pObjectList( NULL )
55 , pFactoryList( NULL )
56 , pSotObjectFactory( NULL )
57 , pSotStorageStreamFactory( NULL )
58 , pSotStorageFactory( NULL )
59 , pDataFlavorList( NULL )
62 /*************************************************************************
63 |* SOTDATA()
65 |* Beschreibung
66 *************************************************************************/
67 namespace { struct ImplData : public rtl::Static<SotData_Impl, ImplData> {}; }
68 SotData_Impl * SOTDATA()
70 return &ImplData::get();
73 /*************************************************************************
74 |* SotFactory::DeInit()
76 |* Beschreibung
77 *************************************************************************/
78 void SotFactory::DeInit()
80 SotData_Impl * pSotData = SOTDATA();
82 if( pSotData->nSvObjCount )
84 #ifdef DBG_UTIL
85 ByteString aStr( "Objects alive: " );
86 aStr.Append( ByteString::CreateFromInt32( pSotData->nSvObjCount ) );
87 DBG_WARNING( aStr.GetBuffer() );
90 SotObjectList *pObjList = pSotData->pObjectList;
92 if( pObjList )
94 SotObject * p = pObjList->First();
95 while( p )
97 String aStr( "Factory: " );
98 aStr += p->GetSvFactory()->GetClassName();
99 aStr += " Count: ";
100 aStr += p->GetRefCount();
101 DBG_TRACE( "\tReferences:" );
102 p->TestObjRef( FALSE );
103 #ifdef TEST_INVARIANT
104 DBG_TRACE( "\tInvariant:" );
105 p->TestInvariant( TRUE );
106 #endif
107 p = pObjList->Next();
111 #endif
112 return;
115 // Muss von hinten nach vorne zerstoert werden. Das ist die umgekehrte
116 // Reihenfolge der Erzeugung
117 SotFactoryList* pFactoryList = pSotData->pFactoryList;
118 if( pFactoryList )
120 SotFactory * pFact = pFactoryList->Last();
121 while( NULL != (pFact = pFactoryList->Remove()) )
123 delete pFact;
124 pFact = pFactoryList->Last();
126 delete pFactoryList;
127 pSotData->pFactoryList = NULL;
130 delete pSotData->pObjectList;
131 pSotData->pObjectList = NULL;
132 if( pSotData->pDataFlavorList )
135 for( ULONG i = 0, nMax = pSotData->pDataFlavorList->Count(); i < nMax; i++ )
136 delete (::com::sun::star::datatransfer::DataFlavor*) pSotData->pDataFlavorList->GetObject( i );
137 delete pSotData->pDataFlavorList;
138 pSotData->pDataFlavorList = NULL;
140 //delete pSOTDATA();
141 //SOTDATA() = NULL;
145 /************** class SotFactory *****************************************/
146 /*************************************************************************
147 |* SotFactory::SotFactory()
149 |* Beschreibung
150 *************************************************************************/
151 TYPEINIT0(SotFactory);
153 SotFactory::SotFactory( const SvGlobalName & rName,
154 const String & rClassName,
155 CreateInstanceType pCreateFuncP )
156 : SvGlobalName ( rName )
157 , nSuperCount ( 0 )
158 , pSuperClasses ( NULL )
159 , pCreateFunc ( pCreateFuncP )
160 , aClassName ( rClassName )
162 #ifdef DBG_UTIL
163 SvGlobalName aEmptyName;
164 if( aEmptyName != *this )
165 { // wegen Sfx-BasicFactories
166 DBG_ASSERT( aEmptyName != *this, "create factory without SvGlobalName" );
167 if( Find( *this ) )
170 String aStr( GetClassName() );
171 aStr += ", UniqueName: ";
172 aStr += GetHexName();
173 aStr += ", create factories with the same unique name";
174 DBG_ERROR( aStr );
176 DBG_ERROR( "create factories with the same unique name" );
179 #endif
180 SotData_Impl * pSotData = SOTDATA();
181 if( !pSotData->pFactoryList )
182 pSotData->pFactoryList = new SotFactoryList();
183 // muss nach hinten, wegen Reihenfolge beim zerstoeren
184 pSotData->pFactoryList->Insert( this, LIST_APPEND );
188 //=========================================================================
189 SotFactory::~SotFactory()
191 delete [] pSuperClasses;
195 /*************************************************************************
196 |* SotFactory::
198 |* Beschreibung Zugriffsmethoden auf SotData_Impl-Daten
199 *************************************************************************/
200 UINT32 SotFactory::GetSvObjectCount()
202 return SOTDATA()->nSvObjCount;
206 const SotFactoryList * SotFactory::GetFactoryList()
208 return SOTDATA()->pFactoryList;
211 /*************************************************************************
212 |* SotFactory::Find()
214 |* Beschreibung
215 *************************************************************************/
216 const SotFactory* SotFactory::Find( const SvGlobalName & rFactName )
218 SvGlobalName aEmpty;
219 SotData_Impl * pSotData = SOTDATA();
220 if( rFactName != aEmpty && pSotData->pFactoryList )
222 SotFactory * pFact = pSotData->pFactoryList->First();
223 while( pFact )
225 if( *pFact == rFactName )
226 return pFact;
227 pFact = pSotData->pFactoryList->Next();
231 return 0;
234 /*************************************************************************
235 |* SotFactory::PutSuperClass()
237 |* Beschreibung
238 *************************************************************************/
239 void SotFactory::PutSuperClass( const SotFactory * pFact )
241 nSuperCount++;
242 if( !pSuperClasses )
243 pSuperClasses = new const SotFactory * [ nSuperCount ];
244 else
246 const SotFactory ** pTmp = new const SotFactory * [ nSuperCount ];
247 memcpy( (void *)pTmp, (void *)pSuperClasses,
248 sizeof( void * ) * (nSuperCount -1) );
249 delete [] pSuperClasses;
250 pSuperClasses = pTmp;
252 pSuperClasses[ nSuperCount -1 ] = pFact;
256 /*************************************************************************
257 |* SotFactory::IncSvObjectCount()
259 |* Beschreibung
260 *************************************************************************/
261 void SotFactory::IncSvObjectCount( SotObject * pObj )
263 SotData_Impl * pSotData = SOTDATA();
264 pSotData->nSvObjCount++;
265 if( !pSotData->pObjectList )
266 pSotData->pObjectList = new SotObjectList();
267 if( pObj )
268 pSotData->pObjectList->Insert( pObj );
272 /*************************************************************************
273 |* SotFactory::DecSvObjectCount()
275 |* Beschreibung
276 *************************************************************************/
277 void SotFactory::DecSvObjectCount( SotObject * pObj )
279 SotData_Impl * pSotData = SOTDATA();
280 pSotData->nSvObjCount--;
281 if( pObj )
282 pSotData->pObjectList->Remove( pObj );
283 if( !pSotData->nSvObjCount )
285 //keine internen und externen Referenzen mehr
290 /*************************************************************************
291 |* SotFactory::TestInvariant()
293 |* Beschreibung
294 *************************************************************************/
295 void SotFactory::TestInvariant()
297 #ifdef TEST_INVARIANT
298 SotData_Impl * pSotData = SOTDATA();
299 if( pSotData->pObjectList )
301 ULONG nCount = pSotData->pObjectList->Count();
302 for( ULONG i = 0; i < nCount ; i++ )
304 pSotData->pObjectList->GetObject( i )->TestInvariant( FALSE );
307 #endif
310 /*************************************************************************
311 |* SotFactory::CreateInstance()
313 |* Beschreibung
314 *************************************************************************/
315 void * SotFactory::CreateInstance( SotObject ** ppObj ) const
317 DBG_ASSERT( pCreateFunc, "SotFactory::CreateInstance: pCreateFunc == 0" );
318 return pCreateFunc( ppObj );
321 //=========================================================================
322 void * SotFactory::CastAndAddRef
324 SotObject * pObj /* Das Objekt von dem der Typ gepr"uft wird. */
325 ) const
326 /* [Beschreibung]
328 Ist eine Optimierung, damit die Ref-Klassen k"urzer implementiert
329 werden k"onnen. pObj wird auf den Typ der Factory gecastet.
330 In c++ (wenn es immer erlaubt w"are) w"urde der void * wie im
331 Beispiel gebildet.
332 Factory der Klasse SvPersist.
333 void * p = (void *)(SvPersist *)pObj;
335 [R"uckgabewert]
337 void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
338 der Factory.
339 Ansonsten wird pObj zuerst auf den Typ der Factory
340 gecastet und dann auf void *.
342 [Querverweise]
344 <SotObject::CastAndAddRef>
347 return pObj ? pObj->CastAndAddRef( this ) : NULL;
350 //=========================================================================
351 void * SotFactory::AggCastAndAddRef
353 SotObject * pObj /* Das Objekt von dem der Typ gepr"uft wird. */
354 ) const
355 /* [Beschreibung]
357 Ist eine Optimierung, damit die Ref-Klassen k"urzer implementiert
358 werden k"onnen. pObj wird auf den Typ der Factory gecastet.
359 In c++ (wenn es immer erlaubt w"are) w"urde der void * wie im
360 Beispiel gebildet.
361 Factory der Klasse SvPersist.
362 void * p = (void *)(SvPersist *)pObj;
363 Hinzu kommt noch, dass ein Objekt aus meheren c++ Objekten
364 zusammengesetzt sein kann. Diese Methode sucht nach einem
365 passenden Objekt.
367 [R"uckgabewert]
369 void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
370 der Factory.
371 Ansonsten wird pObj zuerst auf den Typ der Factory
372 gecastet und dann auf void *.
374 [Querverweise]
376 <SvObject::AggCast>
379 void * pRet = NULL;
380 if( pObj )
382 pRet = pObj->AggCast( this );
383 if( pRet )
384 pObj->AddRef();
386 return pRet;
389 /*************************************************************************
390 |* SotFactory::Is()
392 |* Beschreibung
393 *************************************************************************/
394 BOOL SotFactory::Is( const SotFactory * pSuperCl ) const
396 if( this == pSuperCl )
397 return TRUE;
399 for( USHORT i = 0; i < nSuperCount; i++ )
401 if( pSuperClasses[ i ]->Is( pSuperCl ) )
402 return TRUE;
404 return FALSE;