home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Storage / Link.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  24.5 KB  |  902 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Link.cpp
  3.  
  4.     Contains:    Implementation of ODLink class
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>     9/26/96    CC        1332671: Call LinkManager to register &
  13.                                     unregister sections.
  14.          <5>     9/13/96    jpa        1386060: SOM methods pass ptrs to
  15.                                     EditionContainerSpec
  16.          <4>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  17.          <3>     3/19/96    TJ        Included TempObj.h
  18.          <2>     3/15/96    CC        1331422: CreateLinkEdition & GetLinkEdition
  19.                                     return an ODByteArray instead of an
  20.                                     uncopied  handle.
  21.  
  22.     To Do:
  23.     In Progress:
  24.         
  25. */
  26.  
  27. #define VARIABLE_MACROS
  28.  
  29. #define ODLink_Class_Source
  30. #include <Link.xih>
  31.  
  32. #ifndef _LINKDLGS_
  33. #include <LinkDlgs.h>
  34. #endif
  35.  
  36. #ifndef _EXCEPT_
  37. #include <Except.h>
  38. #endif
  39.  
  40. #ifndef _ODMEMORY_
  41. #include <ODMemory.h>
  42. #endif
  43.  
  44. #ifndef _CONSTDEF_
  45. #include <ConstDef.h>
  46. #endif
  47.  
  48. #ifndef SOM_ODLinkSource_xh
  49. #include <LinkSrc.xh>
  50. #endif
  51.  
  52. #ifndef SOM_ODLinkManager_xh
  53. #include <LinkMgr.xh>
  54. #endif
  55.  
  56. #ifndef SOM_ODPart_xh
  57. #include <Part.xh>
  58. #endif
  59.  
  60. #ifndef SOM_ODSession_xh
  61. #include <ODSessn.xh>
  62. #endif
  63.  
  64. #ifndef SOM_ODContainer_xh
  65. #include <ODCtr.xh>
  66. #endif
  67.  
  68. #ifndef SOM_ODDocument_xh
  69. #include <Document.xh>
  70. #endif
  71.  
  72. #ifndef SOM_ODDraft_xh
  73. #include <Draft.xh>
  74. #endif
  75.  
  76. #ifndef SOM_ODStorageSystem_xh
  77. #include <ODStor.xh>
  78. #endif
  79.  
  80. #ifndef _PLFMFILE_
  81. #include <PlfmFile.h>
  82. #endif
  83.  
  84. #ifndef SOM_ODStorageUnit_xh
  85. #include <StorageU.xh>
  86. #endif
  87.  
  88. #ifndef SOM_Module_OpenDoc_StdProps_defined
  89. #include <StdProps.xh>
  90. #endif
  91.  
  92. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  93. #include <StdTypes.xh>
  94. #endif
  95.  
  96. #ifndef __ERRORS__
  97. #include <Errors.h>
  98. #endif
  99.  
  100. #ifndef _ODDEBUG_
  101. #include <ODDebug.h>
  102. #endif
  103.  
  104. #ifndef _BARRAY_
  105. #include <BArray.h>
  106. #endif
  107.  
  108. #ifndef _STDTYPIO_
  109. #include <StdTypIO.h>
  110. #endif
  111.  
  112. #ifndef _STORUTIL_
  113. #include <StorUtil.h>
  114. #endif
  115.  
  116. #ifndef SOM_ODTranslation_xh
  117. #include <Translt.xh>
  118. #endif
  119.  
  120. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  121. #include <StdDefs.xh>
  122. #endif
  123.  
  124. #ifndef _TEMPOBJ_
  125. #include "TempObj.h"
  126. #endif
  127.  
  128. #if ODDebug
  129. #define ODDebugLink 1
  130. #else
  131. #define ODDebugLink 0
  132. #endif
  133.  
  134. #pragma segment ODLink
  135.  
  136. //==============================================================================
  137. // Local Functions
  138. //==============================================================================
  139.  
  140. static ODBoolean IsTopDraft(Environment* ev, ODDraft* draft);
  141.  
  142. //------------------------------------------------------------------------------
  143. // IsTopDraft
  144. //------------------------------------------------------------------------------
  145.  
  146. static ODBoolean IsTopDraft(Environment* ev, ODDraft* draft)
  147. {
  148. #if ODDebugLink
  149.     somPrintf("IsTopDraft: draft refcount is %d\n", draft->GetRefCount(ev));
  150. #endif
  151.  
  152.     return !(draft->GetDocument(ev)->Exists(ev, kODNULLID, draft, kODPosFirstAbove));
  153. }
  154.  
  155. //==============================================================================
  156. // ODLink
  157. //==============================================================================
  158.  
  159. //------------------------------------------------------------------------------
  160. // ODLink: somUninit
  161. //------------------------------------------------------------------------------
  162.  
  163. SOM_Scope void  SOMLINK ODLinksomUninit(ODLink *somSelf)
  164. {
  165.     /* ODLinkData *somThis = ODLinkGetData(somSelf); */
  166.     ODLinkMethodDebug("ODLink","somUninit");
  167.  
  168.     parent_somUninit(somSelf);
  169. }
  170.  
  171. //------------------------------------------------------------------------------
  172. // ODLink: InitLink
  173. //------------------------------------------------------------------------------
  174.  
  175. SOM_Scope void  SOMLINK ODLinkInitLink(ODLink *somSelf, Environment *ev,
  176.         ODStorageUnit* storageUnit)
  177. {
  178.     ODLinkData *somThis = ODLinkGetData(somSelf);
  179.     ODLinkMethodDebug("ODLink","InitLink");
  180.  
  181.     SOM_TRY
  182.  
  183.     /* Moved from somInit. SOM itself sets fields to zero
  184.     _fSection = (SectionHandle) kODNULL;
  185.     _fDirty = kODFalse;
  186.     */
  187.     somSelf->InitBaseLink(ev, storageUnit);
  188.     
  189.     somSelf->SetLinkDirty(ev);
  190.  
  191.     SOM_CATCH_ALL
  192.     SOM_ENDTRY
  193. }
  194.  
  195. //------------------------------------------------------------------------------
  196. // ODLink: InitLinkFromStorage
  197. //------------------------------------------------------------------------------
  198.  
  199. SOM_Scope void  SOMLINK ODLinkInitLinkFromStorage(ODLink *somSelf, Environment *ev,
  200.         ODStorageUnit* storageUnit)
  201. {
  202.     ODLinkData *somThis = ODLinkGetData(somSelf);
  203.     ODLinkMethodDebug("ODLink","InitLinkFromStorage");
  204.  
  205.     SOM_TRY
  206.     
  207.     /* Moved from somInit. SOM itself sets fields to zero
  208.     _fSection = (SectionHandle) kODNULL;
  209.     _fDirty = kODFalse;
  210.     */
  211.     somSelf->InitBaseLinkFromStorage(ev, storageUnit);
  212.  
  213.     if (ODSUExistsThenFocus(ev, storageUnit, kODPropLinkSection, kODApplesect)) 
  214.     {
  215.         const int sectionRecordSize = sizeof(SectionRecord);
  216.  
  217.         if ( storageUnit->GetSize(ev) != sectionRecordSize )
  218.             THROW(kODErrCorruptLink);
  219.  
  220.         AliasHandle alias = kODNULL;
  221.         ODVolatile(alias);
  222.  
  223.         TRY
  224.             _fSection = (SectionHandle) ODNewHandle(sectionRecordSize);
  225.             ODValue theSectionPtr = ODLockHandle((ODHandle) _fSection);
  226.             StorageUnitGetValue(storageUnit, ev, sectionRecordSize, theSectionPtr);
  227.             ODUnlockHandle((ODHandle) _fSection);
  228.             
  229.             if ( (**_fSection).kind != stPublisher )
  230.                 THROW(kODErrCorruptLink);
  231.         
  232.             storageUnit->Focus(ev, kODPropEditionAlias, kODPosUndefined, kODApplealis, (ODValueIndex)0, kODPosUndefined);
  233.             ODULong size = storageUnit->GetSize(ev);
  234.         
  235.             if ( size < sizeof(AliasRecord) )
  236.                 THROW(kODErrCorruptLink);
  237.         
  238.             alias = (AliasHandle) ODNewHandle(size);
  239.             ODValue theAliasPtr = ODLockHandle((ODHandle) alias);
  240.             StorageUnitGetValue(storageUnit, ev, size, theAliasPtr);
  241.             ODUnlockHandle((ODHandle) alias);
  242.         CATCH_ALL
  243.             ODDisposeHandle((ODHandle) _fSection);
  244.             _fSection = (SectionHandle) kODNULL;
  245.             ODDisposeHandle((ODHandle) alias);
  246.             RERAISE;
  247.         ENDTRY
  248.  
  249.         (**_fSection).alias = alias;
  250.         (**_fSection).refCon = (long) somSelf;
  251.  
  252.         if ( IsTopDraft(ev, storageUnit->GetDraft(ev)) )
  253.         {
  254.             if ( IsRegisteredSection(_fSection) != noErr )
  255.             {
  256.                 ODBoolean aliasWasUpdated;
  257.  
  258.                 ODLinkManager* linkManager = storageUnit->GetSession(ev)->GetLinkManager(ev);
  259.  
  260.                 linkManager->RegisterSection(ev, _fSection, storageUnit->GetDraft(ev), &aliasWasUpdated);
  261.                 
  262.                 // For now, ignore any error returned by RegisterSection.  The most likely errors are:
  263.                 //    multiplePublisherWrn = -460,        A Publisher is already registered for that container
  264.                 //    containerNotFoundWrn = -461,        Could not find editionContainer at this time
  265.                 //    containerAlreadyOpenWrn = -462,        Container already opened by this section
  266.                 //    notThePublisherWrn = -463,            Not the first registered publisher for that container
  267.     
  268.                 if ( IsRegisteredSection(_fSection) == noErr )
  269.                     somSelf->Acquire(ev);    // Link must not be deleted untill its section is unregistered!
  270.             }
  271.         }
  272.     }
  273.  
  274.     SOM_CATCH_ALL
  275.     SOM_ENDTRY
  276. }
  277.  
  278. //------------------------------------------------------------------------------
  279. // ODLink: Release (OVERRIDE)
  280. //------------------------------------------------------------------------------
  281.  
  282. SOM_Scope void  SOMLINK ODLinkRelease(ODLink *somSelf, Environment *ev)
  283. {
  284.     ODLinkData *somThis = ODLinkGetData(somSelf);
  285.     ODLinkMethodDebug("ODLink","Release");
  286.  
  287.     SOM_TRY
  288.  
  289.     parent_Release(somSelf, ev);
  290.  
  291. #if ODDebugLink
  292.     somPrintf("ODLink %d::Release: Ref count is %d\n", somSelf->GetID(ev), somSelf->GetRefCount(ev));
  293. #endif
  294.  
  295.     if (somSelf->GetRefCount(ev) == 0)
  296.         somSelf->GetStorageUnit(ev)->GetDraft(ev)->ReleaseLink(ev, somSelf);
  297.  
  298.     SOM_CATCH_ALL
  299.     SOM_ENDTRY
  300. }
  301.  
  302. //------------------------------------------------------------------------------
  303. // ODLink: Externalize (OVERRIDE)
  304. //------------------------------------------------------------------------------
  305.  
  306. SOM_Scope void  SOMLINK ODLinkExternalize(ODLink *somSelf, Environment *ev)
  307. {
  308.     ODLinkData *somThis = ODLinkGetData(somSelf);
  309.     ODLinkMethodDebug("ODLink","Externalize");
  310.  
  311.     SOM_TRY
  312.  
  313.     parent_Externalize(somSelf,ev);
  314.  
  315.     ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  316.  
  317.     if ( _fDirty )
  318.     {
  319.         if ( _fSection == (SectionHandle) kODNULL ) 
  320.         {
  321.             ODSURemoveProperty(ev, su, kODPropLinkSection);
  322.             ODSURemoveProperty(ev, su, kODPropEditionAlias);
  323.         }
  324.         else 
  325.         {
  326.             SectionPtr theSectionPtr = (SectionPtr) ODLockHandle((ODHandle) _fSection);
  327.     
  328.             ODSUForceFocus(ev, su, kODPropLinkSection, kODApplesect);
  329.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) _fSection), (ODValue) theSectionPtr);
  330.             
  331.             ODValue theAliasPtr = ODLockHandle((ODHandle) theSectionPtr->alias);
  332.             ODSUForceFocus(ev, su, kODPropEditionAlias, kODApplealis);
  333.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) theSectionPtr->alias), theAliasPtr);
  334.             
  335.             ODUnlockHandle((ODHandle) theSectionPtr->alias);
  336.             ODUnlockHandle((ODHandle) _fSection);
  337.         }
  338.         _fDirty = kODFalse;
  339.     }
  340.  
  341.     SOM_CATCH_ALL
  342.     SOM_ENDTRY
  343. }
  344.  
  345. //------------------------------------------------------------------------------
  346. // ODLink: CloneInto (OVERRIDE)
  347. //------------------------------------------------------------------------------
  348. // We don't clone the cross-document link info, so a second publisher can't be created.
  349. // This depends on this method being called rather than ODStorageUnit::CloneInto().
  350. // Currently, all link objects are internalized when a draft is opened, so this is true.
  351.  
  352. SOM_Scope void  SOMLINK ODLinkCloneInto(ODLink *somSelf, Environment *ev,
  353.         ODDraftKey key,
  354.         ODStorageUnit* toSU,
  355.         ODFrame* scopeFrame)
  356. {
  357.     ODLinkData *somThis = ODLinkGetData(somSelf);
  358.     ODLinkMethodDebug("ODLink","CloneInto");
  359.  
  360.     SOM_TRY
  361.     
  362.     // If one of our properties already exists, this object has been cloned already
  363.     if ( toSU->Exists(ev, kODPropLinkSection, kODApplesect, 0) )
  364.         return;
  365.  
  366.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  367.  
  368.     SOM_CATCH_ALL
  369.     SOM_ENDTRY
  370. }
  371.  
  372. //------------------------------------------------------------------------------
  373. // ODLink: ReleaseAll (OVERRIDE)
  374. //------------------------------------------------------------------------------
  375.  
  376. SOM_Scope void  SOMLINK ODLinkReleaseAll(ODLink *somSelf, Environment *ev)
  377. {
  378.     ODLinkData *somThis = ODLinkGetData(somSelf);
  379.     ODLinkMethodDebug("ODLink","ReleaseAll");
  380.  
  381.     SOM_TRY
  382.  
  383.     parent_ReleaseAll(somSelf,ev);
  384.  
  385.     if ( _fSection != (SectionHandle) kODNULL ) 
  386.     {
  387.         if ( IsTopDraft(ev, somSelf->GetStorageUnit(ev)->GetDraft(ev)) )
  388.         {
  389.             if ( IsRegisteredSection(_fSection) == noErr )
  390.             {
  391.                 ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  392.                 linkManager->UnregisterSection(ev, _fSection);;
  393.                 somSelf->Release(ev);    // RefCount incremented when section was registered
  394.             }
  395.         }
  396.  
  397.         ODDisposeHandle((ODHandle) (**_fSection).alias);
  398.         ODDisposeHandle((ODHandle) _fSection);
  399.         _fSection = (SectionHandle) kODNULL;
  400.     }
  401.  
  402.     SOM_CATCH_ALL
  403.     SOM_ENDTRY
  404. }
  405.  
  406. //------------------------------------------------------------------------------
  407. // ODLink: UpdateDependents (OVERRIDE)
  408. //------------------------------------------------------------------------------
  409.  
  410. SOM_Scope void  SOMLINK ODLinkUpdateDependents(ODLink *somSelf, Environment *ev)
  411. {
  412.     ODLinkData *somThis = ODLinkGetData(somSelf);
  413.     ODLinkMethodDebug("ODLink","UpdateDependents");
  414.  
  415.     SOM_TRY
  416.  
  417.     parent_UpdateDependents(somSelf, ev);
  418.  
  419.     if ( (_fSection != (SectionHandle) kODNULL) )
  420.     {
  421.         ODBoolean autoUpdate = somSelf->GetLinkSource(ev)->IsAutoUpdate(ev);
  422.         if ( autoUpdate )
  423.         {
  424.             ODLinkManager*    linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  425.             linkManager->ExportOnSave(ev, somSelf, kODTrue);
  426.         }
  427.         else
  428.         {
  429.             ODLinkKey key;
  430.             ODVolatile(key);
  431.             if ( somSelf->Lock(ev, 0, &key) ) 
  432.             {
  433.                 TRY
  434.                     somSelf->UpdateLinkEdition(ev, key);
  435.                 CATCH_ALL
  436.                     somSelf->Unlock(ev, key);
  437.                     RERAISE;
  438.                 ENDTRY
  439.                 somSelf->Unlock(ev, key);
  440.             }
  441.         }
  442.     }
  443.  
  444.     SOM_CATCH_ALL
  445.     SOM_ENDTRY
  446. }
  447.  
  448. //------------------------------------------------------------------------------
  449. // ODLink::ShowLinkDestinationInfo (OVERRIDE)
  450. //------------------------------------------------------------------------------
  451.  
  452. SOM_Scope ODBoolean  SOMLINK ODLinkShowLinkDestinationInfo(ODLink *somSelf, Environment *ev,
  453.         ODFacet* facet,
  454.         ODLinkInfo* info,
  455.         ODBoolean changesAllowed,
  456.         ODLinkInfoResult* infoResult)
  457. {
  458.     ODLinkData *somThis = ODLinkGetData(somSelf);
  459.     ODLinkMethodDebug("ODLink","ShowLinkDestinationInfo");
  460.  
  461.     SOM_TRY
  462.     
  463.     ODLinkSource* linkSource = somSelf->GetLinkSource(ev);
  464.     
  465.     ODError error = linkSource->GetStatus(ev);
  466.  
  467.     if ( error )
  468.         ShowLinkStatusAlert(error);
  469.  
  470.     return parent_ShowLinkDestinationInfo(somSelf, ev, facet, info, changesAllowed, infoResult);
  471.  
  472.     SOM_CATCH_ALL
  473.     SOM_ENDTRY
  474.     return kODFalse;
  475. }
  476.  
  477. //------------------------------------------------------------------------------
  478. // ODLink: SetLinkDirty
  479. //------------------------------------------------------------------------------
  480.  
  481. SOM_Scope void  SOMLINK ODLinkSetLinkDirty(ODLink *somSelf, Environment *ev)
  482. {
  483.     ODLinkData *somThis = ODLinkGetData(somSelf);
  484.     ODLinkMethodDebug("ODLink","SetLinkDirty");
  485.  
  486.     SOM_TRY    
  487.         _fDirty = kODTrue;
  488.  
  489.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  490.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  491.             draft->SetChangedFromPrev(ev);
  492.     SOM_CATCH_ALL
  493.     SOM_ENDTRY
  494. }
  495.  
  496. //------------------------------------------------------------------------------
  497. // ODLink: CreateLinkEdition
  498. //------------------------------------------------------------------------------
  499.  
  500. SOM_Scope void  SOMLINK ODLinkCreateLinkEdition(ODLink *somSelf, Environment *ev,
  501.         EditionContainerSpec *editionContainer,
  502.         ODFileSpec* documentSpec,
  503.         ODULong sectionID,
  504.         ODLinkKey key,
  505.         ODByteArray* aliasData)
  506. {
  507.     ODLinkData *somThis = ODLinkGetData(somSelf);
  508.     ODLinkMethodDebug("ODLink","CreateLinkEdition");
  509.  
  510.     OSErr error;
  511.     OSErr createError = mFulErr;    // Anything but noErr
  512.     SectionHandle tempSection = kODNULL;
  513.     
  514.     ODVolatile(createError);
  515.     ODVolatile(tempSection);
  516.     ODVolatile(editionContainer);
  517.  
  518.     SOM_TRY
  519.     
  520.         somSelf->KeyValid(ev, key);
  521.     
  522.         // Should throw kODErrCannotCreateLink if linkSource imports
  523.         
  524.         if ( _fSection != kODNULL)
  525.             THROW(kODErrLinkAlreadyExported);    // Internal error
  526.         
  527.         FInfo documentFInfo;
  528.         error = FSpGetFInfo((FSSpecPtr) documentSpec, &documentFInfo);
  529.         THROW_IF_ERROR(error);
  530.     
  531.         createError = CreateEditionContainerFile(&editionContainer->theFile, 
  532.                     documentFInfo.fdCreator, editionContainer->theFileScript);
  533.         THROW_IF_ERROR(createError);
  534.     
  535.         error = NewSection(editionContainer, (FSSpecPtr) documentSpec, stPublisher, sectionID, pumOnSave, &tempSection);
  536.         if ( (error != noErr) && 
  537.              (error != multiplePublisherWrn) &&
  538.              (error != notThePublisherWrn) ) 
  539.         {
  540.             THROW(error);
  541.         }
  542.     
  543.         (**tempSection).mdDate = (TimeStamp) somSelf->GetChangeTime(ev);
  544.         (**tempSection).refCon = (long) somSelf;
  545.     
  546.         somSelf->WriteLinkEdition(ev, tempSection, (FSSpecPtr) documentSpec, key);
  547.  
  548.         // Edition file was successfully created and written, so add section to persistent state.
  549.         // This Link must not be deleted until its section is unregistered!
  550.         ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  551.         linkManager->SectionCreated(ev, tempSection);
  552.  
  553.         _fSection = tempSection;
  554.         somSelf->Acquire(ev);
  555.  
  556.         somSelf->SetLinkDirty(ev);
  557.     
  558.         TempODHandleLock aHandle((ODHandle) (**_fSection).alias);
  559.         if ( (ODHandle) aHandle )
  560.             *aliasData = CreateByteArrayStruct(*(ODHandle) aHandle, ODGetHandleSize(aHandle));
  561.         
  562.     SOM_CATCH_ALL
  563.  
  564.         if ( createError == noErr )
  565.             DeleteEditionContainerFile(&editionContainer->theFile);
  566.  
  567.         if ( tempSection ) 
  568.         {
  569.             UnRegisterSection(tempSection);
  570.             ODDisposeHandle((ODHandle) (**tempSection).alias);
  571.             ODDisposeHandle((ODHandle) tempSection);
  572.         }
  573.  
  574.     SOM_ENDTRY
  575. }
  576.  
  577. //------------------------------------------------------------------------------
  578. // ODLink: GetLinkEdition
  579. //------------------------------------------------------------------------------
  580.  
  581. SOM_Scope ODBoolean  SOMLINK ODLinkGetLinkEdition(ODLink *somSelf, Environment *ev,
  582.         ODLinkKey key,
  583.         ODByteArray* aliasData)
  584. {
  585.     ODLinkData *somThis = ODLinkGetData(somSelf);
  586.     ODLinkMethodDebug("ODLink","GetLinkEdition");
  587.  
  588.     ODBoolean result = kODFalse;
  589.     
  590.     SOM_TRY
  591.  
  592.         somSelf->KeyValid(ev, key);
  593.     
  594.         if ( _fSection != (SectionHandle) kODNULL )
  595.         {
  596.             TempODHandleLock aHandle((ODHandle) (**_fSection).alias);
  597.             if ( (ODHandle) aHandle )
  598.             {
  599.                 *aliasData = CreateByteArrayStruct(*(ODHandle) aHandle, ODGetHandleSize(aHandle));
  600.                 result = kODTrue;
  601.             }
  602.         }
  603.  
  604.     SOM_CATCH_ALL
  605.     SOM_ENDTRY
  606.  
  607.     return result;
  608. }
  609.  
  610. //------------------------------------------------------------------------------
  611. // ODLink: DeleteLinkEdition
  612. //------------------------------------------------------------------------------
  613.  
  614. SOM_Scope void  SOMLINK ODLinkDeleteLinkEdition(ODLink *somSelf, Environment *ev,
  615.         ODLinkKey key)
  616. {
  617.     ODLinkData *somThis = ODLinkGetData(somSelf);
  618.     ODLinkMethodDebug("ODLink","DeleteLinkEdition");
  619.  
  620.     SOM_TRY
  621.  
  622.     somSelf->KeyValid(ev, key);
  623.  
  624.     if ( _fSection != (SectionHandle) kODNULL )
  625.     {
  626.         if ( IsTopDraft(ev, somSelf->GetStorageUnit(ev)->GetDraft(ev)) )
  627.         {
  628.             FSSpec editionFile;
  629.             ODBoolean wasChanged;
  630.     
  631.             OSErr error = ResolveAlias(nil, (**_fSection).alias, &editionFile, &wasChanged);
  632.             THROW_IF_ERROR(error);
  633.  
  634.             if ( IsRegisteredSection(_fSection) == noErr )
  635.             {
  636.                 ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  637.                 
  638.                 error = linkManager->UnregisterSection(ev, _fSection);;
  639.                 if ( error == noErr )
  640.                     somSelf->Release(ev);    // RefCount incremented when section was registered
  641.             }
  642.  
  643.             error = DeleteEditionContainerFile(&editionFile);
  644.             THROW_IF_ERROR(error);
  645.  
  646.             ODDisposeHandle((ODHandle) (**_fSection).alias);
  647.             ODDisposeHandle((ODHandle) _fSection);
  648.             _fSection = (SectionHandle) kODNULL;
  649.             
  650.             somSelf->SetLinkDirty(ev);
  651.         }
  652.     }
  653.  
  654.     SOM_CATCH_ALL
  655.     SOM_ENDTRY
  656. }
  657.  
  658. //------------------------------------------------------------------------------
  659. // ODLink: UpdateLinkEdition
  660. //------------------------------------------------------------------------------
  661.  
  662. SOM_Scope void  SOMLINK ODLinkUpdateLinkEdition(ODLink *somSelf, Environment *ev,
  663.         ODLinkKey key)
  664. {
  665.     ODLinkData *somThis = ODLinkGetData(somSelf);
  666.     ODLinkMethodDebug("ODLink","UpdateLinkEdition");
  667.  
  668.     SOM_TRY
  669.  
  670.     if (_fSection != (SectionHandle) kODNULL) 
  671.     {
  672.         ODTime changeTime = somSelf->GetChangeTime(ev);
  673.         if ((TimeStamp) changeTime != (**_fSection).mdDate) 
  674.         {
  675.             ODStorageUnit* storageUnit = somSelf->GetStorageUnit(ev);
  676.             ODContainer* container = storageUnit->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);;
  677.             ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  678.  
  679.             (**_fSection).mdDate = (TimeStamp) changeTime;
  680.             somSelf->WriteLinkEdition(ev, _fSection, &documentSpec, key);
  681.         }
  682.     }
  683.  
  684.     SOM_CATCH_ALL
  685.     SOM_ENDTRY
  686. }
  687.  
  688. //------------------------------------------------------------------------------
  689. // ODLink: GetPlatformValue
  690. //------------------------------------------------------------------------------
  691.  
  692. SOM_Scope ODHandle  SOMLINK ODLinkGetPlatformValue(ODLink *somSelf, Environment *ev,
  693.         ODPlatformType platformType,
  694.         ODLinkKey key)
  695. {
  696.     ODLinkData *somThis = ODLinkGetData(somSelf);
  697.     ODLinkMethodDebug("ODLink","GetPlatformValue");
  698.  
  699.     ODHandle        dataHandle = (ODHandle) kODNULL;
  700.     
  701.     SOM_TRY
  702.     
  703.     ODULong            dataSize;
  704.     ODStorageUnit*    contentSU = somSelf->GetContentStorageUnit(ev, key);
  705.     ODValueType        isoType = kODNULL;
  706.  
  707.     ODVolatile(isoType);
  708.     ODVolatile(dataHandle);
  709.     TRY
  710.         ODTranslation* translation = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetTranslation(ev);
  711.         isoType = translation->GetISOTypeFromPlatformType(ev, platformType, kODPlatformDataType);
  712.  
  713.         if ( ODSUExistsThenFocus(ev, contentSU, kODPropContents, isoType) )
  714.         {
  715.             dataSize = contentSU->GetSize(ev);
  716.             dataHandle = ODNewHandle(dataSize);
  717.             ODValue dataPtr = ODLockHandle(dataHandle);
  718.             StorageUnitGetValue(contentSU, ev, dataSize, dataPtr);
  719.             ODUnlockHandle(dataHandle);
  720.         }
  721.     CATCH_ALL
  722.         ODDisposeHandle(dataHandle);
  723.         dataHandle = (ODHandle) kODNULL;
  724.     ENDTRY
  725.  
  726.     ODDisposePtr(isoType);
  727.     
  728.     SOM_CATCH_ALL
  729.         dataHandle = kODNULL;
  730.     SOM_ENDTRY
  731.  
  732.     return dataHandle;
  733. }
  734.  
  735. //------------------------------------------------------------------------------
  736. // ODLink: CloneToMemoryContainer
  737. //------------------------------------------------------------------------------
  738.  
  739. SOM_Scope ODHandle  SOMLINK ODLinkCloneToMemoryContainer(ODLink *somSelf, Environment *ev,
  740.         ODLinkKey key)
  741. {
  742.     ODLinkData *somThis = ODLinkGetData(somSelf);
  743.     ODLinkMethodDebug("ODLink","CloneToMemoryContainer");
  744.  
  745.     SOM_TRY
  746.  
  747.     ODHandle            containerHandle;
  748.     ODContainer*        container = (ODContainer*) kODNULL;
  749.     ODDocument*            document = (ODDocument*) kODNULL;
  750.     ODDraft*            draft = (ODDraft*) kODNULL;
  751.     ODStorageUnit*        draftProperties = (ODStorageUnit*) kODNULL;
  752.     ODStorageUnit*        contentSU = (ODStorageUnit*) kODNULL;
  753.     ODDraft*            myDraft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  754.     ODSession*            session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  755.     ODStorageUnitID        rootSUID = 0;
  756.  
  757.     ODVolatile(draft);
  758.     ODVolatile(draftProperties);
  759.     ODVolatile(document);
  760.     ODVolatile(container);
  761.     ODVolatile(containerHandle);
  762.     ODVolatile(myDraft);
  763.     
  764.     contentSU = somSelf->GetContentStorageUnit(ev, key);
  765.  
  766.     // Externalize contentSU to force resolution of promises before the
  767.     // clone into the memory container is begun.
  768.     contentSU->Externalize(ev);
  769.  
  770.     containerHandle = ODNewHandle(0);
  771.     TRY
  772.         container = CreateMemoryContainer(ev, session, containerHandle, kODBentoMemoryContainer);
  773.         
  774.         document = container->AcquireDocument(ev, kODDefaultDocument);
  775.             
  776.         draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  777.         
  778.         ODDraftKey draftKey = myDraft->BeginClone(ev, draft, kODNULL, kODCloneAll);
  779.         ODVolatile(draftKey);
  780.         TRY
  781.             rootSUID = myDraft->Clone(ev, draftKey, contentSU->GetID(ev), kODNULLID, 0);    
  782.  
  783.             if ( ODSUExistsThenFocus(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef) )
  784.             {
  785.                 ODID contentFrameID = ODGetWeakSURefProp(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef);
  786.                 myDraft->Clone(ev, draftKey, contentFrameID, kODNULLID, 0);                
  787.             }        
  788.         CATCH_ALL
  789.             myDraft->AbortClone(ev, draftKey);
  790.             RERAISE;
  791.         ENDTRY
  792.         
  793.         myDraft->EndClone(ev, draftKey);
  794.  
  795.         draftProperties = draft->AcquireDraftProperties(ev);
  796.         ODSetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef, rootSUID);
  797.         draftProperties->Release(ev);
  798.         draftProperties = kODNULL;
  799.  
  800.         draft->Externalize(ev);
  801.         draft->Release(ev);
  802.         document->Release(ev);
  803.         container->Release(ev);
  804.  
  805.     CATCH_ALL
  806.         ODReleaseObject(ev, draftProperties);
  807.         ODReleaseObject(ev, draft);
  808.         ODReleaseObject(ev, document);
  809.         ODReleaseObject(ev, container);
  810.         
  811.         ODDisposeHandle(containerHandle);
  812.         RERAISE;
  813.     ENDTRY
  814.  
  815.     return containerHandle;
  816.  
  817.     SOM_CATCH_ALL
  818.     SOM_ENDTRY
  819.     return (ODHandle) kODNULL;
  820. }
  821.  
  822. //------------------------------------------------------------------------------
  823. // ODLink: WriteLinkEdition
  824. //------------------------------------------------------------------------------
  825.  
  826. SOM_Scope void  SOMLINK ODLinkWriteLinkEdition(ODLink *somSelf, Environment *ev,
  827.         SectionHandle section,
  828.         ODFileSpec* documentSpec,
  829.         ODLinkKey key)
  830. {
  831.     ODLinkData *somThis = ODLinkGetData(somSelf);
  832.     ODLinkMethodDebug("ODLink","WriteLinkEdition");
  833.  
  834.     OSErr            infoError;
  835.     OSErr            openError;
  836.     OSErr            writeError = noErr;
  837.     EditionRefNum    edRefNum = 0;
  838.     ODHandle        dataHandle = (ODHandle) kODNULL;
  839.     ODBoolean        successful = kODTrue;
  840.  
  841.     ODVolatile(dataHandle);
  842.     ODVolatile(successful);
  843.     
  844.     SOM_TRY 
  845.  
  846.         if ( section == (SectionHandle) kODNULL ) 
  847.             THROW(kODErrNotExportedLink);
  848.     
  849.         FInfo documentFInfo;
  850.         infoError = FSpGetFInfo((FSSpecPtr) documentSpec, &documentFInfo);
  851.         THROW_IF_ERROR(infoError);
  852.     
  853.         openError = OpenNewEdition(section, documentFInfo.fdCreator, documentSpec, &edRefNum);
  854.         THROW_IF_ERROR(openError);
  855.     
  856.         dataHandle = somSelf->CloneToMemoryContainer(ev, key);
  857.         if ( dataHandle != (ODHandle) kODNULL ) 
  858.         {
  859.             ODPtr dataPtr = ODLockHandle(dataHandle);
  860.             writeError = WriteEdition(edRefNum, kODScrapTypeODBentoContainer, dataPtr, ODGetHandleSize(dataHandle));
  861.             ODDisposeHandle(dataHandle);
  862.             dataHandle = kODNULL;
  863.         }
  864.         THROW_IF_ERROR(writeError);
  865.     
  866.         // Also write out any text content property (unnecessary for OpenDoc, but allows
  867.         // subscribing by non-OpenDoc applications, and allows the Edition Manager to display
  868.         // content in the GetInfo dialog.
  869.         dataHandle = somSelf->GetPlatformValue(ev, 'TEXT', key);
  870.         if ( dataHandle != (ODHandle) kODNULL ) 
  871.         {
  872.             ODPtr dataPtr = ODLockHandle(dataHandle);
  873.             writeError = WriteEdition(edRefNum, 'TEXT', dataPtr, ODGetHandleSize(dataHandle));
  874.             ODUnlockHandle(dataHandle);
  875.             ODDisposeHandle(dataHandle);
  876.             dataHandle = kODNULL;
  877.         }
  878.         THROW_IF_ERROR(writeError);
  879.  
  880.         dataHandle = somSelf->GetPlatformValue(ev, 'PICT', key);
  881.         if ( dataHandle != (ODHandle) kODNULL ) 
  882.         {
  883.             ODPtr dataPtr = ODLockHandle(dataHandle);
  884.             writeError = WriteEdition(edRefNum, 'PICT', dataPtr, ODGetHandleSize(dataHandle));
  885.             ODUnlockHandle(dataHandle);
  886.             ODDisposeHandle(dataHandle);
  887.             dataHandle = kODNULL;
  888.         }
  889.         THROW_IF_ERROR(writeError);
  890.  
  891.  
  892.     SOM_CATCH_ALL
  893.  
  894.         ODDisposeHandle(dataHandle);
  895.         successful = kODFalse;
  896.  
  897.     SOM_ENDTRY;
  898.  
  899.     if ( edRefNum != 0 )
  900.         CloseEdition(edRefNum, successful);
  901. }
  902.