home *** CD-ROM | disk | FTP | other *** search
- /*
- File: CMDraft.cpp
-
- Contains: Implementation for CMDraft class.
-
- Owned by: Vincent Lo
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <20> 8/13/96 DM 1362809: in CloseVersion(), close embedded
- container before release, fatal error on
- failure
- <19> 7/31/96 DH #1373676:Fixed ConstructRealPart so that
- the real part will not be set erroneously.
- <18> 7/25/96 DH Fixed NewCMxx methods to check the
- somClassReference allocation and throw if
- null (No bug #, approved by Bern).
- <17> 7/23/96 DH Bug# 1371089: OD crashes when parts throw
- out of InitPartFromStorage: Approved by
- Bern.
- <16> 7/11/96 jpa 1364071: Don't pass "NoPart" as preferred
- editor name to NoPart. Catch
- kODErrOutOfMemory when creating parts.
- <15> 6/27/96 EL 1361735: if no editor user string, use SOM
- class name
- <14> 6/27/96 jpa 1361886: ConstructRealPart sets NoPart user
- message.
- <13> 6/23/96 EL 1344140: if out of memory when new part is
- initialized, tread as cannot load part.
- <12> 6/22/96 EL 1344140: put up alert if we cannot create
- part.
- <11> 5/30/96 CC 1332786: Add std prefix to private property
- & value type.
- <10> 5/24/96 jpa 1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
- <8> 3/22/96 CC 1330388: Support direct clone between
- document drafts.
- <7> 3/15/96 DM 1295410: create list iterators on stack
- (avoid mem thrash during purge)
- 1292140: throw when persistent object has
- no storage unit getting draft or session
- <6> 3/15/96 CC 1316917: Don't remove valuable data
- interchange properties when cloning with
- kODCloneAll.
- <5> 3/13/96 VL 1305064: Removed class purging code as it
- is done by SOM now.
- <4> 3/8/96 EL 1308013: If loading of editor fails,
- replace by NoPart. Code reviewed by DM.
- <3> 1/16/96 VL 1170098: Emptied out PartDeleted and
- PartInstantiated as they are no longer
- needed.
- <2> 1/15/96 TJ Cleaned Up
-
- To Do:
- In Progress:
-
- */
-
- #define CMDraft_Class_Source
- #define VARIABLE_MACROS
- #include <CMDraft.xih>
-
- #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
-
- #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
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef SOM_ODDragAndDrop_xh
- #include <DragDrp.xh>
- #endif
-
- #ifndef SOM_ODArbitrator_xh
- #include <Arbitrat.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Foci_defined
- #include <Foci.xh>
- #endif
-
- #ifndef _ODNEWOBJ_
- #include <ODNewObj.h>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include <StdDefs.xh>
- #endif
-
- #ifndef SOM_SOMClassMgr_xh
- #include <somcm.xh>
- #endif
-
- #ifndef _STORRSRC_
- #include <StorRsrc.h>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _BNDNSUTL_
- #include <BndNSUtl.h>
- #endif
-
- #ifndef SOM_Module_Apple_defined
- #include <NoPart.xh>
- #endif
-
- // remove later
-
- #ifndef SOM_ODDispatcher_xh
- #include <Disptch.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- // remove to here
-
- #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";
-
- #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 IsEitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID);
- static ODBoolean IsNeitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID);
-
- static void itoa(ODULong number, ODSByte* cstring);
-
- 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);
-
- // 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 = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:ClonedObjectTable";
- const ODValueType kODTypeClonedObjectTable = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Type:ClonedObjectTable";
-
- ODStatic void ReadClonedObjectTable(Environment* ev, OpenHashTable* clonedSUIDs, ODDraft* destDraft)
- {
- #ifdef DebugClone
- somPrintf("CMDraft: ReadClonedObjectTable\n");
- #endif
-
- TempODStorageUnit su = destDraft->AcquireDraftProperties(ev);
- 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);
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // WriteClonedObjectTable
- //------------------------------------------------------------------------------
-
- ODStatic void WriteClonedObjectTable(Environment* ev, OpenHashTable* clonedSUIDs, ODDraft* destDraft)
- {
- #ifdef DebugClone
- somPrintf("CMDraft: WriteClonedObjectTable\n");
- #endif
-
- TempODStorageUnit su = destDraft->AcquireDraftProperties(ev);
-
- 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(" from ID %d to ID %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);
- }
-
- //==============================================================================
- // 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");
-
- SOM_TRY
-
- CMObject draftPropertiesObject;
- CMStorageUnit* draftProperties;
- 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);
- return _fDraftProperties;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Acquire
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftAcquire(CMDraft *somSelf, Environment *ev)
- {
- // CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Acquire");
-
- SOM_TRY
- parent_Acquire(somSelf, ev);
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Release
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRelease(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Release");
-
- SOM_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);
- }
-
- SOM_CATCH_ALL
-
- ODError err = ErrorCode();
-
- WARN("Error occurred in ODContainer::Release: %d %s", err, ErrorMessage() ?ErrorMessage() :"");
-
- SetErrorCode(kODNoError);
-
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // 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);
-
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- su = somSelf->CreateSU(ev, kODNULL, kODStorageUnit);
- SetStorageUnitType(ev, _fPermissions, su, kODStorageUnit);
-
- somSelf->SetChangedFromPrevFlag(ev, kODTrue);
-
- SOM_CATCH_ALL
- if (su != kODNULL) {
- TRY{
- somSelf->ReleaseStorageUnit(ev, su->GetID(ev));
- }CATCH_ALL{
- // ignore exception
- }ENDTRY
- su = kODNULL;
- }
- SOM_ENDTRY
- return su;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: IsValidID
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBoolean SOMLINK CMDraftIsValidID(CMDraft *somSelf, Environment *ev,
- ODID id)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","IsValidID");
-
- SOM_TRY
-
- if ( id != kODNULLID )
- return _fIDList->Exists(id);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: AcquireStorageUnit
- //------------------------------------------------------------------------------
-
- SOM_Scope ODStorageUnit* SOMLINK CMDraftAcquireStorageUnit(CMDraft *somSelf, Environment *ev,
- ODStorageUnitID id)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","AcquireStorageUnit");
-
- SOM_TRY
-
- if (id == kODNULLID)
- THROW(kODErrIllegalNullIDInput);
-
- ODStorageUnit* su = kODNULL;
-
- if (_fStorageUnits->GetValue(&id, &su)) {
- su->Acquire(ev);
- }
- else if ((_fIDList->Exists(id) == kODFalse) ||
- (_fIDList->Get(id) != kODNULL)) {
- su = somSelf->CreateSU(ev, id, kODStorageUnit);
- }
- return su;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemoveStorageUnit
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemoveStorageUnit(CMDraft *somSelf, Environment *ev,
- ODStorageUnit* su)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemoveStorageUnit");
-
- SOM_TRY
-
- CMContainer cmContainer = somSelf->GetCMContainer(ev);
- ODSessionMustHaveCMAllocReserve(cmContainer);
-
- ODID id;
- CMObject object;
- ODStorageUnit* draftProperties;
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- 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);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ChangedFromPrev
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBoolean SOMLINK CMDraftChangedFromPrev(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ChangedFromPrev");
-
- SOM_TRY
-
- ODBoolean changedFromPrev;
- VersionList* versionList = kODNULL;
-
- versionList = _fDocument->TestAndGetVersionList(ev);
- ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
-
- TRY
- changedFromPrev = somSelf->IsChangedFromPrev(ev, versionList);
-
- CATCH_ALL
-
- _fDocument->ReleaseVersionList(ev);
- RERAISE;
-
- ENDTRY
-
- _fDocument->ReleaseVersionList(ev);
-
- return changedFromPrev;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: SetChangedFromPrev
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftSetChangedFromPrev(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","SetChangedFromPrev");
-
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- somSelf->SetChangedFromPrevFlag(ev, kODTrue);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemoveFromDocument
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemoveFromDocument(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemoveFromDocument");
-
- SOM_TRY
-
- _fDocument->CollapseDrafts(ev, somSelf, kODNULL);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemoveChanges
- //------------------------------------------------------------------------------
-
- SOM_Scope ODDraft* SOMLINK CMDraftRemoveChanges(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemoveChanges");
-
- SOM_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_ALL
-
- _fDocument->ReleaseVersionList(ev);
- RERAISE;
-
- ENDTRY
-
- #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
-
- return somSelf;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Externalize
- //------------------------------------------------------------------------------
-
- SOM_Scope ODDraft* SOMLINK CMDraftExternalize(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Externalize");
-
- SOM_TRY
-
- somSelf->ExternalizeCollections(ev);
-
- _fExternalized = kODTrue;
-
- // DO THE ACTUAL EXTERNALIZATION HERE
-
- somSelf->FlushVersion(ev);
-
- return somSelf;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: SaveToAPrevious
- //------------------------------------------------------------------------------
-
- SOM_Scope ODDraft* SOMLINK CMDraftSaveToAPrevious(CMDraft *somSelf, Environment *ev,
- ODDraft* to)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","SaveToAPrevious");
-
- SOM_TRY
-
- _fDocument->SaveToAPrevDraft(ev, somSelf, to);
- return somSelf;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- 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);
-
- SOM_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);
-
-
- SOM_CATCH_ALL
- 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_ALL{
- // ignore exception
- }ENDTRY
- frame = kODNULL;
- }
- SOM_ENDTRY
-
- 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);
-
- SOM_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);
- }
-
- SOM_CATCH_ALL
- ODSafeReleaseObject(su);
- if( frame ) WASSERT(frame->GetRefCount(ev)==1);
- ODSafeReleaseObject(frame);
- SOM_ENDTRY
-
- return frame;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleaseFrame
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftReleaseFrame(CMDraft *somSelf, Environment *ev,
- ODFrame* frame)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleaseFrame");
-
- SOM_TRY
-
- somSelf->ReleasePersistentObject(ev, frame);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemoveFrame
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemoveFrame(CMDraft *somSelf, Environment *ev,
- ODFrame* frame)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemoveFrame");
-
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- if (frame->GetStorageUnit(ev) == kODNULL)
- frame->Release(ev);
- else
- somSelf->RemovePersistentObject(ev, frame);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // 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;
-
- SOM_TRY
-
- ODSession* session = (ODSession*) _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
- ODBinding* binding = session->GetBinding(ev);
- ODBoolean degradeToNoPart = kODFalse;
- ODError partLoadErr = noErr;
- Str255 partLoadErrStr = "\p";
-
- if (theEditor == kODNULL)
- editorForPart = binding->ChooseEditorForPart(ev, su, partType);
- else
- {
- editorForPart = theEditor;
- if (_fPermissions != kODDPReadOnly)
- ODSetISOStrProp(ev, su, kODPropPreferredEditor, kODEditor, editorForPart);
- }
-
- do {
- // if (degradeToNoPart) {
- // partWrapper->SetRealPart(ev, part, kODBlackBoxHandlerOfLastResort);
- /* Don't display alert now, set NoPart message instead:
- ODIText* editorUserString = kODNULL;
- Str255 editorString = "\p";
- GetUserEditorFromEditor( session->GetNameSpaceManager(ev), editorForPart, &editorUserString );
- TempODIText tempEditorUserString = editorUserString; // ensure it's deleted
- GetITextPString( editorUserString, editorString );
- ParamText(editorString, "\p", "\p", "\p");
- (void) ShowAlert(ev, kODAlertCannotLoadPartError, kODNULL, session);
- */
- // }
-
- ODBoolean editorIsNoPart = ODISOStrEqual(editorForPart, kODBlackBoxHandlerOfLastResort);
- if (degradeToNoPart || editorIsNoPart) {
- part = binding->ConstructNoPart(ev);
- // Set message in part to explain to user why it appeared:
- ODError err;
- ODIText *editorName = kODNULL;
- if( degradeToNoPart ) { // Reason 1: Error loading part
- err = partLoadErr;
- if (!GetUserEditorFromEditor( session->GetNameSpaceManager(ev), editorForPart, &editorName ))
- editorName = CreateIText(smRoman,langEnglish,theEditor);
- } else {
- err = 0; // Reason 2: Couldn't find part editor
- ODULong size;
- // We *must* use preferred-editor-user-string property here once it exists:
- TempODEditor editor = ODGetISOStrProp(ev, su,
- kODPropPreferredEditor, kODEditor, kODNULL, &size);
- if( editor && !ODISOStrEqual(editor,kODBlackBoxHandlerOfLastResort) )
- editorName = CreateIText(smRoman,langEnglish,editor); // SOM classnames are always Roman...
- }
- CAST(part,Apple_NoPart)->SetUserMessage(ev, err,editorName,p2cstr(partLoadErrStr));
-
- } else {
- // try to construct a part, if it fails then construct a NoPart instead
- TRY
- part = (ODPart*) ODNewObject(editorForPart,partLoadErrStr);
- CATCH_ALL
- partLoadErr = ErrorCode();
- degradeToNoPart = kODTrue;
- // note that part is still not valid because the allocation failed
- continue;
- ENDTRY
- }
-
- if (part == kODNULL)
- THROW(kODErrCannotCreatePart);
-
- if (degradeToNoPart) {
- partWrapper->SetRealPart(ev, part, kODBlackBoxHandlerOfLastResort);
- } else
- partWrapper->SetRealPart(ev, part, editorForPart);
-
- ODID id = su->GetID(ev);
- _fPersistentObjects->ReplaceEntry(&id, &partWrapper);
-
- su->Acquire(ev); //This new reference belongs to the part
-
- TRY
- if (isInitPartFromStorage)
- partWrapper->InitPartFromStorage(ev, su, partWrapper);
- else
- partWrapper->InitPart(ev, su, partWrapper);
- CATCH_ALL
- // if ( ErrorCode() != memFullErr && ErrorCode()!=kODErrOutOfMemory )
- // RERAISE;
- // not enough memory to Init, treat as can't load part
- if (part) {
- part->Release(ev); // ReleaseRealPart expect ref count 0
- somSelf->ReleaseRealPart(ev, part);
- part = kODNULL;
- }
- if (degradeToNoPart)
- RERAISE;
- degradeToNoPart = kODTrue;
- partLoadErr = ErrorCode();
- ENDTRY
- } while (degradeToNoPart && (part == kODNULL));
-
- SOM_CATCH_ALL
-
- part = kODNULL;
-
- if( ErrorCode() == kODErrCantLoadSOMClass )
- SetErrorCode(kODErrCannotCreatePart); // Map to more specific error
-
- SOM_ENDTRY
-
- if (editorForPart != theEditor)
- ODDisposePtr(editorForPart);
-
- return part;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleaseRealPart
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftReleaseRealPart(CMDraft *somSelf, Environment *ev,
- ODPart* realPart)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleaseRealPart");
-
- SOM_TRY
-
- if (realPart == kODNULL)
- THROW(kODErrIllegalNullPartInput);
-
- if (realPart->GetRefCount(ev) != 0)
- THROW(kODErrRefCountGreaterThanZero);
-
- realPart->ReleaseAll(ev);
-
- delete realPart;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DeleteRealPart
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftDeleteRealPart(CMDraft *somSelf, Environment *ev,
- ODPart* realPart)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DeleteRealPart");
-
- SOM_TRY
-
- if (realPart == kODNULL)
- THROW(kODErrIllegalNullPartInput);
-
- delete realPart;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // 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);
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- TempODStorageUnit su = somSelf->CreateSU(ev, kODNULL, kODPartObject);
-
- 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);
-
- SOM_CATCH_ALL
-
- ODSafeReleaseObject(partWrapper);
- partWrapper = kODNULL;
-
- SOM_ENDTRY
-
- 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);
- SOM_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);
- TempODStorageUnit tempSU = su; // ensure it's released
-
- 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);
- }
-
- SOM_CATCH_ALL
-
- ODSafeReleaseObject(partWrapper);
- part = kODNULL;
-
- SOM_ENDTRY
-
- return part;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleasePart
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftReleasePart(CMDraft *somSelf, Environment *ev,
- ODPart* part)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleasePart");
-
- SOM_TRY
-
- somSelf->ReleasePersistentObject(ev, part);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemovePart
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemovePart(CMDraft *somSelf, Environment *ev,
- ODPart* part)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemovePart");
-
- SOM_TRY
-
- somSelf->RemovePersistentObject(ev, part);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // 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);
- SOM_TRY
- ls = new ODLinkSpec;
- THROW_IF_NULL(ls, kODErrOutOfMemory);
- ls->InitLinkSpec(ev, part, data);
- SOM_CATCH_ALL
- ODDeleteObject(ls);
- SOM_ENDTRY
-
- return ls;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CreateLinkSource
- //------------------------------------------------------------------------------
-
- SOM_Scope ODLinkSource* SOMLINK CMDraftCreateLinkSource(CMDraft *somSelf, Environment *ev,
- ODPart* part)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CreateLinkSource");
-
- SOM_TRY
-
- ODStorageUnitID id;
- ODLinkSource* linkSource = kODNULL;
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- TempODStorageUnit su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
-
- // 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);
-
- TempODLink link = kODNULL;
- TRY
- link = somSelf->CreateLink(ev);
- CATCH_ALL
- linkSource->ReleaseAll(ev);
- delete linkSource;
- RERAISE;
- ENDTRY
-
- id = su->GetID(ev);
-
- _fPersistentObjects->ReplaceEntry(&id, &linkSource);
-
- linkSource->InitLinkSource(ev, su.DontRelease(), part);
- // ("DontDelete" prevents su from being auto-released by destructor)
-
- link->SetLinkSource(ev, linkSource);
- linkSource->SetLink(ev, link);
-
- somSelf->SetChangedFromPrevFlag(ev, kODTrue);
-
- return linkSource;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: AcquireLinkSource
- //------------------------------------------------------------------------------
-
- SOM_Scope ODLinkSource* SOMLINK CMDraftAcquireLinkSource(CMDraft *somSelf, Environment *ev,
- ODStorageUnitID id)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","AcquireLinkSource");
-
- SOM_TRY
-
- if (id == kODNULLID)
- THROW(kODErrIllegalNullIDInput);
-
- ODLinkSource* linkSource = (ODLinkSource*) kODNULL;
-
- 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_ALL
- if (su != (ODStorageUnit*) kODNULL) {
- _fPersistentObjects->RemoveEntry(&id);
- su->Release(ev);
- }
- linkSource->ReleaseAll(ev);
- delete linkSource;
- RERAISE;
- ENDTRY
- }
-
- return linkSource;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemoveLinkSource
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemoveLinkSource(CMDraft *somSelf, Environment *ev,
- ODLinkSource* linkSource)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemoveLinkSource");
-
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- somSelf->RemovePersistentObject(ev, linkSource);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CreateLink
- //------------------------------------------------------------------------------
-
- SOM_Scope ODLink* SOMLINK CMDraftCreateLink(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CreateLink");
-
- SOM_TRY
-
- ODStorageUnitID id;
- ODLink* link = kODNULL;
- 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);
-
- return link;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: AcquireLink
- //------------------------------------------------------------------------------
-
- SOM_Scope ODLink* SOMLINK CMDraftAcquireLink(CMDraft *somSelf, Environment *ev,
- ODStorageUnitID id,ODLinkSpec* linkSpec)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","AcquireLink");
-
- SOM_TRY
-
- ODLink* link = (ODLink*) kODNULL;
-
- 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_ALL
- if (su != (ODStorageUnit*) kODNULL) {
- _fPersistentObjects->RemoveEntry(&id);
- su->Release(ev);
- }
- link->ReleaseAll(ev);
- delete link;
- RERAISE;
- ENDTRY
- }
- }
- 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_ALL
- DisposeByteArrayStruct(partData);
- ODReleaseObject(ev, linkSource);
- RERAISE;
- ENDTRY
- 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_ALL
- ODReleaseObject(ev, linkSource);
- RERAISE;
- ENDTRY
- ODReleaseObject(ev, linkSource);
- }
- }
- return link;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleaseLink
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftReleaseLink(CMDraft *somSelf, Environment *ev,
- ODLink* link)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleaseLink");
-
- SOM_TRY
-
- somSelf->ReleasePersistentObject(ev, link);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleaseLinkSource
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftReleaseLinkSource(CMDraft *somSelf, Environment *ev,
- ODLinkSource* linkSource)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleaseLinkSource");
-
- SOM_TRY
-
- somSelf->ReleasePersistentObject(ev, linkSource);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemoveLink
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemoveLink(CMDraft *somSelf, Environment *ev,
- ODLink* link)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemoveLink");
-
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- somSelf->RemovePersistentObject(ev, link);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: GetPersistentObjectID
- //------------------------------------------------------------------------------
-
- SOM_Scope ODPersistentObjectID SOMLINK CMDraftGetPersistentObjectID(CMDraft *somSelf, Environment *ev,
- ODPersistentObject* object,
- ODObjectType objectType)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","GetPersistentObjectID");
-
- SOM_TRY
-
- ASSERT(ODISOStrEqual(objectType, kODPartObject) || ODISOStrEqual(objectType, kODFrameObject),
- kODErrInvalidObjectType);
-
- CMStorageUnit* su = (CMStorageUnit*) object->GetStorageUnit(ev);
-
- if (su == kODNULL)
- THROW(kODErrInvalidPersistentObject);
-
- return su->GetObjectID(ev);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULLID;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: AcquirePersistentObject
- //------------------------------------------------------------------------------
-
- SOM_Scope ODPersistentObject* SOMLINK CMDraftAcquirePersistentObject(CMDraft *somSelf, Environment *ev,
- ODPersistentObjectID objectID,
- ODObjectType* objectType)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","AcquirePersistentObject");
-
- SOM_TRY
-
- *objectType = kODNULL;
- ODPersistentObject* object = 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);
-
- TempODStorageUnit su = somSelf->AcquireStorageUnit(ev, id);
- if (su == kODNULL)
- THROW(kODErrInvalidPersistentObjectID);
-
- 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);
- }
-
- return object;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleaseStorageUnit
- //------------------------------------------------------------------------------
-
- SOM_Scope ODDraft* SOMLINK CMDraftReleaseStorageUnit(CMDraft *somSelf, Environment *ev,
- ODStorageUnitID id)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleaseStorageUnit");
-
- SOM_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;
- }
-
- return somSelf;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ~CMDraft
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftsomUninit(CMDraft *somSelf)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","somUninit");
-
- TRY{
- Environment* ev = somGetGlobalEnvironment();
-
- #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
-
- somSelf->DeleteCollections(ev);
- }CATCH_ALL{
- // Ignore exception
- }ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: InitDraft
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftInitDraft(CMDraft *somSelf, Environment *ev,
- ODDocument* document, ODDraftID id, ODDraftPermissions perms)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","InitDraft");
-
- SOM_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;
- _fLinksToCloneSUIDs = 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 ODDebug_Unloading_Classes
- SetOutputMode(kWriteToFile);
- #endif
-
- #ifdef ODDebug_VersionList
- _fDocument->GetVersionList(ev)->Print(">>>Exiting InitDraft");
- #endif
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Purge
- //------------------------------------------------------------------------------
-
- SOM_Scope ODSize SOMLINK CMDraftPurge(CMDraft *somSelf, Environment *ev,
- ODSize size)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Purge");
-
- ODULong runningTotal = 0; ODVolatile( runningTotal );
-
- SOM_TRY
-
- OpenHashTableIterator i(_fPersistentObjects);
- ODStorageUnitID id;
- ODPersistentObject* object;
- for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
- TRY
- runningTotal += object->Purge(ev, size);
- CATCH_ALL
- ENDTRY
-
- TRY
- if (object->GetRefCount(ev) == 0) {
- object->ReleaseAll(ev);
- }
- CATCH_ALL
- ENDTRY
- }
- for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
- if (object->GetRefCount(ev) == 0) {
- i.RemoveCurrent();
- delete object;
- }
- }
- // ShrinkToFit() allocates new tables first, and this aggravates
- // low memory conditions during Purge().
- // _fPersistentObjects->ShrinkToFit(/*extraSlots*/ 0);
-
- // purge all storage units, but don't release CMObjects
- runningTotal += PurgeAllStorageUnits(ev, _fStorageUnits, kODNULL);
-
- // dh - call parent Purge method
- runningTotal += parent_Purge(somSelf, ev, size);
-
- SOM_CATCH_ALL
- WARN("Error %ld trying to purge in CMDraftPurge",ErrorCode());
- SetErrorCode(kODNoError); // dh - Eat the exception; Purge should not
- // propagate it because clients function
- // fine whether memory was purged or not.
- SOM_ENDTRY
-
- 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;
-
- SOM_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_ALL
-
- if (object != kODNULL)
- CMReleaseObject(object);
-
- if (su != kODNULL)
- delete su;
-
- if (ErrorCode() == kODErrBentoInvalidObject)
- THROW(kODErrInvalidID);
- else
- RERAISE;
-
- ENDTRY
- ODSessionRestoreCMAllocReserve(cmContainer);
-
- // Add Storage Unit to outstanding SU collection
-
- _fStorageUnits->ReplaceEntry(&id, &su);
-
- SOM_CATCH_ALL
- su = kODNULL;
- SOM_ENDTRY
-
- 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) {
- SOM_TRY
- somSelf->FailIfNotExclusiveWrite(ev);
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- _fChangedFromPrev = changed;
- }
-
- static void SetupForUpdatingDraft(Environment* ev,
- CMDocument* localDoc,
- ODVersionID prevVersionID,
- CMValue version)
- {
- 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;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CreateVersion
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftCreateVersion(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CreateVersion");
-
- SOM_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;
-
- somSelf->OpenCollections(ev);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: OpenVersion
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftOpenVersion(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","OpenVersion");
-
- SOM_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);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CloseVersion
- //------------------------------------------------------------------------------
-
- extern void ODBentoFatalError(ODBoolean allowSuppress); // SessHdr.cpp
-
- SOM_Scope void SOMLINK CMDraftCloseVersion(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CloseVersion");
-
- SOM_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) {
- // In order to prevent closing errors from being eaten silently inside
- // Release(), we are going to close the embedded container first. This
- // is necessary so that closing errors will propagate up to
- // CMDraft::Close() (called from either CMDocument::ReleaseDraft() or
- // CMDocument::SaveToAPrevDraft()). Otherwise, the bogus draft (with
- // an invalid Bento label) will be blessed by externalizing its id
- // in the new draft version list, which would corrupt the document.
- // Note that we have made sure that closing the embedded container a
- // second time in Release() is silently harmless.
-
- _fEmbeddedContainer->Close(ev);
-
- _fEmbeddedContainer->Release(ev);
- _fEmbeddedContainer = kODNULL;
- }
-
- _fIsNewDraft = kODFalse;
-
- SOM_CATCH_ALL
-
- ODBentoFatalError(/*allowSuppress*/ kODTrue);
-
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // 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) {
- SOM_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;
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- }
-
- //------------------------------------------------------------------------------
- // 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");
-
- SOM_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);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Open
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftOpen(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Open");
-
- SOM_TRY
-
- if (_fEmbeddedContainer == kODNULL) {
- #if lazyOpen
- _fExternalized = kODFalse;
- #else
- if (_fPermissions == kODDPReadOnly)
- somSelf->OpenVersion(ev);
- else
- somSelf->CreateVersion(ev);
- #endif
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- #pragma segment CMDraft2
-
- //------------------------------------------------------------------------------
- // CMDraft: Close
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftClose(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Close");
-
- SOM_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
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Abort
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftAbort(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Abort");
-
- SOM_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_ALL
-
- _fDocument->ReleaseVersionList(ev);
- RERAISE;
-
- ENDTRY
- }
- #else
- _fDocument->InternalizeVersionList(ev);
- #endif
- somSelf->DestroyVersion(ev);
- // _fDocument->Reopen(ev);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Flush
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftFlush(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","Flush");
-
- if (_fPermissions == kODDPExclusiveWrite) {
- SOM_TRY
- somSelf->FlushVersion(ev);
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- }
-
-
- //------------------------------------------------------------------------------
- // 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
- SOM_TRY
- if (_fEmbeddedContainer == kODNULL) {
- if (_fPermissions == kODDPReadOnly)
- somSelf->OpenVersion(ev);
- else
- somSelf->CreateVersion(ev);
- }
- SOM_CATCH_ALL
- SOM_ENDTRY
- #endif
-
- return _fEmbeddedContainer;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: GetCMContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope CMContainer SOMLINK CMDraftGetCMContainer(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","GetCMContainer");
-
- SOM_TRY
-
- #if lazyOpen
- if (_fEmbeddedContainer == kODNULL) {
- if (_fPermissions == kODDPReadOnly)
- somSelf->OpenVersion(ev);
- else
- somSelf->CreateVersion(ev);
- }
- #endif
-
- if (_fEmbeddedContainer == kODNULL)
- THROW(kODErrCannotGetDraftVersion);
- return _fEmbeddedContainer->GetCMContainer(ev);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // AcquireDraftPropertiesObject
- //------------------------------------------------------------------------------
-
- // Callers must ODSessionMustHaveCMAllocReserve() first:
-
- static CMObject AcquireDraftPropertiesObject(CMContainer container)
- {
- CMObject draftPropertiesObject = kODNULL;
- 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);
- }
-
- return draftPropertiesObject;
- }
-
- //------------------------------------------------------------------------------
- // GetVersionNameFromVersionID
- //------------------------------------------------------------------------------
-
- static ODType GetVersionNameFromVersionID(ODVersionID id, ODMemoryHeapID heapID)
- {
- ODSByte* versionName = kODNULL;
- ODSByte cString[kMaxStringSize];
-
- if (id != 0) {
- itoa(id, cString);
- versionName = (ODSByte*) ODNewPtr(strlen(kODVersionNamePrefix) + strlen(cString) + 1, heapID);
- strcpy(versionName, kODVersionNamePrefix);
- strcat(versionName, cString);
- }
- 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;
-
- SOM_TRY
-
- if (_fPersistentObjects->GetValue(&id, &object))
- object->Acquire(ev);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return object;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ReleasePersistentObject
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftReleasePersistentObject(CMDraft *somSelf, Environment *ev,
- ODPersistentObject* object)
- {
- // CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ReleasePersistentObject");
-
- SOM_TRY
-
- if (object->GetRefCount(ev) != 0)
- THROW(kODErrRefCountGreaterThanZero);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: RemovePersistentObject
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftRemovePersistentObject(CMDraft *somSelf, Environment *ev,
- ODPersistentObject* object)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","RemovePersistentObject");
-
- SOM_TRY
-
- 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);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CreateCollections
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftCreateCollections(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CreateCollections");
-
- SOM_TRY
-
- ODMemoryHeapID heap = somSelf->GetHeap(ev);
-
- _fPersistentObjects = new(heap)
- OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash, heap);
- _fPersistentObjects->Initialize(kODInitialNumEntries,
- sizeof(ODStorageUnitID),
- sizeof(ODPersistentObject*));
-
- _fStorageUnits = new(heap)
- OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash, heap);
- _fStorageUnits->Initialize(kODInitialNumEntries,
- sizeof(ODStorageUnitID),
- sizeof(ODStorageUnit*));
-
- _fIDList = new(somSelf->GetHeap(ev)) IDList;
- _fIDList->Initialize();
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DeleteCollections
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftDeleteCollections(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DeleteCollections");
-
- SOM_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) {
- SOM_TRY
- object->ReleaseAll(ev);
- SOM_CATCH_ALL
- WARN("Exception thrown by object %x ID %x error %d\n", object, object->GetID(ev), ErrorCode());
- SOM_ENDTRY
- }
- }
-
- 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);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: ExternalizeCollections
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftExternalizeCollections(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","ExternalizeCollections");
-
- SOM_TRY
-
- ODID id;
- ODStorageUnit* su;
-
- OpenHashTableIterator persistentObjects(_fPersistentObjects);
- ODPersistentObject* object;
-
- for (persistentObjects.First(&id, &object);
- persistentObjects.IsNotComplete();
- persistentObjects.Next(&id, &object)) {
- // Temporarily bump the refcount to make sure that the object is
- // in a valid state.
- object->Acquire(ev);
- TempODRefCntObject tempObject = object; // ensure it's released
- su = object->GetStorageUnit(ev);
- if ((su != kODNULL) && (su->Exists(ev, kODNULL, kODNULL, 0) != kODFalse))
- object->Externalize(ev);
- }
-
- 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);
- TempODStorageUnit tempSU = su; // ensure it's released
- if (su->Exists(ev, kODNULL, kODNULL, 0) != kODFalse)
- su->Externalize(ev);
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CloseCollections
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftCloseCollections(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CloseCollections");
-
- SOM_TRY
-
- somSelf->FailIfNotExclusiveWrite(ev);
-
- somSelf->Purge(ev, 0);
- PurgeAllStorageUnits(ev, _fStorageUnits, _fIDList); // purge SU, relase CMObjects
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: OpenCollections
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftOpenCollections(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","OpenCollections");
-
- SOM_TRY
-
- OpenHashTableIterator storageUnits(_fStorageUnits);
-
- ODID id;
- ODStorageUnit* su;
-
- for (storageUnits.First(&id, &su);
- storageUnits.IsNotComplete();
- storageUnits.Next(&id, &su)) {
- su->Internalize(ev);
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: AreEmptyCollections
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBoolean SOMLINK CMDraftAreEmptyCollections(CMDraft *somSelf, Environment *ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","AreEmptyCollections");
-
- SOM_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;
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // 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.
-
- SOM_TRY
- changedFromPrev = versionList->ChangedFromPrev(_fID);
-
- if ((changedFromPrev != kODFalse) && (_fPermissions == kODDPExclusiveWrite)) {
- prevDraftID = versionList->GetPreviousDraftID(_fID);
- prevVersionID = versionList->GetDraft(prevDraftID);
- if (prevVersionID == _fPrevVersionID)
- changedFromPrev = kODFalse;
- }
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- 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);
- OpenHashTable* linksToCloneSUIDs = kODNULL; ODVolatile(linksToCloneSUIDs);
-
- ODDraftKey result = 0;
-
- SOM_TRY
-
- // 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)
- THROW(kODErrCloningInProgress);
-
- #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:
- if ( somSelf == destDraft )
- THROW(kODErrInvalidDestinationDraft);
- break;
-
- case kODCloneToLink:
- case kODCloneFromLink:
- if ( somSelf != destDraft )
- THROW(kODErrInvalidDestinationDraft);
- break;
-
- case kODCloneAll:
- break;
-
- default:
- THROW(kODErrInvalidCloneKind);
- break;
- }
-
- ODMemoryHeapID heap = somSelf->GetHeap(ev);
-
- // Ensure both hash tables can be allocated
- if ( _fLockCount == 0 )
- {
- clonedSUIDs = new(heap)
- OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash, heap);
- clonedSUIDs->Initialize(kInitialHashTableEntries,
- sizeof(ODStorageUnitID),
- sizeof(ODStorageUnitID));
-
- if ( (kind == kODCloneCut) || (kind == kODCloneCopy) )
- ReadClonedObjectTable(ev, clonedSUIDs, destDraft);
-
- if ( (kind == kODCloneDropCopy) ||
- (kind == kODCloneDropMove) ||
- (kind == kODClonePaste) ||
- (kind == kODCloneToFile) )
- {
- if ( GetOriginalDraft(ev, somSelf) == kODNULL )
- {
- // Clone is from a document draft to a document draft,
- // so create the table for deferred strong clones
- linksToCloneSUIDs = new(heap)
- OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash, heap);
- linksToCloneSUIDs->Initialize(kInitialHashTableEntries,
- sizeof(ODStorageUnitID),
- sizeof(ODStorageUnitID));
- }
- }
- }
-
- weakClonedSUIDs = new(heap)
- OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash, heap);
- 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;
- _fLinksToCloneSUIDs = linksToCloneSUIDs;
- }
-
- _fSavedWeakClonedSUIDs = _fWeakClonedSUIDs;
- _fWeakClonedSUIDs = weakClonedSUIDs;
-
- result = _fCurrentKey;
-
- SOM_CATCH_ALL
-
- ODDeleteObject(clonedSUIDs);
- ODDeleteObject(linksToCloneSUIDs);
- ODDeleteObject(weakClonedSUIDs);
-
- SOM_ENDTRY
-
- return result;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: GetClonedSUIDs
- //------------------------------------------------------------------------------
-
- SOM_Scope OpenHashTable* SOMLINK CMDraftGetClonedSUIDs(CMDraft *somSelf, Environment *ev,
- ODDraft* destDraft)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","GetClonedSUIDs");
-
- if ((_fDestDraft != kODNULL) && (_fDestDraft != destDraft)) {
- ODDeleteObject(_fClonedSUIDs);
- ODDeleteObject(_fWeakClonedSUIDs);
- ODSetSOMException(ev,kODErrInvalidDestinationDraft);
- return kODNULL;
- }
- _fDestDraft = destDraft;
-
- 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;
-
- SOM_TRY
-
- if ((key != _fCurrentKey) || (_fLockCount == 0))
- THROW(kODErrInvalidDraftKey);
-
- somSelf->DoDeferredClones(ev, key);
-
- 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 weakly cloned ID %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(_fLinksToCloneSUIDs);
- }
-
- ODDeleteObject(_fWeakClonedSUIDs);
- _fWeakClonedSUIDs = _fSavedWeakClonedSUIDs;
-
- #ifdef DebugClone
- somPrintf("CMDraft::EndClone - Clone completed\n\n");
- #endif
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: AbortClone
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftAbortClone(CMDraft *somSelf, Environment *ev,
- ODDraftKey key)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","AbortClone");
-
- SOM_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(_fLinksToCloneSUIDs);
- }
-
- ODDeleteObject(_fWeakClonedSUIDs);
- _fWeakClonedSUIDs = _fSavedWeakClonedSUIDs;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: SetOriginalID
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftSetOriginalID(CMDraft *somSelf, Environment* ev,
- ODStorageUnitID destID,
- ODStorageUnitID originalID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","SetOriginalID");
-
- SOM_TRY
-
- TempODStorageUnit destSU = _fDestDraft->AcquireStorageUnit(ev, destID);
- ODSetULongProp(ev, destSU, kODPropOriginalID, kODULong, originalID);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // 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");
-
- SOM_TRY
-
- TempODStorageUnit fromSU = somSelf->AcquireStorageUnit(ev, fromID);
- return (ODStorageUnitID)ODGetULongProp(ev, fromSU, kODPropOriginalID, kODULong);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return 0;
- }
-
- //------------------------------------------------------------------------------
- // CheckPartAction
- //------------------------------------------------------------------------------
-
- static ODBoolean CheckPartAction(void* k, void* v, ODULong s, void* r)
- {
- ODID originalID = * (ODID *) k;
- ODID interupdateID = * (ODID *) v;
- OpenHashTable* targetParts = (OpenHashTable*) r;
- ODBoolean result = kODFalse;
- Environment* ev = somGetGlobalEnvironment();
-
- // 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
-
- TempODStorageUnit interchangeSU = ::sInterchangeDraft->AcquireStorageUnit(ev, interupdateID);
- 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
- }
- }
- }
- }
-
- 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;
-
- SOM_TRY
-
- ODMemoryHeapID heap = somSelf->GetHeap(ev);
-
- #ifdef DebugClone
- somPrintf("ContainingPartInClone called with target frame id %d <%x>\n", targetFrame->GetID(ev), targetFrame);
- #endif
-
- OpenHashTable* targetParts = new(heap) OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash,
- heap);
- 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 )
- {
- TempODFrame tempFrame = frame; // ensure it's released
- 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 )
- {
- { TempODWindow window = frame->AcquireWindow(ev);
- nextFrame = window->AcquireSourceFrame(ev);
- }
-
- // 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 )
- {
- TempODFrame sourceFrame = nextFrame;
- nextFrame = sourceFrame->AcquireContainingFrame(ev);
- }
- }
- frame = nextFrame;
- }
-
- clonedSUIDs = new(heap) OpenHashTable(OpenHashTable::StdEqual,
- OpenHashTable::StdHash,
- heap);
-
- 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) );
- result = clonedSUIDs->Walk(CheckPartAction, targetParts);
- ODDisposePtr(::sSUTypeBuffer);
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- ODDeleteObject(targetParts);
- ODDeleteObject(clonedSUIDs);
-
- #ifdef DebugClone
- somPrintf("ContainingPartInClone returns %d\n", result);
- #endif
-
- return result;
- }
-
- //------------------------------------------------------------------------------
- // CompanionObjectID
- //------------------------------------------------------------------------------
-
- SOM_Scope ODID SOMLINK CMDraftCompanionObjectID(CMDraft *somSelf, Environment *ev,
- ODID objectID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CompanionObjectID");
-
- ODStorageUnitID companionID = kODNULLID;
- ODPropertyName companionProperty = kODNULL;
-
- SOM_TRY
-
- if ( IsLinkObject(ev, somSelf, objectID) )
- companionProperty = kODPropLinkSource;
- else if ( IsLinkSourceObject(ev, somSelf, objectID) )
- companionProperty = kODPropLink;
-
- if ( companionProperty != kODNULL )
- {
- TempODStorageUnit objectSU = somSelf->AcquireStorageUnit(ev, objectID);
- if ( objectSU != kODNULL )
- {
- companionID = ODGetWeakSURefProp(ev, objectSU, companionProperty, kODWeakStorageUnitRef);
- }
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- return companionID;
- }
-
- //------------------------------------------------------------------------------
- // 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);
-
- SOM_TRY
-
- ODStorageUnitID companionID = somSelf->CompanionObjectID(ev, fromID);
- 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);
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- return toID;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: CompanionWasCloned
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBoolean SOMLINK CMDraftCompanionWasCloned(CMDraft *somSelf, Environment* ev,
- ODStorageUnitID fromID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","CompanionWasCloned");
-
- ODBoolean result = kODFalse;
-
- SOM_TRY
- result = (somSelf->CompanionObjectID(ev, fromID) != kODNULLID);
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- return result;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: GetCloneKind
- //------------------------------------------------------------------------------
-
- SOM_Scope ODCloneKind SOMLINK CMDraftGetCloneKind(CMDraft *somSelf, Environment* ev)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","GetCloneKind");
-
- ODCloneKind cloneKind = _fCloneKind;
-
- SOM_TRY
-
- if ( cloneKind == kODClonePaste )
- {
- if ( (GetOriginalCloneKind(ev, somSelf) == kODCloneCut) && (GetOriginalDraft(ev, somSelf) == _fDestDraft) )
- cloneKind = kODCloneDropMove;
- else
- cloneKind = kODCloneDropCopy;
- }
- else if ( cloneKind == kODCloneToFile )
- {
- cloneKind = kODCloneDropCopy;
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return cloneKind;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DeferStrongClone
- //------------------------------------------------------------------------------
- //
- // Defers cloning of a link or link source object in this draft to the
- // destination draft. As in a weak clone, a storage unit is created in the
- // destination draft an its ID is returned. In addition, the object is put
- // in a list of link objects. EndClone should iterate over the list and
- // clone those objects once the fate of their companion objects is known.
-
- SOM_Scope ODID SOMLINK CMDraftDeferStrongClone(CMDraft *somSelf, Environment* ev,
- ODID fromID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DeferStrongClone");
-
- ODID toID = kODNULLID; ODVolatile(toID);
-
- SOM_TRY
-
- ASSERT(IsEitherLinkObject(ev, somSelf, fromID), kODErrInvalidID);
-
- ASSERT(_fLinksToCloneSUIDs != kODNULL, kODErrCannotDeferClone);
-
- _fWeakClonedSUIDs->GetValue(&fromID, &toID);
- if ( toID == kODNULLID )
- {
- TempODStorageUnit toSU = _fDestDraft->CreateStorageUnit(ev);
- toID = toSU->GetID(ev);
- _fWeakClonedSUIDs->ReplaceEntry(&fromID, &toID);
- #ifdef DebugClone
- somPrintf("Putting deferred clone from ID %d to ID %d on weak clone list\n", fromID, toID);
- #endif
- }
-
- ODID toCloneID = kODNULLID;
- _fLinksToCloneSUIDs->GetValue(&fromID, &toCloneID);
- if ( toCloneID == kODNULLID )
- {
- _fLinksToCloneSUIDs->ReplaceEntry(&fromID, &toID);
- #ifdef DebugClone
- somPrintf("Deferring clone from ID %d to ID %d\n", fromID, toID);
- #endif
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- return toID;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DoDeferredClones
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftDoDeferredClones(CMDraft *somSelf, Environment* ev,
- ODDraftKey key)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DoDeferredClones");
-
- ODStorageUnitID fromID;
- ODStorageUnitID toID;
- ODStorageUnitID companionID;
- ODStorageUnitID toCompanionID;
-
- if ( _fLinksToCloneSUIDs != kODNULL )
- {
- SOM_TRY
-
- #ifdef DebugClone
- somPrintf("Cloning deferred link and link source objects\n");
- #endif
-
- OpenHashTableIterator iter(_fLinksToCloneSUIDs);
- for (iter.First(&fromID, &toID); iter.IsNotComplete(); iter.Next(&fromID, &toID))
- {
- companionID = somSelf->CompanionObjectID(ev, fromID);
- if ( companionID != kODNULLID )
- {
- // Because cloning both link and link source objects is deferred,
- // it suffices to check just _fLinksToCloneSUIDs to see if the
- // companion has also been deferred.
- toCompanionID = kODNULLID; // GetValue doesn't change if not found
- _fLinksToCloneSUIDs->GetValue(&companionID, &toCompanionID);
- if ( toCompanionID != kODNULLID )
- {
- // Previously, we just created a storage unit for the object,
- // so now we must clone into that storage unit
- somSelf->StrongClone(ev, key, fromID, toID, kODNULLID);
- }
- else
- {
- // The empty storage unit created in the destination draft
- // will be removed with others that were only weakly cloned
- #ifdef DebugClone
- somPrintf("Companion object ID %d of ID %d was not cloned\n", companionID, fromID);
- #endif
- }
- }
- else
- {
- #ifdef DebugClone
- somPrintf("No companion for object ID %d\n", fromID);
- #endif
- }
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
- }
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DropCopyClone
- //------------------------------------------------------------------------------
- //
- // Implements strong cloning of objects during a paste or drop of copied content.
- // Takes into consideration whether the source draft is an
- // intermediate draft or a document draft (for example, an OpenDoc file dragged
- // in from the Finder). If the clone is from an intermediat draft back into
- // the same document draft, the original object ID may be substituted, or a null
- // object ID may be returned. Enforces rules for copying link source and link
- // objects.
-
- SOM_Scope ODID SOMLINK CMDraftDropCopyClone(CMDraft *somSelf, Environment* ev,
- ODDraftKey key,
- ODID fromID,
- ODID toID,
- ODID scopeID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DropCopyClone");
-
- ODID clonedID = kODNULLID; ODVolatile(clonedID);
-
- SOM_TRY
-
- ASSERT(somSelf->GetCloneKind(ev) == kODCloneDropCopy, kODErrInvalidCloneKind);
-
- if ( IsLinkObject(ev, somSelf, fromID) )
- {
- ODDraft* originalDraft = GetOriginalDraft(ev, somSelf);
- if ( originalDraft == _fDestDraft )
- {
- // Clone is from an intermediate draft back into the original draft.
- // Because the clone is from an intermediate draft, we can check
- // to see if the link source object was also cloned into the
- // intermediate draft.
- if ( somSelf->CompanionWasCloned(ev, fromID) )
- {
- // The link source object was copied, so clone the link object
- // to create a new one.
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
- else
- {
- // The link source object was not cloned, so substitute the ID
- // of the original link object so copied destinations reference
- // the original link object.
- ASSERT(toID == 0, kODErrInvalidID);
- clonedID = somSelf->GetOriginalID(ev, fromID);
- ASSERT(_fDestDraft->IsValidID(ev, clonedID), kODErrInvalidID);
- #ifdef DebugClone
- somPrintf("Reusing existing link object id = %d for cloned object %d\n", clonedID, fromID);
- #endif
- }
- }
- else if ( originalDraft != kODNULL )
- {
- // Clone is cross-draft via an intermediate draft. Only link
- // and link source pairs are copied.
- // Because the clone is from an intermediate draft, we can check
- // to see if the link source object was also cloned into the
- // intermediate draft.
- if ( somSelf->CompanionWasCloned(ev, fromID) )
- {
- // The link source object was copied, so clone the link object
- // to create a new one.
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
- else
- {
- // The link source object was not cloned, so don't clone the link
- clonedID = kODNULLID;
- #ifdef DebugClone
- somPrintf("CMDraftStrongClone NOT cloning from ID %d\n", fromID);
- #endif
- }
- }
- else
- {
- // Clone is from a document draft. Create a storage unit and return
- // its ID. EndClone will either clone the object or remove the
- // storage unit from the destination draft.
- clonedID = somSelf->DeferStrongClone(ev, fromID);
- }
- }
- else if ( IsLinkSourceObject(ev, somSelf, fromID) )
- {
- if ( GetOriginalDraft(ev, somSelf) != kODNULL )
- {
- // Clone is from an intermediate draft (it doesn't matter if the
- // destination draft is the same as the original draft or not).
- // Because the clone is from an intermediate draft, we can check
- // to see if the link object was also cloned into the
- // intermediate draft.
- if ( somSelf->CompanionWasCloned(ev, fromID) )
- {
- // The link object was copied, so clone the link source object
- // to create a new one.
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
- else
- {
- // The link object was not cloned, so don't clone the link source
- clonedID = kODNULLID;
- #ifdef DebugClone
- somPrintf("CMDraftStrongClone NOT cloning from ID %d\n", fromID);
- #endif
- }
- }
- else
- {
- // Clone is from a document draft. Create a storage unit and return
- // its ID. EndClone will either clone the object or remove the
- // storage unit from the destination draft.
- clonedID = somSelf->DeferStrongClone(ev, fromID);
- }
- }
- else
- {
- // Not a link or link source object, so clone it
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- return clonedID;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DropMoveClone
- //------------------------------------------------------------------------------
- //
- // Implements strong cloning of objects during a paste of cut content or a drop
- // of moved content. Takes into consideration wether the source draft is an
- // intermediate draft or a document draft (for example, an OpenDoc file dragged
- // in from the Finder). If the clone is from an intermediate draft back into
- // the same document draft, the original object ID may be substituted, or a null
- // object ID may be returned. Enforces rules for moving link source and link
- // objects. When moved to another draft, links behave as if copied.
-
- SOM_Scope ODID SOMLINK CMDraftDropMoveClone(CMDraft *somSelf, Environment* ev,
- ODDraftKey key,
- ODID fromID,
- ODID toID,
- ODID scopeID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DropMoveClone");
-
- ODID clonedID = kODNULLID; ODVolatile(clonedID);
-
- SOM_TRY
-
- ASSERT(somSelf->GetCloneKind(ev) == kODCloneDropMove, kODErrInvalidCloneKind);
-
- ODDraft* originalDraft = GetOriginalDraft(ev, somSelf);
- if ( originalDraft == _fDestDraft )
- {
- // Clone is from an intermediate draft back into the original draft.
- // In this case, no distinction is made between link, link source,
- // and other objects being cloned.
- // toID will be non-zero if the object has already been weakly cloned.
- // If the original object is still present in the destination draft,
- // use it unless the caller explicitly cloned into another storage unit.
- ODID originalID = somSelf->GetOriginalID(ev, fromID);
- if ( _fDestDraft->IsValidID(ev, originalID) )
- {
- if ( (toID == 0) || (toID == originalID) )
- {
- clonedID = originalID;
- #ifdef DebugClone
- somPrintf("CMDraftStrongClone from ID %d to substitute ID %d\n", fromID, clonedID);
- #endif
- }
- else
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
- else
- {
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- #ifdef DebugClone
- if ( originalID != kODNULLID )
- somPrintf("Original id = %d is not valid\n", originalID);
- #endif
- }
- somSelf->CheckClonedObject(ev, fromID, clonedID, originalID);
- }
- else if ( IsEitherLinkObject(ev, somSelf, fromID) )
- {
- if ( originalDraft != kODNULL )
- {
- // Clone is cross-draft via an intermediate draft. Only link
- // and link source pairs are copied.
- // Because the clone is from an intermediate draft, we can check
- // to see if the companion object was also cloned into the
- // intermediate draft.
- if ( somSelf->CompanionWasCloned(ev, fromID) )
- {
- // The link source object was copied, so clone the link object
- // to create a new one.
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
- else
- {
- // The companion object was not cloned, so don't clone the link
- clonedID = kODNULLID;
- #ifdef DebugClone
- somPrintf("CMDraftStrongClone NOT cloning from ID %d\n", fromID);
- #endif
- }
- }
- else
- {
- // Clone is from a document draft. Create a storage unit and return
- // its ID. EndClone will either clone the object or remove the
- // storage unit from the destination draft.
- clonedID = somSelf->DeferStrongClone(ev, fromID);
- }
- }
- else
- {
- // Other objects moved across drafts are always cloned
- clonedID = somSelf->StrongClone(ev, key, fromID, toID, scopeID);
- }
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- return clonedID;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: DoWeakClone
- //------------------------------------------------------------------------------
- //
- // Implements weak clone of objects that have not already been strongly or
- // weakly cloned.
- // If link objects are copied or moved across a draft...
-
- SOM_Scope ODID SOMLINK CMDraftDoWeakClone(CMDraft *somSelf, Environment* ev,
- ODID fromID)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","DoWeakClone");
-
- ODID clonedID = kODNULLID; ODVolatile(clonedID);
- ODBoolean doWeakClone = kODFalse;
- ODDraft* originalDraft = kODNULL;
-
- SOM_TRY
-
- ODCloneKind cloneKind = somSelf->GetCloneKind(ev);
-
- if ( cloneKind == kODCloneDropCopy )
- {
- if ( IsLinkObject(ev, somSelf, fromID) )
- {
- originalDraft = GetOriginalDraft(ev, somSelf);
- if ( originalDraft == _fDestDraft )
- {
- // Clone is from an intermediate draft back into the original draft.
- // Because the clone is from an intermediate draft, we can check
- // to see if the link source object was also cloned into the
- // intermediate draft.
- if ( somSelf->CompanionWasCloned(ev, fromID) )
- {
- // The link source object was copied, so clone the link object
- // to create a new one.
- doWeakClone = kODTrue;
- }
- else
- {
- // The link source object was not cloned, so substitute the ID
- // of the original link object so copied destinations reference
- // the original link object.
- clonedID = somSelf->GetOriginalID(ev, fromID);
- ASSERT(_fDestDraft->IsValidID(ev, clonedID), kODErrInvalidID);
- #ifdef DebugClone
- somPrintf("Reusing existing link object id = %d for weakly cloned object %d\n", clonedID, fromID);
- #endif
- }
- }
- else if ( originalDraft != kODNULL )
- {
- // Clone is cross-draft via an intermediate draft. Only link
- // and link source pairs are copied.
- // Because the clone is from an intermediate draft, we can check
- // to see if the link source object was also cloned into the
- // intermediate draft. If the link source was cloned, we can
- // weakly clone this link object.
-
- doWeakClone = somSelf->CompanionWasCloned(ev, fromID);
- }
- else
- {
- // Clone is from a document draft. Weakly clone it.
- doWeakClone = kODTrue;
- }
- }
- else if ( IsLinkSourceObject(ev, somSelf, fromID) )
- {
- originalDraft = GetOriginalDraft(ev, somSelf);
- if ( originalDraft != kODNULL )
- {
- // Clone is from an intermediate draft.
- // Because the clone is from an intermediate draft, we can check
- // to see if the link object was also cloned into the
- // intermediate draft.
- doWeakClone = somSelf->CompanionWasCloned(ev, fromID);
- }
- else
- {
- // Clone is from a document draft. Weakly clone it.
- doWeakClone = kODTrue;
- }
- }
- else
- {
- // Weakly clone all other objects
- doWeakClone = kODTrue;
- }
- }
- else if ( cloneKind == kODCloneDropMove )
- {
- originalDraft = GetOriginalDraft(ev, somSelf);
- if ( originalDraft == _fDestDraft )
- {
- // Clone is from an intermediate draft back into the original draft.
- // In this case, no distinction is made between link, link source,
- // and other objects being cloned.
- ODID originalID = somSelf->GetOriginalID(ev, fromID);
- if ( _fDestDraft->IsValidID(ev, originalID) )
- {
- clonedID = originalID;
-
- // Assumption: If the original object is substituted for a
- // weakly-referenced clone, the clone is also strongly-referenced
- // and will be strongly cloned back into the draft, so its
- // unnecessary to call somSelf->CheckClonedObject here.
- }
- else
- {
- doWeakClone = kODTrue;
- #ifdef DebugClone
- if ( originalID != kODNULLID )
- somPrintf("Original id = %d is not valid\n", originalID);
- #endif
- }
- }
- else if ( IsEitherLinkObject(ev, somSelf, fromID) )
- {
- if ( originalDraft != kODNULL )
- {
- // Clone is cross-draft via an intermediate draft. Only link
- // and link source pairs are copied.
- // Because the clone is from an intermediate draft, we can check
- // to see if the link source object was also cloned into the
- // intermediate draft.
- doWeakClone = somSelf->CompanionWasCloned(ev, fromID);
- }
- else
- {
- // Clone is from a document draft.
- doWeakClone = kODTrue;
- }
- }
- else
- {
- // Other objects moved across drafts are always cloned
- doWeakClone = kODTrue;
- }
- }
- else
- {
- // Note a paste or a drop; do a weak clone
- doWeakClone = kODTrue;
- }
-
- if ( doWeakClone )
- {
- TempODStorageUnit toSU = _fDestDraft->CreateStorageUnit(ev);
- clonedID = toSU->GetID(ev);
- _fWeakClonedSUIDs->ReplaceEntry(&fromID, &clonedID);
- }
-
- #ifdef DebugClone
- if ( doWeakClone )
- somPrintf("CMDraftWeakClone from ID %d to ID %d", fromID, clonedID);
- else
- somPrintf("CMDraftWeakClone from ID %d to substitute ID %d", fromID, clonedID);
- TempODISOStr suType = GetStorageUnitType(ev, somSelf, fromID);
- somPrintf(" type %s\n", (ODISOStr) suType);
- #endif
-
- SOM_CATCH_ALL
-
- SOM_ENDTRY
-
- return clonedID;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: Clone
- //------------------------------------------------------------------------------
- //
- // 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");
-
- SOM_TRY
-
- if ((key != _fCurrentKey) || (_fLockCount == 0))
- THROW(kODErrInvalidDraftKey);
-
- ODStorageUnitID toID = 0;
-
- 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:
- toID = somSelf->DropCopyClone(ev, key, fromID, toObjectID, scopeID);
- break;
-
- case kODCloneDropMove:
- toID = somSelf->DropMoveClone(ev, key, fromID, toObjectID, scopeID);
- break;
-
- default:
- break;
- }
-
- return toID;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return 0;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: StrongClone
- //------------------------------------------------------------------------------
-
- SOM_Scope ODID SOMLINK CMDraftStrongClone(CMDraft *somSelf, Environment *ev,
- ODDraftKey key,
- ODID fromID,
- ODID toObjectID,
- ODID scopeID)
- {
- SOM_TRY
-
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","StrongClone");
-
- #ifdef DebugClone
- somPrintf("CMDraftStrongClone from ID %d to ID %d scope ID %d\n", fromID, toObjectID, scopeID);
- #endif
-
- ODStorageUnitID toID = 0;
- TempODStorageUnit toSU = kODNULL;
-
- _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 ) {
- TempODRefCntObject tempFromObject = fromObject; // so it gets released
- TempODFrame scopeFrame = kODNULL;
- 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);
- }
- else {
- TempODStorageUnit fromSU = somSelf->AcquireStorageUnit(ev, fromID);
- if (fromSU != kODNULL) {
- fromSU->CloneInto(ev, key, toSU, scopeID);
- ODBoolean keepProxyProperties = (_fCloneKind == kODCloneToFile)
- || (_fCloneKind == kODCloneAll);
- RemoveDataInterchangeProperties(ev, toSU, keepProxyProperties);
- // CopyDraftAnnotations(ev, fromSU, toSU);
- }
- }
-
- #ifdef DebugClone
- somPrintf("Done CMDraftStrongClone from ID %d to ID %d\n", fromID, toID);
- #endif
-
- return toID;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return 0;
- }
-
- //------------------------------------------------------------------------------
- // 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");
-
- ODUnused(scopeID);
-
- SOM_TRY
-
- ODStorageUnitID toID = 0;
-
- _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!
- toID = somSelf->DoWeakClone(ev, fromID);
- }
- }
- }
- if ((toObjectID != 0) && (toObjectID != toID))
- THROW(kODErrInvalidID);
-
- return toID;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return 0;
- }
-
- //------------------------------------------------------------------------------
- // 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.
-
- 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);
- }
- }
-
- //------------------------------------------------------------------------------
- // CopyDraftAnnotations
- //------------------------------------------------------------------------------
-
- static void CopyDraftAnnotations(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU)
- {
- 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);
- }
-
- //------------------------------------------------------------------------------
- // IsLinkObject
- //------------------------------------------------------------------------------
-
- static ODBoolean IsLinkObject(Environment* ev, ODDraft* draft, ODID objectID)
- {
- // Only link objects contain a kODPropLinkSource property
-
- TRY
-
- TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
- ODBoolean isLink = su->Exists(ev, kODPropLinkSource, kODNULL, 0);
-
- #ifdef DebugClone
- if ( isLink )
- somPrintf("Object ID %d is a link\n", objectID);
- #endif
-
- return isLink;
-
- CATCH_ALL
- ENDTRY
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // IsLinkSourceObject
- //------------------------------------------------------------------------------
-
- static ODBoolean IsLinkSourceObject(Environment* ev, ODDraft* draft, ODID objectID)
- {
- // Only link source objects contain a kODPropLink property
-
- TRY
-
- TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
- ODBoolean isLinkSource = su->Exists(ev, kODPropLink, kODNULL, 0);
-
- #ifdef DebugClone
- if ( isLinkSource )
- somPrintf("Object ID %d is a link source\n", objectID);
- #endif
-
- return isLinkSource;
-
- CATCH_ALL
- ENDTRY
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // IsEitherLinkObject
- //------------------------------------------------------------------------------
-
- static ODBoolean IsEitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID)
- {
- if ( IsLinkObject(ev, draft, objectID) )
- return kODTrue;
- else
- return IsLinkSourceObject(ev, draft, objectID);
- }
-
- //------------------------------------------------------------------------------
- // 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)
- {
- if (perms == kODDPExclusiveWrite)
- {
- TempODType curType = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
- if (!curType || !ODISOStrEqual(curType, suType))
- ODSetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, suType);
- }
- }
-
- //------------------------------------------------------------------------------
- // GetStorageUnitType
- //------------------------------------------------------------------------------
-
- static ODISOStr GetStorageUnitType(Environment* ev, ODDraft* draft, ODID objectID)
- {
- TRY
-
- TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
- PreserveFocus fromFocus(ev, su);
-
- return ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
-
- CATCH_ALL
- ENDTRY
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // RootPartID
- //------------------------------------------------------------------------------
-
- static ODID RootPartID(Environment* ev, ODDraft* draft)
- {
- TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
- return ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
- }
-
- //------------------------------------------------------------------------------
- // 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);
-
- SOM_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
- }
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- ODDisposePtr(storageUnitType);
- }
-
- //------------------------------------------------------------------------------
- // SetOriginalDraft
- //------------------------------------------------------------------------------
-
- static void SetOriginalDraft(Environment* ev, ODDraft* targetDraft, ODDraft* originalDraft)
- {
- TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
- ODSetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong, (ODULong) originalDraft);
- }
-
- //------------------------------------------------------------------------------
- // 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)
- {
- TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
- return (ODDraft*)ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
- }
-
- //------------------------------------------------------------------------------
- // OriginalCloneKindExists
- //------------------------------------------------------------------------------
-
- static ODBoolean OriginalCloneKindExists(Environment* ev, ODDraft* draft)
- {
- TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
- return draftProperties->Exists(ev, kODPropOriginalCloneKind, kODULong, 0);
- }
-
- //------------------------------------------------------------------------------
- // SetOriginalCloneKind
- //------------------------------------------------------------------------------
-
- static void SetOriginalCloneKind(Environment* ev, ODDraft* targetDraft, ODCloneKind cloneKind)
- {
- TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
- ODSetULongProp(ev, draftProperties, kODPropOriginalCloneKind, kODULong, (ODULong) cloneKind);
- }
-
- //------------------------------------------------------------------------------
- // 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);
- SOM_TRY
-
- iter = new CMLinkIterator();
- THROW_IF_NULL(iter, kODErrOutOfMemory);
- iter->InitCMLinkIterator(ev, somSelf);
-
- SOM_CATCH_ALL
-
- ODDeleteObject(iter);
-
- SOM_ENDTRY
-
- 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);
- SOM_TRY
-
- iter = new CMLinkSourceIterator();
- THROW_IF_NULL(iter, kODErrOutOfMemory);
- iter->InitCMLinkSourceIterator(ev, somSelf);
-
- SOM_CATCH_ALL
-
- ODDeleteObject(iter);
-
- SOM_ENDTRY
-
- return (ODLinkSourceIterator*) iter;
- }
-
- //------------------------------------------------------------------------------
- // itoa
- //------------------------------------------------------------------------------
- static void 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)
- {
- SOMClass* cmStorageUnitClass = somNewClassReference(CMStorageUnit);
- THROW_IF_NULL( cmStorageUnitClass );
- ODULong size = cmStorageUnitClass->somGetInstanceSize();
- ODPtr buffer = ODNewPtr(size, heapID);
- CMStorageUnit* cmStorageUnit = (CMStorageUnit*) cmStorageUnitClass->somRenew(buffer);
- somReleaseClassReference ( cmStorageUnitClass );
-
- return cmStorageUnit;
- }
-
- //------------------------------------------------------------------------------
- // PurgeAllStorageUnits
- //------------------------------------------------------------------------------
-
- static ODULong PurgeAllStorageUnits(Environment* ev, OpenHashTable* storageUnits, IDList* idList)
- {
- ODID id;
- ODStorageUnit* su;
- ODULong runningTotal = 0;
-
- // 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;
- }
- }
- */
- // ShrinkToFit() allocates new tables first, and this aggravates
- // low memory conditions during Purge().
- // storageUnits->ShrinkToFit(/*extraSlots*/ 0);
-
- return runningTotal;
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: PartInstantiated
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftPartInstantiated(CMDraft *somSelf, Environment *ev,
- ODPart* realPart)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","PartInstantiated");
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: PartDeleted
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftPartDeleted(CMDraft *somSelf, Environment *ev,
- ODPart* realPart)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","PartDeleted");
- }
-
- //------------------------------------------------------------------------------
- // CMDraft: SwapPart
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK CMDraftSwapPart(CMDraft *somSelf, Environment *ev,
- ODPart* part)
- {
- CMDraftData *somThis = CMDraftGetData(somSelf);
- CMDraftMethodDebug("CMDraft","SwapPart");
-
- SOM_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);
- }
- }
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-