home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osr1.exe / src / CMDraft.cpp < prev    next >
Text File  |  1997-03-21  |  265KB  |  6,870 lines

  1. /* @(#)Z 1.45 com/src/bento/CMDraft.cpp, odstorage, od96os2, odos29712d 97/03/21 17:19:03 (97/03/03 14:38:44) */
  2. //====START_GENERATED_PROLOG======================================
  3. //
  4. //
  5. //   COMPONENT_NAME: odstorage
  6. //
  7. //   CLASSES: none
  8. //
  9. //   ORIGINS: 82,27
  10. //
  11. //
  12. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  13. //   All Rights Reserved
  14. //   Licensed Materials - Property of IBM
  15. //   US Government Users Restricted Rights - Use, duplication or
  16. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17. //       
  18. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  22. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  23. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24. //   OR PERFORMANCE OF THIS SOFTWARE.
  25. //
  26. //====END_GENERATED_PROLOG========================================
  27. //
  28. /*
  29.         File:           CMDraft.cpp
  30.  
  31.         Contains:       Implementation for CMDraft class.
  32.  
  33.         Owned by:       Vincent Lo
  34.  
  35.         Copyright:      ⌐ 1993-1995 by Apple Computer, Inc., all rights reserved.
  36.  
  37.         Change History (most recent first):
  38.  
  39.            <125>        10/24/95        TJ              Changed string to corbastring
  40.            <124>        10/24/95        jpa             1293441: DM/VL: Bento memory reserve &
  41.                                                                         fatal container err & don't throw in
  42.                                                                         Release.
  43.            <123>        10/20/95        VL              1293256: Changed
  44.                                                                         kODErrBentoInvalidVersionList to
  45.                                                                         kODErrDraftDoesNotExist.
  46.            <122>        10/19/95        EL              1292685: After purging we may get a
  47.                                                                         different storage unit for the same
  48.                                                                         CMObject.
  49.            <121>        10/17/95        jpa             1289153: CreatePart, AcquirePart,
  50.                                                                         AcquireFrame handle failure gracefully.
  51.            <120>        10/13/95        EL              1287340: Use standard ISO prefix
  52.            <119>         10/8/95        TJ              Fixes Recomended by Refball
  53.            <118>         10/5/95        CC              1286180: Added CloneCompanionObject method.
  54.                                                                         1286180: Clone: Call CloneCompanionObject
  55.                                                                         if clone kind is kODCloneAll.
  56.            <117>         10/3/95        TJ              Changes done by RefBall Team
  57.            <116>         9/29/95        TJ              Made Changes for MAC SOM
  58.            <115>         9/14/95        VL              1283566: Fixed Clone so that CloneFromLink
  59.                                                                         would also skip links (i.e., return 0 as
  60.                                                                         the id).
  61.            <114>         9/11/95        VL              1283326: CreateFrame now takes ODObjectType
  62.                                                                         instead of ODType. 1283157: Fixed memory
  63.                                                                         Leak in CMDraft::ConstructRealPart.
  64.            <113>          9/8/95        VL              1276955: Make sure draft is not read-only
  65.                                                                         before writing out preferred kind.
  66.            <112>          9/8/95        Té              1281096 FB2:Many constants in ODTypesB
  67.                                                                         without kOD prefix!
  68.            <111>          9/1/95        CC              1273646, 1279220:  Support kODCloneToFile.
  69.            <110>         8/29/95        VL              1279830, 1279074: THROW_IF_NULL after new
  70.                                                                         on SOM objects. 1279505: Catches exceptions
  71.                                                                         returned from ReleaseAll.
  72.            <109>         8/26/95        Té              1270499Two editors which support same kind
  73.                                                                         binding problem
  74.            <108>         8/25/95        JBS             1263078 FB: fix part editor swapping
  75.            <107>         8/24/95        CC              1251959: BeginClone must clean up before
  76.                                                                         returning an error.
  77.            <106>         8/24/95        EL              1274602: cmObject not released resulting in
  78.                                                                         wrong internal Bento ref count.
  79.            <105>         8/22/95        VL              1277720, 1278310: Cleaned up error code in
  80.                                                                         Release/RemoveStorageUnit.
  81.            <104>         8/21/95        VL              1278330, 1278315: Error code cleanup.
  82.            <103>         8/21/95        VL              1277291: Use GetOriginalCloneKind from
  83.                                                                         StorUtil. 1258660: Rewrote exception
  84.                                                                         handling for CreateFrame to ensure that the
  85.                                                                         correct exception are propogated.
  86.            <102>         8/17/95        CC              1277781: CheckPartAction: Check size of
  87.                                                                         storage unit type before comparing strings;
  88.                                                                         check for invalid part ID returned by
  89.                                                                         ODGetStrongSURefProp.
  90.            <101>         8/16/95        EL              Disable ODDebug_CloningAnnotations
  91.            <100>         8/16/95        NP              1274946: ErrorDef.idl problems. Add include
  92.                                                                         file. 1277286: CMDraft: ConstructRealPart
  93.                                                                         gropes ev->_major when it doesn't mean to.
  94.                 <99>     8/16/95        VL              1266007: IsValidDraftKey returns kODFalse
  95.                                                                         for kODNULLKey.
  96.                 <98>     8/15/95        CC              1274794, 1273863: CopyProperties: Focus to
  97.                                                                         property (don't assume already focused).
  98.                                                                         CopyDraftAnnotations: Always copy the
  99.                                                                         storage unit type property.
  100.                 <97>     8/12/95        Té              1276812 Need to use TempObjs and TempRefs
  101.                                                                         for exception safety and to avoid TRY
  102.                                                                         blocks, 1276807 Opt./Bug: use StdTypIO
  103.                                                                         routines for portable streaming & smaller
  104.                                                                         footprint, 1276806 Optimization: use
  105.                                                                         kODFalse instead of kODTrue in comparisons
  106.                 <96>      8/3/95        RR              #1257260: Collapse B classes. Remove
  107.                                                                         somInit methods. Don't call IsInitialized
  108.                                                                         or SubclassResponsibility
  109.                 <95>     7/26/95        VL              1270320: Dispose of valueName in
  110.                                                                         CopyProperty.
  111.                 <94>     7/21/95        VL              1270320: Freeing internal field. Disposed
  112.                                                                         ba._buffer of ID.
  113.                 <93>     7/20/95        CC              1268790: Clone: Make sure original ID is
  114.                                                                         still valid before substituting!
  115.                 <92>      7/3/95        VL              1255736: Every instantiated persistent
  116.                                                                         object has the object type correctly set.
  117.                 <91>     6/29/95        VL              1242642: Release DraftProperties in
  118.                                                                         DeleteCollections. Release SU before
  119.                                                                         removing it.
  120.                 <90>     6/23/95        JBS             1261323 Draft::CreateFrame: add isSubframe
  121.                                                                         param, remove isRoot
  122.                 <89>     6/19/95        VL              1170098: Added code to count part instances
  123.                                                                         (PartInstantiated, PartDeleted,
  124.                                                                         PurgeClasses). Code for the actual
  125.                                                                         unloading of the libraries is commented out
  126.                                                                         now. Added DeleteRealPart.
  127.                 <88>     6/16/95        VL              1244940: Made Externalize which triggers
  128.                                                                         promise resolution work.
  129.                 <87>     6/14/95        VL              1251227: Delete the collections and their
  130.                                                                         objects in somUninit.
  131.                 <86>     6/13/95        VL              1241352: Moved PreserveFocus to DrafPriv.
  132.                 <85>     6/12/95        CC              1252059: BeginClone: Allow clone to link
  133.                                                                         when clone from link is in progress.
  134.                 <84>     6/10/95        VL              1255300: Updated CopyDraftAnnotations for
  135.                                                                         cloning annotations and metadata.
  136.                 <83>      6/7/95        CC              1255762: EndClone() now uses destFrame
  137.                                                                         passed to BeginClone().
  138.                                                                         CheckClonedObject, ContainingPartInClone,
  139.                                                                         CheckPartAction: Changed kODFrame to
  140.                                                                         kODFrameObject.
  141.                                                                         CheckClonedObject: Changed kODPart to
  142.                                                                         kODPartObject.
  143.                                                                         ContainingPartInClone: Fixed refcount
  144.                                                                         problem.
  145.                 <82>      6/2/95        CC              1255476: CreateVersion, et. al. : release
  146.                                                                         document acquired for debug string.
  147.                                                                         1255476: ContainingPartInClone: Release
  148.                                                                         acquired parts and frames.
  149.                                                                         1255474: AcquireDocument restored to
  150.                                                                         GetDocument.
  151.                                                                         1255474: GetPersistentObject restored to
  152.                                                                         AcquirePersistentObject.
  153.                                                                         1255474: AcquireStorageUnitType restored to
  154.                                                                         GetStorageUnitType.
  155.                 <81>      6/1/95        jpa             Handle errs thrown from ODNewObject.
  156.                                                                         [1242839]
  157.                 <80>     5/26/95        VL              1251403: Multithreading naming support.
  158.                 <79>     5/25/95        jpa             Fixed usage of ODDebug. [1253321]
  159.                 <78>     5/22/95        CC              1242879: Added IsValidID.
  160.                 <77>     5/22/95        VL              1246940: Preserve focus during Clone.
  161.                 <76>     5/19/95        VL              1250574: Added check for kODNULLID in Get
  162.                                                                         methods.
  163.                 <75>     5/18/95        CC              1238898: Add destFrame argument to
  164.                                                                         BeginClone call; added fDestFrame field.
  165.                 <74>     5/17/95        VL              1170098: Added ConstructRealPart and
  166.                                                                         ReleaseRealPart.
  167.                 <73>     5/17/95        RR              #1250135/1250137/1250143 Getters increment
  168.                                                                         refcount
  169.                 <72>      5/3/95        CC              Split file into two segments to avoid
  170.                                                                         16-bit PC-relative offset problems on 68K.
  171.                 <71>      5/2/95        CC              1207493: Detect embedding part within
  172.                                                                         itself.
  173.                                                                         New methods: ContainingPartInClone and
  174.                                                                         CheckClonedObject.
  175.                                                                         New fields: fAnyFrameCloned and
  176.                                                                         fRootPartCloned.
  177.                                                                         New static variables: sIntermediateDraft,
  178.                                                                         sSUTypeBuffer, and sRootPartIDToIgnore.
  179.                                                                         New static functions: CheckPartAction,
  180.                                                                         CopyDraftAnnotations, CopyProperty,
  181.                                                                         GetStorageUnitType, RootPartID.
  182.                                                                         1245718: StrongClone: Call
  183.                                                                         CopyDraftAnnotations.
  184.                                                                         1245706: CreatePart creates
  185.                                                                         kODPropPreferredKind property, not
  186.                                                                         kODPropPart.
  187.                 <70>      5/2/95        VL              1211972: RemoveFrame does not dirty draft
  188.                                                                         if frame is non-persistent. 1243122: Use
  189.                                                                         kODErrValueIndexOutOfRange. 1221370:
  190.                                                                         AcquirePersistentObject works on read-only
  191.                                                                         draft.
  192.                 <69>      5/2/95        EL              1234685: Container manager does not like
  193.                                                                         value created but not written to, so always
  194.                                                                         write something after CMNewValue.
  195.                 <68>     4/25/95        DM              1172791: Replace AEHashTable with
  196.                                                                         OpenHashTable
  197.                 <67>     4/25/95        VL              1210982: Removed 5$.
  198.                 <66>     4/25/95        CC              1242555: CreateLinkSource, CreateLink,
  199.                                                                         Clone, AbortClone: Removed $5 from comment.
  200.                 <65>     4/10/95        VL              1230350: Release Part before trying to
  201.                                                                         remove it.
  202.                 <64>      4/7/95        EL              1226127: make sure code works when
  203.                                                                         TestFlushContainer is false.
  204.                 <63>     3/31/95        Té              1223505 BB: Opening and creating documents
  205.                                                                         on read only media.  Fixed Creation of
  206.                                                                         Non-persistent frames on readonly drafts.
  207.                 <62>     3/24/95        EL              1209355: Abort would remove changes in
  208.                                                                         version list rather than reinitialize it.
  209.                                                                         Cut down on version list externalization.
  210.                 <61>     3/23/95        VL              1228003: Added debug code for versionlist.
  211.                                                                         1230371: Check before calling
  212.                                                                         IDList::Remove.
  213.                 <60>     3/17/95        CC              1194656: SetOriginalDraft must check for
  214.                                                                         existence of property and value before
  215.                                                                         adding.
  216.                 <59>     3/13/95        VL              1226094: Added error handling in CreateSU
  217.                                                                         to handle the case when any invalid ID is
  218.                                                                         passed in.
  219.                 <58>     3/10/95        VL              1222416: Write out 0 at the end of
  220.                                                                         persistent object ISOString.
  221.                 <57>      3/9/95        VL              1225504: Use GetTargetDocument to prevent
  222.                                                                         ref-counting problem.
  223.                 <56>      3/7/95        CC              1224121: ODPart::CreateLink()  and
  224.                                                                         ODLinkManager::CreateLink() return an
  225.                                                                         ODLinkSource object.
  226.                 <55>      3/6/95        EL              1182275: Replace SetDraftPropertyObject by
  227.                                                                         CMKeepObject.
  228.                 <54>     2/28/95        VL              1194656: Check for existence before adding
  229.                                                                         property or value.
  230.                 <53>     2/21/95        EL              1182275: Do not externalize object if it
  231.                                                                         was garbage collected. Tell embedded
  232.                                                                         container about the draft property object.
  233.                 <52>     2/21/95        eeh             1222416: add 1 to len in
  234.                                                                         GetPersistentObjectID
  235.                 <51>     2/17/95        VL              1220231: CreateFrame now calls
  236.                                                                         InitFrameNonPersistent.
  237.                 <50>     2/15/95        EL              1182275: Set embedded container to no merge
  238.                                                                         if draft is created. 1158620: Lazy open
  239.                                                                         would avoid reopening of embedded container
  240.                                                                         when document is closed.
  241.                 <49>     2/10/95        VL              1205627: Use TargetContainer in
  242.                                                                         CreateVersion.
  243.                 <48>      2/6/95        TJ              Sorry, the last comment should be touched
  244.                                                                         copy right date.
  245.                 <47>      2/6/95        TJ              Updated Check in Date.
  246.                 <46>      2/3/95        VL              1216535: Implemented storage support for
  247.                                                                         non-persistent frames.
  248.                 <45>     1/18/95        VL              1193559: Added new 2
  249.                                                                         methods(AcquirePersistentObject and
  250.                                                                         GetPersistentObjectID). Renamed
  251.                                                                         AcquirePersistentObject to
  252.                                                                         RetrievePersistentObject. Removed
  253.                                                                         GetPersistentLinkID and AcquireLinkID.
  254.                 <44>     1/11/95        VL              1185688: Reverted one of the changes in
  255.                                                                         ExternalizeCollections to fix a refcounting
  256.                                                                         problem.
  257.                 <43>     1/11/95        VL              1185688: Made storage more robust in terms
  258.                                                                         of error handling. Also did some code
  259.                                                                         review cleanup.
  260.                 <42>    12/20/94        VL              1195012: Make Storage calls be
  261.                                                                         marshallable.
  262.                 <41>    12/16/94        CC              1203516 Modified CreateLinkSource to use
  263.                                                                         SetLink() and SetLinkSource() methods,
  264.                                                                         modified CreateLink().
  265.                 <40>    12/15/94        CC              1193569 CreateLinkSpec() takes ODByteArray
  266.                                                                         parameter.
  267.                                                                         1197221 AcquireLink() - added SOM_CATCH;
  268.                                                                         changed call to ODPart::CreateLink() to
  269.                                                                         pass byte array.
  270.                 <39>     11/1/94        CC              1190911, 1192030, 1196908 - Clone reuses
  271.                                                                         same objects if moved within same draft;
  272.                                                                         Clone while fulfilling promises won't
  273.                                                                         recopy already cloned objects.
  274.                 <38>     11/1/94        VL              1151339: Preparation for MergeContainer.
  275.                 <37>    10/19/94        VL              1155857: Added ODDebug_Drafts to debug
  276.                                                                         "Cannot create more than 10 drafts"
  277.                                                                         problem.
  278.                 <36>    10/12/94        VL              (JPA) Added debugstrs for frames.
  279.                 <35>     10/4/94        CC              1190858 - Added ReleaseLinkSource().
  280.                 <34>     9/29/94        RA              1189812: Mods for 68K build.
  281.                 <33>     9/23/94        VL              1184272: ContainerID is now a sequence of
  282.                                                                         octets. This affects EmbeddedContainers
  283.                                                                         also.
  284.                 <32>     9/23/94        CC              1187509 - Added somPrintfs for debugging
  285.                                                                         clone operations.
  286.                 <31>     9/16/94        CC              1186957 - Fix to clone newly created links
  287.                                                                         correctly (added AcquireLinkSourceFromLink and
  288.                                                                         AcquireLinkFromLinkSource).
  289.                 <30>     9/15/94        CC              1186776 - Enforce correct link behavior
  290.                                                                         during clone operations.
  291.                                                                         1160117 - Strip links when cloning into a
  292.                                                                         link.
  293.                                                                         1186657 - Correct ref count on object
  294.                                                                         returned by CreateLinkSource().
  295.                                                                         1153940 - Clone must support new clone kind
  296.                                                                         constants.
  297.                 <29>      9/9/94        CG              #1183531: ConstructPart instantiates a
  298.                                                                         PartWrapper which in turn creates a part.
  299.                 <28>      9/6/94        VL              1184177: Removed GetName and SetName.
  300.                 <27>      9/5/94        VL              1184871: Used Renew to remove dependency on
  301.                                                                         default heap.
  302.                 <26>     8/31/94        Té              #1183129, #1183116, #1183119, #1183111:
  303.                                                                         Lots of ErrorCode cleanup.
  304.                 <25>     8/31/94        VL              1106013: Fixed GetName to return kODNULL if
  305.                                                                         the draft does not have a name.
  306.                 <24>     8/26/94        VL              1183174: Added destDraft to BeginClone and
  307.                                                                         added toID to Clone.
  308.                 <23>     8/19/94        Té              #1181622 Fix Written to Owned & name &
  309.                                                                         reference to ASLM Build
  310.                 <22>     8/17/94        CG              #1181487: Instantiating parts by name
  311.                                                                         again!
  312.                 <21>     8/16/94        Té              #1180922  Remove more obsolete types from
  313.                                                                         StdTypes.idl.  Localized kODStorageUnit to
  314.                                                                         this file.
  315.                 <20>     8/16/94        VL              1143605: Added CloneInto.
  316.                 <19>     8/15/94        VL              #???: Added frameType parameter to
  317.                                                                         CreateFrame.
  318.                 <18>     8/13/94        Té              #1180814 Added support for ODPartWrapper
  319.                                                                         API
  320.                 <17>     8/12/94        JBS             1179919: add biasCanvas param to
  321.                                                                         Draft::CreateFrame()
  322.                 <16>     8/11/94        CC              Added implementation of
  323.                                                                         CreateLinkIterator() and
  324.                                                                         CreateLinkSourceIterator() methods.
  325.                 <15>     8/10/94        JBS             1179919: coordinate system bias changes
  326.                 <14>      8/4/94        eeh             bug 1179054: fix kODPartPartsBin
  327.                 <13>      8/3/94        VL              1153123: Storage to ODStor.
  328.                 <12>     7/28/94        Té              Create Clock statically
  329.                 <11>     7/27/94        CC              Removed static functions IsMyProcess() and
  330.                                                                         IsRunningProcess(); changed AcquireLink()
  331.                                                                         method to use new ODLinkSpec methods.
  332.                 <10>     7/26/94        VL              Got rid of MacStorageUnit and
  333.                                                                         MacDragAndDropStorageUnit.
  334.                  <9>     7/26/94        eeh             
  335.                  <8>     7/21/94        VL              Removed ASLM BUILD.
  336.                  <7>     7/19/94        CC              Create DragText statically.
  337.                  <6>     7/18/94        Té              moved refcounting fixes to PstObj.cpp
  338.                  <5>     7/18/94        Té              fixed another refcount problem
  339.                  <4>     7/17/94        Té              fixed ReleasePersistentObject to release
  340.                                                                         the storageUnit of a persistentObject
  341.                  <3>     7/14/94        eeh             Apple module name -> AppleTestDraw
  342.                  <2>     7/12/94        VL              Added code to Create DrawPart statically.
  343.                  <1>      7/5/94        VL              first checked in
  344.                 -----------------------------------------------------------------------
  345.                 <10>      6/1/94        CG              Changed to use public binding object.
  346.                  <9>     5/27/94        jpa             Use ODNewObject to avoid ASLM dependency,
  347.                                                                         to support new exception scheme [1165267]
  348.                  <8>      5/9/94        MB              #1162181: Changes necessary to install MMM.
  349.                  <7>      4/6/94        JBS             1155480
  350.                  <6>     3/28/94        Té              #1145834.  Remove PrtType.h & .cpp from the
  351.                                                                         project.  Noted a few places where there is
  352.                                                                         code which is only needed by the static
  353.                                                                         build.
  354.                  <5>     3/28/94        CG              1153547: Changed XMPSessn.h to XMPSessM.h
  355.                  <4>     3/27/94        Té              localized use of kXMPPropRootSU
  356.                  <3>     3/25/94        CC              Change name of included file to
  357.                                                                         "LinkMgrM.h". (1153348)
  358.                  <2>     3/25/94        MB              Symantec ASLM fixes. #1150864
  359.                  <1>     3/24/94        VL              first checked in
  360.                  <7>     3/18/94        CC              CMRegisterType(): Changed kXMPAppleTEXT
  361.                                                                         argument to kXMPISOStr. (1151636)
  362.                  <6>     3/15/94        MB              Changes to support SCpp/ASLM builds,
  363.                                                                         #1150864.
  364.                  <5>     3/14/94        CC              Added internal methods FixReusedLinks() and
  365.                                                                         ReferencedStorageUnitCloned(); Revised
  366.                                                                         EndClone(), PrepareLinksForClone().
  367.                                                                         (1149492)
  368.                  <4>     2/22/94        VL              THROW -> THROW_IF_ERROR.
  369.                  <3>     2/18/94        VL              #1142972, #1144024: Added
  370.                                                                         GetDragDropStorageUnit to enable importing
  371.                                                                         data from a foreign source (e.g. the
  372.                                                                         Finder).
  373.                  <2>     2/17/94        CC              Bug #1142584 - GetOriginalCloneKind returns
  374.                                                                         kXMPCloneCopy by default in case content
  375.                                                                         was put directly onto the clipboard without
  376.                                                                         cloning.
  377.            <106>          2/8/94        VL              Corrected capitalization of include files
  378.                                                                         and used <> for Toolbox headers.
  379.            <105>          2/8/94        VL              Use new exception macros.
  380.            <104>          2/4/94        VL              Session.h -> XMPSessn.h.
  381.            <103>          2/4/94        VL              More code cleanup.
  382.            <102>          2/4/94        VL              Moved to PPC Header and began code cleanup.
  383.                                                                         (Added itoa to replace NumToString. Got rid
  384.                                                                         of some warnings.)
  385.            <101>          2/3/94        CG              System Session break out.
  386.            <100>          2/2/94        VL              Made Hash Table use system heap when
  387.                                                                         appropriate.
  388.                 <99>      2/2/94        CC              Revised PrepareLinksForClone() and
  389.                                                                         AnnotateLinksForNextClone().
  390.                 <98>      2/2/94        RR              Added isRoot to CreateFrame
  391.                 <97>      2/1/94        CC              Added PrepareLinksForClone()
  392.                                                                         AnnotateLinksForNextClone(), and non-member
  393.                                                                         support functions; not yet called by
  394.                                                                         EndClone().  Added XMPCloneType argument to
  395.                                                                         BeginClone.
  396.                 <96>     1/28/94        CC              Removed UniqueUpdateID(),
  397.                                                                         ShowLinkBorders(), and SetLinkBorders().
  398.                                                                         Implemented Purge() (VL).  Abort() now
  399.                                                                         releases draft properties (VL).  Fixed
  400.                                                                         sequence of deletions in
  401.                                                                         RemovePersistentObject() (VL).
  402.                                                                         DeleteCollections() - call ReleaseAll() on
  403.                                                                         all objects, then delete all objects.
  404.                 <95>     1/27/94        VL              Used ReleaseAll. Fixed up
  405.                                                                         ReleasePersistentObject. Added
  406.                                                                         IsValidDraftKey.
  407.                 <94>     1/25/94        CC              Use fShowLinkBorders field.
  408.                 <93>     1/22/94        CC              AcquireLink(), AcquireLinkSource(): Avoid infinite
  409.                                                                         recursion by adding persistent object to
  410.                                                                         the draft before calling
  411.                                                                         InitFromStorageUnit().
  412.                 <92>     1/21/94        CC              Added CreateLinkSource(), AcquireLinkSource(),
  413.                                                                         RemoveLinkSource(), and
  414.                                                                         AcquireLinkSourceIterator().  Moved calls to
  415.                                                                         XMPLinkManager::DraftOpened,
  416.                                                                         ::DraftClosing, and ::DraftSaved into
  417.                                                                         document shell.
  418.                 <91>     1/21/94        CG              Renamed kXMPEmbeddedContainer to
  419.                                                                         kXMPBentoEmbeddedContainer.  Changed calls
  420.                                                                         to NewObject to take current heap.
  421.                 <90>     1/18/94        CG              Added include for BentoDef.h for
  422.                                                                         kXMPEmbeddedContainer.
  423.                 <89>     1/18/94        CC              Added stub implementations of
  424.                                                                         ShowLinkBorders() and SetLinkBorders();
  425.                                                                         changed DraftClosed() to DraftClosing().
  426.                 <88>     1/15/94        VL              Made sure that the Part Destructor is
  427.                                                                         called.
  428.                 <87>     1/14/94        CC              Externalize(): Call
  429.                                                                         XMPLinkManager::DraftSaved();
  430.                                                                         RemoveChanges(): Call
  431.                                                                         XMPLinkManager::DraftClosed().
  432.                 <86>     1/12/94        CG              Changed CreatePart and AcquirePart to use the
  433.                                                                         new Binding object in ASLM build.
  434.                 <85>     1/12/94        VL              Init... Changes.
  435.                 <84>    12/22/93        CC              AcquireLink() - Better error handling and
  436.                                                                         clean-up.
  437.                 <83>    12/21/93        VL              Added support for Persistent Link ID.
  438.                 <82>    12/21/93        JBS             CreateFrame with viewType & presentation
  439.                 <81>    12/20/93        SS              Added PartsBin to Get/CreatePart
  440.                 <80>    12/20/93        VL              Removed window-related stuff (XMPWindow is
  441.                                                                         no longer a persistent object).
  442.                 <79>    12/16/93        CC              AcquireLink: Instantiate link objects, moved
  443.                                                                         code into LinkMgr.cp.  CreateLink: object
  444.                                                                         type is kXMPLink not kXMPPart!
  445.                 <78>    12/16/93        Té              CreatePart now takes an optional Editor
  446.                                                                         parameter
  447.                 <77>    12/14/93        VL              Added private methods to GetCMContainer and
  448.                                                                         used AcquireDraft instead of fDraft.
  449.                 <76>    12/14/93        Té              InitFrame, InitLink, InitWindow changes.
  450.                                                                         PstObj::Initialize, PstObj:Internalize,
  451.                                                                         PstObj::InitializePersistent all went away.
  452.                 <75>    12/13/93        Té              InitPart changes
  453.                 <74>     12/8/93        CC              Changes to CreateLinkSpec
  454.                                                                         AcquireLink sends apple event to resolve
  455.                                                                         linkSpec.
  456.                 <73>     12/3/93        Té              Stop including XMPError.h, it is included
  457.                                                                         as ErrorDef.h inside Except.h
  458.                 <72>    11/30/93        VL              Changed frameGroup from XMPUShort to
  459.                                                                         XMPULong.
  460.                 <71>    11/24/93        VL              Added document check in Initialize.
  461.                 <70>    11/23/93        VL              Made XMPDraft pool-aware.
  462.                 <69>    11/18/93        PH              Call parent method in
  463.                                                                         RemovePersistentObject
  464.                 <68>    11/18/93        PH              Fixed RemovePersistentObject to call
  465.                                                                         Release before calling delete
  466.                 <67>    11/17/93        CC              Fixed CreateLink to compile with CFront.
  467.                 <66>    11/16/93        EL              Use OpenDoc instead of Amber.
  468.                 <65>    11/16/93        SS              Reactivated DragPart
  469.                 <64>    11/16/93        EL              Part name is ISOStr and should be null
  470.                                                                         terminated.
  471.                 <63>    11/15/93        CC              Implemented AcquireLink for LinkSpec parameter
  472.                                                                         Implemented CreateLink and CreateLinkSpec
  473.                                                                         Added IsMyProcess
  474.                 <62>    11/12/93        JBS             remove Layout methods
  475.                 <61>     11/9/93        PH              Added CreateDragDropStorageUnit
  476.                 <60>     11/4/93        SS              Added #ifdef QUALITY_PARTS too
  477.                                                                         Get/CreatePart for quality team
  478.                 <59>     11/1/93        VL              Added BeginClone, EndClone and AbortClone.
  479.                                                                         Collapsed fStorageUnits and
  480.                                                                         fReleasedStorageUnits into one hash table.
  481.                                                                         Collapsed fPersistentObjects and
  482.                                                                         fReleasedPersistentObjects into one hash
  483.                                                                         table.
  484.                 <58>    10/29/93        PH              Fix AcquirePart and add check to
  485.                                                                         ReleaseStorageU
  486.                 <57>    10/21/93        RR              CreateWindow takes new window flags (at
  487.                                                                         least until we have new Initialize strategy
  488.                                                                         for SOM)
  489.                 <56>    10/12/93        VL              Uncommented WASSERTs. Release
  490.                                                                         fDraftProperties in ::RemoveChanges.
  491.                 <55>     10/8/93        VL              Temporarily removed WASSERT.
  492.                 <54>     10/7/93        RR              Added rootPart to CreateWindow call
  493.                 <53>     10/7/93        VL              Moved error codes to XMPError.h.
  494.                 <52>     10/6/93        Té              remove obsolete parts (StylPart)
  495.                 <51>     9/30/93        VL              Removed SetFinished.
  496.                 <50>     9/30/93        VL              Removed unnecessary STORAGE_TEST ifdefs.
  497.                 <49>     9/29/93        VL              Added code for smart internalization.
  498.                 <48>     9/24/93        PH              Use new AppleTEXT
  499.                 <47>     9/24/93        VL              Removed unnecessary Throws.
  500.                 <46>     9/24/93        JA              Minor syntactic tweaks for THINK C++.
  501.                 <45>     9/23/93        VL              Added code to handle StorageUnitType
  502.                                                                         property. Fixed SetName to use Exists
  503.                                                                         instead of exception. Moved methods around
  504.                                                                         to conform to .h file.
  505.                 <44>     9/22/93        JA              Updated ASSERTs for new macro.
  506.                 <43>     9/21/93        VL              Avoid creating unnecessary versions.
  507.                 <42>     9/16/93        JA              Fixed polarity of ASSERTs.
  508.                 <40>     9/14/93        VL              Made Draft thread-safe.
  509.                 <39>      9/9/93        VL              Set up the Session global for
  510.                                                                         EmbeddedContainers. Fixed casting problem
  511.                                                                         caused in <38>.
  512.                 <38>      9/9/93        VL              Fixed RemovePersistentObject to
  513.                                                                         CMDeleteObject the real object, not ID.
  514.                 <37>      9/8/93        VL              Draft can handle flushing now.
  515.                 <36>      9/7/93        PH              Add code to create a DragPart
  516.                 <35>      9/3/93        JBS             added support for XMPLayout class
  517.                 <34>     8/26/93        VL              Used new VersionList calls.
  518.                 <33>     8/23/93        VL              Added FailIfNotExclusiveWrite check. Used
  519.                                                                         fExternalized flag to show the state of the
  520.                                                                         draft. Implemented NeedExternalizing.
  521.                 <32>     8/20/93        Té              Commented out #ifdef PROTOTYPEBUILD stuff
  522.                                                                         so that the implementation shell could use
  523.                                                                         the full functionality of Draft
  524.                 <31>     8/20/93        VL              Cast XMPPtr to XMPName.
  525.                 <30>     8/20/93        VL              Used ODMemory.h
  526.                 <29>     8/19/93        VL              Put in CMDeleteObject again.
  527.                 <28>     8/18/93        VL              ReleaseStorageUnit takes an ID now.
  528.                 <27>     8/18/93        PH              Don't call CMDeleteObject in
  529.                                                                         RemoveStorageUnit
  530.                 <26>     8/18/93        VL              Fixed ReleaseSTorageUnit.
  531.                 <25>     8/17/93        PH              Call internalize in AcquirePart and don't
  532.                                                                         increment the ref count of the SU in
  533.                                                                         GetPstObj if the object exists
  534.                 <24>     8/13/93        VL              Used VersionList::GetLatestVersionID.
  535.                                                                         Commented out some code in Externalize.
  536.                 <23>     8/12/93        VL              Made GetName raise an exception instead of
  537.                                                                         returning kXMPNULL. Used kXMP props and
  538.                                                                         types.
  539.                 <22>     8/11/93        VL              ifdef out implementation code for
  540.                                                                         CreateFrame because the XMPFrame class is
  541.                                                                         not there yet.
  542.                 <21>     8/10/93        VL              Put some real code in CreateFrame.
  543.                 <20>     8/10/93        PH              Call release on su in ReleasePstObj
  544.                 <19>     8/10/93        PH              Really fix ReleasePstObj
  545.                 <18>      8/9/93        PH              Fix ReleasePersistentObject to do ref
  546.                                                                         counting properly
  547.                 <17>      8/9/93        VL              Moved error code to XMPError.h.
  548.                 <16>      8/6/93        PH              Change kPartType to kXMPPart
  549.                 <15>      8/6/93        VL              Used CreateCollections and
  550.                                                                         DeleteCollections.
  551.                 <14>      8/6/93        PH              Storage integration
  552.                 <13>      8/6/93        VL              Added support for
  553.                                                                         creating/getting/releasing/removing
  554.                                                                         persistent objects.
  555.                 <12>     7/29/93        VL              Removed getting persistent objects by name.
  556.                                                                         Implemented GetName and SetName.
  557.                 <11>     7/23/93        VL              Removed root SU creation code in
  558.                                                                         AcquireDraftPropertiesObject.
  559.                 <10>     7/14/93        VL              Implemented basic storage unit functions.
  560.                  <9>      7/6/93        VL              Implemented RemoveFromDocument.
  561.                  <8>      7/6/93        VL              XMPStorageUnitName should be
  562.                                                                         XMPStorageUnitName* in AcquireStorageUnit.
  563.                  <7>      7/2/93        Té              CreateSU should take XMPType, not XMPName.
  564.                  <6>     6/30/93        VL              Changed XMPName to XMPType.
  565.                  <5>     6/30/93        VL              Added Reinitialize, Open, Close, Abort.
  566.                                                                         Also added utility calls
  567.                                                                         Open/Close/AbortVersion.
  568.                  <4>     6/22/93        VL              Used RefCount from RefCtObj. Added
  569.                                                                         SetChangedFromPrev() and
  570.                                                                         AcquireDraftPropertiesObject. Initialize() gets
  571.                                                                         SU for Draft Properties.
  572.                  <3>     6/15/93        VL              Put it some test code.
  573.                  <1>      6/2/93        VL              first checked in
  574.  
  575.         To Do:
  576.         In Progress:
  577.  
  578. */
  579.  
  580. #define CMDraft_Class_Source
  581. #define VARIABLE_MACROS
  582. #include <CMDraft.xih>
  583.  
  584. #ifdef _PLATFORM_WIN32_
  585. #include <process.h>
  586. #endif
  587.  
  588. #ifdef _PLATFORM_OS2_
  589.  
  590. // headers for DSOM linking
  591.  
  592. #include <process.h>
  593. #include <somd.xh>
  594.  
  595. #ifndef _ISOSTR_
  596. #include <ISOStr.h>
  597. #endif
  598.  
  599. #include <tpllitr.xh>
  600. #include <tpll.xh>
  601.  
  602. #ifndef _IODDEFS_
  603. #include <IODDefs.xh>
  604. #endif
  605.  
  606. // #include <link.xh>
  607. #include <ICIDItr.xh>
  608. #include <ILinkSrc.xh>
  609. #include <ILnkSrvc.xh>
  610. #include <ILnkTrgt.xh>
  611.  
  612. #endif  // PLATFORM_OS2_
  613.  
  614. #ifndef _DRAFPRIV_
  615. #include "DrafPriv.h"
  616. #endif
  617.  
  618. #ifndef SOM_ODSession_xh
  619. #include <ODSessn.xh>
  620. #endif
  621.  
  622. #ifndef SOM_CMDocument_xh
  623. #include <CMDoc.xh>
  624. #endif
  625.  
  626. #ifndef SOM_CMStorageUnit_xh
  627. #include <CMSU.xh>
  628. #endif
  629.  
  630. #ifndef _DOCPRIV_
  631. #include "DocPriv.h"
  632. #endif
  633.  
  634. #ifndef SOM_ODContainer_xh
  635. #include <ODCtr.xh>
  636. #endif
  637.  
  638. #ifndef SOM_ODStorageSystem_xh
  639. #include <ODStor.xh>
  640. #endif
  641.  
  642. #ifndef SOM_ODStorageUnitCursor_xh
  643. #include <SUCursor.xh>
  644. #endif
  645.  
  646. #ifndef SOM_ODFrame_xh
  647. #include <Frame.xh>
  648. #endif
  649.  
  650. #ifndef SOM_ODLink_xh
  651. #include <Link.xh>
  652. #endif
  653.  
  654. #ifndef SOM_ODLinkSource_xh
  655. #include <LinkSrc.xh>
  656. #endif
  657.  
  658. #ifndef SOM_ODLinkSpec_xh
  659. #include <LinkSpec.xh>
  660. #endif
  661.  
  662. #ifndef SOM_ODLinkManager_xh
  663. #include <LinkMgr.xh>
  664. #endif
  665.  
  666. #ifndef SOM_ODPart_xh
  667. #include <Part.xh>
  668. #endif
  669.  
  670. #ifndef _EXCEPT_
  671. #include "Except.h"
  672. #endif
  673.  
  674. #ifndef SOM_ODBentoContainer_xh
  675. #include "CMCtr.xh"
  676. #endif
  677.  
  678. #ifndef _CMAPI_
  679. #include "CMAPI.h"
  680. #endif
  681.  
  682. #ifndef __CM_API_TYPE_
  683. #include "CMAPITyp.h"
  684. #endif
  685.  
  686. #ifndef SOM_ODEmbeddedContainer_xh
  687. #include <EmbedCtr.xh>
  688. #endif
  689.  
  690. #ifndef _SESSHDR_
  691. #include "SessHdr.h"
  692. #endif
  693.  
  694. #ifndef _ODMEMORY_
  695. #include "ODMemory.h"
  696. #endif
  697.  
  698. #ifndef _ODNEW_
  699. #include "ODNew.h"
  700. #endif
  701.  
  702. #ifndef SOM_Module_OpenDoc_StdProps_defined
  703. #include <StdProps.xh>
  704. #endif
  705.  
  706. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  707. #include <StdTypes.xh>
  708. #endif
  709.  
  710. #ifndef SOM_CMLinkIterator_xh
  711. #include <CMLkItr.xh>
  712. #endif
  713.  
  714. #ifndef SOM_CMLinkSourceIterator_xh
  715. #include <CMLkSItr.xh>
  716. #endif
  717.  
  718. #ifdef _PLATFORM_OS2_
  719. #ifndef SOM_ODWindow_xh
  720. #include <Window.xh>
  721. #endif
  722. #endif
  723.  
  724. #ifndef _INDHDR_
  725. #include "IndHdr.h"                     // for some const ODName
  726. #endif
  727.  
  728. #ifndef _OPENHASH_
  729. #include "OpenHash.h"
  730. #endif
  731.  
  732. #ifndef _ISOSTR_
  733. #include "ISOStr.h"
  734. #endif
  735.  
  736. #ifndef __STRING__
  737. #include <string.h>                     // For strlen, strcpy....
  738. #endif
  739.  
  740. #ifndef _ODDEBUG_
  741. #include "ODDebug.h"    // Adkins -- added
  742. #endif
  743.  
  744. #ifndef _STORUTIL_
  745. #include <StorUtil.h>
  746. #endif
  747.  
  748. #ifndef SOM_ODBinding_xh
  749. #include <ODBindng.xh>
  750. #endif
  751.  
  752. #ifndef SOM_ODPartWrapper_xh
  753. #include <PartWrap.xh>
  754. #endif
  755.  
  756. #ifndef _BENTODEF_
  757. #include "BentoDef.h"
  758. #endif
  759.  
  760. #ifndef _BARRAY_
  761. #include <BArray.h>
  762. #endif
  763.  
  764. #ifdef _PLATFORM_OS2_
  765. #ifndef _ODUTILS_
  766. #include <ODUtils.h>
  767. #endif
  768. #endif
  769.  
  770. #ifndef _UTILERRS_
  771. #include "UtilErrs.h"
  772. #endif
  773.  
  774. #ifdef _PLATFORM_MACINTOSH_
  775. #ifndef SOM_ODDragAndDrop_xh
  776. #include <DragDrp.xh>
  777. #endif
  778. #endif
  779.  
  780. #ifndef SOM_ODArbitrator_xh
  781. #include <Arbitrat.xh>
  782. #endif
  783.  
  784. #ifndef SOM_Module_OpenDoc_Foci_defined
  785. #include <Foci.xh>
  786. #endif
  787.  
  788. #ifndef _NO_TMP_OBJS_
  789. #ifndef _ODNEWOBJ_
  790. #include <ODNewObj.h>
  791. #endif
  792. #endif
  793.  
  794. #ifndef _STDTYPIO_
  795. #include <StdTypIO.h>
  796. #endif
  797.  
  798. #ifndef _NO_TMP_OBJS_
  799. #ifndef _TEMPOBJ_
  800. #include <TempObj.h>
  801. #endif
  802. #endif
  803.  
  804. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  805. #include <StdDefs.xh>
  806. #endif
  807.  
  808. #ifndef SOM_SOMClassMgr_xh
  809. #include <somcm.xh>
  810. #endif
  811.  
  812. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  813. #ifndef _ODUTILS_
  814. #include "ODUtils.h"
  815. #endif
  816. #endif
  817.  
  818. #ifndef SOM_ODWindow_xh
  819. #include <Window.xh>
  820. #endif
  821.  
  822. #ifndef SOM_NoPart_xh
  823. #include <NoPart.xh>
  824. #endif
  825.  
  826. #ifdef _PLATFORM_WIN32_
  827. #ifndef _OLEWRAP_H_
  828. #include "olewrap.h"
  829. #endif
  830.  
  831. #ifndef _OLEMGRW_H_
  832. #include "olemgrw.h"
  833. #endif
  834.  
  835. #ifndef SOM_OpenDocShell_xh
  836. #include "odshell.xh"
  837. #endif
  838.  
  839. #ifndef SOM_DocumentManager_xh
  840. #include "docmgr.xh"
  841. #endif
  842. #endif
  843.  
  844. #ifndef _BENTOERR_
  845. #include "BentoErr.h"
  846. #endif
  847.  
  848.  
  849. #ifdef _PLATFORM_OS2_
  850.  
  851. #include <ILnkSrvc.xh>
  852. #include <ILinkSrc.xh>
  853.  
  854. #ifndef SOM_ODNameSpaceManager_xh
  855. #include <NmSpcMg.xh>
  856. #endif
  857.  
  858. #ifndef LMGRDEFS_H
  859. #include "lmgrdefs.h"
  860. #endif
  861.   
  862. #endif  // PLATFORM_OS2_
  863.  
  864. #pragma segment CMDraft
  865.  
  866. //==============================================================================
  867. // Constants
  868. //==============================================================================
  869.  
  870. const ODType    kODVersionNamePrefix = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:Bento Version Name";
  871. const ODPropertyName kODPropRootSU  = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:DraftRootStorageUnit";
  872. const ODType    kODStorageUnitType      = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Type:StorageUnit";
  873. const ODType    kODStorageUnit          = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:ObjectType:StorageUnit";
  874. const ODULong   kODInitialNumEntries = 8;
  875.  
  876. const corbastring kFrameClassName = "ODFrame";
  877.                 // $$$$$ This seems like a bad hardcoded dependency on a classname.
  878.  
  879. #define kODPropOriginalPID "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Metadata:OriginalPID"
  880. #define kMaxStringSize  32
  881. #define kInitialHashTableEntries 8
  882.  
  883. #define lazyOpen 1
  884.  
  885. // For debugging
  886.  
  887. #if ODDebug
  888. // #define ODDebug_Drafts       1
  889. // #define ODDebug_DebugRefCount 1
  890. // #define ODDebug_CMDraft 1
  891. // #define DebugClone 1
  892. // #define ODDebug_VersionList  1
  893. // #define ODDebug_CloningAnnotations 1
  894. // #define ODDebug_Unloading_Classes 1
  895. #endif
  896.  
  897.  
  898. //==============================================================================
  899. // Local Classes
  900. //==============================================================================
  901.  
  902. class SULink : public Link {
  903.  
  904. public:
  905.  
  906.         SULink(ODStorageUnitID fromID, ODStorageUnitID toID)
  907.         {
  908.                 fFromID = fromID;
  909.                 fToID = toID;
  910.         }
  911.         ~  SULink() {;};
  912.  
  913.         ODStorageUnitID GetFromID() {return fFromID;};
  914.         ODStorageUnitID GetToID() {return fToID;};
  915.  
  916. private:
  917.  
  918.         ODStorageUnitID                         fFromID;
  919.         ODStorageUnitID                         fToID;
  920. };
  921.  
  922. //==============================================================================
  923. // Function Prototypes
  924. //==============================================================================
  925.  
  926. static CMStorageUnit* NewCMStorageUnit(ODMemoryHeapID heapID);
  927.  
  928. static CMObject AcquireDraftPropertiesObject(CMContainer container);
  929. static ODType GetVersionNameFromVersionID(ODVersionID id, ODMemoryHeapID heapID);
  930.  
  931. static void SetOriginalDraft(Environment* ev, ODDraft* targetDraft, ODDraft* originalDraft);
  932. static ODDraft* GetOriginalDraft(Environment* ev, ODDraft* draft);
  933. static ODBoolean OriginalCloneKindExists(Environment* ev, ODDraft* draft);
  934. static void SetOriginalCloneKind(Environment* ev, ODDraft* targetDraft, ODCloneKind cloneKind);
  935.  
  936. static ODBoolean IsLinkObject(Environment* ev, ODDraft* draft, ODID objectID);
  937. static ODBoolean IsLinkSourceObject(Environment* ev, ODDraft* draft, ODID objectID);
  938. static ODBoolean IsNeitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID);
  939.  
  940. static void CM_itoa(ODULong number, ODSByte* cstring);   // KP
  941.  
  942. static ODULong PurgeAllStorageUnits(Environment* ev, OpenHashTable* storageUnits, IDList* idList);
  943.  
  944. static void SetupForUpdatingDraft(Environment* ev,
  945.                                                                                 CMDocument* localDoc,
  946.                                                                                 ODVersionID prevVersionID,
  947.                                                                                 CMValue version);
  948.  
  949. static ODBoolean CheckPartAction(void* k, void* v, ODULong s, void* r);
  950.  
  951. static void CopyProperty(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU, ODPropertyName prop);
  952. static void CopyDraftAnnotations(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU);
  953. static void SetStorageUnitType(Environment* ev, ODDraftPermissions perms, ODStorageUnit* su, ODType suType);
  954. static ODISOStr GetStorageUnitType(Environment* ev, ODDraft* draft, ODID objectID);
  955. static ODID RootPartID(Environment* ev, ODDraft* draft);
  956.  
  957. static void PurgeClasses(Environment* ev, OpenHashTable* partClasses);
  958.  
  959. // For debugging
  960.  
  961. #ifdef DebugStorage
  962.  
  963. #define MyDebugStr(s) do {somPrintf(s);} while (0)
  964. #define MyDebug2Str(f,p1,p2) do {somPrintf(f, p1, p2);} while (0)
  965.  
  966. #else
  967.  
  968. #define MyDebugStr(s)
  969. #define MyDebug2Str(f,p1,p2)
  970.  
  971. #endif
  972.  
  973. //==============================================================================
  974. // Static variables
  975. //==============================================================================
  976.  
  977. // Used by CheckPartAction
  978. static CMDraft* sInterchangeDraft = kODNULL;
  979. static ODISOStr sSUTypeBuffer;
  980. static ODID             sRootPartIDToIgnore;
  981.  
  982. //------------------------------------------------------------------------------
  983. // ReadClonedObjectTable
  984. //------------------------------------------------------------------------------
  985.  
  986. // These are private property and value for Bento Container Suite.
  987. // They are used for data interchange. They enable multiple clones to the clipboard
  988. // and d&d container.
  989. const ODPropertyName    kODPropClonedObjectTable  = "OpenDoc:Property:Draft:ClonedObjectTable";
  990. const ODValueType               kODTypeClonedObjectTable  = "OpenDoc:Type:Draft:ClonedObjectTable";
  991.  
  992. #ifdef _PLATFORM_OS2_
  993. const ODPropertyName   kODPropCloneOfALink = "OpenDoc:Property:Link:Cloned";
  994. #endif
  995.  
  996.  
  997. ODStatic void ReadClonedObjectTable(Environment* ev, OpenHashTable* clonedSUIDs, ODDraft* destDraft)
  998. {
  999.     try
  1000.     {
  1001. #ifdef DebugClone
  1002.         somPrintf("CMDraft: ReadClonedObjectTable\n");
  1003. #endif
  1004.  
  1005.     if (!destDraft)
  1006.         THROW(kODErrIllegalNullDraftInput);
  1007.  
  1008. #ifdef _NO_TMP_OBJS_
  1009.         ODStorageUnit *su = destDraft->AcquireDraftProperties(ev);
  1010. #else
  1011.         TempODStorageUnit su = destDraft->AcquireDraftProperties(ev);
  1012. #endif
  1013.         if (ODSUExistsThenFocus(ev, su, kODPropClonedObjectTable, kODTypeClonedObjectTable) )
  1014.         {
  1015.                 su->SetOffset(ev, 0);
  1016.  
  1017.                 ODULong size = su->GetSize(ev);
  1018.                 ODID    fromID;
  1019.                 ODID    toID;
  1020.  
  1021.                 while ( su->GetOffset(ev) < size )
  1022.                 {
  1023.                         StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue) &fromID);
  1024.                         StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue) &toID);
  1025. #ifdef DebugClone
  1026.                         somPrintf("     fromID %d, toID %d\n", fromID, toID);
  1027. #endif
  1028.                         clonedSUIDs->ReplaceEntry(&fromID, &toID);
  1029.                 }
  1030.         }
  1031. #ifdef _NO_TMP_OBJS_
  1032.         su->Release(ev);
  1033. #endif
  1034.    }
  1035.    catch (ODException _exception)
  1036.    {
  1037.         ODSetSOMException(ev, _exception);
  1038.    }
  1039. }
  1040.  
  1041. //------------------------------------------------------------------------------
  1042. // WriteClonedObjectTable
  1043. //------------------------------------------------------------------------------
  1044.  
  1045. ODStatic void WriteClonedObjectTable(Environment* ev, OpenHashTable* clonedSUIDs, ODDraft* destDraft)
  1046. {
  1047.     try
  1048.     {
  1049. #ifdef DebugClone
  1050.         somPrintf("CMDraft: WriteClonedObjectTable\n");
  1051. #endif
  1052.  
  1053. #ifdef _NO_TMP_OBJS_
  1054.         ODStorageUnit *su = destDraft->AcquireDraftProperties(ev);
  1055. #else
  1056.         TempODStorageUnit su = destDraft->AcquireDraftProperties(ev);
  1057. #endif
  1058.  
  1059.         ODSUForceFocus(ev, su, kODPropClonedObjectTable, kODTypeClonedObjectTable);
  1060.  
  1061.         su->SetOffset(ev, 0);
  1062.  
  1063.         ODULong oldSize = su->GetSize(ev);
  1064.  
  1065.         ODID            fromID;
  1066.         ODID            toID;
  1067.  
  1068.         OpenHashTableIterator iter(clonedSUIDs);
  1069.         for (iter.First(&fromID, &toID); iter.IsNotComplete(); iter.Next(&fromID, &toID))
  1070.         {
  1071. #ifdef DebugClone
  1072.                 somPrintf("     fromID %d, toID %d\n", fromID, toID);
  1073. #endif
  1074.                 StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue) &fromID);
  1075.                 StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue) &toID);
  1076.         }
  1077.  
  1078.         ODULong newSize = su->GetOffset(ev);
  1079.         if ( oldSize > newSize )
  1080.                 su->DeleteValue(ev, oldSize - newSize);
  1081. #ifdef _NO_TMP_OBJS_
  1082.         su->Release(ev);
  1083. #endif
  1084.    }
  1085.    catch (ODException _exception)
  1086.    {
  1087.         ODSetSOMException(ev, _exception);
  1088.    }
  1089. }
  1090.  
  1091. //==============================================================================
  1092. // CMDraft
  1093. //==============================================================================
  1094.  
  1095. //------------------------------------------------------------------------------
  1096. // CMDraft: FailIfNotExclusiveWrite
  1097. //------------------------------------------------------------------------------
  1098.  
  1099. SOM_Scope void  SOMLINK CMDraftFailIfNotExclusiveWrite(CMDraft *somSelf, Environment *ev)
  1100. {
  1101.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1102.     CMDraftMethodDebug("CMDraft","FailIfNotExclusiveWrite");
  1103.  
  1104.         if (_fPermissions != kODDPExclusiveWrite)
  1105.                 ODSetSOMException(ev,kODErrInvalidPermissions);
  1106. }
  1107.  
  1108. //------------------------------------------------------------------------------
  1109. // CMDraft: GetDocument
  1110. //------------------------------------------------------------------------------
  1111.  
  1112. SOM_Scope ODDocument*  SOMLINK CMDraftGetDocument(CMDraft *somSelf, Environment *ev)
  1113. {
  1114.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1115.     CMDraftMethodDebug("CMDraft","GetDocument");
  1116.  
  1117.         return _fDocument;
  1118. }
  1119.  
  1120. //------------------------------------------------------------------------------
  1121. // CMDraft: GetID
  1122. //------------------------------------------------------------------------------
  1123.  
  1124. SOM_Scope ODDraftID  SOMLINK CMDraftGetID(CMDraft *somSelf, Environment *ev)
  1125. {
  1126.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1127.     CMDraftMethodDebug("CMDraft","GetID");
  1128.  
  1129.         return _fID;
  1130. }
  1131.  
  1132. //------------------------------------------------------------------------------
  1133. // CMDraft: AcquireDraftProperties
  1134. //------------------------------------------------------------------------------
  1135.  
  1136. SOM_Scope ODStorageUnit*  SOMLINK CMDraftAcquireDraftProperties(CMDraft *somSelf, Environment *ev)
  1137. {
  1138.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1139.     CMDraftMethodDebug("CMDraft","AcquireDraftProperties");
  1140.  
  1141.         ODStorageUnit *retStorageUnit = kODNULL;
  1142.         CMStorageUnit*          draftProperties;
  1143.  
  1144.     try
  1145.     {
  1146.         CMObject                        draftPropertiesObject;
  1147.         ODStorageUnitID id;
  1148.  
  1149.         if (_fDraftProperties != kODNULL) {
  1150.                 _fDraftProperties->Internalize(ev);
  1151.         }
  1152.         else {
  1153.  
  1154.                 CMContainer cmContainer = somSelf->GetCMContainer(ev);
  1155.                 ODSessionMustHaveCMAllocReserve(cmContainer);
  1156.                 // AcquireDraftPropertiesObject() makes CM calls:
  1157.  
  1158.                 draftPropertiesObject = AcquireDraftPropertiesObject(somSelf->GetCMContainer(ev));
  1159.                 if (draftPropertiesObject == kODNULL)
  1160.                         THROW(kODErrNoDraftProperties);
  1161.  
  1162.                 id = _fIDList->Add(draftPropertiesObject);
  1163.                 draftProperties = NewCMStorageUnit(somSelf->GetHeap(ev));
  1164.                 draftProperties->InitStorageUnit(ev, somSelf, id);
  1165.                 _fStorageUnits->ReplaceEntry(&id, &draftProperties);
  1166.                 _fDraftProperties = draftProperties;
  1167.  
  1168.                 ODSessionRestoreCMAllocReserve(cmContainer);
  1169.         }
  1170.  
  1171.         _fDraftProperties->Acquire(ev);
  1172.         retStorageUnit = _fDraftProperties;
  1173.  
  1174.     }
  1175.     catch (ODException _exception)
  1176.     {
  1177.         ODSetSOMException(ev, _exception);
  1178.        
  1179.     }
  1180.         return _fDraftProperties;
  1181. }
  1182.  
  1183. //------------------------------------------------------------------------------
  1184. // CMDraft: Acquire
  1185. //------------------------------------------------------------------------------
  1186.  
  1187. SOM_Scope void  SOMLINK CMDraftAcquire(CMDraft *somSelf, Environment *ev)
  1188. {
  1189. //  CMDraftData *somThis = CMDraftGetData(somSelf);
  1190.     CMDraftMethodDebug("CMDraft","Acquire");
  1191.  
  1192.      try
  1193.      {
  1194.                 parent_Acquire(somSelf, ev);
  1195.      }
  1196.      catch (ODException _exception)
  1197.      {
  1198.           ODSetSOMException(ev, _exception);
  1199.      }
  1200. }
  1201.  
  1202. //------------------------------------------------------------------------------
  1203. // CMDraft: Release
  1204. //------------------------------------------------------------------------------
  1205.  
  1206. SOM_Scope void  SOMLINK CMDraftRelease(CMDraft *somSelf, Environment *ev)
  1207. {
  1208.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1209.     CMDraftMethodDebug("CMDraft","Release");
  1210.  
  1211.  
  1212.     try
  1213.     {
  1214.         parent_Release(somSelf, ev);
  1215.         if (somSelf->GetRefCount(ev) == 0) {
  1216.                 if (_fDraftProperties != kODNULL) {
  1217.                         _fDraftProperties->Release(ev);
  1218.                         _fDraftProperties = kODNULL;
  1219.                 }
  1220. //              WASSERTM((somSelf->AreEmptyCollections(ev) != kODFalse), "OutstandingObjects in CMDraft: Release.");
  1221.                 _fDocument->ReleaseDraft(ev, somSelf);
  1222.         }
  1223.  
  1224.  
  1225.     }
  1226.     catch (ODException _exception)
  1227.     {
  1228.                 ODError err = ErrorCode();
  1229.  
  1230.                 WARNMSG(WARN_INDEX(AMSG_610),"Error occurred in ODDraft::Release: %d %s",
  1231.                         err, ErrorMessage() ?ErrorMessage() :"");
  1232.  
  1233.                 if (err == kODErrBentoErr){
  1234.                         SetErrorCode(kODErrFatalContainerError);
  1235.                         ODSetSOMException(ev, _exception);
  1236.                 }
  1237.                 else{
  1238.                      if (err != kODErrFatalContainerError)
  1239.                         SetErrorCode(kODNoError);
  1240.                      else
  1241.                         ODSetSOMException(ev, _exception);
  1242.                 }
  1243.  
  1244.     }
  1245. }
  1246.  
  1247. //------------------------------------------------------------------------------
  1248. // CMDraft: GetPermissions
  1249. //------------------------------------------------------------------------------
  1250.  
  1251. SOM_Scope ODDraftPermissions  SOMLINK CMDraftGetPermissions(CMDraft *somSelf, Environment *ev)
  1252. {
  1253.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1254.     CMDraftMethodDebug("CMDraft","GetPermissions");
  1255.  
  1256.         return _fPermissions;
  1257. }
  1258.  
  1259. //------------------------------------------------------------------------------
  1260. // CMDraft: CreateStorageUnit
  1261. //------------------------------------------------------------------------------
  1262.  
  1263. SOM_Scope ODStorageUnit*  SOMLINK CMDraftCreateStorageUnit(CMDraft *somSelf, Environment *ev)
  1264. {
  1265.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1266.     CMDraftMethodDebug("CMDraft","CreateStorageUnit");
  1267.  
  1268.         ODStorageUnit*  su = kODNULL; ODVolatile(su);
  1269.  
  1270.     try
  1271.     {
  1272.  
  1273.         somSelf->FailIfNotExclusiveWrite(ev);
  1274.  
  1275.         su = somSelf->CreateSU(ev, kODNULL, kODStorageUnit);
  1276.         SetStorageUnitType(ev, _fPermissions, su, kODStorageUnit);
  1277.  
  1278.         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1279.  
  1280.      }
  1281.      catch (ODException _exception)
  1282.      {
  1283.                 ODError error = ErrorCode();
  1284.                 SaveEv();
  1285.                 if (su != kODNULL) {
  1286.                         try
  1287.                         {
  1288.                                 somSelf->ReleaseStorageUnit(ev, su->GetID(ev));
  1289.                         }
  1290.                         catch (ODException _exception)
  1291.                         {
  1292.                              SetErrorCode(kODNoError);   // ignore exception
  1293.                         }
  1294.                         su = kODNULL;
  1295.                 }
  1296.                 RestoreEv();
  1297.                 ODSetSOMException(ev, error);
  1298.       }
  1299.         return su;
  1300. }
  1301.  
  1302. //------------------------------------------------------------------------------
  1303. // CMDraft: IsValidID
  1304. //------------------------------------------------------------------------------
  1305.  
  1306. SOM_Scope ODBoolean  SOMLINK CMDraftIsValidID(CMDraft *somSelf, Environment *ev,
  1307.                 ODID id)
  1308. {
  1309.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1310.     CMDraftMethodDebug("CMDraft","IsValidID");
  1311.  
  1312.     ODBoolean  isValidID = kODFalse;
  1313.     try
  1314.     {
  1315.         if ( id != kODNULLID )
  1316.                 isValidID =  _fIDList->Exists(id);
  1317.  
  1318.     }
  1319.     catch (ODException _exception)
  1320.     {
  1321.           ODSetSOMException(ev, _exception);
  1322.     }
  1323.         return isValidID;
  1324. }
  1325.  
  1326. //------------------------------------------------------------------------------
  1327. // CMDraft: AcquireStorageUnit
  1328. //------------------------------------------------------------------------------
  1329.  
  1330. SOM_Scope ODStorageUnit*  SOMLINK CMDraftAcquireStorageUnit(CMDraft *somSelf, Environment *ev,
  1331.                 ODStorageUnitID id)
  1332. {
  1333.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1334.     CMDraftMethodDebug("CMDraft","AcquireStorageUnit");
  1335.  
  1336.         ODStorageUnit*  su = kODNULL;
  1337.  
  1338.  
  1339.     try
  1340.     {
  1341.         if (id == kODNULLID)
  1342.                 THROW(kODErrIllegalNullIDInput);
  1343.  
  1344.  
  1345.         if (_fStorageUnits->GetValue(&id, &su)) {
  1346.                 su->Acquire(ev);
  1347.         }
  1348.         else if ((_fIDList->Exists(id) == kODFalse) ||
  1349.                          (_fIDList->Get(id) != kODNULL)) {
  1350.                 su = somSelf->CreateSU(ev, id, kODStorageUnit);
  1351.         }
  1352.  
  1353.     }
  1354.     catch (ODException _exception)
  1355.     {
  1356.         ODSetSOMException(ev, _exception);
  1357.     }
  1358.         return su;
  1359. }
  1360.  
  1361. //------------------------------------------------------------------------------
  1362. // CMDraft: RemoveStorageUnit
  1363. //------------------------------------------------------------------------------
  1364.  
  1365. SOM_Scope void  SOMLINK CMDraftRemoveStorageUnit(CMDraft *somSelf, Environment *ev,
  1366.                 ODStorageUnit* su)
  1367. {
  1368.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1369.     CMDraftMethodDebug("CMDraft","RemoveStorageUnit");
  1370.  
  1371.    try
  1372.    {
  1373.  
  1374.         CMContainer cmContainer = somSelf->GetCMContainer(ev);
  1375.         ODSessionMustHaveCMAllocReserve(cmContainer);
  1376.  
  1377.         ODID                    id;
  1378.         CMObject                object;
  1379.         ODStorageUnit*  draftProperties;
  1380.  
  1381.         somSelf->FailIfNotExclusiveWrite(ev);
  1382.  
  1383.         if (!su)
  1384.                 THROW(kODErrIllegalNullStorageUnitInput);
  1385.  
  1386.         draftProperties = somSelf->AcquireDraftProperties(ev);
  1387.         if (su == draftProperties) {
  1388.                 draftProperties->Release(ev);
  1389.                 THROW(kODErrIllegalOperationOnSU);
  1390.         }
  1391.         else
  1392.                 draftProperties->Release(ev);
  1393.  
  1394.         // Get Storage Unit ID
  1395.  
  1396.         id = su->GetID(ev);
  1397.         if (id == kODNULL)
  1398.                 THROW(kODErrInvalidStorageUnit);
  1399.  
  1400.         // Release the storage unit
  1401.         su->Release(ev);
  1402.  
  1403.         // Remove Storage Unit from outstanding SU collection
  1404.  
  1405.         _fStorageUnits->RemoveEntry(&id);
  1406.  
  1407.         // Get and delete the CMObject associated with su.
  1408.  
  1409.         object = (CMObject) _fIDList->Get(id);
  1410.  
  1411.         // Remove the entry in the ID-object collection.
  1412.  
  1413.         _fIDList->Remove(id);
  1414.  
  1415.         // Delete the object
  1416.  
  1417.         if (object != kODNULL)
  1418.                 CMDeleteObject(object);
  1419.  
  1420.         // Destroy su
  1421.  
  1422.         delete su;
  1423.  
  1424.         // Mark this draft dirty
  1425.  
  1426.         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1427.  
  1428.         ODSessionRestoreCMAllocReserve(cmContainer);
  1429.  
  1430.     }
  1431.     catch (ODException _exception)
  1432.     {
  1433.         ODSetSOMException(ev, _exception);
  1434.     }
  1435. }
  1436.  
  1437. //------------------------------------------------------------------------------
  1438. // CMDraft: ChangedFromPrev
  1439. //------------------------------------------------------------------------------
  1440.  
  1441. SOM_Scope ODBoolean  SOMLINK CMDraftChangedFromPrev(CMDraft *somSelf, Environment *ev)
  1442. {
  1443.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1444.     CMDraftMethodDebug("CMDraft","ChangedFromPrev");
  1445.  
  1446.         ODBoolean               changedFromPrev = kODFalse;
  1447.  
  1448.     try
  1449.     {
  1450.  
  1451.         VersionList*    versionList = kODNULL;
  1452.  
  1453.         versionList = _fDocument->TestAndGetVersionList(ev);
  1454.         ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  1455.  
  1456.         try
  1457.         {
  1458.                 changedFromPrev = somSelf->IsChangedFromPrev(ev, versionList);
  1459.  
  1460.         }
  1461.         catch (ODException _exception)
  1462.         {
  1463.             ODError error = ErrorCode();
  1464.             SaveEv();
  1465.             try
  1466.             {
  1467.                 _fDocument->ReleaseVersionList(ev);
  1468.             }
  1469.             catch(ODException _exception)
  1470.             {
  1471.                 SetErrorCode(kODNoError);
  1472.             }
  1473.             RestoreEv();
  1474.             ODSetSOMException(ev, error);
  1475.             throw;
  1476.  
  1477.         }
  1478.  
  1479.         _fDocument->ReleaseVersionList(ev);
  1480.  
  1481.     }
  1482.     catch (ODException _exception)
  1483.     {
  1484.           changedFromPrev = kODFalse;
  1485.           ODSetSOMException(ev, _exception);
  1486.     }
  1487.         return changedFromPrev;
  1488. }
  1489.  
  1490. //------------------------------------------------------------------------------
  1491. // CMDraft: SetChangedFromPrev
  1492. //------------------------------------------------------------------------------
  1493.  
  1494. SOM_Scope void  SOMLINK CMDraftSetChangedFromPrev(CMDraft *somSelf, Environment *ev)
  1495. {
  1496.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1497.     CMDraftMethodDebug("CMDraft","SetChangedFromPrev");
  1498.  
  1499.  
  1500.     try
  1501.     {
  1502.  
  1503. #ifdef _PLATFORM_WIN32_
  1504.         DocumentManager  *docMgr = NULL;
  1505.         OleWrapper       *wrapper = NULL;
  1506.  
  1507.         docMgr = ODOLEManager::GetShell()->GetActiveDocumentManager(ev);
  1508.         if (docMgr) {
  1509.             wrapper = docMgr->GetOleWrapper(ev);
  1510.             if (wrapper)
  1511.                 wrapper->OnDataChange();
  1512.         }
  1513. #endif
  1514.  
  1515.         somSelf->FailIfNotExclusiveWrite(ev);
  1516.  
  1517.         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1518.  
  1519.    }
  1520.    catch (ODException _exception)
  1521.    {
  1522.        ODSetSOMException(ev, _exception);
  1523.    }
  1524. }
  1525.  
  1526. //------------------------------------------------------------------------------
  1527. // CMDraft: RemoveFromDocument
  1528. //------------------------------------------------------------------------------
  1529.  
  1530. SOM_Scope void  SOMLINK CMDraftRemoveFromDocument(CMDraft *somSelf, Environment *ev)
  1531. {
  1532.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1533.     CMDraftMethodDebug("CMDraft","RemoveFromDocument");
  1534.  
  1535.  
  1536.     try
  1537.     {
  1538.         _fDocument->CollapseDrafts(ev, somSelf, kODNULL);
  1539.  
  1540.     }
  1541.     catch (ODException _exception)
  1542.     {
  1543.        ODSetSOMException(ev, _exception);
  1544.     }
  1545. }
  1546.  
  1547. //------------------------------------------------------------------------------
  1548. // CMDraft: RemoveChanges
  1549. //------------------------------------------------------------------------------
  1550.  
  1551. SOM_Scope ODDraft*  SOMLINK CMDraftRemoveChanges(CMDraft *somSelf, Environment *ev)
  1552. {
  1553.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1554.     CMDraftMethodDebug("CMDraft","RemoveChanges");
  1555.  
  1556.    try
  1557.    {
  1558.  
  1559.         VersionList*    versionList = kODNULL;
  1560.  
  1561.         somSelf->FailIfNotExclusiveWrite(ev);
  1562.  
  1563.         if (_fDraftProperties != kODNULL) {
  1564.                 _fDraftProperties->Release(ev);
  1565.                 _fDraftProperties = kODNULL;
  1566.         }
  1567.  
  1568. //      WASSERTM((somSelf->AreEmptyCollections(ev) != kODFalse), "OutstandingObjects in CMDraft: RemoveChanges.");
  1569.  
  1570.         somSelf->DestroyVersion(ev);
  1571.  
  1572.         versionList = _fDocument->TestAndGetVersionList(ev);
  1573.         ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  1574.  
  1575. #ifdef ODDebug_VersionList
  1576.         _fDocument->GetVersionList(ev)->Print(">>> Entering RemoveChanges");
  1577. #endif
  1578.  
  1579.         try
  1580.         {
  1581.                 if (versionList->Exists(_fID) != kODFalse)
  1582.                         versionList->RemoveChanges(_fID);
  1583.  
  1584.         }
  1585.         catch (ODException _exception)
  1586.         {
  1587.             ODError error = ErrorCode();
  1588.             SaveEv();
  1589.             try
  1590.             {
  1591.                 _fDocument->ReleaseVersionList(ev);
  1592.             }
  1593.             catch (ODException _exception)
  1594.             {
  1595.                 SetErrorCode(kODNoError);
  1596.             }
  1597.             RestoreEv();
  1598.             ODSetSOMException(ev, error);
  1599.             throw;
  1600.  
  1601.         }
  1602.  
  1603. #if !TestFlushContainer
  1604.         _fDocument->ExternalizeVersionList(ev, kODFalse);
  1605. #endif
  1606.         _fDocument->ReleaseVersionList(ev);
  1607.  
  1608.         somSelf->Open(ev);
  1609.  
  1610.         somSelf->SetChangedFromPrevFlag(ev, kODFalse);
  1611.  
  1612. #ifdef ODDebug_VersionList
  1613.         _fDocument->GetVersionList(ev)->Print(">>> Exiting RemoveChanges");
  1614. #endif
  1615.  
  1616.    }
  1617.    catch (ODException _exception)
  1618.    {
  1619.        ODSetSOMException(ev, _exception);
  1620.    }
  1621.         return somSelf;
  1622. }
  1623.  
  1624. //------------------------------------------------------------------------------
  1625. // CMDraft: Externalize
  1626. //------------------------------------------------------------------------------
  1627.  
  1628. SOM_Scope ODDraft*  SOMLINK CMDraftExternalize(CMDraft *somSelf, Environment *ev)
  1629. {
  1630.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1631.     CMDraftMethodDebug("CMDraft","Externalize");
  1632.  
  1633.     try
  1634.     {
  1635.  
  1636. #ifdef _PLATFORM_OS2_                          // $$$$ dcp # 120702  05/23/95
  1637.         if ( _fPermissions == kODDPReadOnly ) THROW(kODErrInvalidPermissions);
  1638.  
  1639.         // check to see if linking is on or off (131199)
  1640.  
  1641.         ODSession* session = (ODSession*) _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  1642.         char flag = session->GetLinkONOFFflag(ev);
  1643.         if(flag)
  1644.         {
  1645.            // Call LinkService's externalize method so that
  1646.            // tables not yet stored to DraftProperties can be saved
  1647.            if (_fPermissions == kODDPExclusiveWrite) _fLinkService->DraftSaving(ev, somSelf);
  1648.         }
  1649.  
  1650. #endif
  1651.  
  1652.         somSelf->ExternalizeCollections(ev);
  1653.  
  1654.         _fExternalized = kODTrue;
  1655.  
  1656.         // DO THE ACTUAL EXTERNALIZATION HERE
  1657.  
  1658.         somSelf->FlushVersion(ev);
  1659.  
  1660.    }
  1661.    catch (ODException _exception)
  1662.    {
  1663.         ODSetSOMException(ev, _exception);
  1664.    }
  1665.         return somSelf;
  1666. }
  1667.  
  1668. //------------------------------------------------------------------------------
  1669. // CMDraft: SaveToAPrevious
  1670. //------------------------------------------------------------------------------
  1671.  
  1672. SOM_Scope ODDraft*  SOMLINK CMDraftSaveToAPrevious(CMDraft *somSelf, Environment *ev,
  1673.                 ODDraft* to)
  1674. {
  1675.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1676.     CMDraftMethodDebug("CMDraft","SaveToAPrevious");
  1677.  
  1678.  
  1679.    try
  1680.    {
  1681.         _fDocument->SaveToAPrevDraft(ev, somSelf, to);
  1682.  
  1683.    }
  1684.    catch( ODException _exception)
  1685.    {
  1686.         ODSetSOMException(ev, _exception);
  1687.    }
  1688.         return somSelf;
  1689. }
  1690.  
  1691. //------------------------------------------------------------------------------
  1692. // CMDraft: CreateFrame
  1693. //------------------------------------------------------------------------------
  1694.  
  1695. SOM_Scope ODFrame*  SOMLINK CMDraftCreateFrame(CMDraft *somSelf, Environment *ev,
  1696.                 ODObjectType            frameType,
  1697.                 ODFrame*        containingFrame,
  1698.                 ODShape*        frameShape,
  1699.                 ODCanvas*       biasCanvas,
  1700.                 ODPart*                 part,
  1701.                 ODTypeToken     viewType,
  1702.                 ODTypeToken     presentation,
  1703.                 ODBoolean               isSubframe,
  1704.                 ODBoolean               isOverlaid)
  1705. {
  1706.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1707.     CMDraftMethodDebug("CMDraft","CreateFrame");
  1708.  
  1709.         ODStorageUnit*          su = kODNULL;
  1710.         ODFrame*                        frame = kODNULL;
  1711.         ODStorageUnitID         id = kODNULLID;
  1712.  
  1713.         ODVolatile(su);
  1714.         ODVolatile(frame);
  1715.         ODVolatile(id);
  1716.  
  1717.  
  1718.      try
  1719.      {
  1720.                 if (ODISOStrEqual(frameType, kODFrameObject) != kODFalse)
  1721.                         somSelf->FailIfNotExclusiveWrite(ev);
  1722.  
  1723.                 frame = new ODFrame();
  1724.                 if (frame == kODNULL)
  1725.                         THROW(kODErrCannotCreateFrame);
  1726.  
  1727.                  if (ODISOStrEqual(frameType, kODFrameObject) != kODFalse) {
  1728.                         su = somSelf->CreateSU(ev, kODNULL, kODFrameObject);
  1729.                         SetStorageUnitType(ev, _fPermissions, su, kODFrameObject);
  1730.                         id = su->GetID(ev);
  1731.                         _fPersistentObjects->ReplaceEntry(&id, &frame);
  1732.                         frame->InitFrame(ev, su, containingFrame, frameShape, biasCanvas, part,
  1733.                                                          viewType, presentation, isSubframe, isOverlaid);
  1734.                         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1735.                 }
  1736.                 else if (ODISOStrEqual(frameType, kODNonPersistentFrameObject) != kODFalse) {
  1737.                         id = _fIDList->Add(kODNULL);
  1738.                         _fPersistentObjects->ReplaceEntry(&id, &frame);
  1739.                         frame->InitFrameNonPersistent(ev, somSelf, id, containingFrame, frameShape,
  1740.                                                 biasCanvas, part, viewType, presentation, isSubframe, isOverlaid);
  1741.                 }
  1742.                 else
  1743.                         THROW(kODErrInvalidObjectType);
  1744.  
  1745.  
  1746.      }
  1747.      catch (ODException _exception)
  1748.      {
  1749.                 ODError error = ErrorCode();
  1750.                 SaveEv();
  1751.                 if (frame != kODNULL) {
  1752.                         try{
  1753.                                 if (id != kODNULLID)
  1754.                                 {
  1755.                                         if (su == kODNULL)
  1756.                                         {
  1757.                                                 // This is just for non-persistent frame.
  1758.                                                 // Every other real persistent object should use RemovePersistentObject.
  1759.                                                 ODReleaseObject(ev, frame);
  1760.                                                 _fPersistentObjects->RemoveEntry(&id);
  1761.                                         }
  1762.                                         else
  1763.                                                 somSelf->RemovePersistentObject(ev, frame);
  1764.                                 }
  1765.                                 else {
  1766.                                         delete frame;
  1767.                                         if (su != kODNULL)
  1768.                                                 somSelf->RemoveStorageUnit(ev, su);
  1769.                                 }
  1770.                         }catch (ODException _exception){
  1771.                            SetErrorCode(kODNoError);     // ignore exception
  1772.                         }
  1773.                         frame = kODNULL;
  1774.                 }
  1775.                 RestoreEv();
  1776.                 ODSetSOMException(ev, error);
  1777.         }
  1778.  
  1779.         return frame;
  1780. }
  1781.  
  1782. //------------------------------------------------------------------------------
  1783. // CMDraft: AcquireFrame
  1784. //------------------------------------------------------------------------------
  1785.  
  1786. SOM_Scope ODFrame*  SOMLINK CMDraftAcquireFrame(CMDraft *somSelf, Environment *ev,
  1787.                 ODStorageUnitID id)
  1788. {
  1789.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1790.     CMDraftMethodDebug("CMDraft","AcquireFrame");
  1791.  
  1792.         ODStorageUnit*  su = kODNULL; ODVolatile(su);
  1793.         ODFrame*                frame = kODNULL; ODVolatile(frame);
  1794.  
  1795.     try
  1796.     {
  1797.         if (id == kODNULLID)
  1798.                 THROW(kODErrIllegalNullIDInput);
  1799.  
  1800.         frame = (ODFrame*) somSelf->RetrievePersistentObject(ev, id);
  1801.  
  1802.         if (frame == kODNULL) {
  1803.  
  1804.                 su = somSelf->AcquireStorageUnit(ev, id);
  1805.                 frame = new ODFrame();
  1806.  
  1807.                 if (frame == kODNULL)
  1808.                         THROW(kODErrCannotAcquireFrame);
  1809.  
  1810.                 // A better way to do this is to let ODFrame::InitFrameFromStorage or
  1811.                 // ODPersistentObject::InitPersistentObjectFromStorage to increment the
  1812.                 // refcount. In that way, we can always release su here (or even better
  1813.                 // make su into a temp obj. - VL
  1814.                 _fPersistentObjects->ReplaceEntry(&id, &frame);
  1815.                 frame->InitFrameFromStorage(ev, su);
  1816.  
  1817.                 ODStorageUnit *su2 = su;
  1818.                 su = kODNULL;                                                                   // frame owns reference now
  1819.  
  1820.                 SetStorageUnitType(ev, _fPermissions, su2, kODFrameObject);
  1821.         }
  1822.  
  1823.      }
  1824.      catch(ODException _exception)
  1825.      {
  1826.                 ODError error = ErrorCode();
  1827.                 if( frame ) WASSERT(frame->GetRefCount(ev)==1);
  1828.                 SaveAndRestoreEv1(frame);
  1829.                 ODSetSOMException(ev, error);
  1830.      }
  1831.  
  1832.         return frame;
  1833. }
  1834.  
  1835. //------------------------------------------------------------------------------
  1836. // CMDraft: ReleaseFrame
  1837. //------------------------------------------------------------------------------
  1838.  
  1839. SOM_Scope void  SOMLINK CMDraftReleaseFrame(CMDraft *somSelf, Environment *ev,
  1840.                 ODFrame* frame)
  1841. {
  1842.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1843.     CMDraftMethodDebug("CMDraft","ReleaseFrame");
  1844.  
  1845.  
  1846.     try
  1847.     {
  1848.         somSelf->ReleasePersistentObject(ev, frame);
  1849.  
  1850.     }
  1851.     catch (ODException _exception)
  1852.     {
  1853.          ODSetSOMException(ev, _exception);
  1854.     }
  1855. }
  1856.  
  1857. //------------------------------------------------------------------------------
  1858. // CMDraft: RemoveFrame
  1859. //------------------------------------------------------------------------------
  1860.  
  1861. SOM_Scope void  SOMLINK CMDraftRemoveFrame(CMDraft *somSelf, Environment *ev,
  1862.                 ODFrame* frame)
  1863. {
  1864.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1865.     CMDraftMethodDebug("CMDraft","RemoveFrame");
  1866.  
  1867.    try
  1868.    {
  1869.         somSelf->FailIfNotExclusiveWrite(ev);
  1870.  
  1871.         if (!frame)
  1872.                 THROW(kODErrIllegalNullFrameInput);
  1873.  
  1874.         if (frame->GetStorageUnit(ev) == kODNULL)
  1875.                 frame->Release(ev);
  1876.         else
  1877.                 somSelf->RemovePersistentObject(ev, frame);
  1878.    }
  1879.    catch (ODException _exception)
  1880.    {
  1881.        ODSetSOMException(ev, _exception);
  1882.    }
  1883.  
  1884. }
  1885.  
  1886. //------------------------------------------------------------------------------
  1887. // CMDraft: ConstructRealPart
  1888. //------------------------------------------------------------------------------
  1889.  
  1890. SOM_Scope ODPart*  SOMLINK CMDraftConstructRealPart(CMDraft *somSelf, Environment *ev,
  1891.                 ODStorageUnit* su, ODBoolean isInitPartFromStorage,
  1892.                 ODPartWrapper* partWrapper,
  1893.                 ODType partType, ODEditor theEditor)
  1894. {
  1895.     CMDraftData *somThis = CMDraftGetData(somSelf);
  1896.     CMDraftMethodDebug("CMDraft","ConstructRealPart");
  1897.  
  1898.         ODPart* part = kODNULL; ODVolatile(part);
  1899.         ODEditor editorForPart = kODNULL;
  1900. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  1901.         SOMClass*       partClass;
  1902.         somId           partsSomId;
  1903. #endif // _PLATFORM_WIN32_ || _PLATFORM_OS2_ || _PLATFORM_AIX_
  1904.  
  1905.  
  1906.       try
  1907.       {
  1908.                 ODSession* session = (ODSession*) _fDocument->
  1909.                         GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  1910.                 ODBinding* binding = session->GetBinding(ev);
  1911.  
  1912.                 if (theEditor == kODNULL)
  1913.                         editorForPart = binding->
  1914.                                 ChooseEditorForPart(ev, su, partType);
  1915.                 else
  1916.                 {
  1917.                         editorForPart = theEditor;
  1918.                         if (_fPermissions != kODDPReadOnly)
  1919.                                 ODSetISOStrProp(ev, su, kODPropPreferredEditor,
  1920.                                                  kODEditor, editorForPart);
  1921.                 }
  1922.  
  1923. #ifdef _PLATFORM_MACINTOSH_
  1924.                 if (ODISOStrEqual(editorForPart,
  1925.                                   kODBlackBoxHandlerOfLastResort))
  1926.                         part = binding->ConstructNoPart(ev);
  1927. #endif
  1928.  
  1929. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  1930.                 if ( (ODISOStrEqual(editorForPart, "NoPart")) ||
  1931.                      (ODISOStrEqual(editorForPart, "")) )
  1932.                         part = new NoPart;
  1933.  
  1934. #endif // _PLATFORM_WIN32_ || _PLATFORM_OS2_ || _PLATFORM_AIX_
  1935.  
  1936.                 else
  1937.  
  1938. #ifdef _PLATFORM_MACINTOSH_
  1939.                         part = (ODPart*) ODNewObject(editorForPart);
  1940. #endif
  1941.  
  1942. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  1943.                         {
  1944.                         partsSomId = somIdFromString((string)editorForPart);
  1945.                         partClass = SOMClassMgrObject->somFindClass(partsSomId, 0, 0);
  1946.                         if (!partClass) {
  1947.                                 WARNMSG_DEBUG(WARN_INDEX(-1),
  1948.                                    "The Part Handler %s failed to load!",
  1949.                                    editorForPart);
  1950.                                 part = new NoPart;
  1951.                            }
  1952.                         else {
  1953.                                 part = (ODPart *)partClass->somNew();
  1954.                            }
  1955.  
  1956.                         }
  1957.  
  1958. #endif // _PLATFORM_WIN32_ || _PLATFORM_OS2_ || _PLATFORM_AIX_
  1959.  
  1960.                 if (part == kODNULL)
  1961.                         THROW(kODErrCannotCreatePart);
  1962.  
  1963.                 partWrapper->SetRealPart(ev, part, editorForPart);
  1964.  
  1965.                 ODID id = su->GetID(ev);
  1966.                 _fPersistentObjects->ReplaceEntry(&id, &partWrapper);
  1967.  
  1968.                 su->Acquire(ev);                                                                 //This new reference belongs to the part
  1969.                 if (isInitPartFromStorage)
  1970.                         partWrapper->InitPartFromStorage(ev, su, partWrapper);
  1971.                 else
  1972.                         partWrapper->InitPart(ev, su, partWrapper);
  1973.  
  1974.                 if (ODISOStrEqual(editorForPart,
  1975.                         kODBlackBoxHandlerOfLastResort) == kODFalse)
  1976.                         somSelf->PartInstantiated(ev, part);
  1977.       }
  1978.       catch (ODException _exception)
  1979.       {
  1980.                 part = kODNULL;
  1981.  
  1982.                 // Map to more specific error
  1983.                 if( ErrorCode() == kODErrCantLoadSOMClass )
  1984.                         SetErrorCode(kODErrCannotCreatePart);
  1985.                 ODSetSOMException(ev, _exception);
  1986.  
  1987.       }
  1988.  
  1989. #ifdef _PLATFORM_MACINTOSH_
  1990.         if (editorForPart != theEditor)
  1991.                 ODDisposePtr(editorForPart);
  1992. #endif // _PLATFORM_MACINTOSH_
  1993.  
  1994.         return part;
  1995. }
  1996.  
  1997. //------------------------------------------------------------------------------
  1998. // CMDraft: ReleaseRealPart
  1999. //------------------------------------------------------------------------------
  2000.  
  2001. SOM_Scope void  SOMLINK CMDraftReleaseRealPart(CMDraft *somSelf, Environment *ev,
  2002.                                                                                                 ODPart* realPart)
  2003. {
  2004.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2005.     CMDraftMethodDebug("CMDraft","ReleaseRealPart");
  2006.  
  2007.  
  2008.    try
  2009.    {
  2010.         if (realPart == kODNULL)
  2011.                 THROW(kODErrIllegalNullPartInput);
  2012.  
  2013.         if (realPart->GetRefCount(ev) != 0)
  2014.                 THROW(kODErrRefCountGreaterThanZero);
  2015.  
  2016.         realPart->ReleaseAll(ev);
  2017.  
  2018.         somSelf->PartDeleted(ev, realPart);
  2019.  
  2020.         delete realPart;
  2021.  
  2022.    }
  2023.    catch (ODException _exception)
  2024.    {
  2025.       ODSetSOMException(ev, _exception);
  2026.    }
  2027. }
  2028.  
  2029. //------------------------------------------------------------------------------
  2030. // CMDraft: DeleteRealPart
  2031. //------------------------------------------------------------------------------
  2032.  
  2033. SOM_Scope void  SOMLINK CMDraftDeleteRealPart(CMDraft *somSelf, Environment *ev,
  2034.                                                                                                 ODPart* realPart)
  2035. {
  2036.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2037.     CMDraftMethodDebug("CMDraft","DeleteRealPart");
  2038.  
  2039.  
  2040.    try
  2041.    {
  2042.         if (realPart == kODNULL)
  2043.                 THROW(kODErrIllegalNullPartInput);
  2044.  
  2045.         somSelf->PartDeleted(ev, realPart);
  2046.  
  2047.         delete realPart;
  2048.  
  2049.    }
  2050.    catch (ODException _exception)
  2051.    {
  2052.        ODSetSOMException(ev, _exception);
  2053.    }
  2054. }
  2055.  
  2056. //------------------------------------------------------------------------------
  2057. // CMDraft: CreatePart
  2058. //------------------------------------------------------------------------------
  2059.  
  2060. SOM_Scope ODPart*  SOMLINK CMDraftCreatePart(CMDraft *somSelf, Environment *ev,
  2061.                 ODType partType, ODEditor optionalEditor)
  2062. {
  2063.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2064.     CMDraftMethodDebug("CMDraft","CreatePart");
  2065.  
  2066.  
  2067.         ODPartWrapper* partWrapper = kODNULL;
  2068.  
  2069.         ODVolatile(partWrapper);
  2070.  
  2071.     try
  2072.     {
  2073.                 somSelf->FailIfNotExclusiveWrite(ev);
  2074.  
  2075. #ifdef _NO_TMP_OBJS_
  2076.                 ODStorageUnit *su = somSelf->CreateSU(ev, kODNULL, kODPartObject);
  2077. #else
  2078.                 TempODStorageUnit su = somSelf->CreateSU(ev, kODNULL, kODPartObject);
  2079. #endif
  2080.  
  2081.                 SetStorageUnitType(ev, _fPermissions, su, kODPartObject);
  2082.  
  2083.                 if ( partType != kODNULL )
  2084.                 {
  2085.                         ODSetISOStrProp(ev, su, kODPropPreferredKind, kODISOStr, partType);
  2086.                 }
  2087.  
  2088.                 partWrapper = new ODPartWrapper;
  2089.                 THROW_IF_NULL(partWrapper, kODErrOutOfMemory);
  2090.                 partWrapper->InitPartWrapper(ev);
  2091.  
  2092.                 somSelf->ConstructRealPart(ev, su, kODFalse, partWrapper, partType, optionalEditor);
  2093.  
  2094.                 somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2095. #ifdef _NO_TMP_OBJS_
  2096.                 su->Release(ev);
  2097. #endif
  2098.  
  2099.  
  2100.       }
  2101.       catch (ODException _exception)
  2102.       {
  2103.                 ODError error = ErrorCode();
  2104.                 SaveAndRestoreEv1(partWrapper);
  2105.                 partWrapper = kODNULL;
  2106.                 ODSetSOMException(ev, error );
  2107.  
  2108.       }
  2109.  
  2110.         return partWrapper;
  2111. }
  2112.  
  2113. //------------------------------------------------------------------------------
  2114. // CMDraft: AcquirePart
  2115. //------------------------------------------------------------------------------
  2116.  
  2117. SOM_Scope ODPart*  SOMLINK CMDraftAcquirePart(CMDraft *somSelf, Environment *ev,
  2118.                 ODStorageUnitID id)
  2119. {
  2120.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2121.     CMDraftMethodDebug("CMDraft","AcquirePart");
  2122.  
  2123.         ODPart* part = kODNULL;
  2124.         ODPartWrapper* partWrapper = kODNULL;
  2125.  
  2126.         ODVolatile(partWrapper);
  2127.  
  2128.       try
  2129.       {
  2130.                 if (id == kODNULLID)
  2131.                         THROW(kODErrIllegalNullIDInput);
  2132.  
  2133.                 part = (ODPart*) somSelf->RetrievePersistentObject(ev, id);
  2134.                 if (part == kODNULL) {
  2135.                         ODStorageUnit*  su = kODNULL;
  2136.  
  2137.                         if (_fStorageUnits->GetValue(&id, &su) != kODFalse)
  2138.                                 su->Acquire(ev);
  2139.                         else
  2140.                                 su = somSelf->CreateSU(ev, id, kODPartObject);
  2141. #ifdef _NO_TMP_OBJS_
  2142.                         ODStorageUnit *tempSU = su; // ensure it's released
  2143. #else
  2144.                         TempODStorageUnit tempSU = su; // ensure it's released
  2145. #endif
  2146.  
  2147.                         partWrapper = new ODPartWrapper;
  2148.                         THROW_IF_NULL(partWrapper, kODErrOutOfMemory);
  2149.                         partWrapper->InitPartWrapper(ev);
  2150.  
  2151.                         somSelf->ConstructRealPart(ev, su, kODTrue, partWrapper, kODNULL,  kODNULL);
  2152.  
  2153.                         part = partWrapper;
  2154.  
  2155.                         SetStorageUnitType(ev, _fPermissions, su, kODPartObject);
  2156. #ifdef _NO_TMP_OBJS_
  2157.                         tempSU->Release(ev);
  2158. #endif
  2159.                 }
  2160.  
  2161.  
  2162.       }
  2163.       catch (ODException _exception)
  2164.       {
  2165.                 ODError  error = ErrorCode();
  2166.                 SaveAndRestoreEv1(partWrapper);
  2167.                 part = kODNULL;
  2168.                 ODSetSOMException(ev, error);
  2169.  
  2170.       } 
  2171.  
  2172.         return part;
  2173. }
  2174.  
  2175. //------------------------------------------------------------------------------
  2176. // CMDraft: ReleasePart
  2177. //------------------------------------------------------------------------------
  2178.  
  2179. SOM_Scope void  SOMLINK CMDraftReleasePart(CMDraft *somSelf, Environment *ev,
  2180.                 ODPart* part)
  2181. {
  2182.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2183.     CMDraftMethodDebug("CMDraft","ReleasePart");
  2184.  
  2185.    try
  2186.    {
  2187.  
  2188.         somSelf->ReleasePersistentObject(ev, part);
  2189.  
  2190.    }
  2191.    catch (ODException _exception)
  2192.    {
  2193.       ODSetSOMException(ev, _exception);
  2194.    }
  2195. }
  2196.  
  2197. //------------------------------------------------------------------------------
  2198. // CMDraft: RemovePart
  2199. //------------------------------------------------------------------------------
  2200.  
  2201. SOM_Scope void  SOMLINK CMDraftRemovePart(CMDraft *somSelf, Environment *ev,
  2202.                 ODPart* part)
  2203. {
  2204.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2205.     CMDraftMethodDebug("CMDraft","RemovePart");
  2206.  
  2207.    try
  2208.    {
  2209.  
  2210.         if (!part)
  2211.                 THROW(kODErrIllegalNullPartInput);
  2212.  
  2213.         somSelf->RemovePersistentObject(ev, part);
  2214.  
  2215.    }
  2216.    catch (ODException _exception)
  2217.    {
  2218.         ODSetSOMException(ev, _exception);
  2219.    }
  2220. }
  2221.  
  2222. //------------------------------------------------------------------------------
  2223. // CMDraft: CreateLinkSpec
  2224. //------------------------------------------------------------------------------
  2225.  
  2226. SOM_Scope ODLinkSpec*  SOMLINK CMDraftCreateLinkSpec (CMDraft *somSelf, Environment *ev,
  2227.                 ODPart* part,
  2228.                 ODByteArray* data)
  2229. {
  2230.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2231.     CMDraftMethodDebug("CMDraft","CreateLinkSpec");
  2232.  
  2233.         ODLinkSpec* ls = kODNULL;
  2234.  
  2235.         ODVolatile(ls);
  2236. #ifdef _PLATFORM_OS2_
  2237.  
  2238.    try
  2239.    {
  2240.     ls = new ODLinkSpec;
  2241.  
  2242.     // check to see if linking is on or off (131199)
  2243.  
  2244.     ODSession* session = (ODSession*) _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  2245.     char flag = session->GetLinkONOFFflag(ev);
  2246.     if(flag)
  2247.     {
  2248.       if (_fLinkServiceXID == kODNULL)
  2249.       {
  2250.         session->StartServer(ev, (char*)kODNULL);
  2251.         SOMDObject* objRef = SOMD_ServerObject->
  2252.                                somdRefFromSOMObj(ev, _fLinkService);
  2253.         _fLinkServiceXID = SOMD_ORBObject->object_to_string(ev, objRef);
  2254.       }
  2255.  
  2256.       //XXXXX ls->InitLinkSpec(ev, _fLinkServiceXID, part->GetID(ev), data);
  2257.       ls->InitLinkSpec(ev, _fLinkServiceXID, part, data);
  2258.     }
  2259.    }
  2260.    catch (ODException _exception)
  2261.    {
  2262.       ODError error = ErrorCode();
  2263.       SaveEv();
  2264.       try
  2265.       {
  2266.           ODDeleteObject(ls);
  2267.       }
  2268.       catch(ODException _exception)
  2269.       {
  2270.           SetErrorCode(kODNoError);
  2271.       }
  2272.       RestoreEv();
  2273.       ODSetSOMException(ev, error);
  2274.    }
  2275.   
  2276. #else
  2277.  
  2278.     try
  2279.     {
  2280.                 ls = new ODLinkSpec;
  2281.                 THROW_IF_NULL(ls, kODErrOutOfMemory);
  2282. // #ifdef _PLATFORM_OS2_
  2283. //                ls->InitLinkSpec(ev, kODNULL /* 22470 */ , part, data);
  2284. // #endif
  2285. #if defined (_PLATFORM_WIN32_) || defined(_PLATFORM_AIX_)
  2286.                 ls->InitLinkSpec(ev, part, data);
  2287. #endif
  2288.  
  2289.      }
  2290.      catch (ODException _exception)
  2291.      {
  2292.       ODError error = ErrorCode();
  2293.        SaveEv();
  2294.       try
  2295.       {
  2296.           ODDeleteObject(ls);
  2297.       }
  2298.       catch(ODException _exception)
  2299.       {
  2300.           SetErrorCode(kODNoError);
  2301.       }
  2302.       RestoreEv();
  2303.       ODSetSOMException(ev, error);
  2304.      }
  2305. #endif // _PLATFORM_OS2_
  2306.  
  2307.         return ls;
  2308. }
  2309.  
  2310. //------------------------------------------------------------------------------
  2311. // CMDraft: CreateLinkSource
  2312. //------------------------------------------------------------------------------
  2313.  
  2314. SOM_Scope ODLinkSource*  SOMLINK CMDraftCreateLinkSource(CMDraft *somSelf, Environment *ev,
  2315.                 ODPart* part)
  2316. {
  2317.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2318.     CMDraftMethodDebug("CMDraft","CreateLinkSource");
  2319.  
  2320.  
  2321. #ifdef _PLATFORM_OS2_
  2322.  
  2323.     IODLinkSource*  linkSource = kODNULL;
  2324.   try
  2325.   {
  2326.     char            docName[256];
  2327.     char            hostName[256];
  2328.     ODStorageUnitID id;
  2329.     ODStorageUnit*  su;
  2330.     ODISOStr        ASName;
  2331.  
  2332.     if (part==kODNULL)
  2333.       THROW(kODErrCannotCreateLink);
  2334.  
  2335.     somSelf->FailIfNotExclusiveWrite(ev);
  2336.  
  2337.  
  2338.     su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
  2339.  
  2340.     // $$$$$ Links no longer depend on this property
  2341.     // $$$$$  (but LinkSourceIterator does!)
  2342.     su->AddProperty(ev, kODPropStorageUnitType);
  2343.     su->AddValue(ev, kODISOStr);
  2344.     StorageUnitSetValue(su,
  2345.                         ev,
  2346.                         ODISOStrLength(kODLinkSource)+1,
  2347.                         (ODValue)kODLinkSource);
  2348.  
  2349.     linkSource = new IODLinkSource();
  2350.     if (linkSource == kODNULL)
  2351.     {
  2352.       delete su;
  2353.       THROW(kODErrCannotCreateLink);
  2354.     }
  2355.  
  2356.     id = su->GetID(ev);
  2357.     _fPersistentObjects->ReplaceEntry(&id, &linkSource);
  2358.  
  2359.      if(getenv("HOSTNAME") == NULL)                   //@SK [123273]
  2360.        {                                              //@SK [123273]
  2361.  
  2362. #ifdef ODDebug
  2363.        somPrintf("\nError: Incomplete DSOM environment setup: Missing HOSTNAME\n");//@SK [123273]
  2364. #endif
  2365.        DosExit(EXIT_PROCESS, 1);                      //@SK [123273]
  2366.        }
  2367.     else
  2368.        {
  2369.  
  2370.          linkSource->InitILinkSource(ev,
  2371.                                      su,
  2372.                                      part,
  2373.                                      getenv("HOSTNAME"),
  2374.                                      _fLinkService->GetDocName(ev));
  2375.  
  2376.          ODLinkID linkID =
  2377.            _fLinkService->RegisterLinkSource(ev, somSelf, id, linkSource, part, &ASName);
  2378.  
  2379.          linkSource->CompleteInitILinkSource(ev, su, linkID, (IODAuxiliaryState*)kODNULL, kODFalse, ASName);
  2380.          ODDisposePtr(ASName);
  2381.        somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2382.        return (ODLinkSource*)linkSource;
  2383.       }
  2384.    }
  2385.    catch (ODException _exception)
  2386.    {
  2387.        linkSource = kODNULL;
  2388.        ODSetSOMException(ev, _exception);
  2389.    }
  2390.        return (ODLinkSource*)linkSource;
  2391.  
  2392.  
  2393. #else
  2394.         ODLinkSource*   linkSource = kODNULL;
  2395.  
  2396.     try
  2397.     {
  2398.         ODStorageUnitID id;
  2399.  
  2400.         somSelf->FailIfNotExclusiveWrite(ev);
  2401.  
  2402. #ifdef _NO_TMP_OBJS_
  2403.         ODStorageUnit *su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
  2404. #else
  2405.         TempODStorageUnit su = somSelf->CreateSU(ev, kODNULL, kODLinkSource);
  2406. #endif
  2407.  
  2408.         // The implementation of CMLinkSourceIterator depends on this property being present
  2409.         // in link source storage units and nowhere else.
  2410.  
  2411.         SetStorageUnitType(ev, _fPermissions, su, kODLinkSource);
  2412.  
  2413.         linkSource = new ODLinkSource();
  2414.         THROW_IF_NULL(linkSource,kODErrCannotCreateLink);
  2415.  
  2416. #ifdef _NO_TMP_OBJS_
  2417.         ODLink *link = kODNULL;
  2418. #else
  2419.         TempODLink link = kODNULL;
  2420. #endif
  2421.         try
  2422.         {
  2423.                 link = somSelf->CreateLink(ev);
  2424.         }
  2425.         catch (ODException _exception)
  2426.         {
  2427.             ODError error = ErrorCode();
  2428.             SaveEv();
  2429.             try
  2430.             {
  2431.                 linkSource->ReleaseAll(ev);
  2432.                 ODDeleteObject(linkSource);
  2433.             }
  2434.             catch(ODException _exception)
  2435.             {
  2436.                  SetErrorCode(kODNoError);
  2437.             }
  2438.             RestoreEv();
  2439.             ODSetSOMException(ev, error);
  2440.             throw;
  2441.         }
  2442.  
  2443.         id = su->GetID(ev);
  2444.  
  2445.         _fPersistentObjects->ReplaceEntry(&id, &linkSource);
  2446.  
  2447. #ifdef _NO_TMP_OBJS_
  2448.         linkSource->InitLinkSource(ev, su, part);
  2449. #else
  2450.         linkSource->InitLinkSource(ev, su.DontRelease(), part);
  2451. #endif
  2452.         // ("DontDelete" prevents su from being auto-released by destructor)
  2453.  
  2454.         link->SetLinkSource(ev, linkSource);
  2455.         linkSource->SetLink(ev, link);
  2456.  
  2457.         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2458.  
  2459. #ifdef _NO_TMP_OBJS_
  2460.         su->Release(ev);
  2461.         link->Release(ev);
  2462. #endif
  2463.  
  2464.  
  2465.         }
  2466.         catch (ODException _exception)
  2467.         {
  2468.          linkSource = kODNULL;
  2469.              ODSetSOMException(ev, _exception);
  2470.         }
  2471.         return linkSource;
  2472. #endif  // _PLATFORM_OS2_
  2473. }
  2474.  
  2475. //------------------------------------------------------------------------------
  2476. // CMDraft: AcquireLinkSource
  2477. //------------------------------------------------------------------------------
  2478.  
  2479. SOM_Scope ODLinkSource*  SOMLINK CMDraftAcquireLinkSource(CMDraft *somSelf, Environment *ev,
  2480.                 ODStorageUnitID id)
  2481. {
  2482.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2483.     CMDraftMethodDebug("CMDraft","AcquireLinkSource");
  2484.  
  2485.  
  2486.  
  2487. #ifdef _PLATFORM_OS2_
  2488.  
  2489.  
  2490.     // If the id already corresponds to a live linkSource, use it.
  2491.     // If not, create a new one.
  2492.     // Update the cache so that next time this new linkSource will be found.
  2493.     // Get the SU.
  2494.     // If this is a read-only draft, create the linkSource with a null auxState
  2495.     // Otherwise, call LinkService::OpenLinkSource to get auxState/lock
  2496.     //    and use this to internalize the linksource.
  2497.  
  2498.     IODLinkSource* linkSource = (IODLinkSource*)kODNULL;
  2499.   try
  2500.   { 
  2501.         if (id == kODNULLID)
  2502.                 THROW(kODErrIllegalNullIDInput);
  2503.  
  2504.     linkSource = ((IODLinkSource*)somSelf->RetrievePersistentObject(ev, id));
  2505.  
  2506.     if (linkSource == (IODLinkSource*)kODNULL)
  2507.     {
  2508.       linkSource = new IODLinkSource();
  2509.       if (linkSource == (IODLinkSource*)kODNULL)
  2510.       {
  2511.         THROW(kODErrCannotAcquireLink);
  2512.       }
  2513.  
  2514.       ODStorageUnit* su = (ODStorageUnit*)kODNULL;
  2515.       ODVolatile(su);
  2516.       ODVolatile(id);
  2517.  
  2518.       try
  2519.       {
  2520.  
  2521.         su = somSelf->AcquireStorageUnit(ev, id);
  2522.         _fPersistentObjects->ReplaceEntry(&id, &linkSource);
  2523.         if (_fPermissions != kODDPExclusiveWrite)
  2524.         {
  2525.           ODLinkID linkid = linkSource->InitILinkSourceFromStorage(ev, su);
  2526.           linkSource->CompleteInitILinkSource(ev, su, linkid, kODNULL, kODFalse, "");
  2527.         }
  2528.         else
  2529.         {
  2530.           IODAuxiliaryState* auxState;
  2531.           ODBoolean isLocked;
  2532.           ODISOStr        ASName;
  2533.  
  2534.           ODLinkID originalLinkID = linkSource->InitILinkSourceFromStorage(ev, su);
  2535.           ODLinkID finalLinkID = _fLinkService->OpenLinkSource(ev,
  2536.                                         somSelf,
  2537.                                         linkSource->GetID(ev),
  2538.                                         linkSource,
  2539.                                         originalLinkID,
  2540.                                         &auxState,
  2541.                                         &isLocked,
  2542.                                         &ASName);
  2543.  
  2544.           linkSource->CompleteInitILinkSource(ev,
  2545.                                               su,
  2546.                                               finalLinkID,
  2547.                                               auxState,
  2548.                                               isLocked,
  2549.                                               ASName);
  2550.           if (auxState != kODNULL)
  2551.           {
  2552.             SOMFree(auxState->remoteLinkInfos._buffer);
  2553.             SOMFree(auxState);
  2554.           }
  2555.           ODDisposePtr(ASName);
  2556.         }
  2557.  
  2558.       }
  2559.       catch (ODException _exception)
  2560.       {
  2561.  
  2562.        SaveEv();
  2563.        try
  2564.        {
  2565.         if (su != (ODStorageUnit*) kODNULL)
  2566.         {
  2567.           _fPersistentObjects->RemoveEntry(&id);
  2568.           su->Release(ev);
  2569.         }
  2570.  
  2571.         linkSource->ReleaseAll(ev);
  2572.         delete linkSource;
  2573.        }
  2574.        catch(ODException _exception)
  2575.        {
  2576.             SetErrorCode(kODNoError);
  2577.        }
  2578.        ODError error = ErrorCode();
  2579.        ODSetSOMException(ev, error);
  2580.        throw;
  2581.  
  2582.       }
  2583.     }
  2584.    }
  2585.    catch (ODException _exception)
  2586.    {
  2587.         linkSource = kODNULL;
  2588.         ODSetSOMException(ev, _exception);
  2589.    }
  2590.  
  2591.     return (ODLinkSource*)linkSource;
  2592.  
  2593. #else
  2594.         ODLinkSource* linkSource = (ODLinkSource*) kODNULL;
  2595.    try
  2596.    {
  2597.         if (id == kODNULLID)
  2598.                 THROW(kODErrIllegalNullIDInput);
  2599.  
  2600.         linkSource = ((ODLinkSource*) somSelf->RetrievePersistentObject(ev, id));
  2601.  
  2602.         if (linkSource == (ODLinkSource*) kODNULL) {
  2603.                 linkSource = new ODLinkSource();
  2604.                 if (linkSource == (ODLinkSource*) kODNULL)
  2605.                                 THROW(kODErrCannotAcquireLink);
  2606.  
  2607.                 ODStorageUnit*  su = (ODStorageUnit*) kODNULL;
  2608.                 ODVolatile(su);
  2609.                 ODVolatile(id);
  2610.                 try
  2611.                 {
  2612.                         su = somSelf->AcquireStorageUnit(ev, id);
  2613.                         _fPersistentObjects->ReplaceEntry(&id, &linkSource);
  2614.                         linkSource->InitLinkSourceFromStorage(ev, su);
  2615.                         SetStorageUnitType(ev, _fPermissions, su, kODLinkSource);
  2616.                 }
  2617.                 catch (ODException _exception)
  2618.                 {
  2619.                     ODError error = ErrorCode();
  2620.                     SaveEv();
  2621.                   try
  2622.                   {
  2623.  
  2624.                         if (su != (ODStorageUnit*) kODNULL) {
  2625.                                 _fPersistentObjects->RemoveEntry(&id);
  2626.                                 su->Release(ev);
  2627.                                 }
  2628.                         linkSource->ReleaseAll(ev);
  2629.                         delete linkSource;
  2630.                     }
  2631.                     catch(ODException _exception)
  2632.                   {
  2633.                             SetErrorCode(kODNoError);
  2634.                     }
  2635.                       RestoreEv()
  2636.                     ODSetSOMException(ev, error);
  2637.  
  2638.                         throw;
  2639.                 }
  2640.                 }
  2641.  
  2642.      }
  2643.      catch (ODException  _exception)
  2644.      {
  2645.           linkSource = kODNULL;
  2646.           ODSetSOMException(ev, _exception);
  2647.      }
  2648.         return linkSource;
  2649. #endif  // _PLATFORM_OS2_
  2650.  
  2651. }
  2652.  
  2653. //------------------------------------------------------------------------------
  2654. // CMDraft: RemoveLinkSource
  2655. //------------------------------------------------------------------------------
  2656.  
  2657. SOM_Scope void  SOMLINK CMDraftRemoveLinkSource(CMDraft *somSelf, Environment *ev,
  2658.                 ODLinkSource* linkSource)
  2659. {
  2660.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2661.     CMDraftMethodDebug("CMDraft","RemoveLinkSource");
  2662.  
  2663.  
  2664.    try
  2665.    {
  2666.         somSelf->FailIfNotExclusiveWrite(ev);
  2667.  
  2668.         somSelf->RemovePersistentObject(ev, linkSource);
  2669.  
  2670.    }
  2671.    catch (ODException _exception)
  2672.    {
  2673.        ODSetSOMException(ev, _exception);
  2674.    }
  2675. }
  2676.  
  2677. //------------------------------------------------------------------------------
  2678. // CMDraft: CreateLink
  2679. //------------------------------------------------------------------------------
  2680.  
  2681. SOM_Scope ODLink*  SOMLINK CMDraftCreateLink(CMDraft *somSelf, Environment *ev)
  2682. {
  2683.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2684.     CMDraftMethodDebug("CMDraft","CreateLink");
  2685.  
  2686.  
  2687. #ifdef _PLATFORM_OS2_
  2688.  
  2689.     IODLinkTarget*  link = kODNULL;
  2690.    try
  2691.    {
  2692.  
  2693.       ODStorageUnitID id;
  2694.       ODStorageUnit*  su;
  2695.  
  2696.       su = somSelf->CreateSU(ev, kODNULL, kODLink);
  2697.  
  2698.       // $$$$$ Links no longer depend on this property
  2699.       // $$$$$ (but LinkSourceIterator does!)
  2700.       su->AddProperty(ev, kODPropStorageUnitType);
  2701.       su->AddValue(ev, kODISOStr);
  2702.       StorageUnitSetValue(su,
  2703.                           ev,
  2704.                           ODISOStrLength(kODLink)+1,
  2705.                           (ODValue)kODLink);
  2706.  
  2707.       link = new IODLinkTarget();
  2708.       if (link == kODNULL)
  2709.       {
  2710.         delete su;
  2711.         THROW(kODErrCannotCreateLink);
  2712.       }
  2713.  
  2714.       id = su->GetID(ev);
  2715.       _fPersistentObjects->ReplaceEntry(&id, &link);
  2716.  
  2717.       link->InitLinkTarget(ev, su, _fLinkService->GetDocName(ev));
  2718.  
  2719.       somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2720.    }
  2721.    catch (ODException _exception)
  2722.    {
  2723.        link = kODNULL;
  2724.        ODSetSOMException(ev, _exception);
  2725.    }
  2726.  
  2727.       return (ODLink*)link;
  2728.  
  2729. #else
  2730.         ODLink*         link = kODNULL;
  2731.  
  2732.    try
  2733.    {
  2734.         ODStorageUnitID id;
  2735.         ODStorageUnit*  su;
  2736.  
  2737.         su = somSelf->CreateSU(ev, kODNULL, kODLink);
  2738.  
  2739.         // The implementation of CMLinkIterator depends on this property being present
  2740.         // in link storage units and nowhere else.
  2741.         SetStorageUnitType(ev, _fPermissions, su, kODLink);
  2742.  
  2743.         link = new ODLink();
  2744.         if (link == kODNULL)
  2745.         {
  2746.                 delete su;
  2747.                 THROW(kODErrCannotCreateLink);
  2748.         }
  2749.  
  2750.         id = su->GetID(ev);
  2751.         _fPersistentObjects->ReplaceEntry(&id, &link);
  2752.  
  2753.         link->InitLink(ev, su);
  2754.  
  2755.         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2756.  
  2757.     }
  2758.     catch (ODException _exception)
  2759.     {
  2760.          link = kODNULL;
  2761.          ODSetSOMException(ev, _exception);
  2762.     }
  2763.         return link;
  2764. #endif // _PLATFORM_OS2_
  2765. }
  2766.  
  2767. //------------------------------------------------------------------------------
  2768. // CMDraft: AcquireLink
  2769. //------------------------------------------------------------------------------
  2770.  
  2771. SOM_Scope ODLink*  SOMLINK CMDraftAcquireLink(CMDraft *somSelf, Environment *ev,
  2772.                 ODStorageUnitID id,ODLinkSpec* linkSpec)
  2773. {
  2774.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2775.     CMDraftMethodDebug("CMDraft","AcquireLink");
  2776.  
  2777. #ifdef _PLATFORM_OS2_
  2778.         IODLinkTarget* link = (IODLinkTarget*)kODNULL;
  2779. #else
  2780.         ODLink* link = (ODLink*) kODNULL;
  2781. #endif
  2782.  
  2783.    try
  2784.    {
  2785.  
  2786. #ifdef _PLATFORM_OS2_
  2787.  
  2788.     if (id != (ODStorageUnitID)kODNULL)
  2789.     {
  2790.       ODPersistentObject*  object;
  2791.       object = somSelf->RetrievePersistentObject(ev, id);
  2792.  
  2793.       if (IsLinkObject(ev, somSelf, id))
  2794.       {
  2795.        link = (IODLinkTarget*)object;
  2796.       }
  2797.       else
  2798.       {
  2799.        THROW(kODErrInvalidID);
  2800.       }
  2801.       if (link == (IODLinkTarget*)kODNULL)
  2802.       {
  2803.         link = new IODLinkTarget();
  2804.         if (link == (IODLinkTarget*)kODNULL)
  2805.         {
  2806.           THROW(kODErrCannotAcquireLink);
  2807.         }
  2808.  
  2809.         ODStorageUnit* su = (ODStorageUnit*)kODNULL;
  2810.         ODVolatile(su);
  2811.         ODVolatile(id);
  2812.  
  2813.         try
  2814.         {
  2815.  
  2816.           su = somSelf->AcquireStorageUnit(ev, id);
  2817.           _fPersistentObjects->ReplaceEntry(&id, &link);
  2818.           link->InitLinkTargetFromStorage(ev, su, _fLinkService->GetDocName(ev));
  2819.  
  2820.         }
  2821.         catch (ODException _exception)
  2822.         {
  2823.  
  2824.           ODError error = ErrorCode();
  2825.           SaveEv();
  2826.           try
  2827.           {
  2828.               if (su != (ODStorageUnit*) kODNULL)
  2829.               {
  2830.                  _fPersistentObjects->RemoveEntry(&id);
  2831.                  su->Release(ev);
  2832.               }
  2833.               link->ReleaseAll(ev);
  2834.               delete link;
  2835.           }
  2836.           catch(ODException _exception)
  2837.           {
  2838.                 SetErrorCode(kODNoError);
  2839.           }
  2840.           RestoreEv();
  2841.           ODSetSOMException(ev, error);
  2842.  
  2843.           throw;
  2844.  
  2845.         }
  2846.       }
  2847.     }
  2848.     else if (linkSpec == (ODLinkSpec*)kODNULL)
  2849.     {
  2850.        THROW(kODErrInvalidID);
  2851.     }
  2852.     else
  2853.     {
  2854.        link = (IODLinkTarget*)somSelf->CreateLink(ev);
  2855.        link->EstablishLink(ev, linkSpec, _fLinkService);
  2856.     };
  2857.  
  2858.  
  2859. #else
  2860.  
  2861.  
  2862.         if (id != (ODStorageUnitID) kODNULL) {
  2863.                 link = ((ODLink*) somSelf->RetrievePersistentObject(ev, id));
  2864.                 if (link == (ODLink*) kODNULL) {
  2865.                         link = new ODLink();
  2866.                         if (link == kODNULL)
  2867.                                 THROW(kODErrCannotAcquireLink);
  2868.  
  2869.                         ODStorageUnit*  su = (ODStorageUnit*) kODNULL;
  2870.                         ODVolatile(su);
  2871.                         ODVolatile(id);
  2872.                         try
  2873.                         {
  2874.                                 su = somSelf->AcquireStorageUnit(ev, id);
  2875.                                 _fPersistentObjects->ReplaceEntry(&id, &link);
  2876.                                 link->InitLinkFromStorage(ev, su);
  2877.                                 SetStorageUnitType(ev, _fPermissions, su, kODLink);
  2878.                         }
  2879.                         catch(ODException _exception)
  2880.                         {
  2881.                             ODError error = ErrorCode();
  2882.                             SaveEv();
  2883.                       try
  2884.                       {
  2885.  
  2886.                                 if (su != (ODStorageUnit*) kODNULL) {
  2887.                                         _fPersistentObjects->RemoveEntry(&id);
  2888.                                         su->Release(ev);
  2889.                                         }
  2890.                                 link->ReleaseAll(ev);
  2891.                                 delete link;
  2892.                             }
  2893.                       catch(ODException _exception)
  2894.                       {
  2895.                                   SetErrorCode(kODNoError);
  2896.                             }
  2897.                             RestoreEv();
  2898.                             ODSetSOMException(ev, error);
  2899.  
  2900.                                 throw;
  2901.                         }
  2902.                         }
  2903.                 }
  2904.         else if (linkSpec == (ODLinkSpec*) kODNULL) {
  2905.                 THROW(kODErrInsufficientInfoInParams);
  2906.                 }
  2907.         else if (linkSpec->FromThisDraft(ev)) {
  2908.                 ODPart* part = linkSpec->GetPart(ev);
  2909.                 ODByteArray partData = linkSpec->GetPartData(ev);
  2910.                 ODVolatile(partData);
  2911.                 ODLinkSource* linkSource = kODNULL;
  2912.                 ODVolatile(linkSource);
  2913.                 try
  2914.                 {
  2915.                         linkSource = part->CreateLink(ev, &partData);
  2916.                         if ( linkSource != (ODLinkSource*) kODNULL ) {
  2917.                                 link = linkSource->GetLink(ev);
  2918.                                 if ( link != (ODLink*) kODNULL )
  2919.                                         link->Acquire(ev);
  2920.                                 }
  2921.                 }
  2922.                 catch (ODException _exception)
  2923.                 {
  2924.                         ODError error = ErrorCode();
  2925.                         DisposeByteArrayStruct(partData);
  2926.                         SaveAndRestoreEv1(linkSource);
  2927.                         ODSetSOMException(ev, error);
  2928.                         throw;
  2929.                 }
  2930.                 DisposeByteArrayStruct(partData);
  2931.                 ODReleaseObject(ev, linkSource);
  2932.                 }
  2933.         else {
  2934.                 // This link spec originated in another document; forward the
  2935.                 // AcquireLink call to the originating draft.
  2936.                 ODSession* session = _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  2937.                 if (session != kODNULL) {
  2938.                         ODLinkSource* linkSource = kODNULL;
  2939.                         ODVolatile(linkSource);
  2940.                         try
  2941.                         {
  2942.                                 linkSource = session->GetLinkManager(ev)->CreateLink(ev, somSelf, linkSpec);
  2943.                                 if ( linkSource != (ODLinkSource*) kODNULL ) {
  2944.                                         link = linkSource->GetLink(ev);
  2945.                                         if ( link != (ODLink*) kODNULL )
  2946.                                                 link->Acquire(ev);
  2947.                                         }
  2948.                         }
  2949.                         catch (ODException _exception)
  2950.                         {
  2951.                                 ODError error = ErrorCode();
  2952.                                 SaveAndRestoreEv1(linkSource);
  2953.                                 ODSetSOMException(ev, error);
  2954.                                 throw;
  2955.                         }
  2956.                         ODReleaseObject(ev, linkSource);
  2957.                         }
  2958.                 }
  2959. #endif // _PLATFORM_OS2_
  2960.  
  2961.         }
  2962.         catch (ODException _exception)
  2963.         {
  2964.                 link = kODNULL;
  2965.                 ODSetSOMException(ev, _exception);
  2966.         }
  2967.         return (ODLink*)link;
  2968. }
  2969.  
  2970. //------------------------------------------------------------------------------
  2971. // CMDraft: ReleaseLink
  2972. //------------------------------------------------------------------------------
  2973.  
  2974. SOM_Scope void  SOMLINK CMDraftReleaseLink(CMDraft *somSelf, Environment *ev,
  2975.                 ODLink* link)
  2976. {
  2977.     CMDraftData *somThis = CMDraftGetData(somSelf);
  2978.     CMDraftMethodDebug("CMDraft","ReleaseLink");
  2979.  
  2980.    try
  2981.    {
  2982.  
  2983.         somSelf->ReleasePersistentObject(ev, link);
  2984.  
  2985.    }
  2986.    catch (ODException _exception)
  2987.    {
  2988.        ODSetSOMException(ev, _exception);
  2989.    }
  2990. }
  2991.  
  2992. //------------------------------------------------------------------------------
  2993. // CMDraft: ReleaseLinkSource
  2994. //------------------------------------------------------------------------------
  2995.  
  2996. SOM_Scope void  SOMLINK CMDraftReleaseLinkSource(CMDraft *somSelf, Environment *ev,
  2997.                 ODLinkSource* linkSource)
  2998. {
  2999.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3000.     CMDraftMethodDebug("CMDraft","ReleaseLinkSource");
  3001.  
  3002.  
  3003.    try
  3004.    {
  3005.         somSelf->ReleasePersistentObject(ev, linkSource);
  3006.  
  3007.    }
  3008.    catch (ODException _exception)
  3009.    {
  3010.       ODSetSOMException(ev, _exception);
  3011.    }
  3012. }
  3013.  
  3014. //------------------------------------------------------------------------------
  3015. // CMDraft: RemoveLink
  3016. //------------------------------------------------------------------------------
  3017.  
  3018. SOM_Scope void  SOMLINK CMDraftRemoveLink(CMDraft *somSelf, Environment *ev,
  3019.                 ODLink* link)
  3020. {
  3021.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3022.     CMDraftMethodDebug("CMDraft","RemoveLink");
  3023.  
  3024.    try
  3025.    {
  3026.  
  3027.         somSelf->FailIfNotExclusiveWrite(ev);
  3028.  
  3029.         somSelf->RemovePersistentObject(ev, link);
  3030.  
  3031.    }
  3032.    catch (ODException _exception)
  3033.    {
  3034.        ODSetSOMException(ev, _exception);
  3035.    }
  3036. }
  3037.  
  3038. //------------------------------------------------------------------------------
  3039. // CMDraft: GetPersistentObjectID
  3040. //------------------------------------------------------------------------------
  3041.  
  3042. SOM_Scope ODPersistentObjectID  SOMLINK CMDraftGetPersistentObjectID(CMDraft *somSelf, Environment *ev,
  3043.                 ODPersistentObject* object,
  3044.                 ODObjectType    objectType)
  3045. {
  3046.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3047.     CMDraftMethodDebug("CMDraft","GetPersistentObjectID");
  3048.  
  3049.         ODPersistentObjectID retID = kODNULLID;
  3050.  
  3051.    try
  3052.    {
  3053.         ASSERT(ODISOStrEqual(objectType, kODPartObject) || ODISOStrEqual(objectType, kODFrameObject),
  3054.                         kODErrInvalidObjectType);
  3055.  
  3056.         CMStorageUnit* su = (CMStorageUnit*) object->GetStorageUnit(ev);
  3057.  
  3058.         if (su == kODNULL)
  3059.                 THROW(kODErrInvalidPersistentObject);
  3060.  
  3061.         retID = su->GetObjectID(ev);
  3062.     }
  3063.     catch (ODException _exception)
  3064.     {
  3065.          ODSetSOMException (ev, _exception);
  3066.     }
  3067.         return retID;
  3068. }
  3069.  
  3070. //------------------------------------------------------------------------------
  3071. // CMDraft: AcquirePersistentObject
  3072. //------------------------------------------------------------------------------
  3073.  
  3074. SOM_Scope ODPersistentObject* SOMLINK CMDraftAcquirePersistentObject(CMDraft *somSelf, Environment *ev,
  3075.                 ODPersistentObjectID objectID,
  3076.                 ODObjectType*   objectType)
  3077. {
  3078.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3079.     CMDraftMethodDebug("CMDraft","AcquirePersistentObject");
  3080.  
  3081.         ODPersistentObject*     object = kODNULL;
  3082.  
  3083.     try
  3084.     {
  3085.  
  3086.         *objectType = kODNULL;
  3087.         ODStorageUnitID id = kODNULLID;
  3088.  
  3089.         if (objectID == 0)
  3090.                 THROW(kODErrIllegalNullIDInput);
  3091.  
  3092.         CMContainer cmContainer = somSelf->GetCMContainer(ev);
  3093.         ODSessionMustHaveCMAllocReserve(cmContainer);
  3094.  
  3095.         CMObject cmObject = CMGetObject(cmContainer, objectID);
  3096.         if (cmObject == kODNULL)
  3097.                 THROW(kODErrInvalidPersistentObjectID);
  3098.  
  3099.         if (_fIDList->ObjectExists(cmObject) != kODFalse) {
  3100.                 id = _fIDList->GetID(cmObject);
  3101.                 CMReleaseObject(cmObject);
  3102.         }
  3103.         else
  3104.                 id = _fIDList->Add(cmObject);
  3105.  
  3106.         ODSessionRestoreCMAllocReserve(cmContainer);
  3107.  
  3108. #ifdef _NO_TMP_OBJS_
  3109.         ODStorageUnit *su = somSelf->AcquireStorageUnit(ev, id);
  3110. #else
  3111.         TempODStorageUnit su = somSelf->AcquireStorageUnit(ev, id);
  3112. #endif
  3113.         ODPtr buffer;
  3114.         if ((buffer = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL)) != kODNULL)
  3115.         {
  3116.                 if (ODISOStrEqual((ODISOStr) buffer, kODPartObject) != kODFalse)
  3117.                         object = somSelf->AcquirePart(ev, id);
  3118.                 else if (ODISOStrEqual((ODISOStr) buffer, kODFrameObject) != kODFalse)
  3119.                         object = somSelf->AcquireFrame(ev, id);
  3120.                 else
  3121.                         THROW(kODErrInvalidPersistentObjectID);
  3122.  
  3123.                 if (object != kODNULL)
  3124.                         *objectType = (ODType) buffer;
  3125.                 else
  3126.                         ODDisposePtr(buffer);
  3127.         }
  3128.  
  3129. #ifdef _NO_TMP_OBJS_
  3130.         su->Release(ev);
  3131. #endif
  3132.  
  3133.      }
  3134.      catch (ODException _exception)
  3135.      {
  3136.            object = kODNULL;
  3137.            ODSetSOMException(ev, _exception);
  3138.      }
  3139.         return object;
  3140. }
  3141.  
  3142. //------------------------------------------------------------------------------
  3143. // CMDraft: ReleaseStorageUnit
  3144. //------------------------------------------------------------------------------
  3145.  
  3146. SOM_Scope ODDraft*  SOMLINK CMDraftReleaseStorageUnit(CMDraft *somSelf, Environment *ev,
  3147.                 ODStorageUnitID id)
  3148. {
  3149.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3150.     CMDraftMethodDebug("CMDraft","ReleaseStorageUnit");
  3151.  
  3152.  
  3153.     try
  3154.     {
  3155.         ODStorageUnit*  su = kODNULL;
  3156.  
  3157.         if (! _fStorageUnits->GetValue(&id, &su))
  3158.                 THROW(kODErrInvalidStorageUnit);
  3159.  
  3160.         if (su->GetRefCount(ev) != 0)
  3161.                 THROW(kODErrRefCountGreaterThanZero);
  3162.  
  3163.         if (_fDraftProperties != kODNULL) {
  3164.                 if (id == _fDraftProperties->GetID(ev))
  3165.                         _fDraftProperties = kODNULL;
  3166.         }
  3167.  
  3168.     }
  3169.     catch (ODException _exception)
  3170.     {
  3171.         ODSetSOMException(ev, _exception);
  3172.     }
  3173.         return somSelf;
  3174. }
  3175.  
  3176. //------------------------------------------------------------------------------
  3177. // CMDraft: ~CMDraft
  3178. //------------------------------------------------------------------------------
  3179.  
  3180. SOM_Scope void  SOMLINK CMDraftsomUninit(CMDraft *somSelf)
  3181. {
  3182.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3183.     CMDraftMethodDebug("CMDraft","somUninit");
  3184.  
  3185.                 Environment*    ev = somGetGlobalEnvironment();
  3186.      try
  3187.      {
  3188.  
  3189. #if ODDebug_DebugRefCount
  3190.                 if (somSelf->GetRefCount(ev) != 0)
  3191.                         DebugStr("\pRefCount of Draft is not 0 at uninit.");
  3192.                 somPrintf("~CMDraft %x RefCount %d EmbeddedCtr %x CMCtr %x\n",
  3193.                                         somSelf,
  3194.                                         somSelf->GetRefCount(ev),
  3195.                                         somSelf->GetEmbeddedContainer(ev),
  3196.                                         somSelf->GetCMContainer(ev));
  3197. #endif
  3198.  
  3199.  
  3200. #ifdef _PLATFORM_OS2_
  3201.        //XXXXX Added to force LinkTarget to unregister
  3202.        if (_fPermissions == kODDPExclusiveWrite)
  3203.        //XXXXX
  3204.        somSelf->DeleteCollections(ev);
  3205.        parent_somUninit(somSelf);
  3206. #else
  3207.                 delete _fPartClasses;
  3208.  
  3209.                 // Set to NULL so that PartDeleted method is not going
  3210.                 // to try to access _fPartClasses.
  3211.                 _fPartClasses = kODNULL; 
  3212.  
  3213.                 somSelf->DeleteCollections(ev);
  3214.  
  3215. #endif
  3216.  
  3217. /*
  3218. #ifdef _PLATFORM_OS2_
  3219.  
  3220.     if (_fLinkService != kODNULL)
  3221.     (
  3222.       delete _fLinkService;
  3223.       delete _fLinkServiceXID;
  3224.     }
  3225.  
  3226. #endif
  3227. */
  3228.  
  3229.         }
  3230.         catch (ODException _exception)
  3231.         {
  3232.             SetErrorCode(kODNoError); // Ignore exception
  3233.         }
  3234. }
  3235.  
  3236. //------------------------------------------------------------------------------
  3237. // CMDraft: InitDraft
  3238. //------------------------------------------------------------------------------
  3239.  
  3240. SOM_Scope void  SOMLINK CMDraftInitDraft(CMDraft *somSelf, Environment *ev,
  3241.                 ODDocument* document, ODDraftID id, ODDraftPermissions perms)
  3242. {
  3243.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3244.     CMDraftMethodDebug("CMDraft","InitDraft");
  3245.  
  3246.    try
  3247.    {
  3248.  
  3249.         /* Moved from somInit. SOM itself sets fields to zero
  3250.         _fChangedFromPrev = kODFalse;
  3251.  
  3252.         _fDocument = kODNULL;
  3253.         _fID = 0;
  3254.         _fPermissions = kODDPNone;
  3255.         _fEmbeddedContainer = kODNULL;
  3256.         _fVersionID = kODTombstonedVersion;
  3257.         _fIsNewDraft = kODFalse;
  3258.  
  3259.         _fExternalized = kODFalse;
  3260.         _fRemoveChangeOnAbort = kODFalse;
  3261.  
  3262.         _fStorageUnits = kODNULL;
  3263.         _fPersistentObjects = kODNULL;
  3264.  
  3265.         _fIDList = kODNULL;
  3266.         _fDraftProperties = kODNULL;
  3267.  
  3268.         _fDestDraft = kODNULL;
  3269.         _fDestFrame = kODNULL;
  3270.         _fClonedSUIDs = kODNULL;
  3271.         _fWeakClonedSUIDs = kODNULL;
  3272.         _fSavedWeakClonedSUIDs = kODNULL;
  3273.         _fCurrentKey = kODNULL;
  3274.         _fLockCount = 0;
  3275.  
  3276.         _fAnyFrameCloned = kODFalse;
  3277.         _fRootPartReused = kODFalse;
  3278.  
  3279.         _fOrigTopVersionDraftID = 0;
  3280.  
  3281.         _fHeap = kDefaultHeapID;
  3282.         */
  3283.         _fVersionID = kODTombstonedVersion;
  3284.  
  3285.         somSelf->InitRefCntObject(ev);
  3286.  
  3287. #ifdef ODDebug_VersionList
  3288.         ((CMDocument*) document)->GetVersionList(ev)->Print(">>>Entering InitDraft");
  3289. #endif
  3290.  
  3291.         _fDocument = (CMDocument*) document;
  3292.         _fID = id;
  3293.         _fPermissions = perms;
  3294.  
  3295.         VersionList*    versionList = kODNULL;
  3296.  
  3297.         if (_fDocument == kODNULL)
  3298.                 THROW(kODErrIllegalNullDocumentInput);
  3299.  
  3300.         if (_fID == kODNULL) {
  3301.                 versionList = _fDocument->GetVersionList(ev);
  3302.                 ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  3303.  
  3304.                 _fID = versionList->CreateDraft();
  3305.                 _fIsNewDraft = kODTrue;
  3306.                 _fRemoveChangeOnAbort = kODTrue;
  3307.  
  3308. #if !TestFlushContainer
  3309.                 _fDocument->ExternalizeVersionList(ev, kODFalse);
  3310. #endif
  3311.         }
  3312.  
  3313.         somSelf->CreateCollections(ev);
  3314.  
  3315. #if lazyOpen
  3316.         _fExternalized = kODFalse;
  3317. #else
  3318.         if (_fPermissions == kODDPReadOnly)
  3319.                 somSelf->OpenVersion(ev);
  3320.         else
  3321.                 somSelf->CreateVersion(ev);
  3322. #endif
  3323.  
  3324.         _fHeap = _fDocument->GetHeap(ev);
  3325.  
  3326. #ifdef _PLATFORM_OS2_
  3327.  
  3328.     _fLinkService = _fDocument->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev)->GetLinkService(ev);
  3329.  
  3330. #endif
  3331.  
  3332.  
  3333. #ifdef ODDebug_Unloading_Classes
  3334.         SetOutputMode(kWriteToFile);
  3335. #endif
  3336.  
  3337. #ifdef _PLATFORM_MACINTOSH_
  3338.         _fPartClasses = new(_fHeap)
  3339.                 OpenHashTable(OpenHashTable::StdEqual,
  3340.                               OpenHashTable::StdHash, _fHeap);
  3341. #endif
  3342. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  3343. //      The use of heap is not implemented in Windows platform
  3344.         _fPartClasses = new OpenHashTable(OpenHashTable::StdEqual,
  3345.                               OpenHashTable::StdHash, 0);
  3346. #endif
  3347.         _fPartClasses->Initialize(kODInitialNumEntries,
  3348.                                         sizeof(SOMClass*),
  3349.                                         sizeof(ODULong));
  3350.  
  3351. #ifdef ODDebug_VersionList
  3352.         _fDocument->GetVersionList(ev)->Print(">>>Exiting InitDraft");
  3353. #endif
  3354.  
  3355. #ifdef _PLATFORM_WIN32_
  3356.         DocumentManager  *docMgr = NULL;
  3357.         OleWrapper       *wrapper = NULL;
  3358.  
  3359.         docMgr = ODOLEManager::GetShell()->GetActiveDocumentManager(ev);
  3360.         if (docMgr) {
  3361.             wrapper = docMgr->GetOleWrapper(ev);
  3362.             if (wrapper)
  3363.                 wrapper->OnDataChange();
  3364.         }
  3365. #endif
  3366.  
  3367.     }
  3368.     catch (ODException _exception)
  3369.     {
  3370.         ODSetSOMException(ev, _exception);
  3371.     }
  3372. }
  3373.  
  3374. //------------------------------------------------------------------------------
  3375. // CMDraft: Purge
  3376. //------------------------------------------------------------------------------
  3377.  
  3378. SOM_Scope ODSize  SOMLINK CMDraftPurge(CMDraft *somSelf, Environment *ev,
  3379.                 ODSize size)
  3380. {
  3381.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3382.     CMDraftMethodDebug("CMDraft","Purge");
  3383.  
  3384.         ODULong         runningTotal = 0;
  3385.  
  3386.    try
  3387.    {
  3388.  
  3389.         OpenHashTableIterator   i(_fPersistentObjects);
  3390.         ODStorageUnitID         id;
  3391.         ODPersistentObject*     object;
  3392.  
  3393.         for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
  3394.                 runningTotal += object->Purge(ev, size);
  3395.                 if (object->GetRefCount(ev) == 0) {
  3396.                         object->ReleaseAll(ev);
  3397.                 }
  3398.         }
  3399.         for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
  3400.                 if (object->GetRefCount(ev) == 0) {
  3401.                         i.RemoveCurrent();
  3402.                         delete object;
  3403.                 }
  3404.         }
  3405.         _fPersistentObjects->ShrinkToFit(/*extraSlots*/ 0);
  3406.  
  3407.         // purge all storage units, but don't release CMObjects
  3408.         runningTotal += PurgeAllStorageUnits(ev, _fStorageUnits, kODNULL);
  3409.  
  3410.         PurgeClasses(ev, _fPartClasses);
  3411.  
  3412.     }
  3413.     catch (ODException _exception)
  3414.     {
  3415.          runningTotal = 0;
  3416.          ODSetSOMException(ev, _exception);
  3417.     }
  3418.         return runningTotal;
  3419. }
  3420.  
  3421. //------------------------------------------------------------------------------
  3422. // CMDraft: CreateSU
  3423. //------------------------------------------------------------------------------
  3424.  
  3425. SOM_Scope ODStorageUnit*  SOMLINK CMDraftCreateSU(CMDraft *somSelf, Environment *ev,
  3426.                 ODStorageUnitID id, ODType suType)
  3427. {
  3428.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3429.     CMDraftMethodDebug("CMDraft","CreateSU");
  3430.  
  3431.         ODStorageUnit*  su = kODNULL;
  3432.  
  3433.     try
  3434.     {
  3435.         CMObject                object = kODNULL;
  3436.         CMContainer             cmContainer = somSelf->GetCMContainer(ev);
  3437.         ODSessionMustHaveCMAllocReserve(cmContainer);
  3438.  
  3439.         ODVolatile(su);
  3440.         ODVolatile(object);
  3441.         try
  3442.         {
  3443.  
  3444.                 // Create CMObject if necessary
  3445.  
  3446.                 if (id == kODNULL) {
  3447.                         if ((object = CMNewObject(cmContainer)) == kODNULL)
  3448.                                 THROW(kODErrBentoCannotNewObject);
  3449.  
  3450.                         id = _fIDList->Add(object);
  3451.                 }
  3452.  
  3453.                 // Create the Storage Unit
  3454.                 su = NewCMStorageUnit(somSelf->GetHeap(ev));
  3455.                 su->InitStorageUnit(ev, somSelf, id);
  3456.  
  3457.         }
  3458.         catch (ODException _exception)
  3459.         {
  3460.  
  3461.                 if (object != kODNULL)
  3462.                         CMReleaseObject(object);
  3463.  
  3464.                 if (su != kODNULL)
  3465.                         delete su;
  3466.  
  3467.                 if (ErrorCode() == kODErrBentoInvalidObject)
  3468.                         THROW(kODErrInvalidID);
  3469.                 else
  3470.                         throw;
  3471.  
  3472.         }
  3473.         ODSessionRestoreCMAllocReserve(cmContainer);
  3474.  
  3475.         // Add Storage Unit to outstanding SU collection
  3476.  
  3477.         _fStorageUnits->ReplaceEntry(&id, &su);
  3478.  
  3479.         }
  3480.         catch (ODException _exception)
  3481.         {
  3482.             su = kODNULL;
  3483.             ODSetSOMException(ev, _exception);
  3484.         }
  3485.  
  3486.         return su;
  3487. }
  3488.  
  3489. //------------------------------------------------------------------------------
  3490. // CMDraft: SetChangedFromPrevFlag
  3491. //------------------------------------------------------------------------------
  3492.  
  3493. SOM_Scope void  SOMLINK CMDraftSetChangedFromPrevFlag(CMDraft *somSelf, Environment *ev,
  3494.                 ODBoolean changed)
  3495. {
  3496.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3497.     CMDraftMethodDebug("CMDraft","SetChangedFromPrevFlag");
  3498.  
  3499.         if (changed != kODFalse){
  3500.                 try
  3501.                 {
  3502.                         somSelf->FailIfNotExclusiveWrite(ev);
  3503.                 }
  3504.                 catch(ODException _exception)
  3505.                 {
  3506.                       ODSetSOMException(ev, _exception);
  3507.                 }
  3508.         }
  3509.         _fChangedFromPrev = changed;
  3510. }
  3511.  
  3512. static void SetupForUpdatingDraft(Environment* ev,
  3513.                                                                                 CMDocument* localDoc,
  3514.                                                                                 ODVersionID prevVersionID,
  3515.                                                                                 CMValue version)
  3516. {
  3517.    try
  3518.    {
  3519.         ODBentoContainer*       localContainer = (ODBentoContainer*) localDoc->GetContainer(ev);
  3520.         ODBentoContainer*       container = kODNULL;
  3521.  
  3522.         // check to see whether we need to do a update
  3523.         container = localContainer->GetTargetContainer(ev);
  3524.  
  3525.         if (container != kODNULL) {
  3526.  
  3527.                 // get the target document
  3528.                 CMDocument*             targetDoc = localContainer->GetTargetDocument(ev);
  3529.  
  3530.                 // find its version list
  3531.                 VersionList*    versionList = targetDoc->GetVersionList(ev);
  3532.                 ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  3533.  
  3534.                 // get the latest draft
  3535.                 ODDraftID       latestDraftID = versionList->GetLatestDraftID();
  3536.  
  3537.                 // get the version id of the latest draft
  3538.                 prevVersionID = versionList->GetDraft(latestDraftID);
  3539.         }
  3540.         else {
  3541.                 container = localContainer;
  3542.         }
  3543.         // Note: getting/setting refcon's does not allocate memory in Bento:
  3544.  
  3545.         // get the name for indirection
  3546.         ODType prevVersionName = GetVersionNameFromVersionID(prevVersionID, localDoc->GetHeap(ev));
  3547.  
  3548.         // store name so that it can be passed to handler
  3549.         CMSetValueRefCon(version, prevVersionName);
  3550.  
  3551.         // get cmContainer so that we can assess CMSession
  3552.         CMContainer cmContainer = container->GetCMContainer(ev);
  3553.  
  3554.         // Save the outermost container for embedded container creation.
  3555.         ODSessionRefCon* sessionRefCon = (ODSessionRefCon*) CMGetSessionRefCon(cmContainer);
  3556.         sessionRefCon->container = container;
  3557.     }
  3558.     catch (ODException _exception)
  3559.     {
  3560.         ODSetSOMException(ev, _exception);
  3561.     }
  3562. }
  3563.  
  3564. //------------------------------------------------------------------------------
  3565. // CMDraft: CreateVersion
  3566. //------------------------------------------------------------------------------
  3567.  
  3568. SOM_Scope void  SOMLINK CMDraftCreateVersion(CMDraft *somSelf, Environment *ev)
  3569. {
  3570.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3571.     CMDraftMethodDebug("CMDraft","CreateVersion");
  3572.  
  3573.  
  3574.    try
  3575.    {
  3576.         CMContainer                             cmContainer = ((ODBentoContainer*) _fDocument->GetContainer(ev))->GetCMContainer(ev);
  3577.         CMObject                                versionObject = kODNULL;
  3578.         CMType                                  versionNameType = kODNULL;
  3579.         ODType                                  versionName = kODNULL;
  3580.         CMProperty                              versionNameProperty = kODNULL;
  3581.         CMValue                                 versionNameValue = kODNULL;
  3582.         CMType                                  versionDataType = kODNULL;
  3583.         CMProperty                              versionDataProperty = kODNULL;
  3584.         CMValue                                 version = kODNULL;
  3585.  
  3586.         VersionList*                    versionList = kODNULL;
  3587.  
  3588.         versionList = _fDocument->GetVersionList(ev);
  3589.         ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  3590.  
  3591.         _fOrigTopVersionDraftID = versionList->GetSameVersionDraftID(_fID);
  3592.         _fPrevVersionID = versionList->GetCurrentVersion(_fID);
  3593.         _fVersionID = versionList->CreateVersion(_fID);
  3594.  
  3595.         ODSessionMustHaveCMAllocReserve(cmContainer);
  3596.  
  3597.         versionObject = CMNewObject(cmContainer);
  3598.         versionNameType = CMRegisterType(cmContainer, kODISOStr);
  3599.  
  3600.         versionName = GetVersionNameFromVersionID(_fVersionID, somSelf->GetHeap(ev));
  3601.         versionNameProperty = CMRegisterProperty(cmContainer, versionName);
  3602.  
  3603.         versionNameValue = CMNewValue(versionObject, versionNameProperty, versionNameType);
  3604.         CMWriteValueData(versionNameValue, "", 0, 1);
  3605.  
  3606.         versionDataType = CMRegisterType(cmContainer, kODEmbeddedContainerType);
  3607.         versionDataProperty = CMRegisterProperty(cmContainer, kODEmbeddedContainerProperty);
  3608.         version = CMNewValue(versionObject, versionDataProperty, versionDataType);
  3609.         if (version == kODNULL)
  3610.                 THROW(kODErrCannotCreateDraftVersion);
  3611.         CMWriteValueData(version, "", 0, 0);                            /* Make the container manager happy */
  3612.  
  3613.         ODSessionRestoreCMAllocReserve(cmContainer);
  3614.  
  3615.         SetupForUpdatingDraft(ev, _fDocument, _fPrevVersionID, version);
  3616.  
  3617. #ifdef ODDebug_CMDraft
  3618.         ODDocument* tempDoc = somSelf->GetDocument(ev);
  3619.         somPrintf("CreateVersion: CMDocument %x DraftID %d IsNewDraft %d versionID %d prevVersionID %d\n", tempDoc, somSelf->GetID(ev), somSelf->IsNewDraft(ev), _fVersionID, _fPrevVersionID);
  3620. #endif
  3621.  
  3622.         ODEmbeddedContainerID   containerID;
  3623.         containerID.cmValue = version;
  3624.         containerID.shouldMerge = (somSelf->IsNewDraft(ev) ? kODFalse : kODTrue);
  3625.         ODByteArray*    ba = CreateByteArray(&containerID, sizeof(ODEmbeddedContainerID));
  3626.         _fEmbeddedContainer = (ODEmbeddedContainer*)
  3627.                         _fDocument->GetContainer(ev)->GetStorageSystem(ev)->CreateContainer(ev, kODBentoEmbeddedContainer, ba);
  3628.         DisposeByteArray(ba);
  3629.  
  3630.         if (versionName != kODNULL)
  3631.                 ODDisposePtr(versionName);
  3632.  
  3633.         _fExternalized = kODFalse;
  3634.  
  3635. #ifdef _PLATFORM_WIN32_
  3636.         DocumentManager  *docMgr = NULL;
  3637.         OleWrapper       *wrapper = NULL;
  3638.  
  3639.         docMgr = ODOLEManager::GetShell()->GetActiveDocumentManager(ev);
  3640.         if (docMgr) {
  3641.             wrapper = docMgr->GetOleWrapper(ev);
  3642.             if (wrapper)
  3643.                 wrapper->OnDataChange();
  3644.         }
  3645. #endif
  3646.  
  3647.         somSelf->OpenCollections(ev);
  3648.  
  3649.    }
  3650.    catch (ODException _exception)
  3651.    {
  3652.         ODSetSOMException(ev, _exception);
  3653.    }
  3654. }
  3655.  
  3656. //------------------------------------------------------------------------------
  3657. // CMDraft: OpenVersion
  3658. //------------------------------------------------------------------------------
  3659.  
  3660. SOM_Scope void  SOMLINK CMDraftOpenVersion(CMDraft *somSelf, Environment *ev)
  3661. {
  3662.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3663.     CMDraftMethodDebug("CMDraft","OpenVersion");
  3664.  
  3665.  
  3666.     try
  3667.     {
  3668.         CMContainer                             cmContainer = ((ODBentoContainer*) _fDocument->GetContainer(ev))->GetCMContainer(ev);
  3669.         ODType                                  versionName = kODNULL;
  3670.         ODType                                  oldVersionName = kODNULL;
  3671.         CMType                                  versionDataType;
  3672.         CMProperty                              versionDataProperty;
  3673.         CMProperty                              versionNameProperty;
  3674.         CMObject                                versionObject;
  3675.         CMValue                                 version;
  3676.  
  3677.         VersionList*                    versionList;
  3678.  
  3679.         versionList = _fDocument->GetVersionList(ev);
  3680.         ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  3681.  
  3682.         _fVersionID = versionList->GetCurrentVersion(_fID);
  3683.         _fPrevVersionID = _fVersionID;
  3684.         if (_fVersionID == kODTombstonedVersion)
  3685.                 THROW(kODErrDraftHasBeenDeleted);
  3686.  
  3687.         if (_fPermissions == kODDPReadOnly) {
  3688.                 ODSessionMustHaveCMAllocReserve(cmContainer);
  3689.  
  3690.                 MyDebugStr("**** OpenVersion: kODDPReadOnly.\n");
  3691.                 versionDataType = CMRegisterType(cmContainer, kODEmbeddedContainerType);
  3692.                 versionDataProperty = CMRegisterProperty(cmContainer, kODEmbeddedContainerProperty);
  3693.  
  3694.                 versionName = GetVersionNameFromVersionID(_fVersionID, somSelf->GetHeap(ev));
  3695.                 versionNameProperty = CMRegisterProperty(cmContainer, versionName);
  3696.  
  3697.                 versionObject = CMGetNextObjectWithProperty(cmContainer, kODNULL, versionNameProperty);
  3698.                 version = CMUseValue(versionObject, versionDataProperty, versionDataType);
  3699.  
  3700.                 CMSetValueRefCon(version, kODNULL);
  3701.  
  3702.                 // Save the outermost container for embedded container creation.
  3703.                 ODSessionRefCon* sessionRefCon = (ODSessionRefCon*) CMGetSessionRefCon(cmContainer);
  3704.                 sessionRefCon->container = _fDocument->GetContainer(ev);
  3705.  
  3706. #ifdef ODDebug_CMDraft
  3707.         ODDocument* tempDoc = somSelf->GetDocument(ev);
  3708.         somPrintf("OpenVersion: CMDocument %x DraftID %d IsNewDraft %d versionID %d prevVersionID %d\n", tempDoc, somSelf->GetID(ev), somSelf->IsNewDraft(ev), _fVersionID, _fPrevVersionID);
  3709. #endif
  3710.                 ODEmbeddedContainerID   containerID;
  3711.                 containerID.cmValue = version;
  3712.                 containerID.shouldMerge = kODFalse;
  3713.                 ODByteArray*    ba = CreateByteArray(&containerID, sizeof(ODEmbeddedContainerID));
  3714.                 _fEmbeddedContainer = (ODEmbeddedContainer*)
  3715.                         _fDocument->GetContainer(ev)->GetStorageSystem(ev)->AcquireContainer(ev, kODBentoEmbeddedContainer, ba);
  3716.                 DisposeByteArray(ba);
  3717.  
  3718.                 if (versionName != kODNULL)
  3719.                         ODDisposePtr(versionName);
  3720.                 if (oldVersionName != kODNULL)
  3721.                         ODDisposePtr(oldVersionName);
  3722.  
  3723.                 ODSessionRestoreCMAllocReserve(cmContainer);
  3724.  
  3725.                 somSelf->OpenCollections(ev);
  3726.         }
  3727.         else
  3728.                 THROW(kODErrInvalidPermissions);
  3729.  
  3730.     }
  3731.     catch (ODException _exception)
  3732.     {
  3733.         ODSetSOMException(ev, _exception);
  3734.     }
  3735. }
  3736.  
  3737. //------------------------------------------------------------------------------
  3738. // CMDraft: CloseVersion
  3739. //------------------------------------------------------------------------------
  3740.  
  3741. SOM_Scope void  SOMLINK CMDraftCloseVersion(CMDraft *somSelf, Environment *ev)
  3742. {
  3743.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3744.     CMDraftMethodDebug("CMDraft","CloseVersion");
  3745.  
  3746.    try
  3747.    {
  3748.  
  3749. #ifdef ODDebug_CMDraft
  3750.         ODDocument* tempDoc = somSelf->GetDocument(ev);
  3751.         somPrintf("CloseVersion: CMDocument %x DraftID %d versionID %d Permission %d\n", tempDoc, somSelf->GetID(ev), _fVersionID, _fPermissions);
  3752. #endif
  3753.  
  3754.  
  3755.         if (_fPermissions == kODDPExclusiveWrite) {
  3756.                 VersionList*    versionList = kODNULL;
  3757.  
  3758.                 versionList = _fDocument->TestAndGetVersionList(ev);
  3759.                 ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  3760.  
  3761.                 if (versionList->IsBelow(_fOrigTopVersionDraftID, versionList->GetSameVersionDraftID(_fID)))
  3762.                         _fEmbeddedContainer->SetMergeFlag(ev, kODFalse);
  3763.                 somSelf->CloseCollections(ev);
  3764.         }
  3765.         else {
  3766.                 somSelf->DeleteCollections(ev);
  3767.                 somSelf->CreateCollections(ev);
  3768.         }
  3769.  
  3770.         if (_fEmbeddedContainer != kODNULL) {
  3771.                 _fEmbeddedContainer->Release(ev);
  3772.                 _fEmbeddedContainer = kODNULL;
  3773.         }
  3774.  
  3775.         _fIsNewDraft = kODFalse;
  3776.  
  3777.    } 
  3778.    catch (ODException _exception)
  3779.    {
  3780.        ODSetSOMException(ev, _exception);
  3781.    }
  3782. }
  3783.  
  3784. //------------------------------------------------------------------------------
  3785. // CMDraft: DestroyVersion
  3786. //------------------------------------------------------------------------------
  3787.  
  3788. SOM_Scope void  SOMLINK CMDraftDestroyVersion(CMDraft *somSelf, Environment *ev)
  3789. {
  3790.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3791.     CMDraftMethodDebug("CMDraft","DestroyVersion");
  3792.  
  3793. #ifdef ODDebug_CMDraft
  3794.         ODDocument* tempDoc = somSelf->GetDocument(ev);
  3795.         somPrintf("Destroy Version: CMDocument %x DraftID %d versionID %d Permission %d\n", tempDoc, somSelf->GetID(ev), _fVersionID, _fPermissions);
  3796. #endif
  3797.  
  3798.         if (_fPermissions == kODDPExclusiveWrite) {
  3799.  
  3800.            try
  3801.            {
  3802.                 somSelf->DeleteCollections(ev);
  3803.                 somSelf->CreateCollections(ev);
  3804.  
  3805.                 if (_fEmbeddedContainer != kODNULL) {
  3806.                         _fEmbeddedContainer->Abort(ev);
  3807.                         CMObject                parentObject = kODNULL;
  3808.                         ODByteArray     ba = _fEmbeddedContainer->GetID(ev);
  3809.                         CMValue parentValue = *((CMValue*) ba._buffer);
  3810.                         ODDisposePtr(ba._buffer);
  3811.  
  3812.                         CMContainer cmContainer = somSelf->GetCMContainer(ev);
  3813.                         ODSessionMustHaveCMAllocReserve(cmContainer);
  3814.  
  3815.                         CMGetValueInfo(parentValue, kODNULL, &parentObject,
  3816.                                                         kODNULL, kODNULL, kODNULL);
  3817.                         CMDeleteValue(parentValue);
  3818.                         CMDeleteObject(parentObject);
  3819.  
  3820.                         ODSessionRestoreCMAllocReserve(cmContainer);
  3821.  
  3822.                         _fEmbeddedContainer->Release(ev);
  3823.                         _fEmbeddedContainer = kODNULL;
  3824.                 }
  3825.             } 
  3826.             catch (ODException _exception)
  3827.             {
  3828.                 ODSetSOMException(ev, _exception);
  3829.             }
  3830.            
  3831.  
  3832.         }
  3833. }
  3834.  
  3835. //------------------------------------------------------------------------------
  3836. // CMDraft: FlushVersion
  3837. //------------------------------------------------------------------------------
  3838.  
  3839. SOM_Scope void  SOMLINK CMDraftFlushVersion(CMDraft *somSelf, Environment *ev)
  3840. {
  3841.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3842.     CMDraftMethodDebug("CMDraft","FlushVersion");
  3843.  
  3844. }
  3845.  
  3846. //------------------------------------------------------------------------------
  3847. // CMDraft: Reinitialize
  3848. //------------------------------------------------------------------------------
  3849.  
  3850. SOM_Scope void  SOMLINK CMDraftReinitialize(CMDraft *somSelf, Environment *ev,
  3851.                 ODDraftPermissions perms)
  3852. {
  3853.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3854.     CMDraftMethodDebug("CMDraft","Reinitialize");
  3855.  
  3856.  
  3857.    try
  3858.    {
  3859.         if ((perms == kODDPExclusiveWrite) &&
  3860.                 (_fEmbeddedContainer != kODNULL) &&
  3861.                 (_fEmbeddedContainer->GetUseMode(ev) & kCMReading)) {
  3862.                 MyDebugStr("Reinitialize.\n");
  3863.                 THROW(kODErrInvalidPermissions);
  3864.         }
  3865.  
  3866.         // Close this version first
  3867.  
  3868.         // somSelf->CloseVersion(ev);
  3869.  
  3870.         // Set the permissions
  3871.  
  3872.         _fPermissions = perms;
  3873.  
  3874.         // Open or create a new version
  3875.  
  3876.         if (_fEmbeddedContainer == kODNULL) {
  3877. #if lazyOpen
  3878.                 _fExternalized = kODFalse;
  3879. #else
  3880.                 if (_fPermissions == kODDPReadOnly)
  3881.                         somSelf->OpenVersion(ev);
  3882.                 else
  3883.                         somSelf->CreateVersion(ev);
  3884. #endif
  3885.         }
  3886.  
  3887.         //_fDocument->Reopen(ev);
  3888.  
  3889.     }
  3890.     catch (ODException _exception)
  3891.     {
  3892.          ODSetSOMException(ev, _exception);
  3893.     }
  3894. }
  3895.  
  3896. //------------------------------------------------------------------------------
  3897. // CMDraft: Open
  3898. //------------------------------------------------------------------------------
  3899.  
  3900. SOM_Scope void  SOMLINK CMDraftOpen(CMDraft *somSelf, Environment *ev)
  3901. {
  3902.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3903.     CMDraftMethodDebug("CMDraft","Open");
  3904.  
  3905.      try
  3906.      {
  3907.  
  3908.         if (_fEmbeddedContainer == kODNULL) {
  3909. #if lazyOpen
  3910.                 _fExternalized = kODFalse;
  3911. #else
  3912.                 if (_fPermissions == kODDPReadOnly)
  3913.                         somSelf->OpenVersion(ev);
  3914.                 else
  3915.                         somSelf->CreateVersion(ev);
  3916. #endif
  3917.         }
  3918.  
  3919.      }
  3920.      catch (ODException _exception)
  3921.      {
  3922.          ODSetSOMException(ev, _exception);
  3923.      }
  3924. }
  3925.  
  3926. #pragma segment CMDraft2
  3927.  
  3928. //------------------------------------------------------------------------------
  3929. // CMDraft: Close
  3930. //------------------------------------------------------------------------------
  3931.  
  3932. SOM_Scope void  SOMLINK CMDraftClose(CMDraft *somSelf, Environment *ev)
  3933. {
  3934.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3935.     CMDraftMethodDebug("CMDraft","Close");
  3936.  
  3937.  
  3938.     try
  3939.     {
  3940. #if ODDebug_Drafts
  3941.         somPrintf("CMDraftClose: %d\n", somSelf->GetID(ev));
  3942. #endif
  3943.  
  3944. #if lazyOpen
  3945.         if (_fEmbeddedContainer != kODNULL) {
  3946.  
  3947.                 CMContainer cmContainer = somSelf->GetCMContainer(ev);
  3948.                 ODSessionMustHaveCMAllocReserve(cmContainer);
  3949.                 // AcquireDraftPropertiesObject() makes CM calls:
  3950.  
  3951.                 CMObject draftPropertiesObject = AcquireDraftPropertiesObject(somSelf->GetCMContainer(ev));
  3952.                 if (draftPropertiesObject == kODNULL)
  3953.                         THROW(kODErrNoDraftProperties);
  3954.  
  3955.                 CMKeepObject(draftPropertiesObject);
  3956.  
  3957.                 ODSessionRestoreCMAllocReserve(cmContainer);
  3958.  
  3959.                 somSelf->CloseVersion(ev);
  3960.         }
  3961. #else
  3962.         somSelf->CloseVersion(ev);
  3963. #endif
  3964.  
  3965.      }
  3966.      catch (ODException _exception)
  3967.      {
  3968.          ODSetSOMException(ev, _exception);
  3969.      }
  3970. }
  3971.  
  3972. //------------------------------------------------------------------------------
  3973. // CMDraft: Abort
  3974. //------------------------------------------------------------------------------
  3975.  
  3976. SOM_Scope void  SOMLINK CMDraftAbort(CMDraft *somSelf, Environment *ev)
  3977. {
  3978.     CMDraftData *somThis = CMDraftGetData(somSelf);
  3979.     CMDraftMethodDebug("CMDraft","Abort");
  3980.  
  3981.  
  3982.      try
  3983.      {
  3984.         if (_fPermissions == kODDPReadOnly)
  3985.                 THROW(kODErrInvalidPermissions);
  3986.  
  3987.         if (_fDraftProperties != kODNULL) {
  3988.                 _fDraftProperties->Release(ev);
  3989.                 _fDraftProperties = kODNULL;
  3990.         }
  3991.  
  3992. #if TestFlushContainer
  3993.         if (_fRemoveChangeOnAbort) {
  3994.                 VersionList*    versionList = kODNULL;
  3995.  
  3996.                 versionList = _fDocument->TestAndGetVersionList(ev);
  3997.                 ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  3998.  
  3999.                 try
  4000.                 {
  4001.                         if (versionList->Exists(_fID) != kODFalse)
  4002.                                 versionList->RemoveChanges(_fID);
  4003.  
  4004.                 }
  4005.                 catch (ODException _exception)
  4006.                 {
  4007.                  ODError error = ErrorCode();
  4008.                     SaveEv();
  4009.                   try
  4010.                     {
  4011.                         _fDocument->ReleaseVersionList(ev);
  4012.                     }
  4013.                     catch(ODException _exception)
  4014.                     {
  4015.                          SetErrorCode(kODNoError);
  4016.                     }
  4017.                   RestoreEv();
  4018.                   ODSetSOMException(ev, error);
  4019.  
  4020.                         throw;
  4021.  
  4022.                 }
  4023.         }
  4024. #else
  4025.         _fDocument->InternalizeVersionList(ev);
  4026. #endif
  4027.         somSelf->DestroyVersion(ev);
  4028.         //      _fDocument->Reopen(ev);
  4029.  
  4030.      }
  4031.      catch (ODException _exception)
  4032.      {
  4033.           ODSetSOMException(ev, _exception);
  4034.      }
  4035. }
  4036.  
  4037. //------------------------------------------------------------------------------
  4038. // CMDraft: Flush
  4039. //------------------------------------------------------------------------------
  4040.  
  4041. SOM_Scope void  SOMLINK CMDraftFlush(CMDraft *somSelf, Environment *ev)
  4042. {
  4043.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4044.     CMDraftMethodDebug("CMDraft","Flush");
  4045.  
  4046.         if (_fPermissions == kODDPExclusiveWrite) {
  4047.                 try
  4048.                 {
  4049.                         somSelf->FlushVersion(ev);
  4050.                 }
  4051.                 catch (ODException _exception)
  4052.                 {
  4053.                     ODSetSOMException(ev, _exception);
  4054.                 }
  4055.         }
  4056. }
  4057.  
  4058.  
  4059. //------------------------------------------------------------------------------
  4060. // CMDraft: IsNewDraft
  4061. //------------------------------------------------------------------------------
  4062.  
  4063. SOM_Scope ODBoolean  SOMLINK CMDraftIsNewDraft(CMDraft *somSelf, Environment *ev)
  4064. {
  4065.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4066.     CMDraftMethodDebug("CMDraft","IsNewDraft");
  4067.  
  4068.         return _fIsNewDraft;
  4069. }
  4070.  
  4071. //------------------------------------------------------------------------------
  4072. // CMDraft: GetEmbeddedContainer
  4073. //------------------------------------------------------------------------------
  4074.  
  4075. SOM_Scope ODEmbeddedContainer*  SOMLINK CMDraftGetEmbeddedContainer(CMDraft *somSelf, Environment *ev)
  4076. {
  4077.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4078.     CMDraftMethodDebug("CMDraft","GetEmbeddedContainer");
  4079.  
  4080. #if lazyOpen
  4081.       try
  4082.       {
  4083.         if (_fEmbeddedContainer == kODNULL) {
  4084.                 if (_fPermissions == kODDPReadOnly)
  4085.                         somSelf->OpenVersion(ev);
  4086.                 else
  4087.                         somSelf->CreateVersion(ev);
  4088.         }
  4089.       }
  4090.       catch (ODException _exception)
  4091.       {
  4092.           ODSetSOMException(ev, _exception);
  4093.       }
  4094. #endif
  4095.  
  4096.         return _fEmbeddedContainer;
  4097. }
  4098.  
  4099. //------------------------------------------------------------------------------
  4100. // CMDraft: GetCMContainer
  4101. //------------------------------------------------------------------------------
  4102.  
  4103. SOM_Scope CMContainer  SOMLINK CMDraftGetCMContainer(CMDraft *somSelf, Environment *ev)
  4104. {
  4105.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4106.     CMDraftMethodDebug("CMDraft","GetCMContainer");
  4107.  
  4108.           CMContainer container = kODNULL;
  4109.      try
  4110.      {
  4111.  
  4112. #if lazyOpen
  4113.         if (_fEmbeddedContainer == kODNULL) {
  4114.                 if (_fPermissions == kODDPReadOnly)
  4115.                         somSelf->OpenVersion(ev);
  4116.                 else
  4117.                         somSelf->CreateVersion(ev);
  4118.         }
  4119. #endif
  4120.  
  4121.         if (_fEmbeddedContainer == kODNULL)
  4122.                 THROW(kODErrCannotGetDraftVersion);
  4123.         container =  _fEmbeddedContainer->GetCMContainer(ev);
  4124.  
  4125.      }
  4126.      catch (ODException _exception)
  4127.      {
  4128.          ODSetSOMException(ev, _exception);
  4129.      }
  4130.         return container;
  4131. }
  4132.  
  4133. //------------------------------------------------------------------------------
  4134. // AcquireDraftPropertiesObject
  4135. //------------------------------------------------------------------------------
  4136.  
  4137. // Callers must ODSessionMustHaveCMAllocReserve() first:
  4138.  
  4139. static CMObject AcquireDraftPropertiesObject(CMContainer container)
  4140. {
  4141.         CMObject                draftPropertiesObject = kODNULL;
  4142.         Environment* ev = somGetGlobalEnvironment();
  4143.    try
  4144.    {
  4145.         CMType                  rootSUType;
  4146.         CMProperty              rootSUProp;
  4147.         CMValue                 rootSU;
  4148.  
  4149.         CMContainerModeFlags    openMode;
  4150.  
  4151.         if ((rootSUType = CMRegisterType(container, kODStorageUnitType)) == kODNULL)
  4152.                 THROW(kODErrBentoInvalidType);
  4153.         if ((rootSUProp = CMRegisterProperty(container, kODPropRootSU)) == kODNULL)
  4154.                 THROW(kODErrBentoInvalidProperty);
  4155.         draftPropertiesObject = CMGetNextObjectWithProperty(container, kODNULL, rootSUProp);
  4156.  
  4157.         if (draftPropertiesObject == kODNULL) {
  4158.  
  4159.                 CMGetContainerInfo(container, kODNULL, kODNULL, kODNULL, kODNULL, &openMode);
  4160.                 if (openMode == kCMReading)
  4161.                         return kODNULL;
  4162.  
  4163.                 draftPropertiesObject = CMNewObject(container);
  4164.  
  4165.                 if ((rootSU = CMNewValue(draftPropertiesObject, rootSUProp, rootSUType)) == kODNULL)
  4166.                         THROW(kODErrBentoCannotNewValue);
  4167.                 CMWriteValueData(rootSU, "", 0, 0);
  4168.         }
  4169.     }
  4170.     catch (ODException _exception)
  4171.     {
  4172.        draftPropertiesObject = kODNULL;
  4173.        ODSetSOMException(ev, _exception);
  4174.     }
  4175.  
  4176.         return draftPropertiesObject;
  4177. }
  4178.  
  4179. //------------------------------------------------------------------------------
  4180. // GetVersionNameFromVersionID
  4181. //------------------------------------------------------------------------------
  4182.  
  4183. static ODType GetVersionNameFromVersionID(ODVersionID id, ODMemoryHeapID heapID)
  4184. {
  4185.         ODSByte*        versionName = kODNULL;
  4186.         Environment* ev = somGetGlobalEnvironment();
  4187.    try
  4188.    {
  4189.         ODSByte cString[kMaxStringSize];
  4190.  
  4191.         if (id != 0) {
  4192.                 CM_itoa(id, cString);   // KP
  4193.                 versionName = (ODSByte*) ODNewPtr(strlen(kODVersionNamePrefix) + strlen(cString) + 1, heapID);
  4194.                 strcpy(versionName, kODVersionNamePrefix);
  4195.                 strcat(versionName, cString);
  4196.         }
  4197.    }
  4198.    catch (ODException _exception)
  4199.    {
  4200.        versionName = kODNULL;
  4201.        ODSetSOMException(ev, _exception);
  4202.    }    
  4203.         return versionName;
  4204. }
  4205.  
  4206. //------------------------------------------------------------------------------
  4207. // CMDraft: RetrievePersistentObject
  4208. //------------------------------------------------------------------------------
  4209.  
  4210. SOM_Scope ODPersistentObject*  SOMLINK CMDraftRetrievePersistentObject(CMDraft *somSelf, Environment *ev,
  4211.                 ODStorageUnitID id)
  4212. {
  4213.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4214.     CMDraftMethodDebug("CMDraft","RetrievePersistentObject");
  4215.  
  4216.         ODPersistentObject*     object = kODNULL;
  4217.  
  4218.  
  4219.     try
  4220.     {
  4221.         if (_fPersistentObjects->GetValue(&id, &object))
  4222.                 object->Acquire(ev);
  4223.  
  4224.     }
  4225.     catch (ODException _exception)
  4226.     {
  4227.         object = kODNULL;
  4228.         ODSetSOMException(ev, _exception);
  4229.     }
  4230.         return object;
  4231. }
  4232.  
  4233. //------------------------------------------------------------------------------
  4234. // CMDraft: ReleasePersistentObject
  4235. //------------------------------------------------------------------------------
  4236.  
  4237. SOM_Scope void  SOMLINK CMDraftReleasePersistentObject(CMDraft *somSelf, Environment *ev,
  4238.                 ODPersistentObject* object)
  4239. {
  4240. //  CMDraftData *somThis = CMDraftGetData(somSelf);
  4241.     CMDraftMethodDebug("CMDraft","ReleasePersistentObject");
  4242.  
  4243.    try
  4244.    {
  4245.         if (object->GetRefCount(ev) != 0)
  4246.                 THROW(kODErrRefCountGreaterThanZero);
  4247.    }
  4248.    catch (ODException _exception)
  4249.    {
  4250.         ODSetSOMException(ev, _exception);
  4251.    }
  4252.  
  4253. }
  4254.  
  4255. //------------------------------------------------------------------------------
  4256. // CMDraft: RemovePersistentObject
  4257. //------------------------------------------------------------------------------
  4258.  
  4259. SOM_Scope void  SOMLINK CMDraftRemovePersistentObject(CMDraft *somSelf, Environment *ev,
  4260.                 ODPersistentObject* object)
  4261. {
  4262.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4263.     CMDraftMethodDebug("CMDraft","RemovePersistentObject");
  4264.  
  4265.     try
  4266.     {
  4267.         if (!object)
  4268.                 THROW(kODErrInvalidPersistentObject);
  4269.  
  4270.         ODStorageUnit*          su = object->GetStorageUnit(ev);
  4271.         ODStorageUnitID         id = object->GetID(ev);
  4272.         CMObject                        cmObject = kODNULL;
  4273.  
  4274.         if (id == kODNULLID)
  4275.                 THROW(kODErrInvalidPersistentObjectID);
  4276.  
  4277.         object->Release(ev);
  4278.  
  4279.         if (object->GetRefCount(ev) != 0)
  4280.                 THROW(kODErrRefCountGreaterThanZero);
  4281.  
  4282.         if ((su != kODNULL) && (su->GetRefCount(ev) != 1))
  4283.                 THROW(kODErrRefCountNotEqualOne);
  4284.  
  4285.         object->ReleaseAll(ev);
  4286.  
  4287.         _fPersistentObjects->RemoveEntry(&id);
  4288.         delete object;
  4289.  
  4290.         _fStorageUnits->RemoveEntry(&id);
  4291.         delete su;
  4292.  
  4293.         if (_fIDList->Exists(id) != kODFalse) {
  4294.                 cmObject = (CMObject) _fIDList->Get(id);
  4295.                 _fIDList->Remove(id);
  4296.  
  4297.                 CMContainer cmContainer = somSelf->GetCMContainer(ev);
  4298.                 ODSessionMustHaveCMAllocReserve(cmContainer);
  4299.  
  4300.                 if (cmObject != kODNULL)
  4301.                         CMDeleteObject(cmObject);
  4302.  
  4303.                 ODSessionRestoreCMAllocReserve(cmContainer);
  4304.         }
  4305.  
  4306.         somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  4307.  
  4308.      }
  4309.      catch (ODException _exception)
  4310.      {
  4311.          ODSetSOMException(ev, _exception);
  4312.      }
  4313. }
  4314.  
  4315. //------------------------------------------------------------------------------
  4316. // CMDraft: CreateCollections
  4317. //------------------------------------------------------------------------------
  4318.  
  4319. SOM_Scope void  SOMLINK CMDraftCreateCollections(CMDraft *somSelf, Environment *ev)
  4320. {
  4321.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4322.     CMDraftMethodDebug("CMDraft","CreateCollections");
  4323.  
  4324.     try
  4325.     {
  4326.         ODMemoryHeapID heap = somSelf->GetHeap(ev);
  4327.  
  4328. #ifdef _PLATFORM_MACINTOSH_
  4329.         _fPersistentObjects = new(heap)
  4330.                 OpenHashTable(OpenHashTable::StdEqual,
  4331.                               OpenHashTable::StdHash, heap);
  4332. #endif
  4333. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  4334. //      The use of heap is not implemented in Windows platform
  4335.         _fPersistentObjects = new OpenHashTable(OpenHashTable::StdEqual,
  4336.                               OpenHashTable::StdHash, 0);
  4337. #endif
  4338.         _fPersistentObjects->Initialize(kODInitialNumEntries,
  4339.                                         sizeof(ODStorageUnitID),
  4340.                                         sizeof(ODPersistentObject*));
  4341.  
  4342. #ifdef _PLATFORM_MACINTOSH_
  4343.         _fStorageUnits = new(heap)
  4344.                 OpenHashTable(OpenHashTable::StdEqual,
  4345.                               OpenHashTable::StdHash, heap);
  4346. #endif
  4347. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  4348. //      The use of heap is not implemented in Windows platform
  4349.         _fStorageUnits = new OpenHashTable(OpenHashTable::StdEqual,
  4350.                               OpenHashTable::StdHash, 0);
  4351. #endif
  4352.         _fStorageUnits->Initialize(kODInitialNumEntries,
  4353.                                    sizeof(ODStorageUnitID),
  4354.                                    sizeof(ODStorageUnit*));
  4355.  
  4356. #ifdef _PLATFORM_MACINTOSH_
  4357.         _fIDList = new(somSelf->GetHeap(ev)) IDList;
  4358. #endif
  4359. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  4360. //      The use of heap is not implemented in Windows platform
  4361.         _fIDList = new IDList;
  4362. #endif
  4363.         _fIDList->Initialize();
  4364.  
  4365.     }
  4366.     catch (ODException _exception)
  4367.     {
  4368.          ODSetSOMException(ev, _exception);
  4369.     }
  4370. }
  4371.  
  4372. //------------------------------------------------------------------------------
  4373. // CMDraft: DeleteCollections
  4374. //------------------------------------------------------------------------------
  4375.  
  4376. SOM_Scope void  SOMLINK CMDraftDeleteCollections(CMDraft *somSelf, Environment *ev)
  4377. {
  4378.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4379.     CMDraftMethodDebug("CMDraft","DeleteCollections");
  4380.  
  4381.    try
  4382.    {
  4383.         if (_fDraftProperties != kODNULL)
  4384.         {
  4385.                 _fDraftProperties->Release(ev);
  4386.                 _fDraftProperties = kODNULL;
  4387.         }
  4388.         if (_fPersistentObjects != kODNULL) {
  4389.                 ODStorageUnitID         id;
  4390.                 ODPersistentObject*     object;
  4391.                 OpenHashTableIterator   iter(_fPersistentObjects);
  4392.  
  4393.                 for (iter.First(&id, &object); iter.IsNotComplete(); iter.Next(&id, &object)) {
  4394.                         if (object != kODNULL) {
  4395.                                 try
  4396.                                 {
  4397.                                         object->ReleaseAll(ev);
  4398.                                 }
  4399.                                 catch (ODException _exception)
  4400.                                 {
  4401.                                         WARNMSG(WARN_INDEX(AMSG_620),
  4402.                                         "Exception thrown by object %x ID %x error %d\n",
  4403.                                         object, object->GetID(ev), ErrorCode());
  4404.                                 }
  4405.                         }
  4406.                 }
  4407.  
  4408.                 for (iter.First(&id, &object); iter.IsNotComplete(); iter.Next(&id, &object)) {
  4409.                         if (object != kODNULL) {
  4410.                                 delete object;
  4411.                         }
  4412.                 }
  4413.                 delete _fPersistentObjects;
  4414.                 _fPersistentObjects = kODNULL;
  4415.         }
  4416.  
  4417.         if (_fStorageUnits != kODNULL) {
  4418.                 ODStorageUnitID         id;
  4419.                 ODStorageUnit*                  su;
  4420.                 OpenHashTableIterator   iter(_fStorageUnits);
  4421.                 for (iter.First(&id, &su); iter.IsNotComplete(); iter.Next(&id, &su)) {
  4422.                         if (su != kODNULL) {
  4423.                                 delete su;
  4424.                         }
  4425.                 }
  4426.                 delete _fStorageUnits;
  4427.                 _fStorageUnits = kODNULL;
  4428.                 _fDraftProperties = kODNULL;
  4429.         }
  4430.  
  4431.         ODDeleteObject(_fIDList);
  4432.  
  4433.    }
  4434.    catch (ODException _exception)
  4435.    {
  4436.         ODSetSOMException(ev, _exception);
  4437.    }
  4438. }
  4439.  
  4440. //------------------------------------------------------------------------------
  4441. // CMDraft: ExternalizeCollections
  4442. //------------------------------------------------------------------------------
  4443.  
  4444. SOM_Scope void  SOMLINK CMDraftExternalizeCollections(CMDraft *somSelf, Environment *ev)
  4445. {
  4446.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4447.     CMDraftMethodDebug("CMDraft","ExternalizeCollections");
  4448.          
  4449.            ODBoolean acquired = kODFalse;
  4450.     try
  4451.     {
  4452.         ODID                                    id;
  4453.         ODStorageUnit*                  su;
  4454.  
  4455.         OpenHashTableIterator   persistentObjects(_fPersistentObjects);
  4456.         ODPersistentObject*     object;
  4457.  
  4458.         for (persistentObjects.First(&id, &object);
  4459.                         persistentObjects.IsNotComplete();
  4460.                         persistentObjects.Next(&id, &object)) {
  4461.            try
  4462.            {
  4463.                 // Temporarily bump the refcount to make sure that the object is
  4464.                 // in a valid state.
  4465.                 object->Acquire(ev);
  4466.                 acquired = kODTrue;
  4467.                 su = object->GetStorageUnit(ev);
  4468.                 if ((su != kODNULL) && (su->Exists(ev, kODNULL, kODNULL, 0) != kODFalse))
  4469.                 object->Externalize(ev);
  4470.                 object->Release(ev);
  4471.             }
  4472.             catch (ODException _exception)
  4473.             {
  4474.               ODError error = ErrorCode();
  4475.               SaveEv();
  4476.               try
  4477.               {
  4478.                 object->Release(ev);
  4479.               }
  4480.               catch(ODException _exception)
  4481.               {
  4482.                   SetErrorCode(kODNoError);
  4483.               }
  4484.               RestoreEv();
  4485.               ODSetSOMException(ev, error);
  4486.               throw;
  4487.             }
  4488.         }
  4489.  
  4490.         OpenHashTable                   suCollection(*_fStorageUnits);
  4491.         suCollection.InitAndCopyFrom(*_fStorageUnits);
  4492.         OpenHashTableIterator   storageUnits(&suCollection);
  4493.  
  4494.         for (storageUnits.First(&id, &su);
  4495.                         storageUnits.IsNotComplete();
  4496.                         storageUnits.Next(&id, &su)) {
  4497.                 // Temporarily bump the refcount to make sure that the object is
  4498.                 // in a valid state.
  4499.                 su->Acquire(ev);
  4500. #ifdef _NO_TMP_OBJS_
  4501.                 ODStorageUnit *tempSU = su; // ensure it's released
  4502. #else
  4503.                 TempODStorageUnit tempSU = su; // ensure it's released
  4504. #endif
  4505.                 if (su->Exists(ev, kODNULL, kODNULL, 0) != kODFalse)
  4506.                         su->Externalize(ev);
  4507. #ifdef _NO_TMP_OBJS_
  4508.                 tempSU->Release(ev);
  4509. #endif
  4510.         }
  4511.  
  4512.     }
  4513.     catch (ODException _exception)
  4514.     {
  4515.         ODSetSOMException(ev, _exception);
  4516.     }
  4517. }
  4518.  
  4519. //------------------------------------------------------------------------------
  4520. // CMDraft: CloseCollections
  4521. //------------------------------------------------------------------------------
  4522.  
  4523. SOM_Scope void  SOMLINK CMDraftCloseCollections(CMDraft *somSelf, Environment *ev)
  4524. {
  4525.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4526.     CMDraftMethodDebug("CMDraft","CloseCollections");
  4527.  
  4528.  
  4529.     try
  4530.     {
  4531.         somSelf->FailIfNotExclusiveWrite(ev);
  4532.  
  4533.         somSelf->Purge(ev, 0);
  4534.         PurgeAllStorageUnits(ev, _fStorageUnits, _fIDList); // purge SU, relase CMObjects
  4535.  
  4536.     }
  4537.     catch (ODException _exception)
  4538.     {
  4539.          ODSetSOMException(ev, _exception);
  4540.     } 
  4541.  
  4542. }
  4543.  
  4544. //------------------------------------------------------------------------------
  4545. // CMDraft: OpenCollections
  4546. //------------------------------------------------------------------------------
  4547.  
  4548. SOM_Scope void  SOMLINK CMDraftOpenCollections(CMDraft *somSelf, Environment *ev)
  4549. {
  4550.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4551.     CMDraftMethodDebug("CMDraft","OpenCollections");
  4552.  
  4553.  
  4554.    try
  4555.    {
  4556.         OpenHashTableIterator   storageUnits(_fStorageUnits);
  4557.  
  4558.         ODID                                    id;
  4559.         ODStorageUnit*                  su;
  4560.  
  4561.         for (storageUnits.First(&id, &su);
  4562.                         storageUnits.IsNotComplete();
  4563.                         storageUnits.Next(&id, &su)) {
  4564.                 su->Internalize(ev);
  4565.         }
  4566.    }
  4567.    catch (ODException _exception)
  4568.    {
  4569.         ODSetSOMException(ev, _exception);
  4570.    }
  4571.  
  4572. }
  4573.  
  4574. //------------------------------------------------------------------------------
  4575. // CMDraft: AreEmptyCollections
  4576. //------------------------------------------------------------------------------
  4577.  
  4578. SOM_Scope ODBoolean  SOMLINK CMDraftAreEmptyCollections(CMDraft *somSelf, Environment *ev)
  4579. {
  4580.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4581.     CMDraftMethodDebug("CMDraft","AreEmptyCollections");
  4582.  
  4583.            ODBoolean areEmptyCollections = kODTrue;
  4584.    try
  4585.    {
  4586.         OpenHashTableIterator   storageUnits(_fStorageUnits);
  4587.         OpenHashTableIterator   persistentObjects(_fPersistentObjects);
  4588.         ODID                                    id;
  4589.         ODPersistentObject*     object;
  4590.         ODStorageUnit*                  su;
  4591.  
  4592.         for (persistentObjects.First(&id, &object);
  4593.                         persistentObjects.IsNotComplete();
  4594.                         persistentObjects.Next(&id, &object)) {
  4595.                 if (object->GetRefCount(ev) > 0)
  4596.                         return kODFalse;
  4597.         }
  4598.  
  4599.         for (storageUnits.First(&id, &su); storageUnits.IsNotComplete(); storageUnits.Next(&id, &su)) {
  4600.                 if (su->GetRefCount(ev) > 0)
  4601.                         return kODFalse;
  4602.         }
  4603.  
  4604.     }
  4605.     catch (ODException _exception)
  4606.     {
  4607.          areEmptyCollections = kODFalse;
  4608.          ODSetSOMException(ev, _exception);
  4609.     }
  4610.  
  4611.         return areEmptyCollections;
  4612. }
  4613.  
  4614. //------------------------------------------------------------------------------
  4615. // CMDraft: NeedExternalizing
  4616. //------------------------------------------------------------------------------
  4617.  
  4618. SOM_Scope ODBoolean  SOMLINK CMDraftNeedExternalizing(CMDraft *somSelf, Environment *ev)
  4619. {
  4620.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4621.     CMDraftMethodDebug("CMDraft","NeedExternalizing");
  4622.  
  4623.         return _fExternalized;
  4624. }
  4625.  
  4626.  
  4627. //------------------------------------------------------------------------------
  4628. // CMDraft: GetIDList
  4629. //------------------------------------------------------------------------------
  4630.  
  4631. SOM_Scope IDList*  SOMLINK CMDraftGetIDList(CMDraft *somSelf, Environment *ev)
  4632. {
  4633.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4634.     CMDraftMethodDebug("CMDraft","GetIDList");
  4635.  
  4636.         return _fIDList;
  4637. }
  4638.  
  4639. //------------------------------------------------------------------------------
  4640. // CMDraft: IsChangedFromPrev
  4641. //------------------------------------------------------------------------------
  4642.  
  4643. SOM_Scope ODBoolean  SOMLINK CMDraftIsChangedFromPrev(CMDraft *somSelf, Environment *ev,
  4644.                 VersionList* versionList)
  4645. {
  4646.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4647.     CMDraftMethodDebug("CMDraft","IsChangedFromPrev");
  4648.  
  4649.         ODBoolean               changedFromPrev = kODFalse;
  4650.         ODVersionID     prevVersionID;
  4651.         ODDraftID               prevDraftID;
  4652.  
  4653.         // If this draft has been modified, return kODTrue.
  4654.  
  4655.         if (_fChangedFromPrev != kODFalse)
  4656.                 return kODTrue;
  4657.  
  4658.         // versionList->ChangedFromPrev is accurate only when the draft is
  4659.         // opened read-only. Therefore, additional check is needed to ensure that
  4660.         // we don't return kODTrue even when the draft has not be changed.
  4661.  
  4662.         try
  4663.         {
  4664.                 changedFromPrev = versionList->ChangedFromPrev(_fID);
  4665.  
  4666.                 if ((changedFromPrev != kODFalse) && (_fPermissions == kODDPExclusiveWrite)) {
  4667.                         prevDraftID = versionList->GetPreviousDraftID(_fID);
  4668.                         prevVersionID = versionList->GetDraft(prevDraftID);
  4669.                         if (prevVersionID == _fPrevVersionID)
  4670.                                 changedFromPrev = kODFalse;
  4671.                 }
  4672.         }
  4673.         catch (ODException _exception)
  4674.         {
  4675.             changedFromPrev = kODFalse;
  4676.             ODSetSOMException(ev, _exception);
  4677.         }
  4678.  
  4679.         return changedFromPrev;
  4680. }
  4681.  
  4682. //------------------------------------------------------------------------------
  4683. // CMDraft: BeginClone
  4684. //------------------------------------------------------------------------------
  4685.  
  4686. SOM_Scope ODDraftKey  SOMLINK CMDraftBeginClone(CMDraft *somSelf, Environment *ev,
  4687.                 ODDraft* destDraft,
  4688.                 ODFrame* destFrame,
  4689.                 ODCloneKind kind)
  4690. {
  4691.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4692.     CMDraftMethodDebug("CMDraft","BeginClone");
  4693.  
  4694.         OpenHashTable* clonedSUIDs = kODNULL;           ODVolatile(clonedSUIDs);
  4695.         OpenHashTable* weakClonedSUIDs = kODNULL;       ODVolatile(weakClonedSUIDs);
  4696.  
  4697.         ODDraftKey result = 0;
  4698.  
  4699.         try
  4700.         {
  4701.  
  4702. #ifdef _PLATFORM_OS2_          // $$$ dcp # 120111 05/09/95
  4703.         if(destDraft==kODNULL)
  4704.            THROW(kODErrInvalidParameter);
  4705. #endif
  4706.  
  4707.                 // Allow beginning a new clone into a link if a clone from a link
  4708.                 // is in progress; common if the link contains promises
  4709.                 if ( (kind == kODCloneToLink) && (_fCloneKind == kODCloneFromLink) )
  4710.                 {
  4711.                         if ( _fLockCount > 1 )
  4712.                                 THROW(kODErrCloningInProgress);
  4713.                 }
  4714.                 else if (_fLockCount > 0)
  4715. #ifdef _PLATFORM_OS2_
  4716.                 {
  4717. //                 THROW(kODErrCloningInProgress);
  4718.                    // The sleep loop will allow multi-threads entering this same mehtod
  4719.                    // by gating each thread's operation.
  4720.                    // defect 27471
  4721.                    while (_fLockCount > 0) {
  4722.                           DosSleep(1000);
  4723.                          } /* endwhile */
  4724.                 }
  4725. #endif // OS2
  4726. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_AIX_)
  4727.                         THROW(kODErrCloningInProgress);
  4728. #endif // WIN32 or AIX
  4729.  
  4730. #ifdef DebugClone
  4731.                 somPrintf("\nCMDraft::BeginClone - ");
  4732.                 switch (kind)
  4733.                 {
  4734.                 case kODCloneCut:               somPrintf("Cut\n"); break;
  4735.                 case kODCloneCopy:              somPrintf("Copy\n"); break;
  4736.                 case kODClonePaste:             somPrintf("Paste\n"); break;
  4737.                 case kODCloneDropCopy:  somPrintf("Drop Copy\n"); break;
  4738.                 case kODCloneDropMove:  somPrintf("Drop Move\n"); break;
  4739.                 case kODCloneToLink:    somPrintf("To Link\n"); break;
  4740.                 case kODCloneFromLink:  somPrintf("From Link\n"); break;
  4741.                 case kODCloneAll:               somPrintf("All\n"); break;
  4742.                 case kODCloneToFile:    somPrintf("To File\n"); break;
  4743.                 default:                                somPrintf("Invalid clone kind!\n"); break;
  4744.                 }
  4745. #endif
  4746.  
  4747.                 // Validate the clone kind parameter
  4748.                 switch (kind)
  4749.                 {
  4750.                 case kODClonePaste:
  4751.                 case kODCloneDropCopy:
  4752.                 case kODCloneDropMove:
  4753.                 case kODCloneToFile:
  4754.                         {
  4755.                         ODCloneKind origCloneKind = GetOriginalCloneKind(ev, somSelf);
  4756.                         if ( (origCloneKind != kODCloneCut) && (origCloneKind != kODCloneCopy) )
  4757.                                 THROW(kODErrInconsistentCloneKind);
  4758.                         }
  4759.                         if ( somSelf == destDraft )
  4760.                                 THROW(kODErrInvalidDestinationDraft);
  4761.                         break;
  4762.                 case kODCloneCut:
  4763.                 case kODCloneCopy:
  4764.                 #ifdef _PLATFORM_OS2_
  4765.                 #else
  4766.                         if ( somSelf == destDraft )
  4767.                                 THROW(kODErrInvalidDestinationDraft);
  4768.                 #endif
  4769.                         break;
  4770.  
  4771.                 #ifdef _PLATFORM_OS2_
  4772.                 case kODCloneToLink:
  4773.                   if ( somSelf != destDraft )
  4774.                      THROW(kODErrInvalidDestinationDraft);
  4775.                   break;
  4776.  
  4777.                 case kODCloneAll:
  4778.                 case kODCloneFromLink:
  4779.                 break;
  4780.                 #else
  4781.  
  4782.                 case kODCloneToLink:
  4783.                 case kODCloneFromLink:
  4784.                         if ( somSelf != destDraft )
  4785.                                 THROW(kODErrInvalidDestinationDraft);
  4786.                         break;
  4787.  
  4788.                 case kODCloneAll:
  4789.                         break;
  4790.                 #endif
  4791.  
  4792.                 default:
  4793.                         THROW(kODErrInvalidCloneKind);
  4794.                         break;
  4795.                 }
  4796.  
  4797.                 ODMemoryHeapID heap = somSelf->GetHeap(ev);
  4798.  
  4799.                 // Ensure both hash tables can be allocated
  4800.                 if ( _fLockCount == 0 )
  4801.                 {
  4802. #ifdef _PLATFORM_MACINTOSH_
  4803.                         clonedSUIDs = new(heap)
  4804.                                 OpenHashTable(OpenHashTable::StdEqual,
  4805.                                               OpenHashTable::StdHash, heap);
  4806. #endif
  4807. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  4808. //                      The use of heap is not implemented in Windows platform
  4809.                         clonedSUIDs = new OpenHashTable(OpenHashTable::StdEqual,
  4810.                                               OpenHashTable::StdHash, 0);
  4811. #endif
  4812.                         clonedSUIDs->Initialize(kInitialHashTableEntries,
  4813.                                                   sizeof(ODStorageUnitID),
  4814.                                                   sizeof(ODStorageUnitID));
  4815.  
  4816.                         if ( (kind == kODCloneCut) || (kind == kODCloneCopy) )
  4817.                                 ReadClonedObjectTable(ev, clonedSUIDs, destDraft);
  4818.                 }
  4819.  
  4820. #ifdef _PLATFORM_MACINTOSH_
  4821.                 weakClonedSUIDs = new(heap)
  4822.                         OpenHashTable(OpenHashTable::StdEqual,
  4823.                                       OpenHashTable::StdHash, heap);
  4824. #endif
  4825. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  4826. //              The use of heap is not implemented in Windows platform
  4827.                 weakClonedSUIDs = new OpenHashTable(OpenHashTable::StdEqual,
  4828.                                       OpenHashTable::StdHash, 0);
  4829. #endif
  4830.                 weakClonedSUIDs->Initialize(kInitialHashTableEntries,
  4831.                                               sizeof(ODStorageUnitID),
  4832.                                               sizeof(ODStorageUnitID));
  4833.  
  4834.                 // BeginClone must not fail beyond this point
  4835.  
  4836.                 _fLockCount++;
  4837.  
  4838.                 if ( _fLockCount == 1 )
  4839.                 {
  4840.                         _fCurrentKey++;
  4841.                         _fCloneKind = kind;
  4842.                         _fDestDraft = destDraft;
  4843.                         _fDestFrame = destFrame;
  4844.  
  4845.                         _fAnyFrameCloned = kODFalse;
  4846.                         _fRootPartReused = kODFalse;
  4847.  
  4848.                         _fClonedSUIDs = clonedSUIDs;
  4849.                 }
  4850.  
  4851.                 _fSavedWeakClonedSUIDs = _fWeakClonedSUIDs;
  4852.                 _fWeakClonedSUIDs = weakClonedSUIDs;
  4853.  
  4854.                 result = _fCurrentKey;
  4855.  
  4856.         }
  4857.         catch (ODException _exception)
  4858.         {
  4859.  
  4860.              result = 0;
  4861.              ODSetSOMException(ev, _exception);
  4862.              ODDeleteObject(clonedSUIDs);
  4863.              ODDeleteObject(weakClonedSUIDs);
  4864.  
  4865.         }
  4866.  
  4867.         return result;
  4868. }
  4869.  
  4870. //------------------------------------------------------------------------------
  4871. // CMDraft: GetClonedSUIDs
  4872. //------------------------------------------------------------------------------
  4873.  
  4874. SOM_Scope OpenHashTable*  SOMLINK CMDraftGetClonedSUIDs(CMDraft *somSelf, Environment *ev,
  4875.                 ODDraft* destDraft)
  4876. {
  4877.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4878.     CMDraftMethodDebug("CMDraft","GetClonedSUIDs");
  4879.     try
  4880.     {
  4881.  
  4882.         if ((_fDestDraft != kODNULL) && (_fDestDraft != destDraft)) {
  4883.                 ODDeleteObject(_fClonedSUIDs);
  4884.                 ODDeleteObject(_fWeakClonedSUIDs);
  4885.                 THROW(kODErrInvalidDestinationDraft);
  4886.         }
  4887.         _fDestDraft = destDraft;
  4888.     }
  4889.     catch (ODException _exception)
  4890.     {
  4891.         ODSetSOMException(ev, _exception);
  4892.         return kODNULL;
  4893.     }
  4894.  
  4895.         return _fClonedSUIDs;
  4896. }
  4897.  
  4898. //------------------------------------------------------------------------------
  4899. // CMDraft: EndClone
  4900. //------------------------------------------------------------------------------
  4901.  
  4902. SOM_Scope void  SOMLINK CMDraftEndClone(CMDraft *somSelf, Environment *ev,
  4903.                 ODDraftKey key)
  4904. {
  4905.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4906.     CMDraftMethodDebug("CMDraft","EndClone");
  4907.  
  4908.         ODStorageUnitID         fromID;
  4909.         ODStorageUnitID         toID;
  4910.  
  4911.     try
  4912.     {
  4913.  
  4914.         if ((key != _fCurrentKey) || (_fLockCount == 0))
  4915.                 THROW(kODErrInvalidDraftKey);
  4916.  
  4917.         OpenHashTableIterator iter(_fWeakClonedSUIDs);
  4918.         for (iter.First(&fromID, &toID); iter.IsNotComplete(); iter.Next(&fromID, &toID)) {
  4919.                 if (toID != 0) {
  4920.                         ODStorageUnit* toSU = _fDestDraft->AcquireStorageUnit(ev, toID);
  4921. #ifdef DebugClone
  4922.                         somPrintf("Removing %d %d\n", toID, ((CMStorageUnit*) toSU)->GetObjectID(ev));
  4923. #endif
  4924.                         _fDestDraft->RemoveStorageUnit(ev, toSU);
  4925.                 }
  4926.         }
  4927.  
  4928.         switch (_fCloneKind)
  4929.         {
  4930.         case kODCloneCopy:
  4931.         case kODCloneCut:
  4932.                 SetOriginalDraft(ev, _fDestDraft, somSelf);
  4933.                 if ( !OriginalCloneKindExists(ev, _fDestDraft) )
  4934.                         SetOriginalCloneKind(ev, _fDestDraft, _fCloneKind);
  4935.                 WriteClonedObjectTable(ev, _fClonedSUIDs, _fDestDraft);
  4936.                 break;
  4937.  
  4938.         case kODClonePaste:
  4939.         case kODCloneDropCopy:
  4940.         case kODCloneDropMove:
  4941.         case kODCloneToFile:
  4942.                 if ( (_fCloneKind == kODClonePaste) && (GetOriginalCloneKind(ev, somSelf) == kODCloneCut) )
  4943.                         SetOriginalCloneKind(ev, somSelf, kODCloneCopy);
  4944.                 break;
  4945.  
  4946.         default:
  4947.                 break;
  4948.         }
  4949.  
  4950.         if ( somSelf->GetCloneKind(ev) == kODCloneDropMove )
  4951.         {
  4952.                 if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
  4953.                 {
  4954.                         if ( _fAnyFrameCloned )
  4955.                         {
  4956.                                 if ( somSelf->ContainingPartInClone(ev, _fDestFrame) )
  4957.                                         THROW(kODErrMoveIntoSelf);
  4958.                         }
  4959.                 }
  4960.         }
  4961.  
  4962.         --_fLockCount;
  4963.  
  4964.         if ( _fLockCount == 0 )
  4965.         {
  4966.                 _fDestDraft = kODNULL;
  4967.                 _fDestFrame = kODNULL;
  4968.  
  4969.                 ODDeleteObject(_fClonedSUIDs);
  4970.         }
  4971.  
  4972.         ODDeleteObject(_fWeakClonedSUIDs);
  4973.         _fWeakClonedSUIDs = _fSavedWeakClonedSUIDs;
  4974.  
  4975. #ifdef DebugClone
  4976.         somPrintf("CMDraft::EndClone - Clone completed\n\n");
  4977. #endif
  4978.  
  4979.     }
  4980.     catch (ODException _exception)
  4981.     {
  4982.        ODSetSOMException(ev, _exception);
  4983.     }
  4984. }
  4985.  
  4986. //------------------------------------------------------------------------------
  4987. // CMDraft: AbortClone
  4988. //------------------------------------------------------------------------------
  4989.  
  4990. SOM_Scope void  SOMLINK CMDraftAbortClone(CMDraft *somSelf, Environment *ev,
  4991.                 ODDraftKey key)
  4992. {
  4993.     CMDraftData *somThis = CMDraftGetData(somSelf);
  4994.     CMDraftMethodDebug("CMDraft","AbortClone");
  4995.  
  4996.    try
  4997.    {
  4998.  
  4999. #if ODDebug_Drafts
  5000.         somPrintf("CMDraftAbort: %d\n", somSelf->GetID(ev));
  5001. #endif
  5002.  
  5003.         if ((key != _fCurrentKey) || (_fLockCount == 0))
  5004.                 THROW(kODErrInvalidDraftKey);
  5005.  
  5006.         --_fLockCount;
  5007.  
  5008.         if ( _fLockCount == 0 )
  5009.         {
  5010.                 _fDestDraft = kODNULL;
  5011.                 _fDestFrame = kODNULL;
  5012.  
  5013.                 ODDeleteObject(_fClonedSUIDs);
  5014.         }
  5015.  
  5016.         ODDeleteObject(_fWeakClonedSUIDs);
  5017.         _fWeakClonedSUIDs = _fSavedWeakClonedSUIDs;
  5018.  
  5019.    }
  5020.    catch (ODException _exception)
  5021.    {
  5022.        ODSetSOMException(ev, _exception);
  5023.    }
  5024. }
  5025.  
  5026. //------------------------------------------------------------------------------
  5027. // CMDraft: SetOriginalID
  5028. //------------------------------------------------------------------------------
  5029.  
  5030. SOM_Scope void  SOMLINK CMDraftSetOriginalID(CMDraft *somSelf, Environment* ev,
  5031.                 ODStorageUnitID destID,
  5032.                 ODStorageUnitID originalID)
  5033. {
  5034.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5035.     CMDraftMethodDebug("CMDraft","SetOriginalID");
  5036.  
  5037.     try
  5038.     {
  5039.  
  5040. #ifdef _NO_TMP_OBJS_
  5041.         ODStorageUnit *destSU = _fDestDraft->AcquireStorageUnit(ev, destID);
  5042. #else
  5043.         TempODStorageUnit destSU = _fDestDraft->AcquireStorageUnit(ev, destID);
  5044. #endif
  5045.         ODSetULongProp(ev, destSU, kODPropOriginalID, kODULong, originalID);
  5046. #ifdef _NO_TMP_OBJS_
  5047.         destSU->Release(ev);
  5048. #endif
  5049.  
  5050.     }
  5051.     catch (ODException _exception)
  5052.     {
  5053.         ODSetSOMException(ev, _exception);
  5054.     }
  5055. }
  5056.  
  5057. //------------------------------------------------------------------------------
  5058. // CMDraft: GetOriginalID
  5059. //------------------------------------------------------------------------------
  5060. // An original ID may not be present in the root storage unit of the draft,
  5061. // since this SU is often constructed in place rather than cloned.
  5062. // An null object ID is returned if the property is not present.
  5063.  
  5064. SOM_Scope ODStorageUnitID  SOMLINK CMDraftGetOriginalID(CMDraft *somSelf, Environment* ev,
  5065.                 ODStorageUnitID fromID)
  5066. {
  5067.     //CMDraftData *somThis = CMDraftGetData(somSelf);
  5068.     CMDraftMethodDebug("CMDraft","GetOriginalID");
  5069.  
  5070.         ODStorageUnitID retSID = 0;
  5071.  
  5072.     try
  5073.     {
  5074. #ifdef _NO_TMP_OBJS_
  5075.         ODStorageUnit *fromSU = somSelf->AcquireStorageUnit(ev, fromID);
  5076. #else
  5077.         TempODStorageUnit fromSU = somSelf->AcquireStorageUnit(ev, fromID);
  5078. #endif
  5079.  
  5080.         retSID = (ODStorageUnitID)ODGetULongProp(ev, fromSU, kODPropOriginalID, kODULong);
  5081.     }
  5082.     catch (ODException _exception)
  5083.     {
  5084.         ODSetSOMException(ev, _exception);
  5085.     }
  5086.         return retSID;
  5087. }
  5088.  
  5089. //------------------------------------------------------------------------------
  5090. // CheckPartAction
  5091. //------------------------------------------------------------------------------
  5092.  
  5093. static ODBoolean CheckPartAction(void* k, void* v, ODULong s, void* r)
  5094. {
  5095.         Environment*    ev = somGetGlobalEnvironment();
  5096.         ODBoolean               result = kODFalse;
  5097.    try
  5098.    {
  5099.         ODID                    originalID =  * (ODID *) k;
  5100.         ODID                    interupdateID = * (ODID *) v;
  5101.         OpenHashTable*  targetParts = (OpenHashTable*) r;
  5102.  
  5103.         // Note that storage units in the original document draft may not be up to date
  5104.         // if changes have not been externalized.  In particular, a frame's storage
  5105.         // unit may not have a valid reference to its part's storage unit.  For this
  5106.         // reason, use the storage units in the data interchange draft instead.
  5107.  
  5108. #ifdef DebugClone
  5109.         somPrintf("interupdateID %d, originalID %d\n", interupdateID, originalID);
  5110. #endif
  5111.  
  5112. #ifdef _NO_TMP_OBJS_
  5113.         ODStorageUnit *interchangeSU = ::sInterchangeDraft->AcquireStorageUnit(ev, interupdateID);
  5114. #else
  5115.         TempODStorageUnit interchangeSU = ::sInterchangeDraft->AcquireStorageUnit(ev, interupdateID);
  5116. #endif
  5117.         if ( ODSUExistsThenFocus(ev, interchangeSU, kODPropStorageUnitType, kODISOStr) )
  5118.         {
  5119.                 if ( interchangeSU->GetSize(ev) == ODISOStrLength(kODFrameObject)+1 )
  5120.                 {
  5121.                         ODULong size = ODISOStrLength(kODFrameObject)+1;
  5122.                         // Only read the same number of characters as in kODFrameObject, to prevent overwriting the
  5123.                         // terminating zero byte of the buffer.
  5124.                         if (ODGetISOStrProp(ev, interchangeSU, kODPropStorageUnitType, kODISOStr, (ODISOStr) ::sSUTypeBuffer, &size)
  5125.                                 != kODNULL)
  5126.                         {
  5127.                                 if (ODISOStrEqual(kODFrameObject, ::sSUTypeBuffer))
  5128.                                 {
  5129.                                         ODID interchangePartID = ODGetStrongSURefProp(ev, interchangeSU, kODPropPart, kODStrongStorageUnitRef);
  5130.                                         if ( interchangePartID == kODNULLID )
  5131.                                         {
  5132.                                                 // Note: If the reference isn't valid, ODGetStrongSURefProp will return
  5133.                                                 //   kODNULLID so it isn't necessary to call IsValidID instead.
  5134. #ifdef DebugClone
  5135.                                                 somPrintf("Invalid part reference from frame id %d\n", interupdateID);
  5136. #endif
  5137.                                                 result = kODTrue;       // Better safe than sorry!
  5138.                                         }
  5139.                                         else if ( interchangePartID != ::sRootPartIDToIgnore )
  5140.                                         {
  5141.                                                 ODID targetPartID = ::sInterchangeDraft->GetOriginalID(ev, interchangePartID);
  5142. #ifdef DebugClone
  5143.                                                 somPrintf("Checking part id %d from frame id %d\n", targetPartID, originalID);
  5144. #endif
  5145.                                                 result = targetParts->Exists(&targetPartID);
  5146.                                         }
  5147. #ifdef DebugClone
  5148.                                         else
  5149.                                         {
  5150.                                                 somPrintf("Skipping root part id %d because it was not cloned\n", interchangePartID);
  5151.                                         }
  5152. #endif
  5153.                                 }
  5154.                         }
  5155.                 }
  5156.         }
  5157.  
  5158. #ifdef _NO_TMP_OBJS_
  5159.         interchangeSU->Release(ev);
  5160. #endif
  5161.     }
  5162.     catch (ODException _exception)
  5163.     {
  5164.         ODSetSOMException(ev, _exception);
  5165.     }
  5166.         return result;
  5167. }
  5168.  
  5169. //------------------------------------------------------------------------------
  5170. // CMDraft: ContainingPartInClone
  5171. //------------------------------------------------------------------------------
  5172.  
  5173. SOM_Scope ODBoolean  SOMLINK CMDraftContainingPartInClone(CMDraft *somSelf, Environment* ev,
  5174.                 ODFrame* targetFrame)
  5175. {
  5176.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5177.     CMDraftMethodDebug("CMDraft","ContainingPartInClone");
  5178.  
  5179.         ODBoolean               result = kODFalse;
  5180.         ODFrame*                frame;
  5181.         ODFrame*                nextFrame;
  5182.         ODID                    partID;
  5183.  
  5184.         OpenHashTable* targetParts = kODNULL;
  5185.         OpenHashTable* clonedSUIDs = kODNULL;
  5186.  
  5187.         try
  5188.         {
  5189.  
  5190.                 ODMemoryHeapID  heap = somSelf->GetHeap(ev);
  5191.  
  5192. #ifdef DebugClone
  5193.                 somPrintf("ContainingPartInClone called with target frame id %d <%x>\n", targetFrame->GetID(ev), targetFrame);
  5194. #endif
  5195.  
  5196. #ifdef _PLATFORM_MACINTOSH_
  5197.                 OpenHashTable* targetParts = new(heap) OpenHashTable(OpenHashTable::StdEqual,
  5198.                                                                                                         OpenHashTable::StdHash,
  5199.                                                                                                         heap);
  5200. #endif
  5201. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  5202. //              The use of heap is not implemented in Windows platform
  5203.                 OpenHashTable* targetParts = new OpenHashTable(OpenHashTable::StdEqual,
  5204.                                                         OpenHashTable::StdHash,
  5205.                                                         0);
  5206. #endif
  5207.                 targetParts->Initialize(kInitialHashTableEntries, sizeof(ODID), 0, kODTrue);
  5208.  
  5209.                 // Build a table of parts that own or embed the target frame
  5210.                 frame = targetFrame;
  5211.                 if ( frame )
  5212.                         frame->Acquire(ev);
  5213.                 while ( frame != kODNULL )
  5214.                 {
  5215. #ifdef _NO_TMP_OBJS_
  5216.                         ODFrame *tempFrame = frame; // ensure it's released
  5217. #else
  5218.                         TempODFrame tempFrame = frame; // ensure it's released
  5219. #endif
  5220.                         ODPart* part = frame->AcquirePart(ev);
  5221.                         partID = part->GetID(ev);
  5222.                         part->Release(ev);
  5223. #ifdef DebugClone
  5224.                         somPrintf("Adding target part id %d from frame id %d\n", partID, frame->GetID(ev));
  5225. #endif
  5226.                         targetParts->ReplaceEntry(&partID, kODNULL);
  5227.  
  5228.                         nextFrame = frame->AcquireContainingFrame(ev);
  5229.                         if ( nextFrame == kODNULL )
  5230.                         {
  5231. #ifdef _NO_TMP_OBJS_
  5232.                                 { ODWindow *window = frame->AcquireWindow(ev);
  5233. #else
  5234.                                 { TempODWindow window = frame->AcquireWindow(ev);
  5235. #endif
  5236.                                   nextFrame = window->AcquireSourceFrame(ev);
  5237. #ifdef _NO_TMP_OBJS_
  5238.                                 window->Release(ev);
  5239. #endif
  5240.                                 }
  5241.  
  5242.                                 // The source frame always displays the same part, so skip to its containing frame.
  5243.                                 // Note that it must have a containing frame.
  5244.                                 if ( nextFrame != kODNULL )
  5245.                                 {
  5246. #ifdef _NO_TMP_OBJS_
  5247.                                         ODFrame *sourceFrame = nextFrame;
  5248. #else
  5249.                                         TempODFrame sourceFrame = nextFrame;
  5250. #endif
  5251.                                         nextFrame = sourceFrame->AcquireContainingFrame(ev);
  5252. #ifdef _NO_TMP_OBJS_
  5253.                                         sourceFrame->Release(ev);
  5254. #endif
  5255.                                 }
  5256.                         }
  5257.                         frame = nextFrame;
  5258. #ifdef _NO_TMP_OBJS_
  5259.                 tempFrame->Release(ev);
  5260. #endif
  5261.                 }
  5262.  
  5263. #ifdef _PLATFORM_MACINTOSH_
  5264.                 clonedSUIDs = new(heap) OpenHashTable(OpenHashTable::StdEqual,
  5265.                                                                                 OpenHashTable::StdHash,
  5266.                                                                                 heap);
  5267. #endif
  5268. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  5269. //              The use of heap is not implemented in Windows platform
  5270.                 clonedSUIDs = new OpenHashTable(OpenHashTable::StdEqual,
  5271.                                                 OpenHashTable::StdHash,
  5272.                                                 0);
  5273. #endif
  5274.                 clonedSUIDs->Initialize(kInitialHashTableEntries,
  5275.                                           sizeof(ODStorageUnitID),
  5276.                                           sizeof(ODStorageUnitID));
  5277.  
  5278.                 // Get the table of objects cloned into the data interchange draft
  5279.                 ReadClonedObjectTable(ev, clonedSUIDs, somSelf);
  5280.  
  5281.                 // See if any frame of any target part is part of the clone
  5282.                 ::sInterchangeDraft = somSelf;
  5283.                 ::sSUTypeBuffer = (ODISOStr) ODNewPtrClear(ODISOStrLength(kODFrameObject) + 1);
  5284.                 ::sRootPartIDToIgnore = ( _fRootPartReused ? kODNULLID : RootPartID(ev, somSelf) );
  5285.  
  5286. //                This line of code is commented out because the object IDs 
  5287. //                stored in kODPropClonedObjectTable is not valid any more if
  5288. //                the drag and drop storage unit is closed and reopened. IDs
  5289. //                are not persistent objects and cannot be depended on. Since
  5290. //                the main purpose of function CheckPartAction is to prevent
  5291. //                drag and drop to the same frame and part and drag and drop
  5292. //                codes have receipe to prevent this from happen, comment out
  5293. //                this code should not create any ill problem.
  5294. //
  5295. //                result = clonedSUIDs->Walk(CheckPartAction, targetParts);
  5296.                 ODDisposePtr(::sSUTypeBuffer);
  5297.  
  5298.      }
  5299.      catch (ODException _exception)
  5300.      {
  5301.          result = kODFalse;
  5302.          ODSetSOMException(ev, _exception);
  5303.      }
  5304.  
  5305.  
  5306.         ODDeleteObject(targetParts);
  5307.         ODDeleteObject(clonedSUIDs);
  5308.  
  5309. #ifdef DebugClone
  5310.         somPrintf("ContainingPartInClone returns %d\n", result);
  5311. #endif
  5312.  
  5313.         return result;
  5314. }
  5315.  
  5316. //------------------------------------------------------------------------------
  5317. // CMDraft: ValidWeakReferenceProperty
  5318. //------------------------------------------------------------------------------
  5319.  
  5320. SOM_Scope ODBoolean  SOMLINK CMDraftValidWeakReferenceProperty(CMDraft *somSelf, Environment *ev,
  5321.         ODID                    objectID,
  5322.         ODPropertyName  propertyName)
  5323. {
  5324.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5325.     CMDraftMethodDebug("CMDraft","ValidWeakReferenceProperty");
  5326.  
  5327.         ODBoolean result = kODFalse;
  5328.  
  5329.         try
  5330.         {
  5331.  
  5332. #ifdef _NO_TMP_OBJS_
  5333.         ODStorageUnit *objectSU = somSelf->AcquireStorageUnit(ev, objectID);
  5334. #else
  5335.         TempODStorageUnit objectSU = somSelf->AcquireStorageUnit(ev, objectID);
  5336. #endif
  5337.         if (objectSU != kODNULL)
  5338.         {
  5339.                 result = (ODGetWeakSURefProp(ev, objectSU, propertyName, kODWeakStorageUnitRef) != 0);
  5340. //#ifdef DebugClone
  5341. //                      somPrintf("ValidWeakReferenceProperty: %s property does not exist.\n", propertyName);
  5342. //#endif
  5343.         }
  5344.  
  5345. #ifdef _NO_TMP_OBJS_
  5346.         objectSU->Release(ev);
  5347. #endif
  5348.  
  5349.         }
  5350.         catch (ODException _exception)
  5351.         {
  5352. #ifdef DebugClone
  5353.                 somPrintf("ValidWeakReferenceProperty: returning error.\n");
  5354. #endif
  5355.                 ODSetSOMException(ev, _exception);
  5356.                 result =  kODFalse;
  5357.         }
  5358.         return result;
  5359.  
  5360. }
  5361.  
  5362. //------------------------------------------------------------------------------
  5363. //  CMDraft: CloneCompanionObject
  5364. //------------------------------------------------------------------------------
  5365. // If fromID is a link or link source object, clone its companion.
  5366. // Note that kODNULLID is always used as the scopeID, since scope is irrelevant
  5367. // for link and link source objects.
  5368.  
  5369. SOM_Scope ODID  SOMLINK CMDraftCloneCompanionObject(CMDraft *somSelf, Environment *ev,
  5370.                 ODDraftKey key,
  5371.                 ODID fromID)
  5372. {
  5373.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5374.     CMDraftMethodDebug("CMDraft","CloneCompanionObject");
  5375.  
  5376.         ODID toID = kODNULLID;  ODVolatile(toID);
  5377.  
  5378.         try
  5379.         {
  5380.  
  5381.                 ODPropertyName companionProperty = kODNULL;
  5382.  
  5383.                 if ( IsLinkObject(ev, somSelf, fromID) )
  5384.                         companionProperty = kODPropLinkSource;
  5385.                 else if ( IsLinkSourceObject(ev, somSelf, fromID) )
  5386.                         companionProperty = kODPropLink;
  5387.  
  5388.                 if ( companionProperty != kODNULL )
  5389.                 {
  5390. #ifdef _NO_TMP_OBJS_
  5391.                         ODStorageUnit *objectSU = somSelf->AcquireStorageUnit(ev, fromID);
  5392. #else
  5393.                         TempODStorageUnit objectSU = somSelf->AcquireStorageUnit(ev, fromID);
  5394. #endif
  5395.                         if ( objectSU != kODNULL )
  5396.                         {
  5397.                                 ODStorageUnitID companionID = ODGetWeakSURefProp(ev, objectSU, companionProperty, kODWeakStorageUnitRef);
  5398.                                 if ( companionID != kODNULLID )
  5399.                                 {
  5400.                                         // Optimization: If the companion object has already been cloned,
  5401.                                         // there is no need to clone it again since scope is irrelevant for
  5402.                                         // these objects. [cc 9/28/95]
  5403.                                         _fClonedSUIDs->GetValue(&companionID, &toID);
  5404.                                         if ( toID == kODNULLID )
  5405.                                                 toID = somSelf->StrongClone(ev, key, companionID, kODNULLID, kODNULLID);
  5406.                                 }
  5407.                         }
  5408. #ifdef _NO_TMP_OBJS_
  5409.                         objectSU->Release(ev);
  5410. #endif
  5411.                 }
  5412.  
  5413.         }
  5414.         catch (ODException _exception)
  5415.         {
  5416.              toID = kODNULLID;
  5417.              ODSetSOMException(ev, _exception);
  5418.         }
  5419.  
  5420.         return toID;
  5421. }
  5422.  
  5423. //------------------------------------------------------------------------------
  5424. //  CMDraft: CompanionWasCloned
  5425. //------------------------------------------------------------------------------
  5426.  
  5427. SOM_Scope ODBoolean  SOMLINK CMDraftCompanionWasCloned(CMDraft *somSelf, Environment* ev,
  5428.                 ODStorageUnitID fromID,
  5429.                 ODPropertyName prop)
  5430. {
  5431.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5432.     CMDraftMethodDebug("CMDraft","CompanionWasCloned");
  5433.  
  5434.         ODBoolean result = kODFalse;
  5435.  
  5436.         try
  5437.         {
  5438.                 result= somSelf->ValidWeakReferenceProperty(ev, fromID, prop);
  5439.         }
  5440.         catch (ODException _exception)
  5441.         {
  5442.             ODSetSOMException(ev, _exception);
  5443.         }
  5444.         return result;
  5445. }
  5446.  
  5447. //------------------------------------------------------------------------------
  5448. //  CMDraft: GetCloneKind
  5449. //------------------------------------------------------------------------------
  5450.  
  5451. SOM_Scope ODCloneKind  SOMLINK CMDraftGetCloneKind(CMDraft *somSelf, Environment* ev)
  5452. {
  5453.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5454.     CMDraftMethodDebug("CMDraft","GetCloneKind");
  5455.  
  5456.         ODCloneKind cloneKind = _fCloneKind;
  5457.  
  5458.      try
  5459.      {
  5460.  
  5461.         if ( cloneKind == kODClonePaste )
  5462.         {
  5463.                 if ( (GetOriginalCloneKind(ev, somSelf) == kODCloneCut) && (GetOriginalDraft(ev, somSelf) == _fDestDraft) )
  5464.                         cloneKind = kODCloneDropMove;
  5465.                 else
  5466.                         cloneKind = kODCloneDropCopy;
  5467.         }
  5468.         else if ( cloneKind == kODCloneToFile )
  5469.         {
  5470.                 cloneKind = kODCloneDropCopy;
  5471.         }
  5472.  
  5473.      }
  5474.      catch (ODException _exception)
  5475.      {
  5476.            ODSetSOMException(ev, _exception);
  5477.      }
  5478.         return cloneKind;
  5479. }
  5480.  
  5481. //------------------------------------------------------------------------------
  5482. //  CMDraft: CopiedLinkSubstitution
  5483. //------------------------------------------------------------------------------
  5484. //
  5485. // If this clone is a copy, or a move to another draft, substitute the original
  5486. // object ID or the null object id, and return true.  Returns false if the object
  5487. // should be cloned, and does not assign to the toID parameter.
  5488. // The toObjectID parameter is just for validity checking.
  5489.  
  5490. SOM_Scope ODBoolean  SOMLINK CMDraftCopiedLinkSubstitution(CMDraft *somSelf, Environment* ev,
  5491.                 ODDraftKey      key,
  5492.                 ODID            fromID,
  5493.                 ODID            toObjectID,
  5494.                 ODID*           toID)
  5495. {
  5496.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5497.     CMDraftMethodDebug("CMDraft","CopiedLinkSubstitution");
  5498.  
  5499.         ODUnused(key);
  5500.  
  5501.         ODBoolean substitute = kODFalse;
  5502.  
  5503.     try
  5504.     {
  5505.  
  5506.         ODBoolean isCopy = (somSelf->GetCloneKind(ev) == kODCloneDropCopy);
  5507.         ODBoolean isCrossDraftMove =
  5508.                 (somSelf->GetCloneKind(ev) == kODCloneDropMove) && (GetOriginalDraft(ev, somSelf) != _fDestDraft);
  5509.  
  5510.         if ( isCopy || isCrossDraftMove )
  5511.         {
  5512.                 if ( IsLinkObject(ev, somSelf, fromID) )
  5513.                 {
  5514.                         if ( !somSelf->CompanionWasCloned(ev, fromID, kODPropLinkSource) )
  5515.                         {
  5516.                                 if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
  5517.                                 {
  5518.                                         ASSERT(toObjectID == 0, kODErrInvalidID);
  5519.                                         *toID = somSelf->GetOriginalID(ev, fromID);
  5520.                                         ASSERT(*toID != 0, kODErrInvalidID);
  5521.                                 }
  5522.                                 else
  5523.                                         *toID = 0;
  5524.                                 substitute = kODTrue;
  5525.                         }
  5526.                 }
  5527.                 else if ( IsLinkSourceObject(ev, somSelf, fromID) )
  5528.                 {
  5529.                         if ( !somSelf->CompanionWasCloned(ev, fromID, kODPropLink) )
  5530.                         {
  5531.                                 *toID = 0;
  5532.                                 substitute = kODTrue;
  5533.                         }
  5534.                 }
  5535.         }
  5536.  
  5537. #ifdef DebugClone
  5538.         if ( substitute )
  5539.         {
  5540.                 if ( !IsLinkObject(ev, somSelf, fromID) )
  5541.                         IsLinkSourceObject(ev, somSelf, fromID);
  5542.                 somPrintf("Reusing existing object id = %d for cloned object %d\n", toID, fromID);
  5543.         }
  5544. #endif
  5545.  
  5546.     }
  5547.     catch (ODException _exception)
  5548.     {
  5549.         substitute = kODFalse;
  5550.         ODSetSOMException(ev, _exception);
  5551.     }
  5552.         return substitute;
  5553. }
  5554.  
  5555. //------------------------------------------------------------------------------
  5556. // CMDraft: Clone
  5557. //------------------------------------------------------------------------------
  5558. //
  5559. // Why is the switch statement in this method so hard to understand?  It should
  5560. // really be replaced by a table-driven algorithm.  There are only three possible
  5561. // actions when cloning a link or link source object:
  5562. //              (1) Go ahead and clone the link,
  5563. //              (2) Don't clone the link,
  5564. //              (3) Substitute the original link rather than clone in a duplicate
  5565. // However, there are four factors that determine which action should be taken.
  5566. // There are 8x3x2x2 = 96 distinct combinations of these factors; however,
  5567. // most combinations are impossible or illegal.
  5568. // The switch statement is an embodyment in code of the resulting sparse matrix.
  5569. // Several cases are sometimes handled at once.  Only by going back to the full
  5570. // case analysis represented by a table can one understand this code.
  5571. //
  5572. // Note that its possible that a link object's companion doesn't exist; in this
  5573. // case the link is broken and won't be copied.
  5574. //
  5575.  
  5576. SOM_Scope ODID  SOMLINK CMDraftClone(CMDraft *somSelf, Environment *ev,
  5577.                 ODDraftKey key,
  5578.                 ODID fromID,
  5579.                 ODID toObjectID,
  5580.                 ODID scopeID)
  5581. {
  5582.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5583.     CMDraftMethodDebug("CMDraft","Clone");
  5584.  
  5585.         ODStorageUnitID toID = 0;
  5586.  
  5587.     try
  5588.     {
  5589.  
  5590.         if ((key != _fCurrentKey) || (_fLockCount == 0))
  5591.                 THROW(kODErrInvalidDraftKey);
  5592.  
  5593.  
  5594.         ODStorageUnitID companionID = 0;
  5595.  
  5596. #ifdef _PLATFORM_OS2_
  5597.  
  5598.         switch ( somSelf->GetCloneKind(ev) )
  5599.         {
  5600.         case kODCloneAll:
  5601.         case kODCloneFromLink:
  5602.                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5603.                 break;
  5604.  
  5605.         case kODCloneToLink:
  5606.                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5607.                 break;
  5608.  
  5609.         case kODCloneCopy:
  5610.         case kODCloneCut:
  5611.                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5612.                 somSelf->SetOriginalID(ev, toID, fromID);
  5613.                 break;
  5614.  
  5615.         case kODCloneDropCopy:
  5616.                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5617.                 break;
  5618.         case kODCloneDropMove:
  5619.                 // Putting DR4 cloning code to handle drag and drop within the
  5620.                 // same document.
  5621.                 if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
  5622.                 {
  5623.                         // toObjectID will be non-zero if the object has been weakly cloned.
  5624.                         // If the weak clone substituted the original object, set toID so
  5625.                         // the strong clone is avoided.  If the weak clone was into a
  5626.                         // storage unit other than the original, toID is not set, so the
  5627.                         // strong clone will be performed.
  5628.                         ODID originalID = somSelf->GetOriginalID(ev, fromID);
  5629.                         if ( _fDestDraft->IsValidID(ev, originalID)
  5630.                              &&
  5631.                              ((toObjectID == 0) || (toObjectID == originalID)) )
  5632.                                 toID = originalID;
  5633.                         somSelf->CheckClonedObject(ev, fromID, toID, originalID);
  5634.                 }
  5635.                 if ( toID == 0 )
  5636.                 {
  5637.                         toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5638.                 }
  5639.                 break;
  5640.  
  5641.         default:
  5642.                 break;
  5643.         }
  5644.  
  5645.  
  5646. // Notes on cloning in OS2 implementation:
  5647. // In OS2 implementation, we need to distinguish SUs which are clones of links
  5648. // from SUs which are the original links for the following reasons:
  5649. // 1. A stored link which is not a clone comes back up without issuing
  5650. //    AddLinkTarget, whereas a clone must issue AddLinkTarget (unless its
  5651. //    source was also copied)
  5652. // 2. A cloned link which has a valid ref to a link source (meaning that
  5653. //    its link source was also copied) has an invalid linkid for the source,
  5654. //    since new linkids are created lazily.
  5655. //    Such a link cannot be further cloned from a document (copy, cut, copytolink)
  5656. //    for fear that it will be cloned without its linksource and the
  5657. //    correct linksource reference lost.
  5658.  
  5659. //    So whenever we clone a link (target) object, we give it the CloneOfALink property
  5660. //    Whenever the link comes up again, that property is removed.
  5661.  
  5662. #ifdef _NO_TMP_OBJS_
  5663.         ODStorageUnit* destSU  = _fDestDraft->AcquireStorageUnit(ev, toID);
  5664. #else
  5665.         TempODStorageUnit destSU  = _fDestDraft->AcquireStorageUnit(ev, toID);
  5666. #endif
  5667.  
  5668.         if (IsLinkObject(ev,_fDestDraft,toID) &&
  5669.             !destSU->Exists(ev, kODPropCloneOfALink, kODNULL, 0))
  5670.               {
  5671.                 ODSUAddPropValue(ev, destSU, kODPropCloneOfALink, kODBoolean);
  5672.                 ODBoolean True = kODTrue ;
  5673.                 StorageUnitSetValue(destSU, ev, sizeof(ODBoolean), (ODValue)&(True));
  5674.               }
  5675. #ifdef _NO_TMP_OBJS_
  5676.         destSU->Release(ev);
  5677. #endif
  5678.  
  5679. #else
  5680.         switch ( somSelf->GetCloneKind(ev) )
  5681.         {
  5682.         case kODCloneAll:
  5683.                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5684.                 somSelf->CloneCompanionObject(ev, key, fromID);
  5685.                 break;
  5686.  
  5687.         case kODCloneFromLink:
  5688.         case kODCloneToLink:
  5689.                 if ( IsNeitherLinkObject(ev, somSelf, fromID) )
  5690.                         toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5691.                 break;
  5692.  
  5693.         case kODCloneCopy:
  5694.         case kODCloneCut:
  5695.                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5696.                 somSelf->SetOriginalID(ev, toID, fromID);
  5697.                 break;
  5698.  
  5699.         case kODCloneDropCopy:
  5700.                 if ( !somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID) )
  5701.                         toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5702.                 break;
  5703.  
  5704.         case kODCloneDropMove:
  5705.                 // When moved to another draft, links should behave as if copied
  5706.                 if ( !somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID) )
  5707.                 {
  5708.                         if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
  5709.                         {
  5710.                                 // toObjectID will be non-zero if the object has been weakly cloned.
  5711.                                 // If the weak clone substituted the original object, set toID so
  5712.                                 // the strong clone is avoided.  If the weak clone was into a
  5713.                                 // storage unit other than the original, toID is not set, so the
  5714.                                 // strong clone will be performed.
  5715.                                 ODID originalID = somSelf->GetOriginalID(ev, fromID);
  5716.                                 if ( _fDestDraft->IsValidID(ev, originalID)
  5717.                                      &&
  5718.                                      ((toObjectID == 0) || (toObjectID == originalID)) )
  5719.                                         toID = originalID;
  5720.                                 somSelf->CheckClonedObject(ev, fromID, toID, originalID);
  5721.                         }
  5722.                         if ( toID == 0 )
  5723.                         {
  5724.                                 toID = somSelf->StrongClone(ev, key, fromID, toObjectID, scopeID);
  5725.                         }
  5726. #ifdef DebugClone
  5727.                         else
  5728.                         {
  5729.                                 if ( !IsLinkObject(ev, somSelf, fromID) )
  5730.                                         IsLinkSourceObject(ev, somSelf, fromID);
  5731.                                 somPrintf("Reusing existing object id = %d for cloned object %d\n", toID, fromID);
  5732.                         }
  5733. #endif
  5734.                 }
  5735.                 break;
  5736.  
  5737.         default:
  5738.                 break;
  5739.         }
  5740. #endif // _PLATFORM_OS2_
  5741.  
  5742.     }
  5743.     catch (ODException _exception)
  5744.     {
  5745.          toID = 0;
  5746.          ODSetSOMException(ev, _exception);
  5747.     }
  5748.         return toID;
  5749. }
  5750.  
  5751. //------------------------------------------------------------------------------
  5752. // CMDraft: StrongClone
  5753. //------------------------------------------------------------------------------
  5754.  
  5755. SOM_Scope ODID  SOMLINK CMDraftStrongClone(CMDraft *somSelf, Environment *ev,
  5756.                 ODDraftKey key,
  5757.                 ODID fromID,
  5758.                 ODID toObjectID,
  5759.                 ODID scopeID)
  5760. {
  5761.  
  5762.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5763.     CMDraftMethodDebug("CMDraft","StrongClone");
  5764.  
  5765.         ODStorageUnitID         toID = 0;
  5766.  
  5767.    try
  5768.    {
  5769.  
  5770. #ifdef DebugClone
  5771.         somPrintf("CMDraftStrongClone %d %d %d\n", fromID, toObjectID, scopeID);
  5772. #endif
  5773.  
  5774. #ifdef _NO_TMP_OBJS_
  5775.         ODStorageUnit *toSU = kODNULL;
  5776. #else
  5777.         TempODStorageUnit toSU = kODNULL;
  5778. #endif
  5779.  
  5780.         _fClonedSUIDs->GetValue(&fromID, &toID);
  5781.         if (toID == 0) {
  5782.                 _fWeakClonedSUIDs->GetValue(&fromID, &toID);
  5783.                 if (toID == 0) {
  5784.                         if (toObjectID != 0)
  5785.                                 toSU = _fDestDraft->AcquireStorageUnit(ev, toObjectID);
  5786.                         else
  5787.                                 toSU = _fDestDraft->CreateStorageUnit(ev);
  5788.                         toID = toSU->GetID(ev);
  5789.                         _fClonedSUIDs->ReplaceEntry(&fromID, &toID);
  5790.                 }
  5791.                 else {
  5792.                         if ((toObjectID != 0) && (toObjectID != toID))
  5793.                                 THROW(kODErrInvalidID);
  5794.                         _fWeakClonedSUIDs->RemoveEntry(&fromID);
  5795.                         _fClonedSUIDs->ReplaceEntry(&fromID, &toID);
  5796.                         toSU = _fDestDraft->AcquireStorageUnit(ev, toID);
  5797.                 }
  5798.         }
  5799.         else {
  5800.                 if ((toObjectID != 0) && (toObjectID != toID))
  5801.                         THROW(kODErrInvalidID);
  5802.                 toSU = _fDestDraft->AcquireStorageUnit(ev, toID);
  5803.         }
  5804.  
  5805.         ODPersistentObject *fromObject = somSelf->RetrievePersistentObject(ev, fromID);
  5806.         if ( fromObject ) {
  5807. #ifdef _NO_TMP_OBJS_
  5808.                 ODRefCntObject *tempFromObject = fromObject; // so it gets released
  5809.                 ODFrame *scopeFrame = kODNULL;
  5810. #else
  5811.                 TempODRefCntObject tempFromObject = fromObject; // so it gets released
  5812.                 TempODFrame scopeFrame = kODNULL;
  5813. #endif
  5814.                 if (scopeID != 0)
  5815.                         scopeFrame = somSelf->AcquireFrame(ev, scopeID);
  5816.                 fromObject->CloneInto(ev, key, toSU, scopeFrame);
  5817.                 ODStorageUnit* fromSU = fromObject->GetStorageUnit(ev);
  5818.                 if (fromSU != kODNULL)
  5819.                         CopyDraftAnnotations(ev, fromSU, toSU);
  5820. #ifdef _NO_TMP_OBJS_
  5821.                 tempFromObject->Release(ev);
  5822.                 scopeFrame->Release(ev);
  5823. #endif
  5824.         }
  5825.         else {
  5826. #ifdef _NO_TMP_OBJS_
  5827.                 ODStorageUnit *fromSU = somSelf->AcquireStorageUnit(ev, fromID);
  5828. #else
  5829.                 TempODStorageUnit fromSU = somSelf->AcquireStorageUnit(ev, fromID);
  5830. #endif
  5831.                 if (fromSU != kODNULL) {
  5832. #ifdef _PLATFORM_OS2_
  5833.                     // If the following conditions are all met:
  5834.                     // o This SU has the CloneOfALinkProperty
  5835.                     // o This SU has a valid LinkTargetToLinkSource reference
  5836.                     //   (implying the link was cloned together with its linksource)
  5837.                     // o Origin is a live document (clonekind is Copy, Cut, or CopytoLink)
  5838.                     // then we must convert the SU into an object before further cloning.
  5839.                     // The reason is that the linkid information in the SU
  5840.                     // is invalid, as a result of our decision not to register
  5841.                     // copied linksources with the AS until they have been opened.
  5842.                     if (fromSU->Exists(ev, kODPropCloneOfALink, kODNULL, 0) &&
  5843.                         somSelf->CompanionWasCloned(ev, fromID, kODPropLinkTargetToLinkSource) &&
  5844.                         (_fCloneKind == kODCloneCopy || _fCloneKind == kODCloneCut || _fCloneKind == kODCloneToLink) ) {
  5845.  
  5846.                             fromObject = (ODPersistentObject*) somSelf->AcquireLink(ev, fromID, (ODLinkSpec*) kODNULL);
  5847.                             ODFrame* scopeFrame = kODNULL;
  5848.                             if (scopeID != 0)
  5849.                                     scopeFrame = somSelf->AcquireFrame(ev, scopeID);
  5850.                             fromObject->CloneInto(ev, key, toSU, scopeFrame);
  5851.                             fromObject->Release(ev);
  5852.                             if (scopeFrame != kODNULL)
  5853.                                     scopeFrame->Release(ev);
  5854.                     } else {
  5855.                             fromSU->CloneInto(ev, key, toSU, scopeID);
  5856.                     }
  5857. //                    fromSU->Release(ev);
  5858. #else
  5859.                         fromSU->CloneInto(ev, key, toSU, scopeID);
  5860.             ODBoolean keepProxyProperties = (_fCloneKind == kODCloneToFile)
  5861.               || (_fCloneKind == kODCloneAll);
  5862.                         RemoveDataInterchangeProperties(ev, toSU, keepProxyProperties);
  5863. //                      CopyDraftAnnotations(ev, fromSU, toSU);
  5864. #endif // _PLATFORM_OS2_
  5865.                 }
  5866. #ifdef _NO_TMP_OBJS_
  5867.                 fromSU->Release(ev);
  5868. #endif
  5869.  
  5870.         }
  5871.  
  5872. #ifdef DebugClone
  5873.         somPrintf("Done CMDraftStrongClone %d\n", toID);
  5874. #endif
  5875.  
  5876. #ifdef _NO_TMP_OBJS_
  5877.         toSU->Release(ev);
  5878. #endif
  5879.  
  5880.     }
  5881.     catch (ODException _exception)
  5882.     {
  5883.          toID = 0;
  5884.          ODSetSOMException(ev, _exception);
  5885.     }
  5886.         return toID;
  5887. }
  5888.  
  5889. //------------------------------------------------------------------------------
  5890. // CMDraft: WeakClone
  5891. //------------------------------------------------------------------------------
  5892.  
  5893. SOM_Scope ODID  SOMLINK CMDraftWeakClone(CMDraft *somSelf, Environment *ev,
  5894.                 ODDraftKey key,
  5895.                 ODID fromID,
  5896.                 ODID toObjectID,
  5897.                 ODID scopeID)
  5898. {
  5899.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5900.     CMDraftMethodDebug("CMDraft","Clone");
  5901.  
  5902.         ODStorageUnitID toID = 0;
  5903.    try
  5904.    {
  5905.  
  5906.         _fClonedSUIDs->GetValue(&fromID, &toID);
  5907.         if (toID == 0)
  5908.         {
  5909.                 _fWeakClonedSUIDs->GetValue(&fromID, &toID);
  5910.                 if (toID == 0)
  5911.                 {
  5912.                         toID = toObjectID;
  5913.                         if ( toID == 0 )
  5914.                         {
  5915.                                 // Note that this may substitute the null object id, which
  5916.                                 // will be returned instead of a valid object id!
  5917. #ifdef _PLATFORM_OS2_
  5918.                                 ODBoolean substitute = kODFalse;
  5919. #else
  5920.                                 ODBoolean substitute = somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID);
  5921. #endif
  5922.                                 if ( !substitute )
  5923. //                                if ( !somSelf->CopiedLinkSubstitution(ev, key, fromID, toObjectID, &toID) )
  5924.                                 {
  5925.                                         if ( somSelf->GetCloneKind(ev) == kODCloneDropMove )
  5926.                                         {
  5927.                                                 // If this clone is a move back into the original draft,
  5928.                                                 // substitute the original object, making this equivalent to
  5929.                                                 // a strong clone.
  5930.                                                 if ( GetOriginalDraft(ev, somSelf) == _fDestDraft )
  5931.                                                         toID = somSelf->GetOriginalID(ev, fromID);
  5932.                                         }
  5933.                                         if ( toID == 0 )
  5934.                                         {
  5935. #ifdef _NO_TMP_OBJS_
  5936.                                                 ODStorageUnit *toSU = _fDestDraft->CreateStorageUnit(ev);
  5937. #else
  5938.                                                 TempODStorageUnit toSU = _fDestDraft->CreateStorageUnit(ev);
  5939. #endif
  5940.                                                 toID = toSU->GetID(ev);
  5941.                                                 _fWeakClonedSUIDs->ReplaceEntry(&fromID, &toID);
  5942. #ifdef _NO_TMP_OBJS_
  5943.                                                 toSU->Release(ev);
  5944. #endif
  5945.                                         }
  5946.                                 }
  5947.                         }
  5948.                 }
  5949.         }
  5950.         if ((toObjectID != 0) && (toObjectID != toID))
  5951.                 THROW(kODErrInvalidID);
  5952.  
  5953.     }
  5954.     catch (ODException _exception)
  5955.     {
  5956.          toID = 0;
  5957.          ODSetSOMException(ev, _exception);
  5958.     }
  5959.         return toID;
  5960. }
  5961.  
  5962. //------------------------------------------------------------------------------
  5963. // CMDraft: IsValidDraftKey
  5964. //------------------------------------------------------------------------------
  5965.  
  5966. SOM_Scope ODBoolean  SOMLINK CMDraftIsValidDraftKey(CMDraft *somSelf, Environment *ev,
  5967.                 ODDraftKey key)
  5968. {
  5969.     CMDraftData *somThis = CMDraftGetData(somSelf);
  5970.     CMDraftMethodDebug("CMDraft","IsValidDraftKey");
  5971.  
  5972.         return ((key != kODNULLKey) && (_fCurrentKey == key) ? kODTrue : kODFalse);
  5973. }
  5974.  
  5975. //------------------------------------------------------------------------------
  5976. // CopyProperty
  5977. //------------------------------------------------------------------------------
  5978.  
  5979. static void CopyProperty(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU, ODPropertyName prop)
  5980. {
  5981.         // Assuming fromSU is focused to prop.
  5982.         // Copy all values into toSU, overwriting any existing values there.
  5983.  
  5984.    try
  5985.    {
  5986.         PreserveFocus fromFocus(ev, fromSU);
  5987.         PreserveFocus toFocus(ev, toSU);
  5988.  
  5989.         ODULong                 numValues;
  5990.         ODULong                 j;
  5991.         ODValueType             valueName;
  5992.  
  5993.         fromSU->Focus(ev, (ODPropertyName) prop, kODPosUndefined, kODNULL, 0, kODPosAll);
  5994.  
  5995.         numValues = fromSU->CountValues(ev);
  5996.  
  5997.         if ( numValues > 0)
  5998.                 ODSUForceFocus(ev, toSU, prop, kODNULL);
  5999.  
  6000.         for (j = 0; j < numValues; j++)
  6001.         {
  6002.                 fromSU->Focus(ev, (ODPropertyName) kODNULL, kODPosSame, kODNULL, 0, kODPosNextSib);
  6003.  
  6004.                 valueName = fromSU->GetType(ev);
  6005.  
  6006.                 ODSUForceFocus(ev, toSU, prop, valueName);
  6007.                 ODULong toSize = toSU->GetSize(ev);
  6008.                 toSU->DeleteValue(ev, toSize);
  6009.  
  6010.                 ODDisposePtr(valueName);
  6011.  
  6012.                 ODULong size = fromSU->GetSize(ev);
  6013.                 ODPtr buffer = ODNewPtr(size);
  6014.                 StorageUnitGetValue(fromSU, ev, size, (ODValue) buffer);
  6015.                 StorageUnitSetValue(toSU, ev, size, (ODValue) buffer);
  6016.                 ODDisposePtr(buffer);
  6017.         }
  6018.    }
  6019.    catch (ODException _exception)
  6020.    {
  6021.         ODSetSOMException(ev, _exception);
  6022.    }
  6023. }
  6024.  
  6025. //------------------------------------------------------------------------------
  6026. // CopyDraftAnnotations
  6027. //------------------------------------------------------------------------------
  6028.  
  6029. static void CopyDraftAnnotations(Environment *ev, ODStorageUnit* fromSU, ODStorageUnit* toSU)
  6030. {
  6031.    try
  6032.    {
  6033.         ODULong annotationPrefixLength = ODISOStrLength(kODPropPreAnnotation);
  6034.         ODULong metaDataPrefixLength = ODISOStrLength(kODPropPreODMetaData);
  6035.  
  6036.         fromSU->Focus(ev, (ODPropertyName) kODNULL,
  6037.                                                         kODPosAll,
  6038.                                                         kODTypeAll,
  6039.                                                         0,
  6040.                                                         kODPosUndefined);
  6041.         ODULong numProperties = fromSU->CountProperties(ev);
  6042.         for (ODULong i = 1; i <= numProperties; i++) {
  6043.                 fromSU->Focus(ev, (ODPropertyName) kODNULL,
  6044.                                                 kODPosNextSib,
  6045.                                                 kODTypeAll,
  6046.                                                 0,
  6047.                                                 kODPosUndefined);
  6048.                 ODPropertyName propertyName = fromSU->GetProperty(ev);
  6049.                 if (ODISOStrNCompare(propertyName, kODPropPreAnnotation, annotationPrefixLength) == 0)
  6050.                         CopyProperty(ev, fromSU, toSU, propertyName);
  6051.                 else if ((ODISOStrNCompare(propertyName, kODPropPreODMetaData, metaDataPrefixLength) == 0) &&
  6052.                         (toSU->Exists(ev, propertyName, kODNULL, 0) == kODFalse)) {
  6053. #ifdef ODDebug_CloningAnnotations
  6054.                         SetOutputMode(kWriteToFile);
  6055.                         PRINT("metadata property %s does not exist in destination su.\n", propertyName);
  6056. #endif
  6057.                         CopyProperty(ev, fromSU, toSU, propertyName);
  6058.                 }
  6059.                 ODDisposePtr(propertyName);
  6060.         }
  6061.  
  6062.         // Force copying of storage unit type property, which always exists so is
  6063.         // not copied in the iteration above.
  6064.         CopyProperty(ev, fromSU, toSU, kODPropStorageUnitType);
  6065.     }
  6066.     catch (ODException _exception)
  6067.     {
  6068.          ODSetSOMException(ev, _exception);
  6069.     }
  6070. }
  6071.  
  6072. //------------------------------------------------------------------------------
  6073. // IsLinkObject
  6074. //------------------------------------------------------------------------------
  6075.  
  6076. static ODBoolean IsLinkObject(Environment* ev, ODDraft* draft, ODID objectID)
  6077. {
  6078.         // Only link objects contain a kODPropLinkSource property
  6079.         //  in OS2, a kODPropAvailabilityServerName property
  6080.  
  6081.           ODBoolean isLink = kODFalse;
  6082.     try
  6083.     {
  6084.  
  6085. #ifdef _NO_TMP_OBJS_
  6086.         ODStorageUnit *su = draft->AcquireStorageUnit(ev, objectID);
  6087. #else
  6088.         TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
  6089. #endif
  6090. #ifdef _PLATFORM_OS2_
  6091.         isLink = su->Exists(ev, kODPropAvailabilityServerName, kODNULL, 0);
  6092. #else
  6093.         isLink = su->Exists(ev, kODPropLinkSource, kODNULL, 0);
  6094. #endif
  6095.  
  6096. #ifdef DebugClone
  6097.         somPrintf("IsLinkObject returns %u\n", isLink);
  6098. #endif
  6099.  
  6100. #ifdef _NO_TMP_OBJS_
  6101.         su->Release(ev);
  6102. #endif
  6103.  
  6104.     }
  6105.     catch (ODException _exception)
  6106.     {
  6107.         ODSetSOMException(ev, _exception);
  6108.     }
  6109.         return isLink;
  6110.     
  6111. }
  6112.  
  6113. //------------------------------------------------------------------------------
  6114. // IsLinkSourceObject
  6115. //------------------------------------------------------------------------------
  6116.  
  6117. static ODBoolean IsLinkSourceObject(Environment* ev, ODDraft* draft, ODID objectID)
  6118. {
  6119.         // Only link source objects contain a kODPropLink property
  6120.         // in OS2, a kODPropLinkSourceState property
  6121.  
  6122.              ODBoolean isLink = kODFalse;
  6123.  
  6124.     try
  6125.     {
  6126.  
  6127. #ifdef _NO_TMP_OBJS_
  6128.         ODStorageUnit *su = draft->AcquireStorageUnit(ev, objectID);
  6129. #else
  6130.         TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
  6131. #endif
  6132. #ifdef _PLATFORM_OS2_
  6133.         isLink = su->Exists(ev, kODPropLinkSourceState, kODNULL, 0);
  6134. #else
  6135.         isLink = su->Exists(ev, kODPropLink, kODNULL, 0);
  6136. #endif
  6137.  
  6138. #ifdef DebugClone
  6139.         somPrintf("IsLinkSourceObject returns %u\n", isLink);
  6140. #endif
  6141.  
  6142. #ifdef _NO_TMP_OBJS_
  6143.         su->Release(ev);
  6144. #endif
  6145.  
  6146.     }
  6147.     catch (ODException _exception)
  6148.     {
  6149.         isLink =  kODFalse;
  6150.         ODSetSOMException(ev, _exception);
  6151.     }
  6152.         return isLink;
  6153. }
  6154.  
  6155. //------------------------------------------------------------------------------
  6156. // IsNeitherLinkObject
  6157. //------------------------------------------------------------------------------
  6158.  
  6159. static ODBoolean IsNeitherLinkObject(Environment* ev, ODDraft* draft, ODID objectID)
  6160. {
  6161.         if ( IsLinkObject(ev, draft, objectID) )
  6162.                 return kODFalse;
  6163.         else
  6164.                 return !IsLinkSourceObject(ev, draft, objectID);
  6165. }
  6166.  
  6167. //------------------------------------------------------------------------------
  6168. // SetStorageUnitType
  6169. //------------------------------------------------------------------------------
  6170.  
  6171. static void SetStorageUnitType(Environment* ev, ODDraftPermissions perms, ODStorageUnit* su, ODType suType)
  6172. {
  6173.     try
  6174.     {
  6175.         if (perms == kODDPExclusiveWrite)
  6176.         {
  6177. #ifdef _NO_TMP_OBJS_
  6178.                 char *curType = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
  6179. #else
  6180.                 TempODType curType = ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
  6181. #endif
  6182.                 if (!curType || !ODISOStrEqual(curType, suType))
  6183.                         ODSetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, suType);
  6184.         }
  6185.     }
  6186.    catch (ODException _exception)
  6187.    {
  6188.        ODSetSOMException(ev, _exception);
  6189.    }
  6190. }
  6191.  
  6192. //------------------------------------------------------------------------------
  6193. // GetStorageUnitType
  6194. //------------------------------------------------------------------------------
  6195.  
  6196. static ODISOStr GetStorageUnitType(Environment* ev, ODDraft* draft, ODID objectID)
  6197. {
  6198.             ODISOStr Storageunittype = kODNULL;      
  6199.     try
  6200.     {
  6201.  
  6202. #ifdef _NO_TMP_OBJS_
  6203.         ODStorageUnit *su = draft->AcquireStorageUnit(ev, objectID);
  6204. #else
  6205.         TempODStorageUnit su = draft->AcquireStorageUnit(ev, objectID);
  6206. #endif
  6207.         PreserveFocus fromFocus(ev, su);
  6208.  
  6209.         Storageunittype =  ODGetISOStrProp(ev, su, kODPropStorageUnitType, kODISOStr, kODNULL, kODNULL);
  6210.  
  6211.     }
  6212.     catch (ODException _exception)
  6213.     {
  6214.        ODSetSOMException(ev, _exception);
  6215.     }
  6216.          return Storageunittype;
  6217. }
  6218.  
  6219. //------------------------------------------------------------------------------
  6220. // RootPartID
  6221. //------------------------------------------------------------------------------
  6222.  
  6223. static ODID RootPartID(Environment* ev, ODDraft* draft)
  6224. {
  6225.          ODID RootpartID = kODNULLID;
  6226.  
  6227.      try
  6228.      {
  6229. #ifdef _NO_TMP_OBJS_
  6230.         ODStorageUnit *draftProperties = draft->AcquireDraftProperties(ev);
  6231. #else
  6232.         TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  6233. #endif
  6234.         RootpartID =  ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
  6235.     }
  6236.     catch (ODException _exception)
  6237.     {
  6238.         ODSetSOMException(ev, _exception);
  6239.     }
  6240.         return RootpartID;
  6241. }
  6242.  
  6243. //------------------------------------------------------------------------------
  6244. // CheckClonedObject
  6245. //------------------------------------------------------------------------------
  6246.  
  6247. SOM_Scope void  SOMLINK CMDraftCheckClonedObject(CMDraft *somSelf, Environment *ev,
  6248.                 ODID fromID,
  6249.                 ODID toID,
  6250.                 ODID originalID)
  6251. {
  6252.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6253.     CMDraftMethodDebug("CMDraft","CheckClonedObject");
  6254.  
  6255.     ODISOStr storageUnitType = kODNULL; ODVolatile(storageUnitType);
  6256.  
  6257.         try
  6258.         {
  6259.  
  6260.     storageUnitType = GetStorageUnitType(ev, somSelf, fromID);
  6261.  
  6262. #ifdef DebugClone
  6263.     somPrintf("CheckClonedObject: Type is %s\n", storageUnitType);
  6264. #endif
  6265.  
  6266.         if ( ODISOStrEqual(kODFrameObject, storageUnitType) )
  6267.         {
  6268.                 _fAnyFrameCloned = kODTrue;
  6269.         }
  6270.         else if ( ODISOStrEqual(kODPartObject, storageUnitType) )
  6271.         {
  6272.                 if ( (toID == originalID) && (RootPartID(ev, somSelf) == fromID) )
  6273.                 {
  6274.                         _fRootPartReused = kODTrue;
  6275. #ifdef DebugClone
  6276.                         somPrintf("CheckClonedObject: Root part reused\n");
  6277. #endif
  6278.                 }
  6279.         }
  6280.  
  6281.         }
  6282.         catch (ODException _exception)
  6283.         {
  6284.             ODSetSOMException(ev, _exception);
  6285.         }
  6286.  
  6287.         ODDisposePtr(storageUnitType);
  6288. }
  6289.  
  6290. //------------------------------------------------------------------------------
  6291. // SetOriginalDraft
  6292. //------------------------------------------------------------------------------
  6293.  
  6294. static void SetOriginalDraft(Environment* ev, ODDraft* targetDraft, ODDraft* originalDraft)
  6295. {
  6296.     try
  6297.     {
  6298. #ifdef _NO_TMP_OBJS_
  6299.         ODStorageUnit *draftProperties = targetDraft->AcquireDraftProperties(ev);
  6300. #else
  6301.         TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
  6302. #endif
  6303.         ODSetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong, (ODULong) originalDraft);
  6304.  
  6305.     // Save the process ID to be used by the drop/paste site. 
  6306.         // If the process ID in the drag/cut site is the same as the process 
  6307.         // ID in the drop site, then drag-n-drop/cut-n-paste happens within 
  6308.         // the same document.
  6309.         int pid = getpid();
  6310.         ODSetULongProp(ev, draftProperties, kODPropOriginalPID, kODULong, (ODULong) pid);
  6311.  
  6312. #ifdef _NO_TMP_OBJS_
  6313.         draftProperties->Release(ev);
  6314. #endif
  6315.    }
  6316.    catch (ODException _exception)
  6317.    {
  6318.        ODSetSOMException(ev, _exception);
  6319.    }
  6320. }
  6321.  
  6322. //------------------------------------------------------------------------------
  6323. // GetOriginalDraft
  6324. //------------------------------------------------------------------------------
  6325. // Returns kODNULL if the original draft is unknown.  This is the case when content
  6326. // was placed in the draft without cloning.
  6327.  
  6328. static ODDraft* GetOriginalDraft(Environment* ev, ODDraft* draft)
  6329. {
  6330.      ODDraft* retDraft = kODNULL;
  6331.     try
  6332.     {
  6333. #ifdef _NO_TMP_OBJS_
  6334.         ODStorageUnit   *draftProperties = draft->AcquireDraftProperties(ev);
  6335. #else
  6336.         TempODStorageUnit       draftProperties = draft->AcquireDraftProperties(ev);
  6337. #endif
  6338.         // Retrieve the process ID belonging to the drag/cut site
  6339.         int originalPID = ODGetULongProp(ev, draftProperties, kODPropOriginalPID, kODULong);
  6340.       
  6341.         // If the process ID of the drag/cut site is the same as the process ID
  6342.         // of the drop/paste site, then drag-n-drop/cut-n-paste is within the 
  6343.         // same document.
  6344.         // If this is within the same document, then return the original draft. 
  6345.         // Otherwise, if it is across documents, then return kODNULL as
  6346.         // the original draft.
  6347.         if (originalPID == getpid())
  6348.            retDraft =  (ODDraft*)ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
  6349.         else
  6350.            retDraft = kODNULL;
  6351.     }
  6352.     catch (ODException _exception)
  6353.     {
  6354.         ODSetSOMException(ev, _exception);
  6355.     }
  6356.         return retDraft;
  6357. }
  6358.  
  6359. //------------------------------------------------------------------------------
  6360. // OriginalCloneKindExists
  6361. //------------------------------------------------------------------------------
  6362.  
  6363. static ODBoolean OriginalCloneKindExists(Environment* ev, ODDraft* draft)
  6364. {
  6365.         ODBoolean  OrgCloneKindExists = kODFalse;
  6366.    try
  6367.    {
  6368. #ifdef _NO_TMP_OBJS_
  6369.         ODStorageUnit *draftProperties = draft->AcquireDraftProperties(ev);
  6370. #else
  6371.         TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  6372. #endif
  6373.         OrgCloneKindExists =  draftProperties->Exists(ev, kODPropOriginalCloneKind, kODULong, 0);
  6374.    }
  6375.    catch (ODException _exception)
  6376.    {
  6377.       ODSetSOMException(ev, _exception);
  6378.    }
  6379.      return OrgCloneKindExists;
  6380. }
  6381.  
  6382. //------------------------------------------------------------------------------
  6383. // SetOriginalCloneKind
  6384. //------------------------------------------------------------------------------
  6385.  
  6386. static void SetOriginalCloneKind(Environment* ev, ODDraft* targetDraft, ODCloneKind cloneKind)
  6387. {
  6388.    try
  6389.    {
  6390. #ifdef _NO_TMP_OBJS_
  6391.         ODStorageUnit *draftProperties = targetDraft->AcquireDraftProperties(ev);
  6392. #else
  6393.         TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
  6394. #endif
  6395.         ODSetULongProp(ev, draftProperties, kODPropOriginalCloneKind, kODULong, (ODULong) cloneKind);
  6396. #ifdef _NO_TMP_OBJS_
  6397.         draftProperties->Release(ev);
  6398. #endif
  6399.    }
  6400.    catch (ODException _exception)
  6401.    {
  6402.        ODSetSOMException(ev, _exception);
  6403.    }
  6404.     
  6405. }
  6406.  
  6407. //------------------------------------------------------------------------------
  6408. // CMDraft: GetHeap
  6409. //------------------------------------------------------------------------------
  6410.  
  6411. SOM_Scope ODMemoryHeapID  SOMLINK CMDraftGetHeap(CMDraft *somSelf, Environment *ev)
  6412. {
  6413.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6414.     CMDraftMethodDebug("CMDraft","GetHeap");
  6415.  
  6416.         return _fHeap;
  6417. }
  6418.  
  6419. //------------------------------------------------------------------------------
  6420. // CMDraft: CreateLinkIterator
  6421. //------------------------------------------------------------------------------
  6422.  
  6423. SOM_Scope ODLinkIterator*  SOMLINK CMDraftCreateLinkIterator(CMDraft *somSelf, Environment *ev)
  6424. {
  6425.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6426.     CMDraftMethodDebug("CMDraft","CreateLinkIterator");
  6427.  
  6428.         CMLinkIterator* iter = kODNULL;
  6429.         ODVolatile(iter);
  6430.         try
  6431.         {
  6432.                 iter = new CMLinkIterator();
  6433.                 THROW_IF_NULL(iter, kODErrOutOfMemory);
  6434.                 iter->InitCMLinkIterator(ev, somSelf);
  6435.  
  6436.         }
  6437.         catch (ODException _exception)
  6438.         {
  6439.            ODSetSOMException(ev, _exception);
  6440.            ODDeleteObject(iter);
  6441.          }
  6442.  
  6443.  
  6444.         return (ODLinkIterator*) iter;
  6445. }
  6446.  
  6447. //------------------------------------------------------------------------------
  6448. // CMDraft: CreateLinkSourceIterator
  6449. //------------------------------------------------------------------------------
  6450.  
  6451. SOM_Scope ODLinkSourceIterator*  SOMLINK CMDraftCreateLinkSourceIterator(CMDraft *somSelf, Environment *ev)
  6452. {
  6453.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6454.     CMDraftMethodDebug("CMDraft","CreateLinkSourceIterator");
  6455.  
  6456.         CMLinkSourceIterator* iter  = kODNULL;
  6457.         ODVolatile(iter);
  6458.         try
  6459.         {
  6460.                 iter = new CMLinkSourceIterator();
  6461.                 THROW_IF_NULL(iter, kODErrOutOfMemory);
  6462.                 iter->InitCMLinkSourceIterator(ev, somSelf);
  6463.  
  6464.         }
  6465.         catch (ODException _exception)
  6466.         {
  6467.            ODSetSOMException(ev, _exception);
  6468.            ODDeleteObject(iter);
  6469.  
  6470.         }
  6471.  
  6472.         return (ODLinkSourceIterator*) iter;
  6473. }
  6474.  
  6475. //------------------------------------------------------------------------------
  6476. // CM_itoa   KP
  6477. //------------------------------------------------------------------------------
  6478. static void CM_itoa(ODULong number, ODSByte* cstring)
  6479. {
  6480.         ODULong i = 0;
  6481.  
  6482.         do {
  6483.                 cstring[i++] = (ODSByte) (number % 10 + '0');
  6484.         } while ((number /= 10) > 0);
  6485.         cstring[i] = '\0';
  6486.  
  6487.         ODSByte c;
  6488.  
  6489.         ODULong j;
  6490.  
  6491.         for (i = 0, j = strlen(cstring)-1; i < j;i++, j--) {
  6492.                 c = cstring[i];
  6493.                 cstring[i] = cstring[j];
  6494.                 cstring[j] = c;
  6495.         }
  6496. }
  6497.  
  6498. //------------------------------------------------------------------------------
  6499. // NewCMStorageUnit
  6500. //------------------------------------------------------------------------------
  6501.  
  6502. static CMStorageUnit* NewCMStorageUnit(ODMemoryHeapID heapID)
  6503. {
  6504.         CMStorageUnit*  cmStorageUnit = kODNULL;
  6505.         Environment* ev = somGetGlobalEnvironment();
  6506.     try
  6507.     {
  6508. #ifdef _PLATFORM_MACINTOSH_
  6509.         SOMClass*       cmStorageUnitClass = somNewClassReference(CMStorageUnit);
  6510.         ODULong         size = cmStorageUnitClass->somGetInstanceSize();
  6511.         ODPtr           buffer = ODNewPtr(size, heapID);
  6512.         cmStorageUnit = (CMStorageUnit*) cmStorageUnitClass->somRenew(buffer);
  6513.         somReleaseClassReference ( cmStorageUnitClass );
  6514. #endif
  6515. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  6516. //      The use of heap is not implemented in Windows platform
  6517.         cmStorageUnit  = new CMStorageUnit;
  6518. #endif
  6519.     }
  6520.     catch (ODException _exception)
  6521.     {
  6522.       ODError error = ErrorCode();
  6523.       SaveEv();
  6524.       try
  6525.       {
  6526.         ODDeleteObject(cmStorageUnit);
  6527.       }
  6528.       catch(ODException _exception)
  6529.       {
  6530.           SetErrorCode(kODNoError);
  6531.       }
  6532.       RestoreEv();
  6533.       ODSetSOMException(ev, error);
  6534.     }
  6535.  
  6536.         return cmStorageUnit;
  6537. }
  6538.  
  6539. //------------------------------------------------------------------------------
  6540. // PurgeAllStorageUnits
  6541. //------------------------------------------------------------------------------
  6542.  
  6543. static ODULong PurgeAllStorageUnits(Environment* ev, OpenHashTable* storageUnits, IDList* idList)
  6544. {
  6545.         ODULong                                 runningTotal = 0;
  6546.    try
  6547.    {
  6548.         ODID                                    id;
  6549.         ODStorageUnit*                  su;
  6550.  
  6551. // idList is used to indicate whether we need to remove linkage between id and cmObject
  6552.  
  6553.         OpenHashTableIterator   suIter(storageUnits);
  6554.         for (suIter.First(&id, &su); suIter.IsNotComplete(); suIter.Next(&id, &su)) {
  6555.                 if (su->GetRefCount(ev) != 0) {
  6556.                         if (idList) // purge should release CMObject, signal that by removing from idList
  6557.                                 idList->Remove(id);
  6558.                         runningTotal += su->Purge(ev, 0);
  6559.                 }
  6560.         }
  6561. /*
  6562.         for (suIter.First(&id, &su); suIter.IsNotComplete(); suIter.Next(&id, &su)) {
  6563.                 if (su->GetRefCount(ev) == 0) {
  6564.                         suIter.RemoveCurrent();
  6565.                         delete su;
  6566.                 }
  6567.         }
  6568. */
  6569.         storageUnits->ShrinkToFit(/*extraSlots*/ 0);
  6570.     }
  6571.     catch (ODException _exception)
  6572.     {
  6573.          runningTotal = 0;
  6574.          ODSetSOMException(ev, _exception);
  6575.     }
  6576.  
  6577.         return runningTotal;
  6578. }
  6579.  
  6580. //------------------------------------------------------------------------------
  6581. // PurgeClasses
  6582. //------------------------------------------------------------------------------
  6583.  
  6584. static void PurgeClasses(Environment* ev, OpenHashTable* partClasses)
  6585. {
  6586.     try
  6587.     {
  6588.         OpenHashTableIterator   classes(partClasses);
  6589.         SOMClass*                               partClass;
  6590.         ODULong                                 count;
  6591.  
  6592. #ifdef ODDebug_Unloading_Classes
  6593.         PRINT("**** Purging classes.....\n");
  6594. #endif
  6595.  
  6596.         for (classes.First(&partClass, &count); classes.IsNotComplete(); classes.Next(&partClass, &count)) {
  6597. #ifdef ODDebug_Unloading_Classes
  6598.                 if (somIsObj(partClass)) {
  6599.                         corbastring className = partClass->somGetName();
  6600.                         PRINT("Class %x %s count %d\n", partClass, className, count);
  6601.                 }
  6602.                 else {
  6603.                         PRINT("%x is not a valid som object.\n", partClass);
  6604.                 }
  6605. #endif
  6606.                 if (count == 0) {
  6607. //                      SOMClassMgrObject->somUnregisterClass(partClass);
  6608.                         classes.RemoveCurrent();
  6609.                 }
  6610.         }
  6611.     }
  6612.     catch (ODException _exception)
  6613.     {
  6614.        ODSetSOMException(ev, _exception);
  6615.     }
  6616. }
  6617.  
  6618. //------------------------------------------------------------------------------
  6619. // CMDraft: PartInstantiated
  6620. //------------------------------------------------------------------------------
  6621.  
  6622. SOM_Scope void  SOMLINK CMDraftPartInstantiated(CMDraft *somSelf, Environment *ev,
  6623.                 ODPart* realPart)
  6624. {
  6625.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6626.     CMDraftMethodDebug("CMDraft","PartInstantiated");
  6627.  
  6628.         try
  6629.         {
  6630.  
  6631.         SOMClass* partClass = realPart->somGetClass();
  6632.  
  6633. #ifdef ODDebug_Unloading_Classes
  6634.                         corbastring className = partClass->somGetName();
  6635.                         PRINT(">>>> Instantiating %s\n", className);
  6636. #endif
  6637.  
  6638.         ODULong count = 1;
  6639.         if (_fPartClasses->GetValue(&partClass, &count)) {
  6640.                 ++count;
  6641.                 _fPartClasses->ReplaceEntry(&partClass, &count);
  6642.         }
  6643.         else {
  6644.                 _fPartClasses->ReplaceEntry(&partClass, &count);
  6645.         }
  6646.  
  6647.         }
  6648.         catch (ODException _exception)
  6649.         {
  6650.             ODSetSOMException(ev, _exception);
  6651.         }
  6652. }
  6653.  
  6654. //------------------------------------------------------------------------------
  6655. // CMDraft: PartDeleted
  6656. //------------------------------------------------------------------------------
  6657.  
  6658. SOM_Scope void  SOMLINK CMDraftPartDeleted(CMDraft *somSelf, Environment *ev,
  6659.                 ODPart* realPart)
  6660. {
  6661.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6662.     CMDraftMethodDebug("CMDraft","PartDeleted");
  6663.  
  6664.         try
  6665.         {
  6666.  
  6667.         SOMClass* partClass = realPart->somGetClass();
  6668.  
  6669. #ifdef ODDebug_Unloading_Classes
  6670.                         corbastring className = partClass->somGetName();
  6671.                         PRINT("<<<< Deleting %s\n", className);
  6672. #endif
  6673.  
  6674.         ODULong count = 0;
  6675.         // Check if _fPartClasses is valid before accessing it
  6676.         if ((_fPartClasses) && (_fPartClasses->GetValue(&partClass, &count))) 
  6677.         {
  6678.                 if (count > 0) {
  6679.                         --count;
  6680.                         _fPartClasses->ReplaceEntry(&partClass, &count);
  6681.                 }
  6682.                 else
  6683.                         WARNMSG_DEBUG(WARN_INDEX(-1),
  6684.                         "Instances of class %s have been deleted. But %x is found.",
  6685.                         partClass, realPart);
  6686.         }
  6687.  
  6688.         }
  6689.         catch (ODException _exception)
  6690.         {
  6691.             ODSetSOMException(ev, _exception);
  6692.         }
  6693. }
  6694.  
  6695. //------------------------------------------------------------------------------
  6696. // CMDraft: SwapPart
  6697. //------------------------------------------------------------------------------
  6698.  
  6699. SOM_Scope void  SOMLINK CMDraftSwapPart(CMDraft *somSelf, Environment *ev,
  6700.                 ODPart* part)
  6701. {
  6702.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6703.     CMDraftMethodDebug("CMDraft","SwapPart");
  6704.  
  6705.         try
  6706.         {
  6707.                 OpenHashTableIterator   i(_fPersistentObjects);
  6708.                 ODStorageUnitID                 id;
  6709.                 ODPersistentObject*             object;
  6710.                 ODFrame*                                frame;
  6711.  
  6712.                 somSelf->Externalize(ev);
  6713.  
  6714.                 for (i.First(&id, &object); i.IsNotComplete(); i.Next(&id, &object)) {
  6715.                         if ( strcmp(object->somGetClassName(), kFrameClassName)==0 ) {
  6716.                                 frame = (ODFrame*)object;
  6717.                                 if ( frame->IsSubframe(ev) == kODFalse )
  6718.                                         frame->PrepareToSwap(ev, part);
  6719.                         }
  6720.                 }
  6721.         }
  6722.         catch (ODException _exception)
  6723.         {
  6724.             ODSetSOMException(ev, _exception);
  6725.         }
  6726. }
  6727.  
  6728.  
  6729. #ifdef _PLATFORM_OS2_
  6730. //------------------------------------------------------------------------------
  6731. // CMDraft: CreatePartLinkSourceIterator
  6732. //------------------------------------------------------------------------------
  6733.  
  6734. SOM_Scope ODLinkSourceIterator*  SOMLINK CMDraftCreatePartLinkSourceIterator(CMDraft *somSelf, Environment *ev, ODPart* part)
  6735. {
  6736.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6737.     CMDraftMethodDebug("CMDraft","CreatePartLinkSourceIterator");
  6738.  
  6739.     CMLinkSourceIterator* linkSourceIter = kODNULL;
  6740.  
  6741.   try
  6742.   {
  6743.     linkSourceIter  = new CMLinkSourceIterator();
  6744.     linkSourceIter->InitCMLinkSourceIterator(ev, somSelf);
  6745.  
  6746.     _fLinkService->GetLinkSourcesForPart(ev,part,linkSourceIter);
  6747.   }
  6748.   catch (ODException _exception)
  6749.   {
  6750.       ODSetSOMException(ev, _exception);
  6751.       ODDeleteObject(linkSourceIter);
  6752.   }
  6753.  
  6754.     return (ODLinkSourceIterator*)linkSourceIter;
  6755. }
  6756.  
  6757. //------------------------------------------------------------------------------
  6758. // CMDraft: CreatePartLinkIterator
  6759. //------------------------------------------------------------------------------
  6760.  
  6761. SOM_Scope ODLinkIterator*  SOMLINK CMDraftCreatePartLinkIterator(CMDraft *somSelf, Environment *ev, ODPart* part)
  6762. {
  6763.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6764.     CMDraftMethodDebug("CMDraft","CreatePartLinkIterator");
  6765.  
  6766.     CMLinkIterator* linkTargetIter = kODNULL; 
  6767.  
  6768.   try
  6769.   {
  6770.     linkTargetIter = new CMLinkIterator();
  6771.     linkTargetIter->InitCMLinkIterator(ev, somSelf);
  6772.  
  6773.     _fLinkService->GetLinkTargetsForPart(ev,part,linkTargetIter);
  6774.   }
  6775.   catch (ODException _exception)
  6776.   {
  6777.       ODSetSOMException(ev, _exception);
  6778.       ODDeleteObject(linkTargetIter);
  6779.   }
  6780.  
  6781.     return (ODLinkIterator*)linkTargetIter;
  6782. }
  6783.  
  6784. // *=============================================================================
  6785. // * CMDraft: GetLinkSrcForAvlSvr
  6786. // *=============================================================================
  6787.  
  6788. SOM_Scope ODLinkSource*
  6789. SOMLINK CMDraftGetLinkSrcForAvlSvr(CMDraft *somSelf,
  6790.                                        Environment *ev,
  6791.                                        ODStorageUnitID id,
  6792.                                        IODAuxiliaryState *auxState)
  6793. {
  6794.     // We are assuming that this is only called on an id
  6795.     // of a linksource which has not yet been internalized.
  6796.     // This call is only made on surrogate drafts.
  6797.     // The availserver is responsible for releasing the usecount.
  6798.     // This is like AcquireLinkSource but no call is made to the LinkService.
  6799.     // It is impossible for the linkid to change since the
  6800.     // availability server only knows about links after registration.
  6801.     CMDraftData *somThis = CMDraftGetData(somSelf);
  6802.     CMDraftMethodDebug("CMDraft","GetLinkSrcForAvlSvr");
  6803.  
  6804.     IODLinkSource* linkSource = (IODLinkSource*)kODNULL;
  6805.  
  6806.     try
  6807.     {
  6808.  
  6809.  
  6810.     linkSource = ((IODLinkSource*)somSelf->RetrievePersistentObject(ev, id));
  6811.  
  6812.     if (linkSource == (IODLinkSource*)kODNULL)
  6813.     {
  6814.       linkSource = new IODLinkSource();
  6815.       if (linkSource == (IODLinkSource*)kODNULL)
  6816.       {
  6817.         THROW(kODErrCannotAcquireLink);
  6818.       }
  6819.  
  6820.       ODStorageUnit* su = (ODStorageUnit*)kODNULL;
  6821.       ODVolatile(su);
  6822.       ODVolatile(id);
  6823.  
  6824.       try
  6825.       {
  6826.  
  6827.         su = somSelf->AcquireStorageUnit(ev, id);
  6828.         _fPersistentObjects->ReplaceEntry(&id, &linkSource);
  6829.  
  6830.           linkSource->InitILinkSourceFromStorage(ev, su);
  6831.           linkSource->CompleteInitILinkSource(ev, su, 0, auxState, kODFalse, (ODISOStr)"");
  6832.       }
  6833.       catch (ODException _exception)
  6834.       {
  6835.  
  6836.          ODError error = ErrorCode();
  6837.          SaveEv();
  6838.          try
  6839.          {
  6840.  
  6841.             if (su != (ODStorageUnit*) kODNULL)
  6842.             {
  6843.                _fPersistentObjects->RemoveEntry(&id);
  6844.                su->Release(ev);
  6845.             }
  6846.  
  6847.             linkSource->ReleaseAll(ev);
  6848.             delete linkSource;
  6849.          }
  6850.          catch(ODException _exception)
  6851.          {
  6852.                SetErrorCode(kODNoError);
  6853.          }
  6854.          RestoreEv();
  6855.          ODSetSOMException(ev, error);
  6856.          throw;
  6857.  
  6858.       }
  6859.     }
  6860.  
  6861.     }
  6862.     catch (ODException _exception)
  6863.     {
  6864.         ODSetSOMException(ev, _exception);
  6865.         linkSource =  kODNULL;
  6866.     }
  6867.     return (ODLinkSource*)linkSource;
  6868. }
  6869. #endif /* _PLATFORM_OS2_ */
  6870.