home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
opendc12.zip
/
od124os2.exe
/
od12osr1.exe
/
src
/
CMDraft.cpp
< prev
next >
Wrap
Text File
|
1997-03-21
|
265KB
|
6,870 lines
/* @(#)Z 1.45 com/src/bento/CMDraft.cpp, odstorage, od96os2, odos29712d 97/03/21 17:19:03 (97/03/03 14:38:44) */
//====START_GENERATED_PROLOG======================================
//
//
// COMPONENT_NAME: odstorage
//
// CLASSES: none
//
// ORIGINS: 82,27
//
//
// (C) COPYRIGHT International Business Machines Corp. 1995,1996
// All Rights Reserved
// Licensed Materials - Property of IBM
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//
// IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
// ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
// USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
// OR PERFORMANCE OF THIS SOFTWARE.
//
//====END_GENERATED_PROLOG========================================
//
/*
File: CMDraft.cpp
Contains: Implementation for CMDraft class.
Owned by: Vincent Lo
Copyright: ⌐ 1993-1995 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<125> 10/24/95 TJ Changed string to corbastring
<124> 10/24/95 jpa 1293441: DM/VL: Bento memory reserve &
fatal container err & don't throw in
Release.
<123> 10/20/95 VL 1293256: Changed
kODErrBentoInvalidVersionList to
kODErrDraftDoesNotExist.
<122> 10/19/95 EL 1292685: After purging we may get a
different storage unit for the same
CMObject.
<121> 10/17/95 jpa 1289153: CreatePart, AcquirePart,
AcquireFrame handle failure gracefully.
<120> 10/13/95 EL 1287340: Use standard ISO prefix
<119> 10/8/95 TJ Fixes Recomended by Refball
<118> 10/5/95 CC 1286180: Added CloneCompanionObject method.
1286180: Clone: Call CloneCompanionObject
if clone kind is kODCloneAll.
<117> 10/3/95 TJ Changes done by RefBall Team
<116> 9/29/95 TJ Made Changes for MAC SOM
<115> 9/14/95 VL 1283566: Fixed Clone so that CloneFromLink
would also skip links (i.e., return 0 as
the id).
<114> 9/11/95 VL 1283326: CreateFrame now takes ODObjectType
instead of ODType. 1283157: Fixed memory
Leak in CMDraft::ConstructRealPart.
<113> 9/8/95 VL 1276955: Make sure draft is not read-only
before writing out preferred kind.
<112> 9/8/95 Té 1281096 FB2:Many constants in ODTypesB
without kOD prefix!
<111> 9/1/95 CC 1273646, 1279220: Support kODCloneToFile.
<110> 8/29/95 VL 1279830, 1279074: THROW_IF_NULL after new
on SOM objects. 1279505: Catches exceptions
returned from ReleaseAll.
<109> 8/26/95 Té 1270499Two editors which support same kind
binding problem
<108> 8/25/95 JBS 1263078 FB: fix part editor swapping
<107> 8/24/95 CC 1251959: BeginClone must clean up before
returning an error.
<106> 8/24/95 EL 1274602: cmObject not released resulting in
wrong internal Bento ref count.
<105> 8/22/95 VL 1277720, 1278310: Cleaned up error code in
Release/RemoveStorageUnit.
<104> 8/21/95 VL 1278330, 1278315: Error code cleanup.
<103> 8/21/95 VL 1277291: Use GetOriginalCloneKind from
StorUtil. 1258660: Rewrote exception
handling for CreateFrame to ensure that the
correct exception are propogated.
<102> 8/17/95 CC 1277781: CheckPartAction: Check size of
storage unit type before comparing strings;
check for invalid part ID returned by
ODGetStrongSURefProp.
<101> 8/16/95 EL Disable ODDebug_CloningAnnotations
<100> 8/16/95 NP 1274946: ErrorDef.idl problems. Add include
file. 1277286: CMDraft: ConstructRealPart
gropes ev->_major when it doesn't mean to.
<99> 8/16/95 VL 1266007: IsValidDraftKey returns kODFalse
for kODNULLKey.
<98> 8/15/95 CC 1274794, 1273863: CopyProperties: Focus to
property (don't assume already focused).
CopyDraftAnnotations: Always copy the
storage unit type property.
<97> 8/12/95 Té 1276812 Need to use TempObjs and TempRefs
for exception safety and to avoid TRY
blocks, 1276807 Opt./Bug: use StdTypIO
routines for portable streaming & smaller
footprint, 1276806 Optimization: use
kODFalse instead of kODTrue in comparisons
<96> 8/3/95 RR #1257260: Collapse B classes. Remove
somInit methods. Don't call IsInitialized
or SubclassResponsibility
<95> 7/26/95 VL 1270320: Dispose of valueName in
CopyProperty.
<94> 7/21/95 VL 1270320: Freeing internal field. Disposed
ba._buffer of ID.
<93> 7/20/95 CC 1268790: Clone: Make sure original ID is
still valid before substituting!
<92> 7/3/95 VL 1255736: Every instantiated persistent
object has the object type correctly set.
<91> 6/29/95 VL 1242642: Release DraftProperties in
DeleteCollections. Release SU before
removing it.
<90> 6/23/95 JBS 1261323 Draft::CreateFrame: add isSubframe
param, remove isRoot
<89> 6/19/95 VL 1170098: Added code to count part instances
(PartInstantiated, PartDeleted,
PurgeClasses). Code for the actual
unloading of the libraries is commented out
now. Added DeleteRealPart.
<88> 6/16/95 VL 1244940: Made Externalize which triggers
promise resolution work.
<87> 6/14/95 VL 1251227: Delete the collections and their
objects in somUninit.
<86> 6/13/95 VL 1241352: Moved PreserveFocus to DrafPriv.
<85> 6/12/95 CC 1252059: BeginClone: Allow clone to link
when clone from link is in progress.
<84> 6/10/95 VL 1255300: Updated CopyDraftAnnotations for
cloning annotations and metadata.
<83> 6/7/95 CC 1255762: EndClone() now uses destFrame
passed to BeginClone().
CheckClonedObject, ContainingPartInClone,
CheckPartAction: Changed kODFrame to
kODFrameObject.
CheckClonedObject: Changed kODPart to
kODPartObject.
ContainingPartInClone: Fixed refcount
problem.
<82> 6/2/95 CC 1255476: CreateVersion, et. al. : release
document acquired for debug string.
1255476: ContainingPartInClone: Release
acquired parts and frames.
1255474: AcquireDocument restored to
GetDocument.
1255474: GetPersistentObject restored to
AcquirePersistentObject.
1255474: AcquireStorageUnitType restored to
GetStorageUnitType.
<81> 6/1/95 jpa Handle errs thrown from ODNewObject.
[1242839]
<80> 5/26/95 VL 1251403: Multithreading naming support.
<79> 5/25/95 jpa Fixed usage of ODDebug. [1253321]
<78> 5/22/95 CC 1242879: Added IsValidID.
<77> 5/22/95 VL 1246940: Preserve focus during Clone.
<76> 5/19/95 VL 1250574: Added check for kODNULLID in Get
methods.
<75> 5/18/95 CC 1238898: Add destFrame argument to
BeginClone call; added fDestFrame field.
<74> 5/17/95 VL 1170098: Added ConstructRealPart and
ReleaseRealPart.
<73> 5/17/95 RR #1250135/1250137/1250143 Getters increment
refcount
<72> 5/3/95 CC Split file into two segments to avoid
16-bit PC-relative offset problems on 68K.
<71> 5/2/95 CC 1207493: Detect embedding part within
itself.
New methods: ContainingPartInClone and
CheckClonedObject.
New fields: fAnyFrameCloned and
fRootPartCloned.
New static variables: sIntermediateDraft,
sSUTypeBuffer, and sRootPartIDToIgnore.
New static functions: CheckPartAction,
CopyDraftAnnotations, CopyProperty,
GetStorageUnitType, RootPartID.
1245718: StrongClone: Call
CopyDraftAnnotations.
1245706: CreatePart creates
kODPropPreferredKind property, not
kODPropPart.
<70> 5/2/95 VL 1211972: RemoveFrame does not dirty draft
if frame is non-persistent. 1243122: Use
kODErrValueIndexOutOfRange. 1221370:
AcquirePersistentObject works on read-only
draft.
<69> 5/2/95 EL 1234685: Container manager does not like
value created but not written to, so always
write something after CMNewValue.
<68> 4/25/95 DM 1172791: Replace AEHashTable with
OpenHashTable
<67> 4/25/95 VL 1210982: Removed 5$.
<66> 4/25/95 CC 1242555: CreateLinkSource, CreateLink,
Clone, AbortClone: Removed $5 from comment.
<65> 4/10/95 VL 1230350: Release Part before trying to
remove it.
<64> 4/7/95 EL 1226127: make sure code works when
TestFlushContainer is false.
<63> 3/31/95 Té 1223505 BB: Opening and creating documents
on read only media. Fixed Creation of
Non-persistent frames on readonly drafts.
<62> 3/24/95 EL 1209355: Abort would remove changes in
version list rather than reinitialize it.
Cut down on version list externalization.
<61> 3/23/95 VL 1228003: Added debug code for versionlist.
1230371: Check before calling
IDList::Remove.
<60> 3/17/95 CC 1194656: SetOriginalDraft must check for
existence of property and value before
adding.
<59> 3/13/95 VL 1226094: Added error handling in CreateSU
to handle the case when any invalid ID is
passed in.
<58> 3/10/95 VL 1222416: Write out 0 at the end of
persistent object ISOString.
<57> 3/9/95 VL 1225504: Use GetTargetDocument to prevent
ref-counting problem.
<56> 3/7/95 CC 1224121: ODPart::CreateLink() and
ODLinkManager::CreateLink() return an
ODLinkSource object.
<55> 3/6/95 EL 1182275: Replace SetDraftPropertyObject by
CMKeepObject.
<54> 2/28/95 VL 1194656: Check for existence before adding
property or value.
<53> 2/21/95 EL 1182275: Do not externalize object if it
was garbage collected. Tell embedded
container about the draft property object.
<52> 2/21/95 eeh 1222416: add 1 to len in
GetPersistentObjectID
<51> 2/17/95 VL 1220231: CreateFrame now calls
InitFrameNonPersistent.
<50> 2/15/95 EL 1182275: Set embedded container to no merge
if draft is created. 1158620: Lazy open
would avoid reopening of embedded container
when document is closed.
<49> 2/10/95 VL 1205627: Use TargetContainer in
CreateVersion.
<48> 2/6/95 TJ Sorry, the last comment should be touched
copy right date.
<47> 2/6/95 TJ Updated Check in Date.
<46> 2/3/95 VL 1216535: Implemented storage support for
non-persistent frames.
<45> 1/18/95 VL 1193559: Added new 2
methods(AcquirePersistentObject and
GetPersistentObjectID). Renamed
AcquirePersistentObject to
RetrievePersistentObject. Removed
GetPersistentLinkID and AcquireLinkID.
<44> 1/11/95 VL 1185688: Reverted one of the changes in
ExternalizeCollections to fix a refcounting
problem.
<43> 1/11/95 VL 1185688: Made storage more robust in terms
of error handling. Also did some code
review cleanup.
<42> 12/20/94 VL 1195012: Make Storage calls be
marshallable.
<41> 12/16/94 CC 1203516 Modified CreateLinkSource to use
SetLink() and SetLinkSource() methods,
modified CreateLink().
<40> 12/15/94 CC 1193569 CreateLinkSpec() takes ODByteArray
parameter.
1197221 AcquireLink() - added SOM_CATCH;
changed call to ODPart::CreateLink() to
pass byte array.
<39> 11/1/94 CC 1190911, 1192030, 1196908 - Clone reuses
same objects if moved within same draft;
Clone while fulfilling promises won't
recopy already cloned objects.
<38> 11/1/94 VL 1151339: Preparation for MergeContainer.
<37> 10/19/94 VL 1155857: Added ODDebug_Drafts to debug
"Cannot create more than 10 drafts"
problem.
<36> 10/12/94 VL (JPA) Added debugstrs for frames.
<35> 10/4/94 CC 1190858 - Added ReleaseLinkSource().
<34> 9/29/94 RA 1189812: Mods for 68K build.
<33> 9/23/94 VL 1184272: ContainerID is now a sequence of
octets. This affects EmbeddedContainers
also.
<32> 9/23/94 CC 1187509 - Added somPrintfs for debugging
clone operations.
<31> 9/16/94 CC 1186957 - Fix to clone newly created links
correctly (added AcquireLinkSourceFromLink and
AcquireLinkFromLinkSource).
<30> 9/15/94 CC 1186776 - Enforce correct link behavior
during clone operations.
1160117 - Strip links when cloning into a
link.
1186657 - Correct ref count on object
returned by CreateLinkSource().
1153940 - Clone must support new clone kind
constants.
<29> 9/9/94 CG #1183531: ConstructPart instantiates a
PartWrapper which in turn creates a part.
<28> 9/6/94 VL 1184177: Removed GetName and SetName.
<27> 9/5/94 VL 1184871: Used Renew to remove dependency on
default heap.
<26> 8/31/94 Té #1183129, #1183116, #1183119, #1183111:
Lots of ErrorCode cleanup.
<25> 8/31/94 VL 1106013: Fixed GetName to return kODNULL if
the draft does not have a name.
<24> 8/26/94 VL 1183174: Added destDraft to BeginClone and
added toID to Clone.
<23> 8/19/94 Té #1181622 Fix Written to Owned & name &
reference to ASLM Build
<22> 8/17/94 CG #1181487: Instantiating parts by name
again!
<21> 8/16/94 Té #1180922 Remove more obsolete types from
StdTypes.idl. Localized kODStorageUnit to
this file.
<20> 8/16/94 VL 1143605: Added CloneInto.
<19> 8/15/94 VL #???: Added frameType parameter to
CreateFrame.
<18> 8/13/94 Té #1180814 Added support for ODPartWrapper
API
<17> 8/12/94 JBS 1179919: add biasCanvas param to
Draft::CreateFrame()
<16> 8/11/94 CC Added implementation of
CreateLinkIterator() and
CreateLinkSourceIterator() methods.
<15> 8/10/94 JBS 1179919: coordinate system bias changes
<14> 8/4/94 eeh bug 1179054: fix kODPartPartsBin
<13> 8/3/94 VL 1153123: Storage to ODStor.
<12> 7/28/94 Té Create Clock statically
<11> 7/27/94 CC Removed static functions IsMyProcess() and
IsRunningProcess(); changed AcquireLink()
method to use new ODLinkSpec methods.
<10> 7/26/94 VL Got rid of MacStorageUnit and
MacDragAndDropStorageUnit.
<9> 7/26/94 eeh
<8> 7/21/94 VL Removed ASLM BUILD.
<7> 7/19/94 CC Create DragText statically.
<6> 7/18/94 Té moved refcounting fixes to PstObj.cpp
<5> 7/18/94 Té fixed another refcount problem
<4> 7/17/94 Té fixed ReleasePersistentObject to release
the storageUnit of a persistentObject
<3> 7/14/94 eeh Apple module name -> AppleTestDraw
<2> 7/12/94 VL Added code to Create DrawPart statically.
<1> 7/5/94 VL first checked in
-----------------------------------------------------------------------
<10> 6/1/94 CG Changed to use public binding object.
<9> 5/27/94 jpa Use ODNewObject to avoid ASLM dependency,
to support new exception scheme [1165267]
<8> 5/9/94 MB #1162181: Changes necessary to install MMM.
<7> 4/6/94 JBS 1155480
<6> 3/28/94 Té #1145834. Remove PrtType.h & .cpp from the
project. Noted a few places where there is
code which is only needed by the static
build.
<5> 3/28/94 CG 1153547: Changed XMPSessn.h to XMPSessM.h
<4> 3/27/94 Té localized use of kXMPPropRootSU
<3> 3/25/94 CC Change name of included file to
"LinkMgrM.h". (1153348)
<2> 3/25/94 MB Symantec ASLM fixes. #1150864
<1> 3/24/94 VL first checked in
<7> 3/18/94 CC CMRegisterType(): Changed kXMPAppleTEXT
argument to kXMPISOStr. (1151636)
<6> 3/15/94 MB Changes to support SCpp/ASLM builds,
#1150864.
<5> 3/14/94 CC Added internal methods FixReusedLinks() and
ReferencedStorageUnitCloned(); Revised
EndClone(), PrepareLinksForClone().
(1149492)
<4> 2/22/94 VL THROW -> THROW_IF_ERROR.
<3> 2/18/94 VL #1142972, #1144024: Added
GetDragDropStorageUnit to enable importing
data from a foreign source (e.g. the
Finder).
<2> 2/17/94 CC Bug #1142584 - GetOriginalCloneKind returns
kXMPCloneCopy by default in case content
was put directly onto the clipboard without
cloning.
<106> 2/8/94 VL Corrected capitalization of include files
and used <> for Toolbox headers.
<105> 2/8/94 VL Use new exception macros.
<104> 2/4/94 VL Session.h -> XMPSessn.h.
<103> 2/4/94 VL More code cleanup.
<102> 2/4/94 VL Moved to PPC Header and began code cleanup.
(Added itoa to replace NumToString. Got rid
of some warnings.)
<101> 2/3/94 CG System Session break out.
<100> 2/2/94 VL Made Hash Table use system heap when
appropriate.
<99> 2/2/94 CC Revised PrepareLinksForClone() and
AnnotateLinksForNextClone().
<98> 2/2/94 RR Added isRoot to CreateFrame
<97> 2/1/94 CC Added PrepareLinksForClone()
AnnotateLinksForNextClone(), and non-member
support functions; not yet called by
EndClone(). Added XMPCloneType argument to
BeginClone.
<96> 1/28/94 CC Removed UniqueUpdateID(),
ShowLinkBorders(), and SetLinkBorders().
Implemented Purge() (VL). Abort() now
releases draft properties (VL). Fixed
sequence of deletions in
RemovePersistentObject() (VL).
DeleteCollections() - call ReleaseAll() on
all objects, then delete all objects.
<95> 1/27/94 VL Used ReleaseAll. Fixed up
ReleasePersistentObject. Added
IsValidDraftKey.
<94> 1/25/94 CC Use fShowLinkBorders field.
<93> 1/22/94 CC AcquireLink(), AcquireLinkSource(): Avoid infinite
recursion by adding persistent object to
the draft before calling
InitFromStorageUnit().
<92> 1/21/94 CC Added CreateLinkSource(), AcquireLinkSource(),
RemoveLinkSource(), and
AcquireLinkSourceIterator(). Moved calls to
XMPLinkManager::DraftOpened,
::DraftClosing, and ::DraftSaved into
document shell.
<91> 1/21/94 CG Renamed kXMPEmbeddedContainer to
kXMPBentoEmbeddedContainer. Changed calls
to NewObject to take current heap.
<90> 1/18/94 CG Added include for BentoDef.h for
kXMPEmbeddedContainer.
<89> 1/18/94 CC Added stub implementations of
ShowLinkBorders() and SetLinkBorders();
changed DraftClosed() to DraftClosing().
<88> 1/15/94 VL Made sure that the Part Destructor is
called.
<87> 1/14/94 CC Externalize(): Call
XMPLinkManager::DraftSaved();
RemoveChanges(): Call
XMPLinkManager::DraftClosed().
<86> 1/12/94 CG Changed CreatePart and AcquirePart to use the
new Binding object in ASLM build.
<85> 1/12/94 VL Init... Changes.
<84> 12/22/93 CC AcquireLink() - Better error handling and
clean-up.
<83> 12/21/93 VL Added support for Persistent Link ID.
<82> 12/21/93 JBS CreateFrame with viewType & presentation
<81> 12/20/93 SS Added PartsBin to Get/CreatePart
<80> 12/20/93 VL Removed window-related stuff (XMPWindow is
no longer a persistent object).
<79> 12/16/93 CC AcquireLink: Instantiate link objects, moved
code into LinkMgr.cp. CreateLink: object
type is kXMPLink not kXMPPart!
<78> 12/16/93 Té CreatePart now takes an optional Editor
parameter
<77> 12/14/93 VL Added private methods to GetCMContainer and
used AcquireDraft instead of fDraft.
<76> 12/14/93 Té InitFrame, InitLink, InitWindow changes.
PstObj::Initialize, PstObj:Internalize,
PstObj::InitializePersistent all went away.
<75> 12/13/93 Té InitPart changes
<74> 12/8/93 CC Changes to CreateLinkSpec
AcquireLink sends apple event to resolve
linkSpec.
<73> 12/3/93 Té Stop including XMPError.h, it is included
as ErrorDef.h inside Except.h
<72> 11/30/93 VL Changed frameGroup from XMPUShort to
XMPULong.
<71> 11/24/93 VL Added document check in Initialize.
<70> 11/23/93 VL Made XMPDraft pool-aware.
<69> 11/18/93 PH Call parent method in
RemovePersistentObject
<68> 11/18/93 PH Fixed RemovePersistentObject to call
Release before calling delete
<67> 11/17/93 CC Fixed CreateLink to compile with CFront.
<66> 11/16/93 EL Use OpenDoc instead of Amber.
<65> 11/16/93 SS Reactivated DragPart
<64> 11/16/93 EL Part name is ISOStr and should be null
terminated.
<63> 11/15/93 CC Implemented AcquireLink for LinkSpec parameter
Implemented CreateLink and CreateLinkSpec
Added IsMyProcess
<62> 11/12/93 JBS remove Layout methods
<61> 11/9/93 PH Added CreateDragDropStorageUnit
<60> 11/4/93 SS Added #ifdef QUALITY_PARTS too
Get/CreatePart for quality team
<59> 11/1/93 VL Added BeginClone, EndClone and AbortClone.
Collapsed fStorageUnits and
fReleasedStorageUnits into one hash table.
Collapsed fPersistentObjects and
fReleasedPersistentObjects into one hash
table.
<58> 10/29/93 PH Fix AcquirePart and add check to
ReleaseStorageU
<57> 10/21/93 RR CreateWindow takes new window flags (at
least until we have new Initialize strategy
for SOM)
<56> 10/12/93 VL Uncommented WASSERTs. Release
fDraftProperties in ::RemoveChanges.
<55> 10/8/93 VL Temporarily removed WASSERT.
<54> 10/7/93 RR Added rootPart to CreateWindow call
<53> 10/7/93 VL Moved error codes to XMPError.h.
<52> 10/6/93 Té remove obsolete parts (StylPart)
<51> 9/30/93 VL Removed SetFinished.
<50> 9/30/93 VL Removed unnecessary STORAGE_TEST ifdefs.
<49> 9/29/93 VL Added code for smart internalization.
<48> 9/24/93 PH Use new AppleTEXT
<47> 9/24/93 VL Removed unnecessary Throws.
<46> 9/24/93 JA Minor syntactic tweaks for THINK C++.
<45> 9/23/93 VL Added code to handle StorageUnitType
property. Fixed SetName to use Exists
instead of exception. Moved methods around
to conform to .h file.
<44> 9/22/93 JA Updated ASSERTs for new macro.
<43> 9/21/93 VL Avoid creating unnecessary versions.
<42> 9/16/93 JA Fixed polarity of ASSERTs.
<40> 9/14/93 VL Made Draft thread-safe.
<39> 9/9/93 VL Set up the Session global for
EmbeddedContainers. Fixed casting problem
caused in <38>.
<38> 9/9/93 VL Fixed RemovePersistentObject to
CMDeleteObject the real object, not ID.
<37> 9/8/93 VL Draft can handle flushing now.
<36> 9/7/93 PH Add code to create a DragPart
<35> 9/3/93 JBS added support for XMPLayout class
<34> 8/26/93 VL Used new VersionList calls.
<33> 8/23/93 VL Added FailIfNotExclusiveWrite check. Used
fExternalized flag to show the state of the
draft. Implemented NeedExternalizing.
<32> 8/20/93 Té Commented out #ifdef PROTOTYPEBUILD stuff
so that the implementation shell could use
the full functionality of Draft
<31> 8/20/93 VL Cast XMPPtr to XMPName.
<30> 8/20/93 VL Used ODMemory.h
<29> 8/19/93 VL Put in CMDeleteObject again.
<28> 8/18/93 VL ReleaseStorageUnit takes an ID now.
<27> 8/18/93 PH Don't call CMDeleteObject in
RemoveStorageUnit
<26> 8/18/93 VL Fixed ReleaseSTorageUnit.
<25> 8/17/93 PH Call internalize in AcquirePart and don't
increment the ref count of the SU in
GetPstObj if the object exists
<24> 8/13/93 VL Used VersionList::GetLatestVersionID.
Commented out some code in Externalize.
<23> 8/12/93 VL Made GetName raise an exception instead of
returning kXMPNULL. Used kXMP props and
types.
<22> 8/11/93 VL ifdef out implementation code for
CreateFrame because the XMPFrame class is
not there yet.
<21> 8/10/93 VL Put some real code in CreateFrame.
<20> 8/10/93 PH Call release on su in ReleasePstObj
<19> 8/10/93 PH Really fix ReleasePstObj
<18> 8/9/93 PH Fix ReleasePersistentObject to do ref
counting properly
<17> 8/9/93 VL Moved error code to XMPError.h.
<16> 8/6/93 PH Change kPartType to kXMPPart
<15> 8/6/93 VL Used CreateCollections and
DeleteCollections.
<14> 8/6/93 PH Storage integration
<13> 8/6/93 VL Added support for
creating/getting/releasing/removing
persistent objects.
<12> 7/29/93 VL Removed getting persistent objects by name.
Implemented GetName and SetName.
<11> 7/23/93 VL Removed root SU creation code in
AcquireDraftPropertiesObject.
<10> 7/14/93 VL Implemented basic storage unit functions.
<9> 7/6/93 VL Implemented RemoveFromDocument.
<8> 7/6/93 VL XMPStorageUnitName should be
XMPStorageUnitName* in AcquireStorageUnit.
<7> 7/2/93 Té CreateSU should take XMPType, not XMPName.
<6> 6/30/93 VL Changed XMPName to XMPType.
<5> 6/30/93 VL Added Reinitialize, Open, Close, Abort.
Also added utility calls
Open/Close/AbortVersion.
<4> 6/22/93 VL Used RefCount from RefCtObj. Added
SetChangedFromPrev() and
AcquireDraftPropertiesObject. Initialize() gets
SU for Draft Properties.
<3> 6/15/93 VL Put it some test code.
<1> 6/2/93 VL first checked in
To Do:
In Progress:
*/
#define CMDraft_Class_Source
#define VARIABLE_MACROS
#include <CMDraft.xih>
#ifdef _PLATFORM_WIN32_
#include <process.h>
#endif
#ifdef _PLATFORM_OS2_
// headers for DSOM linking
#include <process.h>
#include <somd.xh>
#ifndef _ISOSTR_
#include <ISOStr.h>
#endif
#include <tpllitr.xh>
#include <tpll.xh>
#ifndef _IODDEFS_
#include <IODDefs.xh>
#endif
// #include <link.xh>
#include <ICIDItr.xh>
#include <ILinkSrc.xh>
#include <ILnkSrvc.xh>
#include <ILnkTrgt.xh>
#endif // PLATFORM_OS2_
#ifndef _DRAFPRIV_
#include "DrafPriv.h"
#endif
#ifndef SOM_ODSession_xh
#include <ODSessn.xh>
#endif
#ifndef SOM_CMDocument_xh
#include <CMDoc.xh>
#endif
#ifndef SOM_CMStorageUnit_xh
#include <CMSU.xh>
#endif
#ifndef _DOCPRIV_
#include "DocPriv.h"
#endif
#ifndef SOM_ODContainer_xh
#include <ODCtr.xh>
#endif
#ifndef SOM_ODStorageSystem_xh
#include <ODStor.xh>
#endif
#ifndef SOM_ODStorageUnitCursor_xh
#include <SUCursor.xh>
#endif
#ifndef SOM_ODFrame_xh
#include <Frame.xh>
#endif
#ifndef SOM_ODLink_xh
#include <Link.xh>
#endif
#ifndef SOM_ODLinkSource_xh
#include <LinkSrc.xh>
#endif
#ifndef SOM_ODLinkSpec_xh
#include <LinkSpec.xh>
#endif
#ifndef SOM_ODLinkManager_xh
#include <LinkMgr.xh>
#endif
#ifndef SOM_ODPart_xh
#include <Part.xh>
#endif
#ifndef _EXCEPT_
#include "Except.h"
#endif
#ifndef SOM_ODBentoContainer_xh
#include "CMCtr.xh"
#endif
#ifndef _CMAPI_
#include "CMAPI.h"
#endif
#ifndef __CM_API_TYPE_
#include "CMAPITyp.h"
#endif
#ifndef SOM_ODEmbeddedContainer_xh
#include <EmbedCtr.xh>
#endif
#ifndef _SESSHDR_
#include "SessHdr.h"
#endif
#ifndef _ODMEMORY_
#include "ODMemory.h"
#endif
#ifndef _ODNEW_
#include "ODNew.h"
#endif
#ifndef SOM_Module_OpenDoc_StdProps_defined
#include <StdProps.xh>
#endif
#ifndef SOM_Module_OpenDoc_StdTypes_defined
#include <StdTypes.xh>
#endif
#ifndef SOM_CMLinkIterator_xh
#include <CMLkItr.xh>
#endif
#ifndef SOM_CMLinkSourceIterator_xh
#include <CMLkSItr.xh>
#endif
#ifdef _PLATFORM_OS2_
#ifndef SOM_ODWindow_xh
#include <Window.xh>
#endif
#endif
#ifndef _INDHDR_
#include "IndHdr.h" // for some const ODName
#endif
#ifndef _OPENHASH_
#include "OpenHash.h"
#endif
#ifndef _ISOSTR_
#include "ISOStr.h"
#endif
#ifndef __STRING__
#include <string.h> // For strlen, strcpy....
#endif
#ifndef _ODDEBUG_
#include "ODDebug.h" // Adkins -- added
#endif
#ifndef _STORUTIL_
#include <StorUtil.h>
#endif
#ifndef SOM_ODBinding_xh
#include <ODBindng.xh>
#endif
#ifndef SOM_ODPartWrapper_xh
#include <PartWrap.xh>
#endif
#ifndef _BENTODEF_
#include "BentoDef.h"
#endif
#ifndef _BARRAY_
#include <BArray.h>
#endif
#ifdef _PLATFORM_OS2_
#ifndef _ODUTILS_
#include <ODUtils.h>
#endif
#endif
#ifndef _UTILERRS_
#include "UtilErrs.h"
#endif
#ifdef _PLATFORM_MACINTOSH_
#ifndef SOM_ODDragAndDrop_xh
#include <DragDrp.xh>
#endif
#endif
#ifndef SOM_ODArbitrator_xh
#include <Arbitrat.xh>
#endif
#ifndef SOM_Module_OpenDoc_Foci_defined
#include <Foci.xh>
#endif
#ifndef _NO_TMP_OBJS_
#ifndef _ODNEWOBJ_
#include <ODNewObj.h>
#endif
#endif
#ifndef _STDTYPIO_
#include <StdTypIO.h>
#endif
#ifndef _NO_TMP_OBJS_
#ifndef _TEMPOBJ_
#include <TempObj.h>
#endif
#endif
#ifndef SOM_Module_OpenDoc_StdDefs_defined
#include <StdDefs.xh>
#endif
#ifndef SOM_SOMClassMgr_xh
#include <somcm.xh>
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
#ifndef _ODUTILS_
#include "ODUtils.h"
#endif
#endif
#ifndef SOM_ODWindow_xh
#include <Window.xh>
#endif
#ifndef SOM_NoPart_xh
#include <NoPart.xh>
#endif
#ifdef _PLATFORM_WIN32_
#ifndef _OLEWRAP_H_
#include "olewrap.h"
#endif
#ifndef _OLEMGRW_H_
#include "olemgrw.h"
#endif
#ifndef SOM_OpenDocShell_xh
#include "odshell.xh"
#endif
#ifndef SOM_DocumentManager_xh
#include "docmgr.xh"
#endif
#endif
#ifndef _BENTOERR_
#include "BentoErr.h"
#endif
#ifdef _PLATFORM_OS2_
#include <ILnkSrvc.xh>
#include <ILinkSrc.xh>
#ifndef SOM_ODNameSpaceManager_xh
#include <NmSpcMg.xh>
#endif
#ifndef LMGRDEFS_H
#include "lmgrdefs.h"
#endif
#endif // PLATFORM_OS2_
#pragma segment CMDraft
//==============================================================================
// Constants
//==============================================================================
const ODType kODVersionNamePrefix = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:Bento Version Name";
const ODPropertyName kODPropRootSU = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:DraftRootStorageUnit";
const ODType kODStorageUnitType = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Type:StorageUnit";
const ODType kODStorageUnit = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:ObjectType:StorageUnit";
const ODULong kODInitialNumEntries = 8;
const corbastring kFrameClassName = "ODFrame";
// $$$$$ This seems like a bad hardcoded dependency on a classname.
#define kODPropOriginalPID "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Metadata:OriginalPID"
#define kMaxStringSize 32
#define kInitialHashTableEntries 8
#define lazyOpen 1
// For debugging
#if ODDebug
// #define ODDebug_Drafts 1
// #define ODDebug_DebugRefCount 1
// #define ODDebug_CMDraft 1
// #define DebugClone 1
// #define ODDebug_VersionList 1
// #define ODDebug_CloningAnnotations 1
// #define ODDebug_Unloading_Classes 1
#endif
//==============================================================================
// Local Classes
//==============================================================================
class SULink : public Link {
public:
SULink(ODStorageUnitID fromID, ODStorageUnitID toID)
{
fFromID = fromID;
fToID = toID;
}
~ SULink() {;};
ODStorageUnitID GetFromID() {return fFromID;};
ODStorageUnitID GetToID() {return fToID;};
private:
ODStorageUnitID fFromID;
ODStorageUnitID fToID;
};
//==============================================================================
// Function Prototypes
//==============================================================================
static CMStorageUnit* NewCMStorageUnit(ODMemoryHeapID heapID);
static CMObject AcquireDraftPropertiesObject(CMContainer container);
static ODType GetVersionNameFromVersionID(ODVersionID id, ODMemoryHeapID heapID);
static void SetOriginalDraft(Environment* ev, ODDraft* targetDraft, ODDraft* originalDraft);
static ODDraft* GetOriginalDraft(Environment* ev, ODDraft* draft);
static ODBoolean OriginalCloneKindExists(Environment* ev, ODDraft* draft);
static void SetOriginalCloneKind(Environment* ev, ODDraft* targetDraft, ODCloneKind cloneKind);
static ODBoolean IsLinkObject(Environment* ev, ODDraft* draft, ODID objectID);
static ODBoolean IsLinkSourceObject(Environment* ev, ODDraft* draft, ODID objectID);
static ODBoolean IsNeitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID);
static void CM_itoa(ODULong number, ODSByte* cstring); // KP
static ODULong PurgeAllStorageUnits(Environment* ev, OpenHashTable* storageUnits, IDList* idList);
static void SetupForUpdatingDraft(Environment* ev,
CMDocument* localDoc,
ODVersionID prevVersionID,
CMValue version);
static ODBoolean CheckPartAction(void* k, void* v, ODULong s, void* r);
static void CopyProperty(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU, ODPropertyName prop);
static void CopyDraftAnnotations(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU);
static void SetStorageUnitType(Environment* ev, ODDraftPermissions perms, ODStorageUnit* su, ODType suType);
static ODISOStr GetStorageUnitType(Environment* ev, ODDraft* draft, ODID objectID);
static ODID RootPartID(Environment* ev, ODDraft* draft);
static void PurgeClasses(Environment* ev, OpenHashTable* partClasses);
// For debugging
#ifdef DebugStorage
#define MyDebugStr(s) do {somPrintf(s);} while (0)
#define MyDebug2Str(f,p1,p2) do {somPrintf(f, p1, p2);} while (0)
#else
#define MyDebugStr(s)
#define MyDebug2Str(f,p1,p2)
#endif
//==============================================================================
// Static variables
//==============================================================================
// Used by CheckPartAction
static CMDraft* sInterchangeDraft = kODNULL;
static ODISOStr sSUTypeBuffer;
static ODID sRootPartIDToIgnore;
//------------------------------------------------------------------------------
// ReadClonedObjectTable
//------------------------------------------------------------------------------
// These are private property and value for Bento Container Suite.
// They are used for data interchange. They enable multiple clones to the clipboard
// and d&d container.
const ODPropertyName kODPropClonedObjectTable = "OpenDoc:Property:Draft:ClonedObjectTable";
const ODValueType kODTypeClonedObjectTable = "OpenDoc:Type:Draft:ClonedObjectTable";
#ifdef _PLATFORM_OS2_
const ODPropertyName kODPropCloneOfALink = "OpenDoc:Property:Link:Cloned";
#endif
ODStatic void ReadClonedObjectTable(Environment* ev, OpenHashTable* clonedSUIDs, ODDraft* destDraft)
{
try
{
#ifdef DebugClone
somPrintf("CMDraft: ReadClonedObjectTable\n");
#endif
if (!destDraft)
THROW(kODErrIllegalNullDraftInput);
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = destDraft->AcquireDraftProperties(ev);
#else
TempODStorageUnit su = destDraft->AcquireDraftProperties(ev);
#endif
if (ODSUExistsThenFocus(ev, su, kODPropClonedObjectTable, kODTypeClonedObjectTable) )
{
su->SetOffset(ev, 0);
ODULong size = su->GetSize(ev);
ODID fromID;
ODID toID;
while ( su->GetOffset(ev) < size )
{
StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue) &fromID);
StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue) &toID);
#ifdef DebugClone
somPrintf(" fromID %d, toID %d\n", fromID, toID);
#endif
clonedSUIDs->ReplaceEntry(&fromID, &toID);
}
}
#ifdef _NO_TMP_OBJS_
su->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// WriteClonedObjectTable
//------------------------------------------------------------------------------
ODStatic void WriteClonedObjectTable(Environment* ev, OpenHashTable* clonedSUIDs, ODDraft* destDraft)
{
try
{
#ifdef DebugClone
somPrintf("CMDraft: WriteClonedObjectTable\n");
#endif
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = destDraft->AcquireDraftProperties(ev);
#else
TempODStorageUnit su = destDraft->AcquireDraftProperties(ev);
#endif
ODSUForceFocus(ev, su, kODPropClonedObjectTable, kODTypeClonedObjectTable);
su->SetOffset(ev, 0);
ODULong oldSize = su->GetSize(ev);
ODID fromID;
ODID toID;
OpenHashTableIterator iter(clonedSUIDs);
for (iter.First(&fromID, &toID); iter.IsNotComplete(); iter.Next(&fromID, &toID))
{
#ifdef DebugClone
somPrintf(" fromID %d, toID %d\n", fromID, toID);
#endif
StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue) &fromID);
StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue) &toID);
}
ODULong newSize = su->GetOffset(ev);
if ( oldSize > newSize )
su->DeleteValue(ev, oldSize - newSize);
#ifdef _NO_TMP_OBJS_
su->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//==============================================================================
// CMDraft
//==============================================================================
//------------------------------------------------------------------------------
// CMDraft: FailIfNotExclusiveWrite
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftFailIfNotExclusiveWrite(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","FailIfNotExclusiveWrite");
if (_fPermissions != kODDPExclusiveWrite)
ODSetSOMException(ev,kODErrInvalidPermissions);
}
//------------------------------------------------------------------------------
// CMDraft: GetDocument
//------------------------------------------------------------------------------
SOM_Scope ODDocument* SOMLINK CMDraftGetDocument(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetDocument");
return _fDocument;
}
//------------------------------------------------------------------------------
// CMDraft: GetID
//------------------------------------------------------------------------------
SOM_Scope ODDraftID SOMLINK CMDraftGetID(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetID");
return _fID;
}
//------------------------------------------------------------------------------
// CMDraft: AcquireDraftProperties
//------------------------------------------------------------------------------
SOM_Scope ODStorageUnit* SOMLINK CMDraftAcquireDraftProperties(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquireDraftProperties");
ODStorageUnit *retStorageUnit = kODNULL;
CMStorageUnit* draftProperties;
try
{
CMObject draftPropertiesObject;
ODStorageUnitID id;
if (_fDraftProperties != kODNULL) {
_fDraftProperties->Internalize(ev);
}
else {
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
// AcquireDraftPropertiesObject() makes CM calls:
draftPropertiesObject = AcquireDraftPropertiesObject(somSelf->GetCMContainer(ev));
if (draftPropertiesObject == kODNULL)
THROW(kODErrNoDraftProperties);
id = _fIDList->Add(draftPropertiesObject);
draftProperties = NewCMStorageUnit(somSelf->GetHeap(ev));
draftProperties->InitStorageUnit(ev, somSelf, id);
_fStorageUnits->ReplaceEntry(&id, &draftProperties);
_fDraftProperties = draftProperties;
ODSessionRestoreCMAllocReserve(cmContainer);
}
_fDraftProperties->Acquire(ev);
retStorageUnit = _fDraftProperties;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return _fDraftProperties;
}
//------------------------------------------------------------------------------
// CMDraft: Acquire
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftAcquire(CMDraft *somSelf, Environment *ev)
{
// CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Acquire");
try
{
parent_Acquire(somSelf, ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: Release
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRelease(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Release");
try
{
parent_Release(somSelf, ev);
if (somSelf->GetRefCount(ev) == 0) {
if (_fDraftProperties != kODNULL) {
_fDraftProperties->Release(ev);
_fDraftProperties = kODNULL;
}
// WASSERTM((somSelf->AreEmptyCollections(ev) != kODFalse), "OutstandingObjects in CMDraft: Release.");
_fDocument->ReleaseDraft(ev, somSelf);
}
}
catch (ODException _exception)
{
ODError err = ErrorCode();
WARNMSG(WARN_INDEX(AMSG_610),"Error occurred in ODDraft::Release: %d %s",
err, ErrorMessage() ?ErrorMessage() :"");
if (err == kODErrBentoErr){
SetErrorCode(kODErrFatalContainerError);
ODSetSOMException(ev, _exception);
}
else{
if (err != kODErrFatalContainerError)
SetErrorCode(kODNoError);
else
ODSetSOMException(ev, _exception);
}
}
}
//------------------------------------------------------------------------------
// CMDraft: GetPermissions
//------------------------------------------------------------------------------
SOM_Scope ODDraftPermissions SOMLINK CMDraftGetPermissions(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetPermissions");
return _fPermissions;
}
//------------------------------------------------------------------------------
// CMDraft: CreateStorageUnit
//------------------------------------------------------------------------------
SOM_Scope ODStorageUnit* SOMLINK CMDraftCreateStorageUnit(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateStorageUnit");
ODStorageUnit* su = kODNULL; ODVolatile(su);
try
{
somSelf->FailIfNotExclusiveWrite(ev);
su = somSelf->CreateSU(ev, kODNULL, kODStorageUnit);
SetStorageUnitType(ev, _fPermissions, su, kODStorageUnit);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
if (su != kODNULL) {
try
{
somSelf->ReleaseStorageUnit(ev, su->GetID(ev));
}
catch (ODException _exception)
{
SetErrorCode(kODNoError); // ignore exception
}
su = kODNULL;
}
RestoreEv();
ODSetSOMException(ev, error);
}
return su;
}
//------------------------------------------------------------------------------
// CMDraft: IsValidID
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftIsValidID(CMDraft *somSelf, Environment *ev,
ODID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","IsValidID");
ODBoolean isValidID = kODFalse;
try
{
if ( id != kODNULLID )
isValidID = _fIDList->Exists(id);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return isValidID;
}
//------------------------------------------------------------------------------
// CMDraft: AcquireStorageUnit
//------------------------------------------------------------------------------
SOM_Scope ODStorageUnit* SOMLINK CMDraftAcquireStorageUnit(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquireStorageUnit");
ODStorageUnit* su = kODNULL;
try
{
if (id == kODNULLID)
THROW(kODErrIllegalNullIDInput);
if (_fStorageUnits->GetValue(&id, &su)) {
su->Acquire(ev);
}
else if ((_fIDList->Exists(id) == kODFalse) ||
(_fIDList->Get(id) != kODNULL)) {
su = somSelf->CreateSU(ev, id, kODStorageUnit);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return su;
}
//------------------------------------------------------------------------------
// CMDraft: RemoveStorageUnit
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemoveStorageUnit(CMDraft *somSelf, Environment *ev,
ODStorageUnit* su)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemoveStorageUnit");
try
{
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
ODID id;
CMObject object;
ODStorageUnit* draftProperties;
somSelf->FailIfNotExclusiveWrite(ev);
if (!su)
THROW(kODErrIllegalNullStorageUnitInput);
draftProperties = somSelf->AcquireDraftProperties(ev);
if (su == draftProperties) {
draftProperties->Release(ev);
THROW(kODErrIllegalOperationOnSU);
}
else
draftProperties->Release(ev);
// Get Storage Unit ID
id = su->GetID(ev);
if (id == kODNULL)
THROW(kODErrInvalidStorageUnit);
// Release the storage unit
su->Release(ev);
// Remove Storage Unit from outstanding SU collection
_fStorageUnits->RemoveEntry(&id);
// Get and delete the CMObject associated with su.
object = (CMObject) _fIDList->Get(id);
// Remove the entry in the ID-object collection.
_fIDList->Remove(id);
// Delete the object
if (object != kODNULL)
CMDeleteObject(object);
// Destroy su
delete su;
// Mark this draft dirty
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
ODSessionRestoreCMAllocReserve(cmContainer);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: ChangedFromPrev
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftChangedFromPrev(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ChangedFromPrev");
ODBoolean changedFromPrev = kODFalse;
try
{
VersionList* versionList = kODNULL;
versionList = _fDocument->TestAndGetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
try
{
changedFromPrev = somSelf->IsChangedFromPrev(ev, versionList);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
_fDocument->ReleaseVersionList(ev);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
_fDocument->ReleaseVersionList(ev);
}
catch (ODException _exception)
{
changedFromPrev = kODFalse;
ODSetSOMException(ev, _exception);
}
return changedFromPrev;
}
//------------------------------------------------------------------------------
// CMDraft: SetChangedFromPrev
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftSetChangedFromPrev(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","SetChangedFromPrev");
try
{
#ifdef _PLATFORM_WIN32_
DocumentManager *docMgr = NULL;
OleWrapper *wrapper = NULL;
docMgr = ODOLEManager::GetShell()->GetActiveDocumentManager(ev);
if (docMgr) {
wrapper = docMgr->GetOleWrapper(ev);
if (wrapper)
wrapper->OnDataChange();
}
#endif
somSelf->FailIfNotExclusiveWrite(ev);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: RemoveFromDocument
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemoveFromDocument(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemoveFromDocument");
try
{
_fDocument->CollapseDrafts(ev, somSelf, kODNULL);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: RemoveChanges
//------------------------------------------------------------------------------
SOM_Scope ODDraft* SOMLINK CMDraftRemoveChanges(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemoveChanges");
try
{
VersionList* versionList = kODNULL;
somSelf->FailIfNotExclusiveWrite(ev);
if (_fDraftProperties != kODNULL) {
_fDraftProperties->Release(ev);
_fDraftProperties = kODNULL;
}
// WASSERTM((somSelf->AreEmptyCollections(ev) != kODFalse), "OutstandingObjects in CMDraft: RemoveChanges.");
somSelf->DestroyVersion(ev);
versionList = _fDocument->TestAndGetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
#ifdef ODDebug_VersionList
_fDocument->GetVersionList(ev)->Print(">>> Entering RemoveChanges");
#endif
try
{
if (versionList->Exists(_fID) != kODFalse)
versionList->RemoveChanges(_fID);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
_fDocument->ReleaseVersionList(ev);
}
catch (ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
#if !TestFlushContainer
_fDocument->ExternalizeVersionList(ev, kODFalse);
#endif
_fDocument->ReleaseVersionList(ev);
somSelf->Open(ev);
somSelf->SetChangedFromPrevFlag(ev, kODFalse);
#ifdef ODDebug_VersionList
_fDocument->GetVersionList(ev)->Print(">>> Exiting RemoveChanges");
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return somSelf;
}
//------------------------------------------------------------------------------
// CMDraft: Externalize
//------------------------------------------------------------------------------
SOM_Scope ODDraft* SOMLINK CMDraftExternalize(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Externalize");
try
{
#ifdef _PLATFORM_OS2_ // $$$$ dcp # 120702 05/23/95
if ( _fPermissions == kODDPReadOnly ) THROW(kODErrInvalidPermissions);
// check to see if linking is on or off (131199)
ODSession* session = (ODSession*) _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
char flag = session->GetLinkONOFFflag(ev);
if(flag)
{
// Call LinkService's externalize method so that
// tables not yet stored to DraftProperties can be saved
if (_fPermissions == kODDPExclusiveWrite) _fLinkService->DraftSaving(ev, somSelf);
}
#endif
somSelf->ExternalizeCollections(ev);
_fExternalized = kODTrue;
// DO THE ACTUAL EXTERNALIZATION HERE
somSelf->FlushVersion(ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return somSelf;
}
//------------------------------------------------------------------------------
// CMDraft: SaveToAPrevious
//------------------------------------------------------------------------------
SOM_Scope ODDraft* SOMLINK CMDraftSaveToAPrevious(CMDraft *somSelf, Environment *ev,
ODDraft* to)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","SaveToAPrevious");
try
{
_fDocument->SaveToAPrevDraft(ev, somSelf, to);
}
catch( ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return somSelf;
}
//------------------------------------------------------------------------------
// CMDraft: CreateFrame
//------------------------------------------------------------------------------
SOM_Scope ODFrame* SOMLINK CMDraftCreateFrame(CMDraft *somSelf, Environment *ev,
ODObjectType frameType,
ODFrame* containingFrame,
ODShape* frameShape,
ODCanvas* biasCanvas,
ODPart* part,
ODTypeToken viewType,
ODTypeToken presentation,
ODBoolean isSubframe,
ODBoolean isOverlaid)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateFrame");
ODStorageUnit* su = kODNULL;
ODFrame* frame = kODNULL;
ODStorageUnitID id = kODNULLID;
ODVolatile(su);
ODVolatile(frame);
ODVolatile(id);
try
{
if (ODISOStrEqual(frameType, kODFrameObject) != kODFalse)
somSelf->FailIfNotExclusiveWrite(ev);
frame = new ODFrame();
if (frame == kODNULL)
THROW(kODErrCannotCreateFrame);
if (ODISOStrEqual(frameType, kODFrameObject) != kODFalse) {
su = somSelf->CreateSU(ev, kODNULL, kODFrameObject);
SetStorageUnitType(ev, _fPermissions, su, kODFrameObject);
id = su->GetID(ev);
_fPersistentObjects->ReplaceEntry(&id, &frame);
frame->InitFrame(ev, su, containingFrame, frameShape, biasCanvas, part,
viewType, presentation, isSubframe, isOverlaid);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
}
else if (ODISOStrEqual(frameType, kODNonPersistentFrameObject) != kODFalse) {
id = _fIDList->Add(kODNULL);
_fPersistentObjects->ReplaceEntry(&id, &frame);
frame->InitFrameNonPersistent(ev, somSelf, id, containingFrame, frameShape,
biasCanvas, part, viewType, presentation, isSubframe, isOverlaid);
}
else
THROW(kODErrInvalidObjectType);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
if (frame != kODNULL) {
try{
if (id != kODNULLID)
{
if (su == kODNULL)
{
// This is just for non-persistent frame.
// Every other real persistent object should use RemovePersistentObject.
ODReleaseObject(ev, frame);
_fPersistentObjects->RemoveEntry(&id);
}
else
somSelf->RemovePersistentObject(ev, frame);
}
else {
delete frame;
if (su != kODNULL)
somSelf->RemoveStorageUnit(ev, su);
}
}catch (ODException _exception){
SetErrorCode(kODNoError); // ignore exception
}
frame = kODNULL;
}
RestoreEv();
ODSetSOMException(ev, error);
}
return frame;
}
//------------------------------------------------------------------------------
// CMDraft: AcquireFrame
//------------------------------------------------------------------------------
SOM_Scope ODFrame* SOMLINK CMDraftAcquireFrame(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquireFrame");
ODStorageUnit* su = kODNULL; ODVolatile(su);
ODFrame* frame = kODNULL; ODVolatile(frame);
try
{
if (id == kODNULLID)
THROW(kODErrIllegalNullIDInput);
frame = (ODFrame*) somSelf->RetrievePersistentObject(ev, id);
if (frame == kODNULL) {
su = somSelf->AcquireStorageUnit(ev, id);
frame = new ODFrame();
if (frame == kODNULL)
THROW(kODErrCannotAcquireFrame);
// A better way to do this is to let ODFrame::InitFrameFromStorage or
// ODPersistentObject::InitPersistentObjectFromStorage to increment the
// refcount. In that way, we can always release su here (or even better
// make su into a temp obj. - VL
_fPersistentObjects->ReplaceEntry(&id, &frame);
frame->InitFrameFromStorage(ev, su);
ODStorageUnit *su2 = su;
su = kODNULL; // frame owns reference now
SetStorageUnitType(ev, _fPermissions, su2, kODFrameObject);
}
}
catch(ODException _exception)
{
ODError error = ErrorCode();
if( frame ) WASSERT(frame->GetRefCount(ev)==1);
SaveAndRestoreEv1(frame);
ODSetSOMException(ev, error);
}
return frame;
}
//------------------------------------------------------------------------------
// CMDraft: ReleaseFrame
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReleaseFrame(CMDraft *somSelf, Environment *ev,
ODFrame* frame)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleaseFrame");
try
{
somSelf->ReleasePersistentObject(ev, frame);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: RemoveFrame
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemoveFrame(CMDraft *somSelf, Environment *ev,
ODFrame* frame)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemoveFrame");
try
{
somSelf->FailIfNotExclusiveWrite(ev);
if (!frame)
THROW(kODErrIllegalNullFrameInput);
if (frame->GetStorageUnit(ev) == kODNULL)
frame->Release(ev);
else
somSelf->RemovePersistentObject(ev, frame);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: ConstructRealPart
//------------------------------------------------------------------------------
SOM_Scope ODPart* SOMLINK CMDraftConstructRealPart(CMDraft *somSelf, Environment *ev,
ODStorageUnit* su, ODBoolean isInitPartFromStorage,
ODPartWrapper* partWrapper,
ODType partType, ODEditor theEditor)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ConstructRealPart");
ODPart* part = kODNULL; ODVolatile(part);
ODEditor editorForPart = kODNULL;
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
SOMClass* partClass;
somId partsSomId;
#endif // _PLATFORM_WIN32_ || _PLATFORM_OS2_ || _PLATFORM_AIX_
try
{
ODSession* session = (ODSession*) _fDocument->
GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
ODBinding* binding = session->GetBinding(ev);
if (theEditor == kODNULL)
editorForPart = binding->
ChooseEditorForPart(ev, su, partType);
else
{
editorForPart = theEditor;
if (_fPermissions != kODDPReadOnly)
ODSetISOStrProp(ev, su, kODPropPreferredEditor,
kODEditor, editorForPart);
}
#ifdef _PLATFORM_MACINTOSH_
if (ODISOStrEqual(editorForPart,
kODBlackBoxHandlerOfLastResort))
part = binding->ConstructNoPart(ev);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
if ( (ODISOStrEqual(editorForPart, "NoPart")) ||
(ODISOStrEqual(editorForPart, "")) )
part = new NoPart;
#endif // _PLATFORM_WIN32_ || _PLATFORM_OS2_ || _PLATFORM_AIX_
else
#ifdef _PLATFORM_MACINTOSH_
part = (ODPart*) ODNewObject(editorForPart);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
{
partsSomId = somIdFromString((string)editorForPart);
partClass = SOMClassMgrObject->somFindClass(partsSomId, 0, 0);
if (!partClass) {
WARNMSG_DEBUG(WARN_INDEX(-1),
"The Part Handler %s failed to load!",
editorForPart);
part = new NoPart;
}
else {
part = (ODPart *)partClass->somNew();
}
}
#endif // _PLATFORM_WIN32_ || _PLATFORM_OS2_ || _PLATFORM_AIX_
if (part == kODNULL)
THROW(kODErrCannotCreatePart);
partWrapper->SetRealPart(ev, part, editorForPart);
ODID id = su->GetID(ev);
_fPersistentObjects->ReplaceEntry(&id, &partWrapper);
su->Acquire(ev); //This new reference belongs to the part
if (isInitPartFromStorage)
partWrapper->InitPartFromStorage(ev, su, partWrapper);
else
partWrapper->InitPart(ev, su, partWrapper);
if (ODISOStrEqual(editorForPart,
kODBlackBoxHandlerOfLastResort) == kODFalse)
somSelf->PartInstantiated(ev, part);
}
catch (ODException _exception)
{
part = kODNULL;
// Map to more specific error
if( ErrorCode() == kODErrCantLoadSOMClass )
SetErrorCode(kODErrCannotCreatePart);
ODSetSOMException(ev, _exception);
}
#ifdef _PLATFORM_MACINTOSH_
if (editorForPart != theEditor)
ODDisposePtr(editorForPart);
#endif // _PLATFORM_MACINTOSH_
return part;
}
//------------------------------------------------------------------------------
// CMDraft: ReleaseRealPart
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReleaseRealPart(CMDraft *somSelf, Environment *ev,
ODPart* realPart)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleaseRealPart");
try
{
if (realPart == kODNULL)
THROW(kODErrIllegalNullPartInput);
if (realPart->GetRefCount(ev) != 0)
THROW(kODErrRefCountGreaterThanZero);
realPart->ReleaseAll(ev);
somSelf->PartDeleted(ev, realPart);
delete realPart;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: DeleteRealPart
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftDeleteRealPart(CMDraft *somSelf, Environment *ev,
ODPart* realPart)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","DeleteRealPart");
try
{
if (realPart == kODNULL)
THROW(kODErrIllegalNullPartInput);
somSelf->PartDeleted(ev, realPart);
delete realPart;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CreatePart
//------------------------------------------------------------------------------
SOM_Scope ODPart* SOMLINK CMDraftCreatePart(CMDraft *somSelf, Environment *ev,
ODType partType, ODEditor optionalEditor)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreatePart");
ODPartWrapper* partWrapper = kODNULL;
ODVolatile(partWrapper);
try
{
somSelf->FailIfNotExclusiveWrite(ev);
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = somSelf->CreateSU(ev, kODNULL, kODPartObject);
#else
TempODStorageUnit su = somSelf->CreateSU(ev, kODNULL, kODPartObject);
#endif
SetStorageUnitType(ev, _fPermissions, su, kODPartObject);
if ( partType != kODNULL )
{
ODSetISOStrProp(ev, su, kODPropPreferredKind, kODISOStr, partType);
}
partWrapper = new ODPartWrapper;
THROW_IF_NULL(partWrapper, kODErrOutOfMemory);
partWrapper->InitPartWrapper(ev);
somSelf->ConstructRealPart(ev, su, kODFalse, partWrapper, partType, optionalEditor);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
#ifdef _NO_TMP_OBJS_
su->Release(ev);
#endif
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveAndRestoreEv1(partWrapper);
partWrapper = kODNULL;
ODSetSOMException(ev, error );
}
return partWrapper;
}
//------------------------------------------------------------------------------
// CMDraft: AcquirePart
//------------------------------------------------------------------------------
SOM_Scope ODPart* SOMLINK CMDraftAcquirePart(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquirePart");
ODPart* part = kODNULL;
ODPartWrapper* partWrapper = kODNULL;
ODVolatile(partWrapper);
try
{
if (id == kODNULLID)
THROW(kODErrIllegalNullIDInput);
part = (ODPart*) somSelf->RetrievePersistentObject(ev, id);
if (part == kODNULL) {
ODStorageUnit* su = kODNULL;
if (_fStorageUnits->GetValue(&id, &su) != kODFalse)
su->Acquire(ev);
else
su = somSelf->CreateSU(ev, id, kODPartObject);
#ifdef _NO_TMP_OBJS_
ODStorageUnit *tempSU = su; // ensure it's released
#else
TempODStorageUnit tempSU = su; // ensure it's released
#endif
partWrapper = new ODPartWrapper;
THROW_IF_NULL(partWrapper, kODErrOutOfMemory);
partWrapper->InitPartWrapper(ev);
somSelf->ConstructRealPart(ev, su, kODTrue, partWrapper, kODNULL, kODNULL);
part = partWrapper;
SetStorageUnitType(ev, _fPermissions, su, kODPartObject);
#ifdef _NO_TMP_OBJS_
tempSU->Release(ev);
#endif
}
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveAndRestoreEv1(partWrapper);
part = kODNULL;
ODSetSOMException(ev, error);
}
return part;
}
//------------------------------------------------------------------------------
// CMDraft: ReleasePart
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReleasePart(CMDraft *somSelf, Environment *ev,
ODPart* part)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleasePart");
try
{
somSelf->ReleasePersistentObject(ev, part);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: RemovePart
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemovePart(CMDraft *somSelf, Environment *ev,
ODPart* part)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemovePart");
try
{
if (!part)
THROW(kODErrIllegalNullPartInput);
somSelf->RemovePersistentObject(ev, part);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CreateLinkSpec
//------------------------------------------------------------------------------
SOM_Scope ODLinkSpec* SOMLINK CMDraftCreateLinkSpec (CMDraft *somSelf, Environment *ev,
ODPart* part,
ODByteArray* data)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateLinkSpec");
ODLinkSpec* ls = kODNULL;
ODVolatile(ls);
#ifdef _PLATFORM_OS2_
try
{
ls = new ODLinkSpec;
// check to see if linking is on or off (131199)
ODSession* session = (ODSession*) _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
char flag = session->GetLinkONOFFflag(ev);
if(flag)
{
if (_fLinkServiceXID == kODNULL)
{
session->StartServer(ev, (char*)kODNULL);
SOMDObject* objRef = SOMD_ServerObject->
somdRefFromSOMObj(ev, _fLinkService);
_fLinkServiceXID = SOMD_ORBObject->object_to_string(ev, objRef);
}
//XXXXX ls->InitLinkSpec(ev, _fLinkServiceXID, part->GetID(ev), data);
ls->InitLinkSpec(ev, _fLinkServiceXID, part, data);
}
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
ODDeleteObject(ls);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
}
#else
try
{
ls = new ODLinkSpec;
THROW_IF_NULL(ls, kODErrOutOfMemory);
// #ifdef _PLATFORM_OS2_
// ls->InitLinkSpec(ev, kODNULL /* 22470 */ , part, data);
// #endif
#if defined (_PLATFORM_WIN32_) || defined(_PLATFORM_AIX_)
ls->InitLinkSpec(ev, part, data);
#endif
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
ODDeleteObject(ls);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
}
#endif // _PLATFORM_OS2_
return ls;
}
//------------------------------------------------------------------------------
// CMDraft: CreateLinkSource
//------------------------------------------------------------------------------
SOM_Scope ODLinkSource* SOMLINK CMDraftCreateLinkSource(CMDraft *somSelf, Environment *ev,
ODPart* part)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateLinkSource");
#ifdef _PLATFORM_OS2_
IODLinkSource* linkSource = kODNULL;
try
{
char docName[256];
char hostName[256];
ODStorageUnitID id;
ODStorageUnit* su;
ODISOStr ASName;
if (part==kODNULL)
THROW(kODErrCannotCreateLink);
somSelf->FailIfNotExclusiveWrite(ev);
su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
// $$$$$ Links no longer depend on this property
// $$$$$ (but LinkSourceIterator does!)
su->AddProperty(ev, kODPropStorageUnitType);
su->AddValue(ev, kODISOStr);
StorageUnitSetValue(su,
ev,
ODISOStrLength(kODLinkSource)+1,
(ODValue)kODLinkSource);
linkSource = new IODLinkSource();
if (linkSource == kODNULL)
{
delete su;
THROW(kODErrCannotCreateLink);
}
id = su->GetID(ev);
_fPersistentObjects->ReplaceEntry(&id, &linkSource);
if(getenv("HOSTNAME") == NULL) //@SK [123273]
{ //@SK [123273]
#ifdef ODDebug
somPrintf("\nError: Incomplete DSOM environment setup: Missing HOSTNAME\n");//@SK [123273]
#endif
DosExit(EXIT_PROCESS, 1); //@SK [123273]
}
else
{
linkSource->InitILinkSource(ev,
su,
part,
getenv("HOSTNAME"),
_fLinkService->GetDocName(ev));
ODLinkID linkID =
_fLinkService->RegisterLinkSource(ev, somSelf, id, linkSource, part, &ASName);
linkSource->CompleteInitILinkSource(ev, su, linkID, (IODAuxiliaryState*)kODNULL, kODFalse, ASName);
ODDisposePtr(ASName);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
return (ODLinkSource*)linkSource;
}
}
catch (ODException _exception)
{
linkSource = kODNULL;
ODSetSOMException(ev, _exception);
}
return (ODLinkSource*)linkSource;
#else
ODLinkSource* linkSource = kODNULL;
try
{
ODStorageUnitID id;
somSelf->FailIfNotExclusiveWrite(ev);
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
#else
TempODStorageUnit su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
#endif
// The implementation of CMLinkSourceIterator depends on this property being present
// in link source storage units and nowhere else.
SetStorageUnitType(ev, _fPermissions, su, kODLinkSource);
linkSource = new ODLinkSource();
THROW_IF_NULL(linkSource,kODErrCannotCreateLink);
#ifdef _NO_TMP_OBJS_
ODLink *link = kODNULL;
#else
TempODLink link = kODNULL;
#endif
try
{
link = somSelf->CreateLink(ev);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
linkSource->ReleaseAll(ev);
ODDeleteObject(linkSource);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
id = su->GetID(ev);
_fPersistentObjects->ReplaceEntry(&id, &linkSource);
#ifdef _NO_TMP_OBJS_
linkSource->InitLinkSource(ev, su, part);
#else
linkSource->InitLinkSource(ev, su.DontRelease(), part);
#endif
// ("DontDelete" prevents su from being auto-released by destructor)
link->SetLinkSource(ev, linkSource);
linkSource->SetLink(ev, link);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
#ifdef _NO_TMP_OBJS_
su->Release(ev);
link->Release(ev);
#endif
}
catch (ODException _exception)
{
linkSource = kODNULL;
ODSetSOMException(ev, _exception);
}
return linkSource;
#endif // _PLATFORM_OS2_
}
//------------------------------------------------------------------------------
// CMDraft: AcquireLinkSource
//------------------------------------------------------------------------------
SOM_Scope ODLinkSource* SOMLINK CMDraftAcquireLinkSource(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquireLinkSource");
#ifdef _PLATFORM_OS2_
// If the id already corresponds to a live linkSource, use it.
// If not, create a new one.
// Update the cache so that next time this new linkSource will be found.
// Get the SU.
// If this is a read-only draft, create the linkSource with a null auxState
// Otherwise, call LinkService::OpenLinkSource to get auxState/lock
// and use this to internalize the linksource.
IODLinkSource* linkSource = (IODLinkSource*)kODNULL;
try
{
if (id == kODNULLID)
THROW(kODErrIllegalNullIDInput);
linkSource = ((IODLinkSource*)somSelf->RetrievePersistentObject(ev, id));
if (linkSource == (IODLinkSource*)kODNULL)
{
linkSource = new IODLinkSource();
if (linkSource == (IODLinkSource*)kODNULL)
{
THROW(kODErrCannotAcquireLink);
}
ODStorageUnit* su = (ODStorageUnit*)kODNULL;
ODVolatile(su);
ODVolatile(id);
try
{
su = somSelf->AcquireStorageUnit(ev, id);
_fPersistentObjects->ReplaceEntry(&id, &linkSource);
if (_fPermissions != kODDPExclusiveWrite)
{
ODLinkID linkid = linkSource->InitILinkSourceFromStorage(ev, su);
linkSource->CompleteInitILinkSource(ev, su, linkid, kODNULL, kODFalse, "");
}
else
{
IODAuxiliaryState* auxState;
ODBoolean isLocked;
ODISOStr ASName;
ODLinkID originalLinkID = linkSource->InitILinkSourceFromStorage(ev, su);
ODLinkID finalLinkID = _fLinkService->OpenLinkSource(ev,
somSelf,
linkSource->GetID(ev),
linkSource,
originalLinkID,
&auxState,
&isLocked,
&ASName);
linkSource->CompleteInitILinkSource(ev,
su,
finalLinkID,
auxState,
isLocked,
ASName);
if (auxState != kODNULL)
{
SOMFree(auxState->remoteLinkInfos._buffer);
SOMFree(auxState);
}
ODDisposePtr(ASName);
}
}
catch (ODException _exception)
{
SaveEv();
try
{
if (su != (ODStorageUnit*) kODNULL)
{
_fPersistentObjects->RemoveEntry(&id);
su->Release(ev);
}
linkSource->ReleaseAll(ev);
delete linkSource;
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
ODError error = ErrorCode();
ODSetSOMException(ev, error);
throw;
}
}
}
catch (ODException _exception)
{
linkSource = kODNULL;
ODSetSOMException(ev, _exception);
}
return (ODLinkSource*)linkSource;
#else
ODLinkSource* linkSource = (ODLinkSource*) kODNULL;
try
{
if (id == kODNULLID)
THROW(kODErrIllegalNullIDInput);
linkSource = ((ODLinkSource*) somSelf->RetrievePersistentObject(ev, id));
if (linkSource == (ODLinkSource*) kODNULL) {
linkSource = new ODLinkSource();
if (linkSource == (ODLinkSource*) kODNULL)
THROW(kODErrCannotAcquireLink);
ODStorageUnit* su = (ODStorageUnit*) kODNULL;
ODVolatile(su);
ODVolatile(id);
try
{
su = somSelf->AcquireStorageUnit(ev, id);
_fPersistentObjects->ReplaceEntry(&id, &linkSource);
linkSource->InitLinkSourceFromStorage(ev, su);
SetStorageUnitType(ev, _fPermissions, su, kODLinkSource);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
if (su != (ODStorageUnit*) kODNULL) {
_fPersistentObjects->RemoveEntry(&id);
su->Release(ev);
}
linkSource->ReleaseAll(ev);
delete linkSource;
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv()
ODSetSOMException(ev, error);
throw;
}
}
}
catch (ODException _exception)
{
linkSource = kODNULL;
ODSetSOMException(ev, _exception);
}
return linkSource;
#endif // _PLATFORM_OS2_
}
//------------------------------------------------------------------------------
// CMDraft: RemoveLinkSource
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemoveLinkSource(CMDraft *somSelf, Environment *ev,
ODLinkSource* linkSource)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemoveLinkSource");
try
{
somSelf->FailIfNotExclusiveWrite(ev);
somSelf->RemovePersistentObject(ev, linkSource);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CreateLink
//------------------------------------------------------------------------------
SOM_Scope ODLink* SOMLINK CMDraftCreateLink(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateLink");
#ifdef _PLATFORM_OS2_
IODLinkTarget* link = kODNULL;
try
{
ODStorageUnitID id;
ODStorageUnit* su;
su = somSelf->CreateSU(ev, kODNULL, kODLink);
// $$$$$ Links no longer depend on this property
// $$$$$ (but LinkSourceIterator does!)
su->AddProperty(ev, kODPropStorageUnitType);
su->AddValue(ev, kODISOStr);
StorageUnitSetValue(su,
ev,
ODISOStrLength(kODLink)+1,
(ODValue)kODLink);
link = new IODLinkTarget();
if (link == kODNULL)
{
delete su;
THROW(kODErrCannotCreateLink);
}
id = su->GetID(ev);
_fPersistentObjects->ReplaceEntry(&id, &link);
link->InitLinkTarget(ev, su, _fLinkService->GetDocName(ev));
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
}
catch (ODException _exception)
{
link = kODNULL;
ODSetSOMException(ev, _exception);
}
return (ODLink*)link;
#else
ODLink* link = kODNULL;
try
{
ODStorageUnitID id;
ODStorageUnit* su;
su = somSelf->CreateSU(ev, kODNULL, kODLink);
// The implementation of CMLinkIterator depends on this property being present
// in link storage units and nowhere else.
SetStorageUnitType(ev, _fPermissions, su, kODLink);
link = new ODLink();
if (link == kODNULL)
{
delete su;
THROW(kODErrCannotCreateLink);
}
id = su->GetID(ev);
_fPersistentObjects->ReplaceEntry(&id, &link);
link->InitLink(ev, su);
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
}
catch (ODException _exception)
{
link = kODNULL;
ODSetSOMException(ev, _exception);
}
return link;
#endif // _PLATFORM_OS2_
}
//------------------------------------------------------------------------------
// CMDraft: AcquireLink
//------------------------------------------------------------------------------
SOM_Scope ODLink* SOMLINK CMDraftAcquireLink(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id,ODLinkSpec* linkSpec)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquireLink");
#ifdef _PLATFORM_OS2_
IODLinkTarget* link = (IODLinkTarget*)kODNULL;
#else
ODLink* link = (ODLink*) kODNULL;
#endif
try
{
#ifdef _PLATFORM_OS2_
if (id != (ODStorageUnitID)kODNULL)
{
ODPersistentObject* object;
object = somSelf->RetrievePersistentObject(ev, id);
if (IsLinkObject(ev, somSelf, id))
{
link = (IODLinkTarget*)object;
}
else
{
THROW(kODErrInvalidID);
}
if (link == (IODLinkTarget*)kODNULL)
{
link = new IODLinkTarget();
if (link == (IODLinkTarget*)kODNULL)
{
THROW(kODErrCannotAcquireLink);
}
ODStorageUnit* su = (ODStorageUnit*)kODNULL;
ODVolatile(su);
ODVolatile(id);
try
{
su = somSelf->AcquireStorageUnit(ev, id);
_fPersistentObjects->ReplaceEntry(&id, &link);
link->InitLinkTargetFromStorage(ev, su, _fLinkService->GetDocName(ev));
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
if (su != (ODStorageUnit*) kODNULL)
{
_fPersistentObjects->RemoveEntry(&id);
su->Release(ev);
}
link->ReleaseAll(ev);
delete link;
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
}
}
else if (linkSpec == (ODLinkSpec*)kODNULL)
{
THROW(kODErrInvalidID);
}
else
{
link = (IODLinkTarget*)somSelf->CreateLink(ev);
link->EstablishLink(ev, linkSpec, _fLinkService);
};
#else
if (id != (ODStorageUnitID) kODNULL) {
link = ((ODLink*) somSelf->RetrievePersistentObject(ev, id));
if (link == (ODLink*) kODNULL) {
link = new ODLink();
if (link == kODNULL)
THROW(kODErrCannotAcquireLink);
ODStorageUnit* su = (ODStorageUnit*) kODNULL;
ODVolatile(su);
ODVolatile(id);
try
{
su = somSelf->AcquireStorageUnit(ev, id);
_fPersistentObjects->ReplaceEntry(&id, &link);
link->InitLinkFromStorage(ev, su);
SetStorageUnitType(ev, _fPermissions, su, kODLink);
}
catch(ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
if (su != (ODStorageUnit*) kODNULL) {
_fPersistentObjects->RemoveEntry(&id);
su->Release(ev);
}
link->ReleaseAll(ev);
delete link;
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
}
}
else if (linkSpec == (ODLinkSpec*) kODNULL) {
THROW(kODErrInsufficientInfoInParams);
}
else if (linkSpec->FromThisDraft(ev)) {
ODPart* part = linkSpec->GetPart(ev);
ODByteArray partData = linkSpec->GetPartData(ev);
ODVolatile(partData);
ODLinkSource* linkSource = kODNULL;
ODVolatile(linkSource);
try
{
linkSource = part->CreateLink(ev, &partData);
if ( linkSource != (ODLinkSource*) kODNULL ) {
link = linkSource->GetLink(ev);
if ( link != (ODLink*) kODNULL )
link->Acquire(ev);
}
}
catch (ODException _exception)
{
ODError error = ErrorCode();
DisposeByteArrayStruct(partData);
SaveAndRestoreEv1(linkSource);
ODSetSOMException(ev, error);
throw;
}
DisposeByteArrayStruct(partData);
ODReleaseObject(ev, linkSource);
}
else {
// This link spec originated in another document; forward the
// AcquireLink call to the originating draft.
ODSession* session = _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
if (session != kODNULL) {
ODLinkSource* linkSource = kODNULL;
ODVolatile(linkSource);
try
{
linkSource = session->GetLinkManager(ev)->CreateLink(ev, somSelf, linkSpec);
if ( linkSource != (ODLinkSource*) kODNULL ) {
link = linkSource->GetLink(ev);
if ( link != (ODLink*) kODNULL )
link->Acquire(ev);
}
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveAndRestoreEv1(linkSource);
ODSetSOMException(ev, error);
throw;
}
ODReleaseObject(ev, linkSource);
}
}
#endif // _PLATFORM_OS2_
}
catch (ODException _exception)
{
link = kODNULL;
ODSetSOMException(ev, _exception);
}
return (ODLink*)link;
}
//------------------------------------------------------------------------------
// CMDraft: ReleaseLink
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReleaseLink(CMDraft *somSelf, Environment *ev,
ODLink* link)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleaseLink");
try
{
somSelf->ReleasePersistentObject(ev, link);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: ReleaseLinkSource
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReleaseLinkSource(CMDraft *somSelf, Environment *ev,
ODLinkSource* linkSource)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleaseLinkSource");
try
{
somSelf->ReleasePersistentObject(ev, linkSource);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: RemoveLink
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemoveLink(CMDraft *somSelf, Environment *ev,
ODLink* link)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemoveLink");
try
{
somSelf->FailIfNotExclusiveWrite(ev);
somSelf->RemovePersistentObject(ev, link);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: GetPersistentObjectID
//------------------------------------------------------------------------------
SOM_Scope ODPersistentObjectID SOMLINK CMDraftGetPersistentObjectID(CMDraft *somSelf, Environment *ev,
ODPersistentObject* object,
ODObjectType objectType)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetPersistentObjectID");
ODPersistentObjectID retID = kODNULLID;
try
{
ASSERT(ODISOStrEqual(objectType, kODPartObject) || ODISOStrEqual(objectType, kODFrameObject),
kODErrInvalidObjectType);
CMStorageUnit* su = (CMStorageUnit*) object->GetStorageUnit(ev);
if (su == kODNULL)
THROW(kODErrInvalidPersistentObject);
retID = su->GetObjectID(ev);
}
catch (ODException _exception)
{
ODSetSOMException (ev, _exception);
}
return retID;
}
//------------------------------------------------------------------------------
// CMDraft: AcquirePersistentObject
//------------------------------------------------------------------------------
SOM_Scope ODPersistentObject* SOMLINK CMDraftAcquirePersistentObject(CMDraft *somSelf, Environment *ev,
ODPersistentObjectID objectID,
ODObjectType* objectType)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AcquirePersistentObject");
ODPersistentObject* object = kODNULL;
try
{
*objectType = kODNULL;
ODStorageUnitID id = kODNULLID;
if (objectID == 0)
THROW(kODErrIllegalNullIDInput);
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
CMObject cmObject = CMGetObject(cmContainer, objectID);
if (cmObject == kODNULL)
THROW(kODErrInvalidPersistentObjectID);
if (_fIDList->ObjectExists(cmObject) != kODFalse) {
id = _fIDList->GetID(cmObject);
CMReleaseObject(cmObject);
}
else
id = _fIDList->Add(cmObject);
ODSessionRestoreCMAllocReserve(cmContainer);
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = somSelf->AcquireStorageUnit(ev, id);
#else
TempODStorageUnit su = somSelf->AcquireStorageUnit(ev, id);
#endif
ODPtr buffer;
if ((buffer = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL)) != kODNULL)
{
if (ODISOStrEqual((ODISOStr) buffer, kODPartObject) != kODFalse)
object = somSelf->AcquirePart(ev, id);
else if (ODISOStrEqual((ODISOStr) buffer, kODFrameObject) != kODFalse)
object = somSelf->AcquireFrame(ev, id);
else
THROW(kODErrInvalidPersistentObjectID);
if (object != kODNULL)
*objectType = (ODType) buffer;
else
ODDisposePtr(buffer);
}
#ifdef _NO_TMP_OBJS_
su->Release(ev);
#endif
}
catch (ODException _exception)
{
object = kODNULL;
ODSetSOMException(ev, _exception);
}
return object;
}
//------------------------------------------------------------------------------
// CMDraft: ReleaseStorageUnit
//------------------------------------------------------------------------------
SOM_Scope ODDraft* SOMLINK CMDraftReleaseStorageUnit(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleaseStorageUnit");
try
{
ODStorageUnit* su = kODNULL;
if (! _fStorageUnits->GetValue(&id, &su))
THROW(kODErrInvalidStorageUnit);
if (su->GetRefCount(ev) != 0)
THROW(kODErrRefCountGreaterThanZero);
if (_fDraftProperties != kODNULL) {
if (id == _fDraftProperties->GetID(ev))
_fDraftProperties = kODNULL;
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return somSelf;
}
//------------------------------------------------------------------------------
// CMDraft: ~CMDraft
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftsomUninit(CMDraft *somSelf)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","somUninit");
Environment* ev = somGetGlobalEnvironment();
try
{
#if ODDebug_DebugRefCount
if (somSelf->GetRefCount(ev) != 0)
DebugStr("\pRefCount of Draft is not 0 at uninit.");
somPrintf("~CMDraft %x RefCount %d EmbeddedCtr %x CMCtr %x\n",
somSelf,
somSelf->GetRefCount(ev),
somSelf->GetEmbeddedContainer(ev),
somSelf->GetCMContainer(ev));
#endif
#ifdef _PLATFORM_OS2_
//XXXXX Added to force LinkTarget to unregister
if (_fPermissions == kODDPExclusiveWrite)
//XXXXX
somSelf->DeleteCollections(ev);
parent_somUninit(somSelf);
#else
delete _fPartClasses;
// Set to NULL so that PartDeleted method is not going
// to try to access _fPartClasses.
_fPartClasses = kODNULL;
somSelf->DeleteCollections(ev);
#endif
/*
#ifdef _PLATFORM_OS2_
if (_fLinkService != kODNULL)
(
delete _fLinkService;
delete _fLinkServiceXID;
}
#endif
*/
}
catch (ODException _exception)
{
SetErrorCode(kODNoError); // Ignore exception
}
}
//------------------------------------------------------------------------------
// CMDraft: InitDraft
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftInitDraft(CMDraft *somSelf, Environment *ev,
ODDocument* document, ODDraftID id, ODDraftPermissions perms)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","InitDraft");
try
{
/* Moved from somInit. SOM itself sets fields to zero
_fChangedFromPrev = kODFalse;
_fDocument = kODNULL;
_fID = 0;
_fPermissions = kODDPNone;
_fEmbeddedContainer = kODNULL;
_fVersionID = kODTombstonedVersion;
_fIsNewDraft = kODFalse;
_fExternalized = kODFalse;
_fRemoveChangeOnAbort = kODFalse;
_fStorageUnits = kODNULL;
_fPersistentObjects = kODNULL;
_fIDList = kODNULL;
_fDraftProperties = kODNULL;
_fDestDraft = kODNULL;
_fDestFrame = kODNULL;
_fClonedSUIDs = kODNULL;
_fWeakClonedSUIDs = kODNULL;
_fSavedWeakClonedSUIDs = kODNULL;
_fCurrentKey = kODNULL;
_fLockCount = 0;
_fAnyFrameCloned = kODFalse;
_fRootPartReused = kODFalse;
_fOrigTopVersionDraftID = 0;
_fHeap = kDefaultHeapID;
*/
_fVersionID = kODTombstonedVersion;
somSelf->InitRefCntObject(ev);
#ifdef ODDebug_VersionList
((CMDocument*) document)->GetVersionList(ev)->Print(">>>Entering InitDraft");
#endif
_fDocument = (CMDocument*) document;
_fID = id;
_fPermissions = perms;
VersionList* versionList = kODNULL;
if (_fDocument == kODNULL)
THROW(kODErrIllegalNullDocumentInput);
if (_fID == kODNULL) {
versionList = _fDocument->GetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
_fID = versionList->CreateDraft();
_fIsNewDraft = kODTrue;
_fRemoveChangeOnAbort = kODTrue;
#if !TestFlushContainer
_fDocument->ExternalizeVersionList(ev, kODFalse);
#endif
}
somSelf->CreateCollections(ev);
#if lazyOpen
_fExternalized = kODFalse;
#else
if (_fPermissions == kODDPReadOnly)
somSelf->OpenVersion(ev);
else
somSelf->CreateVersion(ev);
#endif
_fHeap = _fDocument->GetHeap(ev);
#ifdef _PLATFORM_OS2_
_fLinkService = _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev)->GetLinkService(ev);
#endif
#ifdef ODDebug_Unloading_Classes
SetOutputMode(kWriteToFile);
#endif
#ifdef _PLATFORM_MACINTOSH_
_fPartClasses = new(_fHeap)
OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, _fHeap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
_fPartClasses = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, 0);
#endif
_fPartClasses->Initialize(kODInitialNumEntries,
sizeof(SOMClass*),
sizeof(ODULong));
#ifdef ODDebug_VersionList
_fDocument->GetVersionList(ev)->Print(">>>Exiting InitDraft");
#endif
#ifdef _PLATFORM_WIN32_
DocumentManager *docMgr = NULL;
OleWrapper *wrapper = NULL;
docMgr = ODOLEManager::GetShell()->GetActiveDocumentManager(ev);
if (docMgr) {
wrapper = docMgr->GetOleWrapper(ev);
if (wrapper)
wrapper->OnDataChange();
}
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: Purge
//------------------------------------------------------------------------------
SOM_Scope ODSize SOMLINK CMDraftPurge(CMDraft *somSelf, Environment *ev,
ODSize size)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Purge");
ODULong runningTotal = 0;
try
{
OpenHashTableIterator i(_fPersistentObjects);
ODStorageUnitID id;
ODPersistentObject* object;
for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
runningTotal += object->Purge(ev, size);
if (object->GetRefCount(ev) == 0) {
object->ReleaseAll(ev);
}
}
for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
if (object->GetRefCount(ev) == 0) {
i.RemoveCurrent();
delete object;
}
}
_fPersistentObjects->ShrinkToFit(/*extraSlots*/ 0);
// purge all storage units, but don't release CMObjects
runningTotal += PurgeAllStorageUnits(ev, _fStorageUnits, kODNULL);
PurgeClasses(ev, _fPartClasses);
}
catch (ODException _exception)
{
runningTotal = 0;
ODSetSOMException(ev, _exception);
}
return runningTotal;
}
//------------------------------------------------------------------------------
// CMDraft: CreateSU
//------------------------------------------------------------------------------
SOM_Scope ODStorageUnit* SOMLINK CMDraftCreateSU(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id, ODType suType)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateSU");
ODStorageUnit* su = kODNULL;
try
{
CMObject object = kODNULL;
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
ODVolatile(su);
ODVolatile(object);
try
{
// Create CMObject if necessary
if (id == kODNULL) {
if ((object = CMNewObject(cmContainer)) == kODNULL)
THROW(kODErrBentoCannotNewObject);
id = _fIDList->Add(object);
}
// Create the Storage Unit
su = NewCMStorageUnit(somSelf->GetHeap(ev));
su->InitStorageUnit(ev, somSelf, id);
}
catch (ODException _exception)
{
if (object != kODNULL)
CMReleaseObject(object);
if (su != kODNULL)
delete su;
if (ErrorCode() == kODErrBentoInvalidObject)
THROW(kODErrInvalidID);
else
throw;
}
ODSessionRestoreCMAllocReserve(cmContainer);
// Add Storage Unit to outstanding SU collection
_fStorageUnits->ReplaceEntry(&id, &su);
}
catch (ODException _exception)
{
su = kODNULL;
ODSetSOMException(ev, _exception);
}
return su;
}
//------------------------------------------------------------------------------
// CMDraft: SetChangedFromPrevFlag
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftSetChangedFromPrevFlag(CMDraft *somSelf, Environment *ev,
ODBoolean changed)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","SetChangedFromPrevFlag");
if (changed != kODFalse){
try
{
somSelf->FailIfNotExclusiveWrite(ev);
}
catch(ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
_fChangedFromPrev = changed;
}
static void SetupForUpdatingDraft(Environment* ev,
CMDocument* localDoc,
ODVersionID prevVersionID,
CMValue version)
{
try
{
ODBentoContainer* localContainer = (ODBentoContainer*) localDoc->GetContainer(ev);
ODBentoContainer* container = kODNULL;
// check to see whether we need to do a update
container = localContainer->GetTargetContainer(ev);
if (container != kODNULL) {
// get the target document
CMDocument* targetDoc = localContainer->GetTargetDocument(ev);
// find its version list
VersionList* versionList = targetDoc->GetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
// get the latest draft
ODDraftID latestDraftID = versionList->GetLatestDraftID();
// get the version id of the latest draft
prevVersionID = versionList->GetDraft(latestDraftID);
}
else {
container = localContainer;
}
// Note: getting/setting refcon's does not allocate memory in Bento:
// get the name for indirection
ODType prevVersionName = GetVersionNameFromVersionID(prevVersionID, localDoc->GetHeap(ev));
// store name so that it can be passed to handler
CMSetValueRefCon(version, prevVersionName);
// get cmContainer so that we can assess CMSession
CMContainer cmContainer = container->GetCMContainer(ev);
// Save the outermost container for embedded container creation.
ODSessionRefCon* sessionRefCon = (ODSessionRefCon*) CMGetSessionRefCon(cmContainer);
sessionRefCon->container = container;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CreateVersion
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftCreateVersion(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateVersion");
try
{
CMContainer cmContainer = ((ODBentoContainer*) _fDocument->GetContainer(ev))->GetCMContainer(ev);
CMObject versionObject = kODNULL;
CMType versionNameType = kODNULL;
ODType versionName = kODNULL;
CMProperty versionNameProperty = kODNULL;
CMValue versionNameValue = kODNULL;
CMType versionDataType = kODNULL;
CMProperty versionDataProperty = kODNULL;
CMValue version = kODNULL;
VersionList* versionList = kODNULL;
versionList = _fDocument->GetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
_fOrigTopVersionDraftID = versionList->GetSameVersionDraftID(_fID);
_fPrevVersionID = versionList->GetCurrentVersion(_fID);
_fVersionID = versionList->CreateVersion(_fID);
ODSessionMustHaveCMAllocReserve(cmContainer);
versionObject = CMNewObject(cmContainer);
versionNameType = CMRegisterType(cmContainer, kODISOStr);
versionName = GetVersionNameFromVersionID(_fVersionID, somSelf->GetHeap(ev));
versionNameProperty = CMRegisterProperty(cmContainer, versionName);
versionNameValue = CMNewValue(versionObject, versionNameProperty, versionNameType);
CMWriteValueData(versionNameValue, "", 0, 1);
versionDataType = CMRegisterType(cmContainer, kODEmbeddedContainerType);
versionDataProperty = CMRegisterProperty(cmContainer, kODEmbeddedContainerProperty);
version = CMNewValue(versionObject, versionDataProperty, versionDataType);
if (version == kODNULL)
THROW(kODErrCannotCreateDraftVersion);
CMWriteValueData(version, "", 0, 0); /* Make the container manager happy */
ODSessionRestoreCMAllocReserve(cmContainer);
SetupForUpdatingDraft(ev, _fDocument, _fPrevVersionID, version);
#ifdef ODDebug_CMDraft
ODDocument* tempDoc = somSelf->GetDocument(ev);
somPrintf("CreateVersion: CMDocument %x DraftID %d IsNewDraft %d versionID %d prevVersionID %d\n", tempDoc, somSelf->GetID(ev), somSelf->IsNewDraft(ev), _fVersionID, _fPrevVersionID);
#endif
ODEmbeddedContainerID containerID;
containerID.cmValue = version;
containerID.shouldMerge = (somSelf->IsNewDraft(ev) ? kODFalse : kODTrue);
ODByteArray* ba = CreateByteArray(&containerID, sizeof(ODEmbeddedContainerID));
_fEmbeddedContainer = (ODEmbeddedContainer*)
_fDocument->GetContainer(ev)->GetStorageSystem(ev)->CreateContainer(ev, kODBentoEmbeddedContainer, ba);
DisposeByteArray(ba);
if (versionName != kODNULL)
ODDisposePtr(versionName);
_fExternalized = kODFalse;
#ifdef _PLATFORM_WIN32_
DocumentManager *docMgr = NULL;
OleWrapper *wrapper = NULL;
docMgr = ODOLEManager::GetShell()->GetActiveDocumentManager(ev);
if (docMgr) {
wrapper = docMgr->GetOleWrapper(ev);
if (wrapper)
wrapper->OnDataChange();
}
#endif
somSelf->OpenCollections(ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: OpenVersion
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftOpenVersion(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","OpenVersion");
try
{
CMContainer cmContainer = ((ODBentoContainer*) _fDocument->GetContainer(ev))->GetCMContainer(ev);
ODType versionName = kODNULL;
ODType oldVersionName = kODNULL;
CMType versionDataType;
CMProperty versionDataProperty;
CMProperty versionNameProperty;
CMObject versionObject;
CMValue version;
VersionList* versionList;
versionList = _fDocument->GetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
_fVersionID = versionList->GetCurrentVersion(_fID);
_fPrevVersionID = _fVersionID;
if (_fVersionID == kODTombstonedVersion)
THROW(kODErrDraftHasBeenDeleted);
if (_fPermissions == kODDPReadOnly) {
ODSessionMustHaveCMAllocReserve(cmContainer);
MyDebugStr("**** OpenVersion: kODDPReadOnly.\n");
versionDataType = CMRegisterType(cmContainer, kODEmbeddedContainerType);
versionDataProperty = CMRegisterProperty(cmContainer, kODEmbeddedContainerProperty);
versionName = GetVersionNameFromVersionID(_fVersionID, somSelf->GetHeap(ev));
versionNameProperty = CMRegisterProperty(cmContainer, versionName);
versionObject = CMGetNextObjectWithProperty(cmContainer, kODNULL, versionNameProperty);
version = CMUseValue(versionObject, versionDataProperty, versionDataType);
CMSetValueRefCon(version, kODNULL);
// Save the outermost container for embedded container creation.
ODSessionRefCon* sessionRefCon = (ODSessionRefCon*) CMGetSessionRefCon(cmContainer);
sessionRefCon->container = _fDocument->GetContainer(ev);
#ifdef ODDebug_CMDraft
ODDocument* tempDoc = somSelf->GetDocument(ev);
somPrintf("OpenVersion: CMDocument %x DraftID %d IsNewDraft %d versionID %d prevVersionID %d\n", tempDoc, somSelf->GetID(ev), somSelf->IsNewDraft(ev), _fVersionID, _fPrevVersionID);
#endif
ODEmbeddedContainerID containerID;
containerID.cmValue = version;
containerID.shouldMerge = kODFalse;
ODByteArray* ba = CreateByteArray(&containerID, sizeof(ODEmbeddedContainerID));
_fEmbeddedContainer = (ODEmbeddedContainer*)
_fDocument->GetContainer(ev)->GetStorageSystem(ev)->AcquireContainer(ev, kODBentoEmbeddedContainer, ba);
DisposeByteArray(ba);
if (versionName != kODNULL)
ODDisposePtr(versionName);
if (oldVersionName != kODNULL)
ODDisposePtr(oldVersionName);
ODSessionRestoreCMAllocReserve(cmContainer);
somSelf->OpenCollections(ev);
}
else
THROW(kODErrInvalidPermissions);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CloseVersion
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftCloseVersion(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CloseVersion");
try
{
#ifdef ODDebug_CMDraft
ODDocument* tempDoc = somSelf->GetDocument(ev);
somPrintf("CloseVersion: CMDocument %x DraftID %d versionID %d Permission %d\n", tempDoc, somSelf->GetID(ev), _fVersionID, _fPermissions);
#endif
if (_fPermissions == kODDPExclusiveWrite) {
VersionList* versionList = kODNULL;
versionList = _fDocument->TestAndGetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
if (versionList->IsBelow(_fOrigTopVersionDraftID, versionList->GetSameVersionDraftID(_fID)))
_fEmbeddedContainer->SetMergeFlag(ev, kODFalse);
somSelf->CloseCollections(ev);
}
else {
somSelf->DeleteCollections(ev);
somSelf->CreateCollections(ev);
}
if (_fEmbeddedContainer != kODNULL) {
_fEmbeddedContainer->Release(ev);
_fEmbeddedContainer = kODNULL;
}
_fIsNewDraft = kODFalse;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: DestroyVersion
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftDestroyVersion(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","DestroyVersion");
#ifdef ODDebug_CMDraft
ODDocument* tempDoc = somSelf->GetDocument(ev);
somPrintf("Destroy Version: CMDocument %x DraftID %d versionID %d Permission %d\n", tempDoc, somSelf->GetID(ev), _fVersionID, _fPermissions);
#endif
if (_fPermissions == kODDPExclusiveWrite) {
try
{
somSelf->DeleteCollections(ev);
somSelf->CreateCollections(ev);
if (_fEmbeddedContainer != kODNULL) {
_fEmbeddedContainer->Abort(ev);
CMObject parentObject = kODNULL;
ODByteArray ba = _fEmbeddedContainer->GetID(ev);
CMValue parentValue = *((CMValue*) ba._buffer);
ODDisposePtr(ba._buffer);
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
CMGetValueInfo(parentValue, kODNULL, &parentObject,
kODNULL, kODNULL, kODNULL);
CMDeleteValue(parentValue);
CMDeleteObject(parentObject);
ODSessionRestoreCMAllocReserve(cmContainer);
_fEmbeddedContainer->Release(ev);
_fEmbeddedContainer = kODNULL;
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
}
//------------------------------------------------------------------------------
// CMDraft: FlushVersion
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftFlushVersion(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","FlushVersion");
}
//------------------------------------------------------------------------------
// CMDraft: Reinitialize
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReinitialize(CMDraft *somSelf, Environment *ev,
ODDraftPermissions perms)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Reinitialize");
try
{
if ((perms == kODDPExclusiveWrite) &&
(_fEmbeddedContainer != kODNULL) &&
(_fEmbeddedContainer->GetUseMode(ev) & kCMReading)) {
MyDebugStr("Reinitialize.\n");
THROW(kODErrInvalidPermissions);
}
// Close this version first
// somSelf->CloseVersion(ev);
// Set the permissions
_fPermissions = perms;
// Open or create a new version
if (_fEmbeddedContainer == kODNULL) {
#if lazyOpen
_fExternalized = kODFalse;
#else
if (_fPermissions == kODDPReadOnly)
somSelf->OpenVersion(ev);
else
somSelf->CreateVersion(ev);
#endif
}
//_fDocument->Reopen(ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: Open
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftOpen(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Open");
try
{
if (_fEmbeddedContainer == kODNULL) {
#if lazyOpen
_fExternalized = kODFalse;
#else
if (_fPermissions == kODDPReadOnly)
somSelf->OpenVersion(ev);
else
somSelf->CreateVersion(ev);
#endif
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
#pragma segment CMDraft2
//------------------------------------------------------------------------------
// CMDraft: Close
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftClose(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Close");
try
{
#if ODDebug_Drafts
somPrintf("CMDraftClose: %d\n", somSelf->GetID(ev));
#endif
#if lazyOpen
if (_fEmbeddedContainer != kODNULL) {
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
// AcquireDraftPropertiesObject() makes CM calls:
CMObject draftPropertiesObject = AcquireDraftPropertiesObject(somSelf->GetCMContainer(ev));
if (draftPropertiesObject == kODNULL)
THROW(kODErrNoDraftProperties);
CMKeepObject(draftPropertiesObject);
ODSessionRestoreCMAllocReserve(cmContainer);
somSelf->CloseVersion(ev);
}
#else
somSelf->CloseVersion(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: Abort
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftAbort(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Abort");
try
{
if (_fPermissions == kODDPReadOnly)
THROW(kODErrInvalidPermissions);
if (_fDraftProperties != kODNULL) {
_fDraftProperties->Release(ev);
_fDraftProperties = kODNULL;
}
#if TestFlushContainer
if (_fRemoveChangeOnAbort) {
VersionList* versionList = kODNULL;
versionList = _fDocument->TestAndGetVersionList(ev);
ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
try
{
if (versionList->Exists(_fID) != kODFalse)
versionList->RemoveChanges(_fID);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
_fDocument->ReleaseVersionList(ev);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
}
#else
_fDocument->InternalizeVersionList(ev);
#endif
somSelf->DestroyVersion(ev);
// _fDocument->Reopen(ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: Flush
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftFlush(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Flush");
if (_fPermissions == kODDPExclusiveWrite) {
try
{
somSelf->FlushVersion(ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
}
//------------------------------------------------------------------------------
// CMDraft: IsNewDraft
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftIsNewDraft(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","IsNewDraft");
return _fIsNewDraft;
}
//------------------------------------------------------------------------------
// CMDraft: GetEmbeddedContainer
//------------------------------------------------------------------------------
SOM_Scope ODEmbeddedContainer* SOMLINK CMDraftGetEmbeddedContainer(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetEmbeddedContainer");
#if lazyOpen
try
{
if (_fEmbeddedContainer == kODNULL) {
if (_fPermissions == kODDPReadOnly)
somSelf->OpenVersion(ev);
else
somSelf->CreateVersion(ev);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
#endif
return _fEmbeddedContainer;
}
//------------------------------------------------------------------------------
// CMDraft: GetCMContainer
//------------------------------------------------------------------------------
SOM_Scope CMContainer SOMLINK CMDraftGetCMContainer(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetCMContainer");
CMContainer container = kODNULL;
try
{
#if lazyOpen
if (_fEmbeddedContainer == kODNULL) {
if (_fPermissions == kODDPReadOnly)
somSelf->OpenVersion(ev);
else
somSelf->CreateVersion(ev);
}
#endif
if (_fEmbeddedContainer == kODNULL)
THROW(kODErrCannotGetDraftVersion);
container = _fEmbeddedContainer->GetCMContainer(ev);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return container;
}
//------------------------------------------------------------------------------
// AcquireDraftPropertiesObject
//------------------------------------------------------------------------------
// Callers must ODSessionMustHaveCMAllocReserve() first:
static CMObject AcquireDraftPropertiesObject(CMContainer container)
{
CMObject draftPropertiesObject = kODNULL;
Environment* ev = somGetGlobalEnvironment();
try
{
CMType rootSUType;
CMProperty rootSUProp;
CMValue rootSU;
CMContainerModeFlags openMode;
if ((rootSUType = CMRegisterType(container, kODStorageUnitType)) == kODNULL)
THROW(kODErrBentoInvalidType);
if ((rootSUProp = CMRegisterProperty(container, kODPropRootSU)) == kODNULL)
THROW(kODErrBentoInvalidProperty);
draftPropertiesObject = CMGetNextObjectWithProperty(container, kODNULL, rootSUProp);
if (draftPropertiesObject == kODNULL) {
CMGetContainerInfo(container, kODNULL, kODNULL, kODNULL, kODNULL, &openMode);
if (openMode == kCMReading)
return kODNULL;
draftPropertiesObject = CMNewObject(container);
if ((rootSU = CMNewValue(draftPropertiesObject, rootSUProp, rootSUType)) == kODNULL)
THROW(kODErrBentoCannotNewValue);
CMWriteValueData(rootSU, "", 0, 0);
}
}
catch (ODException _exception)
{
draftPropertiesObject = kODNULL;
ODSetSOMException(ev, _exception);
}
return draftPropertiesObject;
}
//------------------------------------------------------------------------------
// GetVersionNameFromVersionID
//------------------------------------------------------------------------------
static ODType GetVersionNameFromVersionID(ODVersionID id, ODMemoryHeapID heapID)
{
ODSByte* versionName = kODNULL;
Environment* ev = somGetGlobalEnvironment();
try
{
ODSByte cString[kMaxStringSize];
if (id != 0) {
CM_itoa(id, cString); // KP
versionName = (ODSByte*) ODNewPtr(strlen(kODVersionNamePrefix) + strlen(cString) + 1, heapID);
strcpy(versionName, kODVersionNamePrefix);
strcat(versionName, cString);
}
}
catch (ODException _exception)
{
versionName = kODNULL;
ODSetSOMException(ev, _exception);
}
return versionName;
}
//------------------------------------------------------------------------------
// CMDraft: RetrievePersistentObject
//------------------------------------------------------------------------------
SOM_Scope ODPersistentObject* SOMLINK CMDraftRetrievePersistentObject(CMDraft *somSelf, Environment *ev,
ODStorageUnitID id)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RetrievePersistentObject");
ODPersistentObject* object = kODNULL;
try
{
if (_fPersistentObjects->GetValue(&id, &object))
object->Acquire(ev);
}
catch (ODException _exception)
{
object = kODNULL;
ODSetSOMException(ev, _exception);
}
return object;
}
//------------------------------------------------------------------------------
// CMDraft: ReleasePersistentObject
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftReleasePersistentObject(CMDraft *somSelf, Environment *ev,
ODPersistentObject* object)
{
// CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ReleasePersistentObject");
try
{
if (object->GetRefCount(ev) != 0)
THROW(kODErrRefCountGreaterThanZero);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: RemovePersistentObject
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftRemovePersistentObject(CMDraft *somSelf, Environment *ev,
ODPersistentObject* object)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","RemovePersistentObject");
try
{
if (!object)
THROW(kODErrInvalidPersistentObject);
ODStorageUnit* su = object->GetStorageUnit(ev);
ODStorageUnitID id = object->GetID(ev);
CMObject cmObject = kODNULL;
if (id == kODNULLID)
THROW(kODErrInvalidPersistentObjectID);
object->Release(ev);
if (object->GetRefCount(ev) != 0)
THROW(kODErrRefCountGreaterThanZero);
if ((su != kODNULL) && (su->GetRefCount(ev) != 1))
THROW(kODErrRefCountNotEqualOne);
object->ReleaseAll(ev);
_fPersistentObjects->RemoveEntry(&id);
delete object;
_fStorageUnits->RemoveEntry(&id);
delete su;
if (_fIDList->Exists(id) != kODFalse) {
cmObject = (CMObject) _fIDList->Get(id);
_fIDList->Remove(id);
CMContainer cmContainer = somSelf->GetCMContainer(ev);
ODSessionMustHaveCMAllocReserve(cmContainer);
if (cmObject != kODNULL)
CMDeleteObject(cmObject);
ODSessionRestoreCMAllocReserve(cmContainer);
}
somSelf->SetChangedFromPrevFlag(ev, kODTrue);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CreateCollections
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftCreateCollections(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateCollections");
try
{
ODMemoryHeapID heap = somSelf->GetHeap(ev);
#ifdef _PLATFORM_MACINTOSH_
_fPersistentObjects = new(heap)
OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, heap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
_fPersistentObjects = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, 0);
#endif
_fPersistentObjects->Initialize(kODInitialNumEntries,
sizeof(ODStorageUnitID),
sizeof(ODPersistentObject*));
#ifdef _PLATFORM_MACINTOSH_
_fStorageUnits = new(heap)
OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, heap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
_fStorageUnits = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, 0);
#endif
_fStorageUnits->Initialize(kODInitialNumEntries,
sizeof(ODStorageUnitID),
sizeof(ODStorageUnit*));
#ifdef _PLATFORM_MACINTOSH_
_fIDList = new(somSelf->GetHeap(ev)) IDList;
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
_fIDList = new IDList;
#endif
_fIDList->Initialize();
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: DeleteCollections
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftDeleteCollections(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","DeleteCollections");
try
{
if (_fDraftProperties != kODNULL)
{
_fDraftProperties->Release(ev);
_fDraftProperties = kODNULL;
}
if (_fPersistentObjects != kODNULL) {
ODStorageUnitID id;
ODPersistentObject* object;
OpenHashTableIterator iter(_fPersistentObjects);
for (iter.First(&id, &object); iter.IsNotComplete(); iter.Next(&id, &object)) {
if (object != kODNULL) {
try
{
object->ReleaseAll(ev);
}
catch (ODException _exception)
{
WARNMSG(WARN_INDEX(AMSG_620),
"Exception thrown by object %x ID %x error %d\n",
object, object->GetID(ev), ErrorCode());
}
}
}
for (iter.First(&id, &object); iter.IsNotComplete(); iter.Next(&id, &object)) {
if (object != kODNULL) {
delete object;
}
}
delete _fPersistentObjects;
_fPersistentObjects = kODNULL;
}
if (_fStorageUnits != kODNULL) {
ODStorageUnitID id;
ODStorageUnit* su;
OpenHashTableIterator iter(_fStorageUnits);
for (iter.First(&id, &su); iter.IsNotComplete(); iter.Next(&id, &su)) {
if (su != kODNULL) {
delete su;
}
}
delete _fStorageUnits;
_fStorageUnits = kODNULL;
_fDraftProperties = kODNULL;
}
ODDeleteObject(_fIDList);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: ExternalizeCollections
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftExternalizeCollections(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ExternalizeCollections");
ODBoolean acquired = kODFalse;
try
{
ODID id;
ODStorageUnit* su;
OpenHashTableIterator persistentObjects(_fPersistentObjects);
ODPersistentObject* object;
for (persistentObjects.First(&id, &object);
persistentObjects.IsNotComplete();
persistentObjects.Next(&id, &object)) {
try
{
// Temporarily bump the refcount to make sure that the object is
// in a valid state.
object->Acquire(ev);
acquired = kODTrue;
su = object->GetStorageUnit(ev);
if ((su != kODNULL) && (su->Exists(ev, kODNULL, kODNULL, 0) != kODFalse))
object->Externalize(ev);
object->Release(ev);
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
object->Release(ev);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
}
OpenHashTable suCollection(*_fStorageUnits);
suCollection.InitAndCopyFrom(*_fStorageUnits);
OpenHashTableIterator storageUnits(&suCollection);
for (storageUnits.First(&id, &su);
storageUnits.IsNotComplete();
storageUnits.Next(&id, &su)) {
// Temporarily bump the refcount to make sure that the object is
// in a valid state.
su->Acquire(ev);
#ifdef _NO_TMP_OBJS_
ODStorageUnit *tempSU = su; // ensure it's released
#else
TempODStorageUnit tempSU = su; // ensure it's released
#endif
if (su->Exists(ev, kODNULL, kODNULL, 0) != kODFalse)
su->Externalize(ev);
#ifdef _NO_TMP_OBJS_
tempSU->Release(ev);
#endif
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: CloseCollections
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftCloseCollections(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CloseCollections");
try
{
somSelf->FailIfNotExclusiveWrite(ev);
somSelf->Purge(ev, 0);
PurgeAllStorageUnits(ev, _fStorageUnits, _fIDList); // purge SU, relase CMObjects
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: OpenCollections
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftOpenCollections(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","OpenCollections");
try
{
OpenHashTableIterator storageUnits(_fStorageUnits);
ODID id;
ODStorageUnit* su;
for (storageUnits.First(&id, &su);
storageUnits.IsNotComplete();
storageUnits.Next(&id, &su)) {
su->Internalize(ev);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: AreEmptyCollections
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftAreEmptyCollections(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AreEmptyCollections");
ODBoolean areEmptyCollections = kODTrue;
try
{
OpenHashTableIterator storageUnits(_fStorageUnits);
OpenHashTableIterator persistentObjects(_fPersistentObjects);
ODID id;
ODPersistentObject* object;
ODStorageUnit* su;
for (persistentObjects.First(&id, &object);
persistentObjects.IsNotComplete();
persistentObjects.Next(&id, &object)) {
if (object->GetRefCount(ev) > 0)
return kODFalse;
}
for (storageUnits.First(&id, &su); storageUnits.IsNotComplete(); storageUnits.Next(&id, &su)) {
if (su->GetRefCount(ev) > 0)
return kODFalse;
}
}
catch (ODException _exception)
{
areEmptyCollections = kODFalse;
ODSetSOMException(ev, _exception);
}
return areEmptyCollections;
}
//------------------------------------------------------------------------------
// CMDraft: NeedExternalizing
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftNeedExternalizing(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","NeedExternalizing");
return _fExternalized;
}
//------------------------------------------------------------------------------
// CMDraft: GetIDList
//------------------------------------------------------------------------------
SOM_Scope IDList* SOMLINK CMDraftGetIDList(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetIDList");
return _fIDList;
}
//------------------------------------------------------------------------------
// CMDraft: IsChangedFromPrev
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftIsChangedFromPrev(CMDraft *somSelf, Environment *ev,
VersionList* versionList)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","IsChangedFromPrev");
ODBoolean changedFromPrev = kODFalse;
ODVersionID prevVersionID;
ODDraftID prevDraftID;
// If this draft has been modified, return kODTrue.
if (_fChangedFromPrev != kODFalse)
return kODTrue;
// versionList->ChangedFromPrev is accurate only when the draft is
// opened read-only. Therefore, additional check is needed to ensure that
// we don't return kODTrue even when the draft has not be changed.
try
{
changedFromPrev = versionList->ChangedFromPrev(_fID);
if ((changedFromPrev != kODFalse) && (_fPermissions == kODDPExclusiveWrite)) {
prevDraftID = versionList->GetPreviousDraftID(_fID);
prevVersionID = versionList->GetDraft(prevDraftID);
if (prevVersionID == _fPrevVersionID)
changedFromPrev = kODFalse;
}
}
catch (ODException _exception)
{
changedFromPrev = kODFalse;
ODSetSOMException(ev, _exception);
}
return changedFromPrev;
}
//------------------------------------------------------------------------------
// CMDraft: BeginClone
//------------------------------------------------------------------------------
SOM_Scope ODDraftKey SOMLINK CMDraftBeginClone(CMDraft *somSelf, Environment *ev,
ODDraft* destDraft,
ODFrame* destFrame,
ODCloneKind kind)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","BeginClone");
OpenHashTable* clonedSUIDs = kODNULL; ODVolatile(clonedSUIDs);
OpenHashTable* weakClonedSUIDs = kODNULL; ODVolatile(weakClonedSUIDs);
ODDraftKey result = 0;
try
{
#ifdef _PLATFORM_OS2_ // $$$ dcp # 120111 05/09/95
if(destDraft==kODNULL)
THROW(kODErrInvalidParameter);
#endif
// Allow beginning a new clone into a link if a clone from a link
// is in progress; common if the link contains promises
if ( (kind == kODCloneToLink) && (_fCloneKind == kODCloneFromLink) )
{
if ( _fLockCount > 1 )
THROW(kODErrCloningInProgress);
}
else if (_fLockCount > 0)
#ifdef _PLATFORM_OS2_
{
// THROW(kODErrCloningInProgress);
// The sleep loop will allow multi-threads entering this same mehtod
// by gating each thread's operation.
// defect 27471
while (_fLockCount > 0) {
DosSleep(1000);
} /* endwhile */
}
#endif // OS2
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_AIX_)
THROW(kODErrCloningInProgress);
#endif // WIN32 or AIX
#ifdef DebugClone
somPrintf("\nCMDraft::BeginClone - ");
switch (kind)
{
case kODCloneCut: somPrintf("Cut\n"); break;
case kODCloneCopy: somPrintf("Copy\n"); break;
case kODClonePaste: somPrintf("Paste\n"); break;
case kODCloneDropCopy: somPrintf("Drop Copy\n"); break;
case kODCloneDropMove: somPrintf("Drop Move\n"); break;
case kODCloneToLink: somPrintf("To Link\n"); break;
case kODCloneFromLink: somPrintf("From Link\n"); break;
case kODCloneAll: somPrintf("All\n"); break;
case kODCloneToFile: somPrintf("To File\n"); break;
default: somPrintf("Invalid clone kind!\n"); break;
}
#endif
// Validate the clone kind parameter
switch (kind)
{
case kODClonePaste:
case kODCloneDropCopy:
case kODCloneDropMove:
case kODCloneToFile:
{
ODCloneKind origCloneKind = GetOriginalCloneKind(ev, somSelf);
if ( (origCloneKind != kODCloneCut) && (origCloneKind != kODCloneCopy) )
THROW(kODErrInconsistentCloneKind);
}
if ( somSelf == destDraft )
THROW(kODErrInvalidDestinationDraft);
break;
case kODCloneCut:
case kODCloneCopy:
#ifdef _PLATFORM_OS2_
#else
if ( somSelf == destDraft )
THROW(kODErrInvalidDestinationDraft);
#endif
break;
#ifdef _PLATFORM_OS2_
case kODCloneToLink:
if ( somSelf != destDraft )
THROW(kODErrInvalidDestinationDraft);
break;
case kODCloneAll:
case kODCloneFromLink:
break;
#else
case kODCloneToLink:
case kODCloneFromLink:
if ( somSelf != destDraft )
THROW(kODErrInvalidDestinationDraft);
break;
case kODCloneAll:
break;
#endif
default:
THROW(kODErrInvalidCloneKind);
break;
}
ODMemoryHeapID heap = somSelf->GetHeap(ev);
// Ensure both hash tables can be allocated
if ( _fLockCount == 0 )
{
#ifdef _PLATFORM_MACINTOSH_
clonedSUIDs = new(heap)
OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, heap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
clonedSUIDs = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, 0);
#endif
clonedSUIDs->Initialize(kInitialHashTableEntries,
sizeof(ODStorageUnitID),
sizeof(ODStorageUnitID));
if ( (kind == kODCloneCut) || (kind == kODCloneCopy) )
ReadClonedObjectTable(ev, clonedSUIDs, destDraft);
}
#ifdef _PLATFORM_MACINTOSH_
weakClonedSUIDs = new(heap)
OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, heap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
weakClonedSUIDs = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash, 0);
#endif
weakClonedSUIDs->Initialize(kInitialHashTableEntries,
sizeof(ODStorageUnitID),
sizeof(ODStorageUnitID));
// BeginClone must not fail beyond this point
_fLockCount++;
if ( _fLockCount == 1 )
{
_fCurrentKey++;
_fCloneKind = kind;
_fDestDraft = destDraft;
_fDestFrame = destFrame;
_fAnyFrameCloned = kODFalse;
_fRootPartReused = kODFalse;
_fClonedSUIDs = clonedSUIDs;
}
_fSavedWeakClonedSUIDs = _fWeakClonedSUIDs;
_fWeakClonedSUIDs = weakClonedSUIDs;
result = _fCurrentKey;
}
catch (ODException _exception)
{
result = 0;
ODSetSOMException(ev, _exception);
ODDeleteObject(clonedSUIDs);
ODDeleteObject(weakClonedSUIDs);
}
return result;
}
//------------------------------------------------------------------------------
// CMDraft: GetClonedSUIDs
//------------------------------------------------------------------------------
SOM_Scope OpenHashTable* SOMLINK CMDraftGetClonedSUIDs(CMDraft *somSelf, Environment *ev,
ODDraft* destDraft)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetClonedSUIDs");
try
{
if ((_fDestDraft != kODNULL) && (_fDestDraft != destDraft)) {
ODDeleteObject(_fClonedSUIDs);
ODDeleteObject(_fWeakClonedSUIDs);
THROW(kODErrInvalidDestinationDraft);
}
_fDestDraft = destDraft;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
return kODNULL;
}
return _fClonedSUIDs;
}
//------------------------------------------------------------------------------
// CMDraft: EndClone
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftEndClone(CMDraft *somSelf, Environment *ev,
ODDraftKey key)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","EndClone");
ODStorageUnitID fromID;
ODStorageUnitID toID;
try
{
if ((key != _fCurrentKey) || (_fLockCount == 0))
THROW(kODErrInvalidDraftKey);
OpenHashTableIterator iter(_fWeakClonedSUIDs);
for (iter.First(&fromID, &toID); iter.IsNotComplete(); iter.Next(&fromID, &toID)) {
if (toID != 0) {
ODStorageUnit* toSU = _fDestDraft->AcquireStorageUnit(ev, toID);
#ifdef DebugClone
somPrintf("Removing %d %d\n", toID, ((CMStorageUnit*) toSU)->GetObjectID(ev));
#endif
_fDestDraft->RemoveStorageUnit(ev, toSU);
}
}
switch (_fCloneKind)
{
case kODCloneCopy:
case kODCloneCut:
SetOriginalDraft(ev, _fDestDraft, somSelf);
if ( !OriginalCloneKindExists(ev, _fDestDraft) )
SetOriginalCloneKind(ev, _fDestDraft, _fCloneKind);
WriteClonedObjectTable(ev, _fClonedSUIDs, _fDestDraft);
break;
case kODClonePaste:
case kODCloneDropCopy:
case kODCloneDropMove:
case kODCloneToFile:
if ( (_fCloneKind == kODClonePaste) && (GetOriginalCloneKind(ev, somSelf) == kODCloneCut) )
SetOriginalCloneKind(ev, somSelf, kODCloneCopy);
break;
default:
break;
}
if ( somSelf->GetCloneKind(ev) == kODCloneDropMove )
{
if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
{
if ( _fAnyFrameCloned )
{
if ( somSelf->ContainingPartInClone(ev, _fDestFrame) )
THROW(kODErrMoveIntoSelf);
}
}
}
--_fLockCount;
if ( _fLockCount == 0 )
{
_fDestDraft = kODNULL;
_fDestFrame = kODNULL;
ODDeleteObject(_fClonedSUIDs);
}
ODDeleteObject(_fWeakClonedSUIDs);
_fWeakClonedSUIDs = _fSavedWeakClonedSUIDs;
#ifdef DebugClone
somPrintf("CMDraft::EndClone - Clone completed\n\n");
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: AbortClone
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftAbortClone(CMDraft *somSelf, Environment *ev,
ODDraftKey key)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","AbortClone");
try
{
#if ODDebug_Drafts
somPrintf("CMDraftAbort: %d\n", somSelf->GetID(ev));
#endif
if ((key != _fCurrentKey) || (_fLockCount == 0))
THROW(kODErrInvalidDraftKey);
--_fLockCount;
if ( _fLockCount == 0 )
{
_fDestDraft = kODNULL;
_fDestFrame = kODNULL;
ODDeleteObject(_fClonedSUIDs);
}
ODDeleteObject(_fWeakClonedSUIDs);
_fWeakClonedSUIDs = _fSavedWeakClonedSUIDs;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: SetOriginalID
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftSetOriginalID(CMDraft *somSelf, Environment* ev,
ODStorageUnitID destID,
ODStorageUnitID originalID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","SetOriginalID");
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *destSU = _fDestDraft->AcquireStorageUnit(ev, destID);
#else
TempODStorageUnit destSU = _fDestDraft->AcquireStorageUnit(ev, destID);
#endif
ODSetULongProp(ev, destSU, kODPropOriginalID, kODULong, originalID);
#ifdef _NO_TMP_OBJS_
destSU->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: GetOriginalID
//------------------------------------------------------------------------------
// An original ID may not be present in the root storage unit of the draft,
// since this SU is often constructed in place rather than cloned.
// An null object ID is returned if the property is not present.
SOM_Scope ODStorageUnitID SOMLINK CMDraftGetOriginalID(CMDraft *somSelf, Environment* ev,
ODStorageUnitID fromID)
{
//CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetOriginalID");
ODStorageUnitID retSID = 0;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *fromSU = somSelf->AcquireStorageUnit(ev, fromID);
#else
TempODStorageUnit fromSU = somSelf->AcquireStorageUnit(ev, fromID);
#endif
retSID = (ODStorageUnitID)ODGetULongProp(ev, fromSU, kODPropOriginalID, kODULong);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return retSID;
}
//------------------------------------------------------------------------------
// CheckPartAction
//------------------------------------------------------------------------------
static ODBoolean CheckPartAction(void* k, void* v, ODULong s, void* r)
{
Environment* ev = somGetGlobalEnvironment();
ODBoolean result = kODFalse;
try
{
ODID originalID = * (ODID *) k;
ODID interupdateID = * (ODID *) v;
OpenHashTable* targetParts = (OpenHashTable*) r;
// Note that storage units in the original document draft may not be up to date
// if changes have not been externalized. In particular, a frame's storage
// unit may not have a valid reference to its part's storage unit. For this
// reason, use the storage units in the data interchange draft instead.
#ifdef DebugClone
somPrintf("interupdateID %d, originalID %d\n", interupdateID, originalID);
#endif
#ifdef _NO_TMP_OBJS_
ODStorageUnit *interchangeSU = ::sInterchangeDraft->AcquireStorageUnit(ev, interupdateID);
#else
TempODStorageUnit interchangeSU = ::sInterchangeDraft->AcquireStorageUnit(ev, interupdateID);
#endif
if ( ODSUExistsThenFocus(ev, interchangeSU, kODPropStorageUnitType, kODISOStr) )
{
if ( interchangeSU->GetSize(ev) == ODISOStrLength(kODFrameObject)+1 )
{
ODULong size = ODISOStrLength(kODFrameObject)+1;
// Only read the same number of characters as in kODFrameObject, to prevent overwriting the
// terminating zero byte of the buffer.
if (ODGetISOStrProp(ev, interchangeSU, kODPropStorageUnitType, kODISOStr, (ODISOStr) ::sSUTypeBuffer, &size)
!= kODNULL)
{
if (ODISOStrEqual(kODFrameObject, ::sSUTypeBuffer))
{
ODID interchangePartID = ODGetStrongSURefProp(ev, interchangeSU, kODPropPart, kODStrongStorageUnitRef);
if ( interchangePartID == kODNULLID )
{
// Note: If the reference isn't valid, ODGetStrongSURefProp will return
// kODNULLID so it isn't necessary to call IsValidID instead.
#ifdef DebugClone
somPrintf("Invalid part reference from frame id %d\n", interupdateID);
#endif
result = kODTrue; // Better safe than sorry!
}
else if ( interchangePartID != ::sRootPartIDToIgnore )
{
ODID targetPartID = ::sInterchangeDraft->GetOriginalID(ev, interchangePartID);
#ifdef DebugClone
somPrintf("Checking part id %d from frame id %d\n", targetPartID, originalID);
#endif
result = targetParts->Exists(&targetPartID);
}
#ifdef DebugClone
else
{
somPrintf("Skipping root part id %d because it was not cloned\n", interchangePartID);
}
#endif
}
}
}
}
#ifdef _NO_TMP_OBJS_
interchangeSU->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return result;
}
//------------------------------------------------------------------------------
// CMDraft: ContainingPartInClone
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftContainingPartInClone(CMDraft *somSelf, Environment* ev,
ODFrame* targetFrame)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ContainingPartInClone");
ODBoolean result = kODFalse;
ODFrame* frame;
ODFrame* nextFrame;
ODID partID;
OpenHashTable* targetParts = kODNULL;
OpenHashTable* clonedSUIDs = kODNULL;
try
{
ODMemoryHeapID heap = somSelf->GetHeap(ev);
#ifdef DebugClone
somPrintf("ContainingPartInClone called with target frame id %d <%x>\n", targetFrame->GetID(ev), targetFrame);
#endif
#ifdef _PLATFORM_MACINTOSH_
OpenHashTable* targetParts = new(heap) OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash,
heap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
OpenHashTable* targetParts = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash,
0);
#endif
targetParts->Initialize(kInitialHashTableEntries, sizeof(ODID), 0, kODTrue);
// Build a table of parts that own or embed the target frame
frame = targetFrame;
if ( frame )
frame->Acquire(ev);
while ( frame != kODNULL )
{
#ifdef _NO_TMP_OBJS_
ODFrame *tempFrame = frame; // ensure it's released
#else
TempODFrame tempFrame = frame; // ensure it's released
#endif
ODPart* part = frame->AcquirePart(ev);
partID = part->GetID(ev);
part->Release(ev);
#ifdef DebugClone
somPrintf("Adding target part id %d from frame id %d\n", partID, frame->GetID(ev));
#endif
targetParts->ReplaceEntry(&partID, kODNULL);
nextFrame = frame->AcquireContainingFrame(ev);
if ( nextFrame == kODNULL )
{
#ifdef _NO_TMP_OBJS_
{ ODWindow *window = frame->AcquireWindow(ev);
#else
{ TempODWindow window = frame->AcquireWindow(ev);
#endif
nextFrame = window->AcquireSourceFrame(ev);
#ifdef _NO_TMP_OBJS_
window->Release(ev);
#endif
}
// The source frame always displays the same part, so skip to its containing frame.
// Note that it must have a containing frame.
if ( nextFrame != kODNULL )
{
#ifdef _NO_TMP_OBJS_
ODFrame *sourceFrame = nextFrame;
#else
TempODFrame sourceFrame = nextFrame;
#endif
nextFrame = sourceFrame->AcquireContainingFrame(ev);
#ifdef _NO_TMP_OBJS_
sourceFrame->Release(ev);
#endif
}
}
frame = nextFrame;
#ifdef _NO_TMP_OBJS_
tempFrame->Release(ev);
#endif
}
#ifdef _PLATFORM_MACINTOSH_
clonedSUIDs = new(heap) OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash,
heap);
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
clonedSUIDs = new OpenHashTable(OpenHashTable::StdEqual,
OpenHashTable::StdHash,
0);
#endif
clonedSUIDs->Initialize(kInitialHashTableEntries,
sizeof(ODStorageUnitID),
sizeof(ODStorageUnitID));
// Get the table of objects cloned into the data interchange draft
ReadClonedObjectTable(ev, clonedSUIDs, somSelf);
// See if any frame of any target part is part of the clone
::sInterchangeDraft = somSelf;
::sSUTypeBuffer = (ODISOStr) ODNewPtrClear(ODISOStrLength(kODFrameObject) + 1);
::sRootPartIDToIgnore = ( _fRootPartReused ? kODNULLID : RootPartID(ev, somSelf) );
// This line of code is commented out because the object IDs
// stored in kODPropClonedObjectTable is not valid any more if
// the drag and drop storage unit is closed and reopened. IDs
// are not persistent objects and cannot be depended on. Since
// the main purpose of function CheckPartAction is to prevent
// drag and drop to the same frame and part and drag and drop
// codes have receipe to prevent this from happen, comment out
// this code should not create any ill problem.
//
// result = clonedSUIDs->Walk(CheckPartAction, targetParts);
ODDisposePtr(::sSUTypeBuffer);
}
catch (ODException _exception)
{
result = kODFalse;
ODSetSOMException(ev, _exception);
}
ODDeleteObject(targetParts);
ODDeleteObject(clonedSUIDs);
#ifdef DebugClone
somPrintf("ContainingPartInClone returns %d\n", result);
#endif
return result;
}
//------------------------------------------------------------------------------
// CMDraft: ValidWeakReferenceProperty
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftValidWeakReferenceProperty(CMDraft *somSelf, Environment *ev,
ODID objectID,
ODPropertyName propertyName)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","ValidWeakReferenceProperty");
ODBoolean result = kODFalse;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *objectSU = somSelf->AcquireStorageUnit(ev, objectID);
#else
TempODStorageUnit objectSU = somSelf->AcquireStorageUnit(ev, objectID);
#endif
if (objectSU != kODNULL)
{
result = (ODGetWeakSURefProp(ev, objectSU, propertyName, kODWeakStorageUnitRef) != 0);
//#ifdef DebugClone
// somPrintf("ValidWeakReferenceProperty: %s property does not exist.\n", propertyName);
//#endif
}
#ifdef _NO_TMP_OBJS_
objectSU->Release(ev);
#endif
}
catch (ODException _exception)
{
#ifdef DebugClone
somPrintf("ValidWeakReferenceProperty: returning error.\n");
#endif
ODSetSOMException(ev, _exception);
result = kODFalse;
}
return result;
}
//------------------------------------------------------------------------------
// CMDraft: CloneCompanionObject
//------------------------------------------------------------------------------
// If fromID is a link or link source object, clone its companion.
// Note that kODNULLID is always used as the scopeID, since scope is irrelevant
// for link and link source objects.
SOM_Scope ODID SOMLINK CMDraftCloneCompanionObject(CMDraft *somSelf, Environment *ev,
ODDraftKey key,
ODID fromID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CloneCompanionObject");
ODID toID = kODNULLID; ODVolatile(toID);
try
{
ODPropertyName companionProperty = kODNULL;
if ( IsLinkObject(ev, somSelf, fromID) )
companionProperty = kODPropLinkSource;
else if ( IsLinkSourceObject(ev, somSelf, fromID) )
companionProperty = kODPropLink;
if ( companionProperty != kODNULL )
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *objectSU = somSelf->AcquireStorageUnit(ev, fromID);
#else
TempODStorageUnit objectSU = somSelf->AcquireStorageUnit(ev, fromID);
#endif
if ( objectSU != kODNULL )
{
ODStorageUnitID companionID = ODGetWeakSURefProp(ev, objectSU, companionProperty, kODWeakStorageUnitRef);
if ( companionID != kODNULLID )
{
// Optimization: If the companion object has already been cloned,
// there is no need to clone it again since scope is irrelevant for
// these objects. [cc 9/28/95]
_fClonedSUIDs->GetValue(&companionID, &toID);
if ( toID == kODNULLID )
toID = somSelf->StrongClone(ev, key, companionID, kODNULLID, kODNULLID);
}
}
#ifdef _NO_TMP_OBJS_
objectSU->Release(ev);
#endif
}
}
catch (ODException _exception)
{
toID = kODNULLID;
ODSetSOMException(ev, _exception);
}
return toID;
}
//------------------------------------------------------------------------------
// CMDraft: CompanionWasCloned
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftCompanionWasCloned(CMDraft *somSelf, Environment* ev,
ODStorageUnitID fromID,
ODPropertyName prop)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CompanionWasCloned");
ODBoolean result = kODFalse;
try
{
result= somSelf->ValidWeakReferenceProperty(ev, fromID, prop);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return result;
}
//------------------------------------------------------------------------------
// CMDraft: GetCloneKind
//------------------------------------------------------------------------------
SOM_Scope ODCloneKind SOMLINK CMDraftGetCloneKind(CMDraft *somSelf, Environment* ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetCloneKind");
ODCloneKind cloneKind = _fCloneKind;
try
{
if ( cloneKind == kODClonePaste )
{
if ( (GetOriginalCloneKind(ev, somSelf) == kODCloneCut) && (GetOriginalDraft(ev, somSelf) == _fDestDraft) )
cloneKind = kODCloneDropMove;
else
cloneKind = kODCloneDropCopy;
}
else if ( cloneKind == kODCloneToFile )
{
cloneKind = kODCloneDropCopy;
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return cloneKind;
}
//------------------------------------------------------------------------------
// CMDraft: CopiedLinkSubstitution
//------------------------------------------------------------------------------
//
// If this clone is a copy, or a move to another draft, substitute the original
// object ID or the null object id, and return true. Returns false if the object
// should be cloned, and does not assign to the toID parameter.
// The toObjectID parameter is just for validity checking.
SOM_Scope ODBoolean SOMLINK CMDraftCopiedLinkSubstitution(CMDraft *somSelf, Environment* ev,
ODDraftKey key,
ODID fromID,
ODID toObjectID,
ODID* toID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CopiedLinkSubstitution");
ODUnused(key);
ODBoolean substitute = kODFalse;
try
{
ODBoolean isCopy = (somSelf->GetCloneKind(ev) == kODCloneDropCopy);
ODBoolean isCrossDraftMove =
(somSelf->GetCloneKind(ev) == kODCloneDropMove) && (GetOriginalDraft(ev, somSelf) != _fDestDraft);
if ( isCopy || isCrossDraftMove )
{
if ( IsLinkObject(ev, somSelf, fromID) )
{
if ( !somSelf->CompanionWasCloned(ev, fromID, kODPropLinkSource) )
{
if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
{
ASSERT(toObjectID == 0, kODErrInvalidID);
*toID = somSelf->GetOriginalID(ev, fromID);
ASSERT(*toID != 0, kODErrInvalidID);
}
else
*toID = 0;
substitute = kODTrue;
}
}
else if ( IsLinkSourceObject(ev, somSelf, fromID) )
{
if ( !somSelf->CompanionWasCloned(ev, fromID, kODPropLink) )
{
*toID = 0;
substitute = kODTrue;
}
}
}
#ifdef DebugClone
if ( substitute )
{
if ( !IsLinkObject(ev, somSelf, fromID) )
IsLinkSourceObject(ev, somSelf, fromID);
somPrintf("Reusing existing object id = %d for cloned object %d\n", toID, fromID);
}
#endif
}
catch (ODException _exception)
{
substitute = kODFalse;
ODSetSOMException(ev, _exception);
}
return substitute;
}
//------------------------------------------------------------------------------
// CMDraft: Clone
//------------------------------------------------------------------------------
//
// Why is the switch statement in this method so hard to understand? It should
// really be replaced by a table-driven algorithm. There are only three possible
// actions when cloning a link or link source object:
// (1) Go ahead and clone the link,
// (2) Don't clone the link,
// (3) Substitute the original link rather than clone in a duplicate
// However, there are four factors that determine which action should be taken.
// There are 8x3x2x2 = 96 distinct combinations of these factors; however,
// most combinations are impossible or illegal.
// The switch statement is an embodyment in code of the resulting sparse matrix.
// Several cases are sometimes handled at once. Only by going back to the full
// case analysis represented by a table can one understand this code.
//
// Note that its possible that a link object's companion doesn't exist; in this
// case the link is broken and won't be copied.
//
SOM_Scope ODID SOMLINK CMDraftClone(CMDraft *somSelf, Environment *ev,
ODDraftKey key,
ODID fromID,
ODID toObjectID,
ODID scopeID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Clone");
ODStorageUnitID toID = 0;
try
{
if ((key != _fCurrentKey) || (_fLockCount == 0))
THROW(kODErrInvalidDraftKey);
ODStorageUnitID companionID = 0;
#ifdef _PLATFORM_OS2_
switch ( somSelf->GetCloneKind(ev) )
{
case kODCloneAll:
case kODCloneFromLink:
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
break;
case kODCloneToLink:
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
break;
case kODCloneCopy:
case kODCloneCut:
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
somSelf->SetOriginalID(ev, toID, fromID);
break;
case kODCloneDropCopy:
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
break;
case kODCloneDropMove:
// Putting DR4 cloning code to handle drag and drop within the
// same document.
if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
{
// toObjectID will be non-zero if the object has been weakly cloned.
// If the weak clone substituted the original object, set toID so
// the strong clone is avoided. If the weak clone was into a
// storage unit other than the original, toID is not set, so the
// strong clone will be performed.
ODID originalID = somSelf->GetOriginalID(ev, fromID);
if ( _fDestDraft->IsValidID(ev, originalID)
&&
((toObjectID == 0) || (toObjectID == originalID)) )
toID = originalID;
somSelf->CheckClonedObject(ev, fromID, toID, originalID);
}
if ( toID == 0 )
{
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
}
break;
default:
break;
}
// Notes on cloning in OS2 implementation:
// In OS2 implementation, we need to distinguish SUs which are clones of links
// from SUs which are the original links for the following reasons:
// 1. A stored link which is not a clone comes back up without issuing
// AddLinkTarget, whereas a clone must issue AddLinkTarget (unless its
// source was also copied)
// 2. A cloned link which has a valid ref to a link source (meaning that
// its link source was also copied) has an invalid linkid for the source,
// since new linkids are created lazily.
// Such a link cannot be further cloned from a document (copy, cut, copytolink)
// for fear that it will be cloned without its linksource and the
// correct linksource reference lost.
// So whenever we clone a link (target) object, we give it the CloneOfALink property
// Whenever the link comes up again, that property is removed.
#ifdef _NO_TMP_OBJS_
ODStorageUnit* destSU = _fDestDraft->AcquireStorageUnit(ev, toID);
#else
TempODStorageUnit destSU = _fDestDraft->AcquireStorageUnit(ev, toID);
#endif
if (IsLinkObject(ev,_fDestDraft,toID) &&
!destSU->Exists(ev, kODPropCloneOfALink, kODNULL, 0))
{
ODSUAddPropValue(ev, destSU, kODPropCloneOfALink, kODBoolean);
ODBoolean True = kODTrue ;
StorageUnitSetValue(destSU, ev, sizeof(ODBoolean), (ODValue)&(True));
}
#ifdef _NO_TMP_OBJS_
destSU->Release(ev);
#endif
#else
switch ( somSelf->GetCloneKind(ev) )
{
case kODCloneAll:
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
somSelf->CloneCompanionObject(ev, key, fromID);
break;
case kODCloneFromLink:
case kODCloneToLink:
if ( IsNeitherLinkObject(ev, somSelf, fromID) )
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
break;
case kODCloneCopy:
case kODCloneCut:
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
somSelf->SetOriginalID(ev, toID, fromID);
break;
case kODCloneDropCopy:
if ( !somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID) )
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
break;
case kODCloneDropMove:
// When moved to another draft, links should behave as if copied
if ( !somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID) )
{
if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
{
// toObjectID will be non-zero if the object has been weakly cloned.
// If the weak clone substituted the original object, set toID so
// the strong clone is avoided. If the weak clone was into a
// storage unit other than the original, toID is not set, so the
// strong clone will be performed.
ODID originalID = somSelf->GetOriginalID(ev, fromID);
if ( _fDestDraft->IsValidID(ev, originalID)
&&
((toObjectID == 0) || (toObjectID == originalID)) )
toID = originalID;
somSelf->CheckClonedObject(ev, fromID, toID, originalID);
}
if ( toID == 0 )
{
toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
}
#ifdef DebugClone
else
{
if ( !IsLinkObject(ev, somSelf, fromID) )
IsLinkSourceObject(ev, somSelf, fromID);
somPrintf("Reusing existing object id = %d for cloned object %d\n", toID, fromID);
}
#endif
}
break;
default:
break;
}
#endif // _PLATFORM_OS2_
}
catch (ODException _exception)
{
toID = 0;
ODSetSOMException(ev, _exception);
}
return toID;
}
//------------------------------------------------------------------------------
// CMDraft: StrongClone
//------------------------------------------------------------------------------
SOM_Scope ODID SOMLINK CMDraftStrongClone(CMDraft *somSelf, Environment *ev,
ODDraftKey key,
ODID fromID,
ODID toObjectID,
ODID scopeID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","StrongClone");
ODStorageUnitID toID = 0;
try
{
#ifdef DebugClone
somPrintf("CMDraftStrongClone %d %d %d\n", fromID, toObjectID, scopeID);
#endif
#ifdef _NO_TMP_OBJS_
ODStorageUnit *toSU = kODNULL;
#else
TempODStorageUnit toSU = kODNULL;
#endif
_fClonedSUIDs->GetValue(&fromID, &toID);
if (toID == 0) {
_fWeakClonedSUIDs->GetValue(&fromID, &toID);
if (toID == 0) {
if (toObjectID != 0)
toSU = _fDestDraft->AcquireStorageUnit(ev, toObjectID);
else
toSU = _fDestDraft->CreateStorageUnit(ev);
toID = toSU->GetID(ev);
_fClonedSUIDs->ReplaceEntry(&fromID, &toID);
}
else {
if ((toObjectID != 0) && (toObjectID != toID))
THROW(kODErrInvalidID);
_fWeakClonedSUIDs->RemoveEntry(&fromID);
_fClonedSUIDs->ReplaceEntry(&fromID, &toID);
toSU = _fDestDraft->AcquireStorageUnit(ev, toID);
}
}
else {
if ((toObjectID != 0) && (toObjectID != toID))
THROW(kODErrInvalidID);
toSU = _fDestDraft->AcquireStorageUnit(ev, toID);
}
ODPersistentObject *fromObject = somSelf->RetrievePersistentObject(ev, fromID);
if ( fromObject ) {
#ifdef _NO_TMP_OBJS_
ODRefCntObject *tempFromObject = fromObject; // so it gets released
ODFrame *scopeFrame = kODNULL;
#else
TempODRefCntObject tempFromObject = fromObject; // so it gets released
TempODFrame scopeFrame = kODNULL;
#endif
if (scopeID != 0)
scopeFrame = somSelf->AcquireFrame(ev, scopeID);
fromObject->CloneInto(ev, key, toSU, scopeFrame);
ODStorageUnit* fromSU = fromObject->GetStorageUnit(ev);
if (fromSU != kODNULL)
CopyDraftAnnotations(ev, fromSU, toSU);
#ifdef _NO_TMP_OBJS_
tempFromObject->Release(ev);
scopeFrame->Release(ev);
#endif
}
else {
#ifdef _NO_TMP_OBJS_
ODStorageUnit *fromSU = somSelf->AcquireStorageUnit(ev, fromID);
#else
TempODStorageUnit fromSU = somSelf->AcquireStorageUnit(ev, fromID);
#endif
if (fromSU != kODNULL) {
#ifdef _PLATFORM_OS2_
// If the following conditions are all met:
// o This SU has the CloneOfALinkProperty
// o This SU has a valid LinkTargetToLinkSource reference
// (implying the link was cloned together with its linksource)
// o Origin is a live document (clonekind is Copy, Cut, or CopytoLink)
// then we must convert the SU into an object before further cloning.
// The reason is that the linkid information in the SU
// is invalid, as a result of our decision not to register
// copied linksources with the AS until they have been opened.
if (fromSU->Exists(ev, kODPropCloneOfALink, kODNULL, 0) &&
somSelf->CompanionWasCloned(ev, fromID, kODPropLinkTargetToLinkSource) &&
(_fCloneKind == kODCloneCopy || _fCloneKind == kODCloneCut || _fCloneKind == kODCloneToLink) ) {
fromObject = (ODPersistentObject*) somSelf->AcquireLink(ev, fromID, (ODLinkSpec*) kODNULL);
ODFrame* scopeFrame = kODNULL;
if (scopeID != 0)
scopeFrame = somSelf->AcquireFrame(ev, scopeID);
fromObject->CloneInto(ev, key, toSU, scopeFrame);
fromObject->Release(ev);
if (scopeFrame != kODNULL)
scopeFrame->Release(ev);
} else {
fromSU->CloneInto(ev, key, toSU, scopeID);
}
// fromSU->Release(ev);
#else
fromSU->CloneInto(ev, key, toSU, scopeID);
ODBoolean keepProxyProperties = (_fCloneKind == kODCloneToFile)
|| (_fCloneKind == kODCloneAll);
RemoveDataInterchangeProperties(ev, toSU, keepProxyProperties);
// CopyDraftAnnotations(ev, fromSU, toSU);
#endif // _PLATFORM_OS2_
}
#ifdef _NO_TMP_OBJS_
fromSU->Release(ev);
#endif
}
#ifdef DebugClone
somPrintf("Done CMDraftStrongClone %d\n", toID);
#endif
#ifdef _NO_TMP_OBJS_
toSU->Release(ev);
#endif
}
catch (ODException _exception)
{
toID = 0;
ODSetSOMException(ev, _exception);
}
return toID;
}
//------------------------------------------------------------------------------
// CMDraft: WeakClone
//------------------------------------------------------------------------------
SOM_Scope ODID SOMLINK CMDraftWeakClone(CMDraft *somSelf, Environment *ev,
ODDraftKey key,
ODID fromID,
ODID toObjectID,
ODID scopeID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","Clone");
ODStorageUnitID toID = 0;
try
{
_fClonedSUIDs->GetValue(&fromID, &toID);
if (toID == 0)
{
_fWeakClonedSUIDs->GetValue(&fromID, &toID);
if (toID == 0)
{
toID = toObjectID;
if ( toID == 0 )
{
// Note that this may substitute the null object id, which
// will be returned instead of a valid object id!
#ifdef _PLATFORM_OS2_
ODBoolean substitute = kODFalse;
#else
ODBoolean substitute = somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID);
#endif
if ( !substitute )
// if ( !somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID) )
{
if ( somSelf->GetCloneKind(ev) == kODCloneDropMove )
{
// If this clone is a move back into the original draft,
// substitute the original object, making this equivalent to
// a strong clone.
if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
toID = somSelf->GetOriginalID(ev, fromID);
}
if ( toID == 0 )
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *toSU = _fDestDraft->CreateStorageUnit(ev);
#else
TempODStorageUnit toSU = _fDestDraft->CreateStorageUnit(ev);
#endif
toID = toSU->GetID(ev);
_fWeakClonedSUIDs->ReplaceEntry(&fromID, &toID);
#ifdef _NO_TMP_OBJS_
toSU->Release(ev);
#endif
}
}
}
}
}
if ((toObjectID != 0) && (toObjectID != toID))
THROW(kODErrInvalidID);
}
catch (ODException _exception)
{
toID = 0;
ODSetSOMException(ev, _exception);
}
return toID;
}
//------------------------------------------------------------------------------
// CMDraft: IsValidDraftKey
//------------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK CMDraftIsValidDraftKey(CMDraft *somSelf, Environment *ev,
ODDraftKey key)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","IsValidDraftKey");
return ((key != kODNULLKey) && (_fCurrentKey == key) ? kODTrue : kODFalse);
}
//------------------------------------------------------------------------------
// CopyProperty
//------------------------------------------------------------------------------
static void CopyProperty(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU, ODPropertyName prop)
{
// Assuming fromSU is focused to prop.
// Copy all values into toSU, overwriting any existing values there.
try
{
PreserveFocus fromFocus(ev, fromSU);
PreserveFocus toFocus(ev, toSU);
ODULong numValues;
ODULong j;
ODValueType valueName;
fromSU->Focus(ev, (ODPropertyName) prop, kODPosUndefined, kODNULL, 0, kODPosAll);
numValues = fromSU->CountValues(ev);
if ( numValues > 0)
ODSUForceFocus(ev, toSU, prop, kODNULL);
for (j = 0; j < numValues; j++)
{
fromSU->Focus(ev, (ODPropertyName) kODNULL, kODPosSame, kODNULL, 0, kODPosNextSib);
valueName = fromSU->GetType(ev);
ODSUForceFocus(ev, toSU, prop, valueName);
ODULong toSize = toSU->GetSize(ev);
toSU->DeleteValue(ev, toSize);
ODDisposePtr(valueName);
ODULong size = fromSU->GetSize(ev);
ODPtr buffer = ODNewPtr(size);
StorageUnitGetValue(fromSU, ev, size, (ODValue) buffer);
StorageUnitSetValue(toSU, ev, size, (ODValue) buffer);
ODDisposePtr(buffer);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CopyDraftAnnotations
//------------------------------------------------------------------------------
static void CopyDraftAnnotations(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU)
{
try
{
ODULong annotationPrefixLength = ODISOStrLength(kODPropPreAnnotation);
ODULong metaDataPrefixLength = ODISOStrLength(kODPropPreODMetaData);
fromSU->Focus(ev, (ODPropertyName) kODNULL,
kODPosAll,
kODTypeAll,
0,
kODPosUndefined);
ODULong numProperties = fromSU->CountProperties(ev);
for (ODULong i = 1; i <= numProperties; i++) {
fromSU->Focus(ev, (ODPropertyName) kODNULL,
kODPosNextSib,
kODTypeAll,
0,
kODPosUndefined);
ODPropertyName propertyName = fromSU->GetProperty(ev);
if (ODISOStrNCompare(propertyName, kODPropPreAnnotation, annotationPrefixLength) == 0)
CopyProperty(ev, fromSU, toSU, propertyName);
else if ((ODISOStrNCompare(propertyName, kODPropPreODMetaData, metaDataPrefixLength) == 0) &&
(toSU->Exists(ev, propertyName, kODNULL, 0) == kODFalse)) {
#ifdef ODDebug_CloningAnnotations
SetOutputMode(kWriteToFile);
PRINT("metadata property %s does not exist in destination su.\n", propertyName);
#endif
CopyProperty(ev, fromSU, toSU, propertyName);
}
ODDisposePtr(propertyName);
}
// Force copying of storage unit type property, which always exists so is
// not copied in the iteration above.
CopyProperty(ev, fromSU, toSU, kODPropStorageUnitType);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// IsLinkObject
//------------------------------------------------------------------------------
static ODBoolean IsLinkObject(Environment* ev, ODDraft* draft, ODID objectID)
{
// Only link objects contain a kODPropLinkSource property
// in OS2, a kODPropAvailabilityServerName property
ODBoolean isLink = kODFalse;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = draft->AcquireStorageUnit(ev, objectID);
#else
TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
#endif
#ifdef _PLATFORM_OS2_
isLink = su->Exists(ev, kODPropAvailabilityServerName, kODNULL, 0);
#else
isLink = su->Exists(ev, kODPropLinkSource, kODNULL, 0);
#endif
#ifdef DebugClone
somPrintf("IsLinkObject returns %u\n", isLink);
#endif
#ifdef _NO_TMP_OBJS_
su->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return isLink;
}
//------------------------------------------------------------------------------
// IsLinkSourceObject
//------------------------------------------------------------------------------
static ODBoolean IsLinkSourceObject(Environment* ev, ODDraft* draft, ODID objectID)
{
// Only link source objects contain a kODPropLink property
// in OS2, a kODPropLinkSourceState property
ODBoolean isLink = kODFalse;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = draft->AcquireStorageUnit(ev, objectID);
#else
TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
#endif
#ifdef _PLATFORM_OS2_
isLink = su->Exists(ev, kODPropLinkSourceState, kODNULL, 0);
#else
isLink = su->Exists(ev, kODPropLink, kODNULL, 0);
#endif
#ifdef DebugClone
somPrintf("IsLinkSourceObject returns %u\n", isLink);
#endif
#ifdef _NO_TMP_OBJS_
su->Release(ev);
#endif
}
catch (ODException _exception)
{
isLink = kODFalse;
ODSetSOMException(ev, _exception);
}
return isLink;
}
//------------------------------------------------------------------------------
// IsNeitherLinkObject
//------------------------------------------------------------------------------
static ODBoolean IsNeitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID)
{
if ( IsLinkObject(ev, draft, objectID) )
return kODFalse;
else
return !IsLinkSourceObject(ev, draft, objectID);
}
//------------------------------------------------------------------------------
// SetStorageUnitType
//------------------------------------------------------------------------------
static void SetStorageUnitType(Environment* ev, ODDraftPermissions perms, ODStorageUnit* su, ODType suType)
{
try
{
if (perms == kODDPExclusiveWrite)
{
#ifdef _NO_TMP_OBJS_
char *curType = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
#else
TempODType curType = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
#endif
if (!curType || !ODISOStrEqual(curType, suType))
ODSetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, suType);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// GetStorageUnitType
//------------------------------------------------------------------------------
static ODISOStr GetStorageUnitType(Environment* ev, ODDraft* draft, ODID objectID)
{
ODISOStr Storageunittype = kODNULL;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *su = draft->AcquireStorageUnit(ev, objectID);
#else
TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
#endif
PreserveFocus fromFocus(ev, su);
Storageunittype = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return Storageunittype;
}
//------------------------------------------------------------------------------
// RootPartID
//------------------------------------------------------------------------------
static ODID RootPartID(Environment* ev, ODDraft* draft)
{
ODID RootpartID = kODNULLID;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *draftProperties = draft->AcquireDraftProperties(ev);
#else
TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
#endif
RootpartID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return RootpartID;
}
//------------------------------------------------------------------------------
// CheckClonedObject
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftCheckClonedObject(CMDraft *somSelf, Environment *ev,
ODID fromID,
ODID toID,
ODID originalID)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CheckClonedObject");
ODISOStr storageUnitType = kODNULL; ODVolatile(storageUnitType);
try
{
storageUnitType = GetStorageUnitType(ev, somSelf, fromID);
#ifdef DebugClone
somPrintf("CheckClonedObject: Type is %s\n", storageUnitType);
#endif
if ( ODISOStrEqual(kODFrameObject, storageUnitType) )
{
_fAnyFrameCloned = kODTrue;
}
else if ( ODISOStrEqual(kODPartObject, storageUnitType) )
{
if ( (toID == originalID) && (RootPartID(ev, somSelf) == fromID) )
{
_fRootPartReused = kODTrue;
#ifdef DebugClone
somPrintf("CheckClonedObject: Root part reused\n");
#endif
}
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
ODDisposePtr(storageUnitType);
}
//------------------------------------------------------------------------------
// SetOriginalDraft
//------------------------------------------------------------------------------
static void SetOriginalDraft(Environment* ev, ODDraft* targetDraft, ODDraft* originalDraft)
{
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *draftProperties = targetDraft->AcquireDraftProperties(ev);
#else
TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
#endif
ODSetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong, (ODULong) originalDraft);
// Save the process ID to be used by the drop/paste site.
// If the process ID in the drag/cut site is the same as the process
// ID in the drop site, then drag-n-drop/cut-n-paste happens within
// the same document.
int pid = getpid();
ODSetULongProp(ev, draftProperties, kODPropOriginalPID, kODULong, (ODULong) pid);
#ifdef _NO_TMP_OBJS_
draftProperties->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// GetOriginalDraft
//------------------------------------------------------------------------------
// Returns kODNULL if the original draft is unknown. This is the case when content
// was placed in the draft without cloning.
static ODDraft* GetOriginalDraft(Environment* ev, ODDraft* draft)
{
ODDraft* retDraft = kODNULL;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *draftProperties = draft->AcquireDraftProperties(ev);
#else
TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
#endif
// Retrieve the process ID belonging to the drag/cut site
int originalPID = ODGetULongProp(ev, draftProperties, kODPropOriginalPID, kODULong);
// If the process ID of the drag/cut site is the same as the process ID
// of the drop/paste site, then drag-n-drop/cut-n-paste is within the
// same document.
// If this is within the same document, then return the original draft.
// Otherwise, if it is across documents, then return kODNULL as
// the original draft.
if (originalPID == getpid())
retDraft = (ODDraft*)ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
else
retDraft = kODNULL;
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return retDraft;
}
//------------------------------------------------------------------------------
// OriginalCloneKindExists
//------------------------------------------------------------------------------
static ODBoolean OriginalCloneKindExists(Environment* ev, ODDraft* draft)
{
ODBoolean OrgCloneKindExists = kODFalse;
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *draftProperties = draft->AcquireDraftProperties(ev);
#else
TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
#endif
OrgCloneKindExists = draftProperties->Exists(ev, kODPropOriginalCloneKind, kODULong, 0);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
return OrgCloneKindExists;
}
//------------------------------------------------------------------------------
// SetOriginalCloneKind
//------------------------------------------------------------------------------
static void SetOriginalCloneKind(Environment* ev, ODDraft* targetDraft, ODCloneKind cloneKind)
{
try
{
#ifdef _NO_TMP_OBJS_
ODStorageUnit *draftProperties = targetDraft->AcquireDraftProperties(ev);
#else
TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
#endif
ODSetULongProp(ev, draftProperties, kODPropOriginalCloneKind, kODULong, (ODULong) cloneKind);
#ifdef _NO_TMP_OBJS_
draftProperties->Release(ev);
#endif
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: GetHeap
//------------------------------------------------------------------------------
SOM_Scope ODMemoryHeapID SOMLINK CMDraftGetHeap(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetHeap");
return _fHeap;
}
//------------------------------------------------------------------------------
// CMDraft: CreateLinkIterator
//------------------------------------------------------------------------------
SOM_Scope ODLinkIterator* SOMLINK CMDraftCreateLinkIterator(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateLinkIterator");
CMLinkIterator* iter = kODNULL;
ODVolatile(iter);
try
{
iter = new CMLinkIterator();
THROW_IF_NULL(iter, kODErrOutOfMemory);
iter->InitCMLinkIterator(ev, somSelf);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
ODDeleteObject(iter);
}
return (ODLinkIterator*) iter;
}
//------------------------------------------------------------------------------
// CMDraft: CreateLinkSourceIterator
//------------------------------------------------------------------------------
SOM_Scope ODLinkSourceIterator* SOMLINK CMDraftCreateLinkSourceIterator(CMDraft *somSelf, Environment *ev)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreateLinkSourceIterator");
CMLinkSourceIterator* iter = kODNULL;
ODVolatile(iter);
try
{
iter = new CMLinkSourceIterator();
THROW_IF_NULL(iter, kODErrOutOfMemory);
iter->InitCMLinkSourceIterator(ev, somSelf);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
ODDeleteObject(iter);
}
return (ODLinkSourceIterator*) iter;
}
//------------------------------------------------------------------------------
// CM_itoa KP
//------------------------------------------------------------------------------
static void CM_itoa(ODULong number, ODSByte* cstring)
{
ODULong i = 0;
do {
cstring[i++] = (ODSByte) (number % 10 + '0');
} while ((number /= 10) > 0);
cstring[i] = '\0';
ODSByte c;
ODULong j;
for (i = 0, j = strlen(cstring)-1; i < j;i++, j--) {
c = cstring[i];
cstring[i] = cstring[j];
cstring[j] = c;
}
}
//------------------------------------------------------------------------------
// NewCMStorageUnit
//------------------------------------------------------------------------------
static CMStorageUnit* NewCMStorageUnit(ODMemoryHeapID heapID)
{
CMStorageUnit* cmStorageUnit = kODNULL;
Environment* ev = somGetGlobalEnvironment();
try
{
#ifdef _PLATFORM_MACINTOSH_
SOMClass* cmStorageUnitClass = somNewClassReference(CMStorageUnit);
ODULong size = cmStorageUnitClass->somGetInstanceSize();
ODPtr buffer = ODNewPtr(size, heapID);
cmStorageUnit = (CMStorageUnit*) cmStorageUnitClass->somRenew(buffer);
somReleaseClassReference ( cmStorageUnitClass );
#endif
#if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
cmStorageUnit = new CMStorageUnit;
#endif
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
ODDeleteObject(cmStorageUnit);
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
}
return cmStorageUnit;
}
//------------------------------------------------------------------------------
// PurgeAllStorageUnits
//------------------------------------------------------------------------------
static ODULong PurgeAllStorageUnits(Environment* ev, OpenHashTable* storageUnits, IDList* idList)
{
ODULong runningTotal = 0;
try
{
ODID id;
ODStorageUnit* su;
// idList is used to indicate whether we need to remove linkage between id and cmObject
OpenHashTableIterator suIter(storageUnits);
for (suIter.First(&id, &su); suIter.IsNotComplete(); suIter.Next(&id, &su)) {
if (su->GetRefCount(ev) != 0) {
if (idList) // purge should release CMObject, signal that by removing from idList
idList->Remove(id);
runningTotal += su->Purge(ev, 0);
}
}
/*
for (suIter.First(&id, &su); suIter.IsNotComplete(); suIter.Next(&id, &su)) {
if (su->GetRefCount(ev) == 0) {
suIter.RemoveCurrent();
delete su;
}
}
*/
storageUnits->ShrinkToFit(/*extraSlots*/ 0);
}
catch (ODException _exception)
{
runningTotal = 0;
ODSetSOMException(ev, _exception);
}
return runningTotal;
}
//------------------------------------------------------------------------------
// PurgeClasses
//------------------------------------------------------------------------------
static void PurgeClasses(Environment* ev, OpenHashTable* partClasses)
{
try
{
OpenHashTableIterator classes(partClasses);
SOMClass* partClass;
ODULong count;
#ifdef ODDebug_Unloading_Classes
PRINT("**** Purging classes.....\n");
#endif
for (classes.First(&partClass, &count); classes.IsNotComplete(); classes.Next(&partClass, &count)) {
#ifdef ODDebug_Unloading_Classes
if (somIsObj(partClass)) {
corbastring className = partClass->somGetName();
PRINT("Class %x %s count %d\n", partClass, className, count);
}
else {
PRINT("%x is not a valid som object.\n", partClass);
}
#endif
if (count == 0) {
// SOMClassMgrObject->somUnregisterClass(partClass);
classes.RemoveCurrent();
}
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: PartInstantiated
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftPartInstantiated(CMDraft *somSelf, Environment *ev,
ODPart* realPart)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","PartInstantiated");
try
{
SOMClass* partClass = realPart->somGetClass();
#ifdef ODDebug_Unloading_Classes
corbastring className = partClass->somGetName();
PRINT(">>>> Instantiating %s\n", className);
#endif
ODULong count = 1;
if (_fPartClasses->GetValue(&partClass, &count)) {
++count;
_fPartClasses->ReplaceEntry(&partClass, &count);
}
else {
_fPartClasses->ReplaceEntry(&partClass, &count);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: PartDeleted
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftPartDeleted(CMDraft *somSelf, Environment *ev,
ODPart* realPart)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","PartDeleted");
try
{
SOMClass* partClass = realPart->somGetClass();
#ifdef ODDebug_Unloading_Classes
corbastring className = partClass->somGetName();
PRINT("<<<< Deleting %s\n", className);
#endif
ODULong count = 0;
// Check if _fPartClasses is valid before accessing it
if ((_fPartClasses) && (_fPartClasses->GetValue(&partClass, &count)))
{
if (count > 0) {
--count;
_fPartClasses->ReplaceEntry(&partClass, &count);
}
else
WARNMSG_DEBUG(WARN_INDEX(-1),
"Instances of class %s have been deleted. But %x is found.",
partClass, realPart);
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
//------------------------------------------------------------------------------
// CMDraft: SwapPart
//------------------------------------------------------------------------------
SOM_Scope void SOMLINK CMDraftSwapPart(CMDraft *somSelf, Environment *ev,
ODPart* part)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","SwapPart");
try
{
OpenHashTableIterator i(_fPersistentObjects);
ODStorageUnitID id;
ODPersistentObject* object;
ODFrame* frame;
somSelf->Externalize(ev);
for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
if ( strcmp(object->somGetClassName(), kFrameClassName)==0 ) {
frame = (ODFrame*)object;
if ( frame->IsSubframe(ev) == kODFalse )
frame->PrepareToSwap(ev, part);
}
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
}
}
#ifdef _PLATFORM_OS2_
//------------------------------------------------------------------------------
// CMDraft: CreatePartLinkSourceIterator
//------------------------------------------------------------------------------
SOM_Scope ODLinkSourceIterator* SOMLINK CMDraftCreatePartLinkSourceIterator(CMDraft *somSelf, Environment *ev, ODPart* part)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreatePartLinkSourceIterator");
CMLinkSourceIterator* linkSourceIter = kODNULL;
try
{
linkSourceIter = new CMLinkSourceIterator();
linkSourceIter->InitCMLinkSourceIterator(ev, somSelf);
_fLinkService->GetLinkSourcesForPart(ev,part,linkSourceIter);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
ODDeleteObject(linkSourceIter);
}
return (ODLinkSourceIterator*)linkSourceIter;
}
//------------------------------------------------------------------------------
// CMDraft: CreatePartLinkIterator
//------------------------------------------------------------------------------
SOM_Scope ODLinkIterator* SOMLINK CMDraftCreatePartLinkIterator(CMDraft *somSelf, Environment *ev, ODPart* part)
{
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","CreatePartLinkIterator");
CMLinkIterator* linkTargetIter = kODNULL;
try
{
linkTargetIter = new CMLinkIterator();
linkTargetIter->InitCMLinkIterator(ev, somSelf);
_fLinkService->GetLinkTargetsForPart(ev,part,linkTargetIter);
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
ODDeleteObject(linkTargetIter);
}
return (ODLinkIterator*)linkTargetIter;
}
// *=============================================================================
// * CMDraft: GetLinkSrcForAvlSvr
// *=============================================================================
SOM_Scope ODLinkSource*
SOMLINK CMDraftGetLinkSrcForAvlSvr(CMDraft *somSelf,
Environment *ev,
ODStorageUnitID id,
IODAuxiliaryState *auxState)
{
// We are assuming that this is only called on an id
// of a linksource which has not yet been internalized.
// This call is only made on surrogate drafts.
// The availserver is responsible for releasing the usecount.
// This is like AcquireLinkSource but no call is made to the LinkService.
// It is impossible for the linkid to change since the
// availability server only knows about links after registration.
CMDraftData *somThis = CMDraftGetData(somSelf);
CMDraftMethodDebug("CMDraft","GetLinkSrcForAvlSvr");
IODLinkSource* linkSource = (IODLinkSource*)kODNULL;
try
{
linkSource = ((IODLinkSource*)somSelf->RetrievePersistentObject(ev, id));
if (linkSource == (IODLinkSource*)kODNULL)
{
linkSource = new IODLinkSource();
if (linkSource == (IODLinkSource*)kODNULL)
{
THROW(kODErrCannotAcquireLink);
}
ODStorageUnit* su = (ODStorageUnit*)kODNULL;
ODVolatile(su);
ODVolatile(id);
try
{
su = somSelf->AcquireStorageUnit(ev, id);
_fPersistentObjects->ReplaceEntry(&id, &linkSource);
linkSource->InitILinkSourceFromStorage(ev, su);
linkSource->CompleteInitILinkSource(ev, su, 0, auxState, kODFalse, (ODISOStr)"");
}
catch (ODException _exception)
{
ODError error = ErrorCode();
SaveEv();
try
{
if (su != (ODStorageUnit*) kODNULL)
{
_fPersistentObjects->RemoveEntry(&id);
su->Release(ev);
}
linkSource->ReleaseAll(ev);
delete linkSource;
}
catch(ODException _exception)
{
SetErrorCode(kODNoError);
}
RestoreEv();
ODSetSOMException(ev, error);
throw;
}
}
}
catch (ODException _exception)
{
ODSetSOMException(ev, _exception);
linkSource = kODNULL;
}
return (ODLinkSource*)linkSource;
}
#endif /* _PLATFORM_OS2_ */