xref: /aoo41x/main/sot/source/base/factory.cxx (revision 046d9d1f)
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