1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: factory.cxx,v $
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>
43 #include <rtl/instance.hxx>
44 #include <com/sun/star/datatransfer/DataFlavor.hpp>
46 /************** class SotData_Impl *********************************************/
47 /*************************************************************************
48 |* SotData_Impl::SotData_Impl
51 *************************************************************************/
52 SotData_Impl::SotData_Impl()
55 , pFactoryList( NULL
)
56 , pSotObjectFactory( NULL
)
57 , pSotStorageStreamFactory( NULL
)
58 , pSotStorageFactory( NULL
)
59 , pDataFlavorList( NULL
)
62 /*************************************************************************
66 *************************************************************************/
67 namespace { struct ImplData
: public rtl::Static
<SotData_Impl
, ImplData
> {}; }
68 SotData_Impl
* SOTDATA()
70 return &ImplData::get();
73 /*************************************************************************
74 |* SotFactory::DeInit()
77 *************************************************************************/
78 void SotFactory::DeInit()
80 SotData_Impl
* pSotData
= SOTDATA();
82 if( pSotData
->nSvObjCount
)
85 ByteString
aStr( "Objects alive: " );
86 aStr
.Append( ByteString::CreateFromInt32( pSotData
->nSvObjCount
) );
87 DBG_WARNING( aStr
.GetBuffer() );
90 SotObjectList *pObjList = pSotData->pObjectList;
94 SotObject * p = pObjList->First();
97 String aStr( "Factory: " );
98 aStr += p->GetSvFactory()->GetClassName();
100 aStr += p->GetRefCount();
101 DBG_TRACE( "\tReferences:" );
102 p->TestObjRef( FALSE );
103 #ifdef TEST_INVARIANT
104 DBG_TRACE( "\tInvariant:" );
105 p->TestInvariant( TRUE );
107 p = pObjList->Next();
115 // Muss von hinten nach vorne zerstoert werden. Das ist die umgekehrte
116 // Reihenfolge der Erzeugung
117 SotFactoryList
* pFactoryList
= pSotData
->pFactoryList
;
120 SotFactory
* pFact
= pFactoryList
->Last();
121 while( NULL
!= (pFact
= pFactoryList
->Remove()) )
124 pFact
= pFactoryList
->Last();
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
;
145 /************** class SotFactory *****************************************/
146 /*************************************************************************
147 |* SotFactory::SotFactory()
150 *************************************************************************/
151 TYPEINIT0(SotFactory
);
153 SotFactory::SotFactory( const SvGlobalName
& rName
,
154 const String
& rClassName
,
155 CreateInstanceType pCreateFuncP
)
156 : SvGlobalName ( rName
)
158 , pSuperClasses ( NULL
)
159 , pCreateFunc ( pCreateFuncP
)
160 , aClassName ( rClassName
)
163 SvGlobalName aEmptyName
;
164 if( aEmptyName
!= *this )
165 { // wegen Sfx-BasicFactories
166 DBG_ASSERT( aEmptyName
!= *this, "create factory without SvGlobalName" );
170 String aStr( GetClassName() );
171 aStr += ", UniqueName: ";
172 aStr += GetHexName();
173 aStr += ", create factories with the same unique name";
176 DBG_ERROR( "create factories with the same unique name" );
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 /*************************************************************************
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()
215 *************************************************************************/
216 const SotFactory
* SotFactory::Find( const SvGlobalName
& rFactName
)
219 SotData_Impl
* pSotData
= SOTDATA();
220 if( rFactName
!= aEmpty
&& pSotData
->pFactoryList
)
222 SotFactory
* pFact
= pSotData
->pFactoryList
->First();
225 if( *pFact
== rFactName
)
227 pFact
= pSotData
->pFactoryList
->Next();
234 /*************************************************************************
235 |* SotFactory::PutSuperClass()
238 *************************************************************************/
239 void SotFactory::PutSuperClass( const SotFactory
* pFact
)
243 pSuperClasses
= new const SotFactory
* [ nSuperCount
];
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()
260 *************************************************************************/
261 void SotFactory::IncSvObjectCount( SotObject
* pObj
)
263 SotData_Impl
* pSotData
= SOTDATA();
264 pSotData
->nSvObjCount
++;
265 if( !pSotData
->pObjectList
)
266 pSotData
->pObjectList
= new SotObjectList();
268 pSotData
->pObjectList
->Insert( pObj
);
272 /*************************************************************************
273 |* SotFactory::DecSvObjectCount()
276 *************************************************************************/
277 void SotFactory::DecSvObjectCount( SotObject
* pObj
)
279 SotData_Impl
* pSotData
= SOTDATA();
280 pSotData
->nSvObjCount
--;
282 pSotData
->pObjectList
->Remove( pObj
);
283 if( !pSotData
->nSvObjCount
)
285 //keine internen und externen Referenzen mehr
290 /*************************************************************************
291 |* SotFactory::TestInvariant()
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
);
310 /*************************************************************************
311 |* SotFactory::CreateInstance()
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. */
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
332 Factory der Klasse SvPersist.
333 void * p = (void *)(SvPersist *)pObj;
337 void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
339 Ansonsten wird pObj zuerst auf den Typ der Factory
340 gecastet und dann auf void *.
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. */
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
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
369 void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
371 Ansonsten wird pObj zuerst auf den Typ der Factory
372 gecastet und dann auf void *.
382 pRet
= pObj
->AggCast( this );
389 /*************************************************************************
393 *************************************************************************/
394 BOOL
SotFactory::Is( const SotFactory
* pSuperCl
) const
396 if( this == pSuperCl
)
399 for( USHORT i
= 0; i
< nSuperCount
; i
++ )
401 if( pSuperClasses
[ i
]->Is( pSuperCl
) )