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: object.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_OBJECT_CXX
36 #include <tools/debug.hxx>
37 #include <sot/object.hxx>
38 #include <sot/factory.hxx>
41 /************** class SvAggregateMemberList *****************************/
42 /************************************************************************/
43 PRV_SV_IMPL_OWNER_LIST(SvAggregateMemberList
,SvAggregate
);
45 /************** class SotObject ******************************************/
46 class SotObjectFactory
: public SotFactory
50 SotObjectFactory( const SvGlobalName
& rName
,
51 const String
& rClassName
,
52 CreateInstanceType pCreateFuncP
)
53 : SotFactory( rName
, rClassName
, pCreateFuncP
)
56 TYPEINIT1(SotObjectFactory
,SotFactory
);
59 SO2_IMPL_BASIC_CLASS_DLL(SotObject
,SotObjectFactory
,
60 SvGlobalName( 0xf44b7830, 0xf83c, 0x11d0,
61 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
62 SO2_IMPL_INVARIANT(SotObject
)
64 /*************************************************************************
65 |* SotObject::TestMemberObjRef()
68 *************************************************************************/
69 void SotObject::TestMemberObjRef( BOOL
/*bFree*/ )
73 /*************************************************************************
74 |* SotObject::TestMemberObjRef()
77 *************************************************************************/
79 void SotObject::TestMemberInvariant( BOOL
/*bPrint*/ )
84 /*************************************************************************
85 |* SotObject::SotObject()
88 *************************************************************************/
89 SotObject::SotObject()
91 , nStrongLockCount( 0 )
92 , nOwnerLockCount( 0 )
97 SotFactory::IncSvObjectCount( this );
100 /*************************************************************************
102 |* SotObject::~SotObject()
105 |* Ersterstellung MM 05.06.94
106 |* Letzte Aenderung MM 05.06.94
108 *************************************************************************/
109 SotObject::~SotObject()
111 SotFactory::DecSvObjectCount( this );
114 /*************************************************************************
115 |* SotObject::GetInterface()
117 |* Beschreibung: Um so3 zu helfen
118 *************************************************************************/
119 IUnknown
* SotObject::GetInterface( const SvGlobalName
& )
124 /*************************************************************************
125 |* SotObject::IsSvClass()
128 *************************************************************************/
129 BOOL
SotObject::IsSvObject() const
131 return Owner() || bSVObject
;
134 /*************************************************************************
135 |* SotObject::QueryDelete()
137 |* Beschreibung: Bei allen aggregierten Objekte muss der RefCount auf
138 |* 0 gehen, damit das Gesammt-Objekt zerstoert wird. Das
139 |* zerst�ren von Teilen ist verboten. Da der Aggregator
140 |* (oder Cast-Verwalter) den Zaehler der aggregierten
141 |* Objekte um 1 erhoeht, muss dies bei der Berechnung
142 |* des 0-RefCounts beruecksichtigt werden.
143 *************************************************************************/
144 BOOL
SotObject::ShouldDelete()
149 SvAggregate
& rMO
= pAggList
->GetObject( 0 );
153 pAggList
->GetObject( 0 ).pObj
->ReleaseRef();
158 for( i
= 1; i
< pAggList
->Count(); i
++ )
160 SvAggregate
& rAgg
= pAggList
->GetObject( i
);
161 // Groesser 1, wegen AddRef() bei AddInterface
162 if( !rAgg
.bFactory
&& rAgg
.pObj
->GetRefCount() > 1 )
164 // den eigenen hochzaehelen
166 // einen Aggregierten runterzaehlen
167 rAgg
.pObj
->ReleaseRef();
171 AddNextRef(); // rekursion stoppen
172 for( i
= pAggList
->Count() -1; i
> 0; i
-- )
174 // Referenzen aufloesen
175 DBG_ASSERT( !pAggList
->GetObject( i
).bMainObj
, "main object reference is opened" );
176 RemoveInterface( i
);
180 // und zerstoeren, dies ist unabhaengig vom RefCount
184 /*************************************************************************
185 |* SotObject::QueryDelete()
188 *************************************************************************/
189 void SotObject::QueryDelete()
192 SvRefBase::QueryDelete();
197 /*************************************************************************
198 |* SotObject::GetAggList()
201 *************************************************************************/
202 SvAggregateMemberList
& SotObject::GetAggList()
206 pAggList
= new SvAggregateMemberList( 2, 1 );
207 pAggList
->Append( SvAggregate() );
213 /*************************************************************************
214 |* SotObject::RemoveInterface()
217 *************************************************************************/
218 void SotObject::RemoveInterface( ULONG nPos
)
220 SvAggregate
& rAgg
= pAggList
->GetObject( nPos
);
223 DBG_ASSERT( rAgg
.pObj
->pAggList
, "no aggregation list" );
224 DBG_ASSERT( rAgg
.pObj
->pAggList
->GetObject( 0 ).pObj
== this,
225 "not owner of aggregated object" );
226 // sich selbst als Cast-Verwalter austragen
227 rAgg
.pObj
->pAggList
->GetObject( 0 ) = SvAggregate();
228 // Referenz aufloesen
229 rAgg
.pObj
->ReleaseRef();
230 // Aus der eigenen List austragen
231 pAggList
->Remove( nPos
);
235 /*************************************************************************
236 |* SotObject::RemoveInterface()
239 *************************************************************************/
240 void SotObject::RemoveInterface( SotObject
* pObjP
)
242 DBG_ASSERT( pObjP
, "null pointer" );
243 DBG_ASSERT( pAggList
, "no aggregation list" );
245 for( i
= 0; i
< pAggList
->Count(); i
++ )
247 SvAggregate
& rAgg
= pAggList
->GetObject( i
);
248 if( !rAgg
.bFactory
&& pObjP
== rAgg
.pObj
)
249 RemoveInterface( i
);
251 DBG_ASSERT( i
< pAggList
->Count(), "object not found" );
254 /*************************************************************************
255 |* SotObject::AddInterface()
258 *************************************************************************/
259 void SotObject::AddInterface( SotObject
* pObjP
)
261 pObjP
->AddRef(); // Objekt festhalten
263 pAggList
->Append( SvAggregate( pObjP
, FALSE
) );
265 // sich selbst als Typecast-Verwalter eintragen
266 SvAggregateMemberList
& rAList
= pObjP
->GetAggList();
267 DBG_ASSERT( !rAList
.GetObject( 0 ).bMainObj
, "try to aggregate twice" );
268 rAList
[ 0 ] = SvAggregate( this, TRUE
);
271 /*************************************************************************
272 |* SotObject::AddInterface()
275 *************************************************************************/
276 void SotObject::AddInterface( SotFactory
* pFactP
)
279 pAggList
->Append( SvAggregate( pFactP
) );
282 /*************************************************************************
283 |* SotObject::CreateAggObj()
286 *************************************************************************/
287 SotObjectRef
SotObject::CreateAggObj( const SotFactory
* )
289 return SotObjectRef();
293 /*************************************************************************
294 |* SotObject::DownAggCast()
297 *************************************************************************/
298 void * SotObject::DownAggCast( const SotFactory
* pFact
)
301 // geht den Pfad nur Richtung aggregierte Objekte
304 for( ULONG i
= 1; !pCast
|| i
< pAggList
->Count(); i
++ )
306 SvAggregate
& rAgg
= pAggList
->GetObject( i
);
309 if( rAgg
.pFact
->Is( pFact
) )
311 // On-Demand erzeugen, wenn Typ gebraucht
312 SotObjectRef
aObj( CreateAggObj( rAgg
.pFact
) );
313 rAgg
.bFactory
= FALSE
;
317 // sich selbst als Typecast-Verwalter eintragen
318 SvAggregateMemberList
& rAList
= rAgg
.pObj
->GetAggList();
319 DBG_ASSERT( !rAList
.GetObject( 0 ).bMainObj
, "try to aggregate twice" );
320 rAList
[ 0 ] = SvAggregate( this, TRUE
);
325 // muss der (void *) auf Klasse pFact sein
326 pCast
= rAgg
.pObj
->Cast( pFact
);
328 pCast
= rAgg
.pObj
->DownAggCast( pFact
);
337 /*************************************************************************
338 |* SotObject::AggCast()
341 *************************************************************************/
342 void * SotObject::AggCast( const SotFactory
* pFact
)
347 SvAggregate
& rAgg
= pAggList
->GetObject( 0 );
349 return rAgg
.pObj
->AggCast( pFact
);
350 pCast
= Cast( pFact
);
352 pCast
= DownAggCast( pFact
);
355 pCast
= Cast( pFact
);
359 /*************************************************************************
360 |* SotObject::CastAndAddRef()
363 *************************************************************************/
364 void * SotObject::CastAndAddRef( const SotFactory
* pFact
)
366 void * pCast
= Cast( pFact
);
372 /*************************************************************************
373 |* SotObject::GetMainObj()
376 *************************************************************************/
377 SotObject
* SotObject::GetMainObj() const
381 if( pAggList
->GetObject( 0 ).bMainObj
)
382 return pAggList
->GetObject( 0 ).pObj
->GetMainObj();
384 return (SotObject
*)this;
387 //=========================================================================
388 USHORT
SotObject::FuzzyLock
390 BOOL bLock
, /* TRUE, lock. FALSE, unlock. */
391 BOOL
/*bIntern*/, /* TRUE, es handelt sich um einen internen Lock.
392 FALSE, der Lock kam von aussen (Ole2, Ipc2) */
393 BOOL bClose
/* TRUE, Close aufrufen wenn letzte Lock */
397 Erlaubte Parameterkombinationen:
398 ( TRUE, TRUE, * ) -> interner Lock.
399 ( FALSE, TRUE, TRUE ) -> interner Unlock mit Close,
400 wenn LockCount() == 0
401 ( TRUE, FALSE, * ) -> externer Lock.
402 ( FALSE, FALSE, TRUE ) -> externer Unlock mit Close,
403 wenn LockCount() == 0
404 ( FALSE, FALSE, FALSE ) -> externer Unlock
406 F"ur !Owner() wird der Aufruf an das externe Objekt weitergeleitet.
407 F"ur diese muss das <IOleItemContainer>-Interface zur Vef"ugung stehen.
408 bIntern und bClose werden dann ignoriert.
409 Wenn der LockCount auf 0 wechselt, wird <SotObject::DoClose>
410 gerufen, wenn kein OwnerLock besteht.
416 SotObjectRef
xHoldAlive( this );
421 nRet
= ++nStrongLockCount
;
425 nRet
= --nStrongLockCount
;
429 if( !nRet
&& bClose
&& !nOwnerLockCount
)
434 //=========================================================================
435 void SotObject::OwnerLock
437 BOOL bLock
/* TRUE, lock. FALSE, unlock. */
441 Wenn der OwnerLock auf Null dekrementiert, dann wird die Methode
442 DoClose gerufen. Dies geschieht unabh"angig vom Lock. bzw. RefCount.
443 Ist der OwnerLock-Z"ahler != Null, dann wird kein DoClose durch
444 <SotObject::FuzzyLock> gerufen.
452 else if ( nOwnerLockCount
)
454 if( 0 == --nOwnerLockCount
)
460 void SotObject::RemoveOwnerLock()
462 if ( nOwnerLockCount
)
468 DBG_ERROR("OwnerLockCount underflow!");
472 //=========================================================================
473 BOOL
SotObject::DoClose()
478 SotObjectRef
xHoldAlive( this );
486 //=========================================================================
487 BOOL
SotObject::Close()