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