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