home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / Link.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  31.5 KB  |  1,030 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.          <3>     3/19/96    TJ        Included TempObj.h
  13.          <2>     3/15/96    CC        1331422: CreateLinkEdition & GetLinkEdition
  14.                                     return an ODByteArray instead of an
  15.                                     uncopied  handle.
  16.         <43>     10/8/95    TJ        Fixes Recomended by Refball
  17.         <42>     10/4/95    jpa        Added missing ODVolatiles [1285799]
  18.         <41>      9/8/95    TÇ        1281096 FB2:Many constants in ODTypesB
  19.                                     without kOD prefix!
  20.         <40>     8/12/95    TÇ        1276807 Opt./Bug: use StdTypIO routines for
  21.                                     portable streaming & smaller footprint
  22.         <39>      8/3/95    RR        #1257260: Collapse B classes. Remove
  23.                                     somInit methods. Don't call IsInitialized
  24.                                     or SubclassResponsibility
  25.         <38>     7/28/95    CC        1183569: Externalize only when dirty.
  26.         <37>     7/27/95    CC        1259986: WriteLinkEdition: Close edition
  27.                                     file on failure.
  28.                                     CreateLinkEdition: Delete edition file on
  29.                                     error writing file.
  30.         <36>     7/24/95    CC        1154714: Removed ODUpdateID parameter from
  31.                                     UpdateDependents.
  32.         <35>     7/21/95    CC        1153788: Write 'TEXT' & 'PICT' formats to
  33.                                     Edition file.
  34.         <34>     6/30/95    CC        1242642: DeleteLinkEdition: Release after
  35.                                     unregistering.
  36.         <33>     5/26/95    VL        1251403: Multithreading naming support.
  37.         <32>     5/22/95    CC        1248361: CloneToMemoryContainer:
  38.                                     Externalize content SU to  resolve promises
  39.                                     before cloning to memory container.
  40.         <31>     5/18/95    CC        1238898: Add destFrame argument to
  41.                                     BeginClone call.
  42.         <30>     5/16/95    CC        1248090: CloneToMemoryContainer: Clone
  43.                                     content frame if present.
  44.         <29>     4/25/95    CC        1242555:  Removed obsolete $5 comment.
  45.         <28>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  46.                                     should take Environment* and SU* when
  47.                                     possible
  48.         <27>     4/11/95    CC        1236452:  Replaced SOM_CATCH with SOM_TRY
  49.                                     in WriteLinkEdition.
  50.                                     Added parenthesis to TopDraft (probably not
  51.                                     necessary).
  52.         <26>      4/3/95    CC        1229068: IsTopDraft: Use ODDocument::Exists
  53.                                     to test for top draft.
  54.         <25>      3/9/95    CC        1221471: Added changesAllowed parameter to
  55.                                     ShowLinkDestinationInfo().
  56.         <24>      3/3/95    CC        1223861, 1153949 Override
  57.                                     ShowLinkDestinationInfo().
  58.         <23>      2/7/95    CC        1185113 Externalize: Lock handles during
  59.                                     writing.
  60.                                     1193560 InitLinkFromStorage: Use ptr
  61.                                     returned by ODLockHandle;
  62.                                     WASSERTS --> if…THROW
  63.         <22>      2/1/95    CC        1153347 Added static function IsTopDraft().
  64.                                     Register sections if draft is topmost.
  65.                                     Use IsRegisteredSection for robustness.
  66.         <21>     1/19/95    CC        1212831, 1193556, 1194158 Use creator of
  67.                                     document file when creating edition file.
  68.         <20>    12/22/94    CC        1153926 UpdateDependents() - Update
  69.                                     cross-document links immediately if source
  70.                                     is manual.
  71.         <19>    12/22/94    CC        1153759 CreateLinkEdition - call ODDRaft::
  72.                                     SetChangedFromPrev().
  73.                                     1207987 Added DeleteLinkEdition().
  74.         <18>    12/20/94    VL        1195012: Make Storage calls be
  75.                                     marshallable.
  76.         <17>    12/16/94    CC        1203516 Removed ODLinkSource parameter from
  77.                                     InitLink().
  78.         <16>     12/8/94    CC        1154711 InitLinkFromStorage(),
  79.                                     ReleaseAll(): Only register & unregister
  80.                                     with the Edition manager if draft has write
  81.                                     permission.
  82.         <15>    11/30/94    RR        1188078 Use ODTime, not time_t
  83.         <14>     10/7/94    CC        1191089 - Use change time for mod date of
  84.                                     edition file.
  85.         <13>     10/4/94    CC        1190862 - Added Release().
  86.         <12>     9/29/94    RA        1189812: Mods for 68K build.
  87.         <11>     9/23/94    VL        1184272: ContainerID is now a sequence of
  88.                                     octets.
  89.         <10>     9/15/94    CC        1186669 - Implemented CloneInto();
  90.                                     CloneToMemoryContainer use draftKey for
  91.                                     Clone() call.
  92.          <9>      9/7/94    CC        #1185114 - Catch throws from KeyValid().
  93.          <8>     8/26/94    VL        1183174: Use updated cloning APIs.
  94.          <7>     8/15/94    TÇ        #1180922 Removed most obsolete types from
  95.                                     StdTypes.idl
  96.          <6>     8/10/94    CC        1179943 - Moved platform-independent
  97.                                     implementation into LinkB.cpp.
  98.          <5>      8/3/94    VL        1153123: Storage to ODStor.
  99.          <4>     6/24/94    CC        Clean up some easy $5 comments.
  100.          <3>     6/24/94    CC        Added call to ShowLinkDestinationInfo().
  101.          <2>     6/24/94    CC        Changed parameters to InitBaseLink().
  102.          <1>     6/21/94    CC        first checked in
  103.  
  104.         ------------------- CC ---- Converted to SOM
  105.  
  106.          <5>      5/9/94    MB        #1162181: Changes necessary to install MMM.
  107.          <4>     4/12/94    CC        Clients may call UnregisterDependent()
  108.                                     after this object's ReleaseAll() method has
  109.                                     run. (1155973)
  110.          <3>     3/28/94    CG        1153547: ODSessn.h renamed to ODSessM.h
  111.          <2>     3/27/94    TÇ        #1153523.  Adjust name of
  112.                                     kODPropRootPartSU to more clearly indicate
  113.                                     what it is supposed to be used for.
  114.          <1>     3/25/94    CC        first checked in
  115.  
  116.         ------------------- CC ---- Moved from Core to Storage subsystem
  117.  
  118.          <7>     3/24/94    CC        Implemented CloneTo() (1153038) and
  119.                                     GetChangeTime() (115340).
  120.          <6>     3/15/94    MB        Changes to support SCpp/ASLM builds,
  121.                                     #1150864.
  122.          <5>      3/2/94    CC        ReleaseAll: Check fLinkSource for NIL
  123.                                     before releasing it! (1144936)
  124.          <4>      3/1/94    JA        Include ODMemory.h. (1147588)
  125.          <3>      3/1/94    CC        Replaced calls to HLock, HUnlock, and
  126.                                     GetHandleSize with OD equivalents.
  127.          <2>     2/17/94    CC        CloneToMemoryContainer: Re-instate fix lost
  128.                                     after 2/2/94    checkin.
  129.         <12>      2/8/94    TÇ        Throw -> THROW & some code clean up
  130.         <11>      2/7/94    TÇ        more fixes to compile with PPC Headers
  131.         <10>      2/4/94    TÇ        fixes to compile with PPC Universal headers
  132.          <9>      2/3/94    CG        System Session break out.
  133.          <8>      2/2/94    CC        CloneToMemoryContainer:  Moved code to set
  134.                                     kODPropRootSU property after the rootSU
  135.                                     has been determined.
  136.          <7>      2/1/94    CC        Pass ODCloneKind argument to BeginClone.
  137.          <6>     1/28/94    CC        Added ReleaseAll(); increment and decrement
  138.                                     ref count of part in ODPartList::AddPart
  139.                                     and ::RemovePart; release parts and delete
  140.                                     list entries in ODPartList destructor.
  141.          <5>     1/27/94    VL        Used ODStorageUnit::CloneInto.
  142.          <4>     1/25/94    CC        CloneToMemoryContainer: use distinct
  143.                                     identifiers for clipboard and draft keys;
  144.                                     RegisterDependent: call LinkUpdated only if
  145.                                     change id is different; GetTextValue: add
  146.                                     Volatile stmt.; UpdateDependents: remove
  147.                                     ODUnused().
  148.          <3>     1/24/94    CC        Added ODUpdateID parameter to call to
  149.                                     LinkUpdated().
  150.          <2>     1/22/94    CC        Don't call release() in destructor.
  151.          <1>     1/21/94    CC        first checked in
  152.         <17>     1/18/94    CG        Added include for StorgDef.h
  153.         <16>     1/18/94    CC        Use kODScrapTypePart; release draft
  154.                                     properties on failure in
  155.                                     CloneToMemoryContainer and
  156.                                     CloneFromMemoryContainer
  157.         <15>     1/14/94    CC        Added Lock(), Unlock(), GetTimeStamp(),
  158.                                     GetStatus(), SetAutoExport(),
  159.                                     IsAutoExport(), Export(),
  160.                                     ShowSourceContent(), type ODLinkKey; added
  161.                                     key parameter to various routines; renamed
  162.                                     Edition Manager support routines.
  163.         <14>     1/11/94    TÇ        Init... changes
  164.         <13>    12/22/93    CC        Maintain persistent fields fContentSU and
  165.                                     fChangedDate.  Read/write link content
  166.                                     from/to edition file by cloning fContentSU
  167.                                     into a memory container.  Increment link
  168.                                     ref count for registered sections.  Write
  169.                                     edition files only on Externalize().
  170.         <12>    12/21/93    VL        Changed ODStorageUnit::GetValueSize to
  171.                                     StorageUnit::GetSize.
  172.         <11>    12/16/93    CC        Added methods to create, write, and read
  173.                                     Edition files.  Save Edition Manager
  174.                                     section records and aliases persistently.
  175.         <10>    12/14/93    TÇ        InitLink changes.  Internalize, Initialize
  176.                                     went away.
  177.          <9>     12/8/93    CC        ODValueLink -> ODPartListLink to avoid
  178.                                     name conflict.  Removed multiple
  179.                                     constructors.  Added InitPartListLink
  180.          <8>    11/18/93    TÇ        call inherited::InitializePersistent()
  181.                                     ::Externalize()
  182.          <7>    11/17/93    CC        RegisterDependent calls the LinkUpdated
  183.                                     method of its part argument.
  184.          <6>     9/29/93    VL        Added InitializePersistent.
  185.          <5>      7/1/93    NP        Abstract/Concrete breakout.
  186.          <4>     6/10/93    NP        Added comments.
  187.          <3>     4/28/93    NP        File name changes.
  188.          <2>     4/27/93    NP        Now compilable.
  189.          <1>     4/21/93    NP        first checked in
  190.  
  191.     To Do:
  192.     In Progress:
  193. */
  194.  
  195. #define VARIABLE_MACROS
  196.  
  197. #define ODLink_Class_Source
  198. #include <Link.xih>
  199.  
  200. #ifndef _LINKDLGS_
  201. #include <LinkDlgs.h>
  202. #endif
  203.  
  204. #ifndef _EXCEPT_
  205. #include <Except.h>
  206. #endif
  207.  
  208. #ifndef _ODMEMORY_
  209. #include <ODMemory.h>
  210. #endif
  211.  
  212. #ifndef _CONSTDEF_
  213. #include <ConstDef.h>
  214. #endif
  215.  
  216. #ifndef SOM_ODLinkSource_xh
  217. #include <LinkSrc.xh>
  218. #endif
  219.  
  220. #ifndef SOM_ODLinkManager_xh
  221. #include <LinkMgr.xh>
  222. #endif
  223.  
  224. #ifndef SOM_ODPart_xh
  225. #include <Part.xh>
  226. #endif
  227.  
  228. #ifndef SOM_ODSession_xh
  229. #include <ODSessn.xh>
  230. #endif
  231.  
  232. #ifndef SOM_ODContainer_xh
  233. #include <ODCtr.xh>
  234. #endif
  235.  
  236. #ifndef SOM_ODDocument_xh
  237. #include <Document.xh>
  238. #endif
  239.  
  240. #ifndef SOM_ODDraft_xh
  241. #include <Draft.xh>
  242. #endif
  243.  
  244. #ifndef SOM_ODStorageSystem_xh
  245. #include <ODStor.xh>
  246. #endif
  247.  
  248. #ifndef _PLFMFILE_
  249. #include <PlfmFile.h>
  250. #endif
  251.  
  252. #ifndef SOM_ODStorageUnit_xh
  253. #include <StorageU.xh>
  254. #endif
  255.  
  256. #ifndef SOM_Module_OpenDoc_StdProps_defined
  257. #include <StdProps.xh>
  258. #endif
  259.  
  260. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  261. #include <StdTypes.xh>
  262. #endif
  263.  
  264. #ifndef __ERRORS__
  265. #include <Errors.h>
  266. #endif
  267.  
  268. #ifndef _ODDEBUG_
  269. #include <ODDebug.h>
  270. #endif
  271.  
  272. #ifndef _BARRAY_
  273. #include <BArray.h>
  274. #endif
  275.  
  276. #ifndef _STDTYPIO_
  277. #include <StdTypIO.h>
  278. #endif
  279.  
  280. #ifndef _STORUTIL_
  281. #include <StorUtil.h>
  282. #endif
  283.  
  284. #ifndef SOM_ODTranslation_xh
  285. #include <Translt.xh>
  286. #endif
  287.  
  288. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  289. #include <StdDefs.xh>
  290. #endif
  291.  
  292. #ifndef _TEMPOBJ_
  293. #include "TempObj.h"
  294. #endif
  295.  
  296. #if ODDebug
  297. #define ODDebugLink 1
  298. #else
  299. #define ODDebugLink 0
  300. #endif
  301.  
  302. #pragma segment ODLink
  303.  
  304. //==============================================================================
  305. // Local Functions
  306. //==============================================================================
  307.  
  308. static ODBoolean IsTopDraft(Environment* ev, ODDraft* draft);
  309.  
  310. //------------------------------------------------------------------------------
  311. // IsTopDraft
  312. //------------------------------------------------------------------------------
  313.  
  314. static ODBoolean IsTopDraft(Environment* ev, ODDraft* draft)
  315. {
  316. #if ODDebugLink
  317.     somPrintf("IsTopDraft: draft refcount is %d\n", draft->GetRefCount(ev));
  318. #endif
  319.  
  320.     return !(draft->GetDocument(ev)->Exists(ev, kODNULLID, draft, kODPosFirstAbove));
  321. }
  322.  
  323. //==============================================================================
  324. // ODLink
  325. //==============================================================================
  326.  
  327. //------------------------------------------------------------------------------
  328. // ODLink: somUninit
  329. //------------------------------------------------------------------------------
  330.  
  331. SOM_Scope void  SOMLINK ODLinksomUninit(ODLink *somSelf)
  332. {
  333.     /* ODLinkData *somThis = ODLinkGetData(somSelf); */
  334.     ODLinkMethodDebug("ODLink","somUninit");
  335.  
  336.     parent_somUninit(somSelf);
  337. }
  338.  
  339. //------------------------------------------------------------------------------
  340. // ODLink: InitLink
  341. //------------------------------------------------------------------------------
  342.  
  343. SOM_Scope void  SOMLINK ODLinkInitLink(ODLink *somSelf, Environment *ev,
  344.         ODStorageUnit* storageUnit)
  345. {
  346.     ODLinkData *somThis = ODLinkGetData(somSelf);
  347.     ODLinkMethodDebug("ODLink","InitLink");
  348.  
  349.     SOM_CATCH return;
  350.  
  351.     /* Moved from somInit. SOM itself sets fields to zero
  352.     _fSection = (SectionHandle) kODNULL;
  353.     _fDirty = kODFalse;
  354.     */
  355.     somSelf->InitBaseLink(ev, storageUnit);
  356.     
  357.     somSelf->SetLinkDirty(ev);
  358. }
  359.  
  360. //------------------------------------------------------------------------------
  361. // ODLink: InitLinkFromStorage
  362. //------------------------------------------------------------------------------
  363.  
  364. SOM_Scope void  SOMLINK ODLinkInitLinkFromStorage(ODLink *somSelf, Environment *ev,
  365.         ODStorageUnit* storageUnit)
  366. {
  367.     ODLinkData *somThis = ODLinkGetData(somSelf);
  368.     ODLinkMethodDebug("ODLink","InitLinkFromStorage");
  369.  
  370.     SOM_CATCH return;
  371.     
  372.     /* Moved from somInit. SOM itself sets fields to zero
  373.     _fSection = (SectionHandle) kODNULL;
  374.     _fDirty = kODFalse;
  375.     */
  376.     somSelf->InitBaseLinkFromStorage(ev, storageUnit);
  377.  
  378.     if (ODSUExistsThenFocus(ev, storageUnit, kODPropLinkSection, kODApplesect)) 
  379.     {
  380.         const int sectionRecordSize = sizeof(SectionRecord);
  381.  
  382.         if ( storageUnit->GetSize(ev) != sectionRecordSize )
  383.             THROW(kODErrCorruptLink);
  384.  
  385.         AliasHandle alias = kODNULL;
  386.         ODVolatile(alias);
  387.  
  388.         TRY
  389.             _fSection = (SectionHandle) ODNewHandle(sectionRecordSize);
  390.             ODValue theSectionPtr = ODLockHandle((ODHandle) _fSection);
  391.             StorageUnitGetValue(storageUnit, ev, sectionRecordSize, theSectionPtr);
  392.             ODUnlockHandle((ODHandle) _fSection);
  393.             
  394.             if ( (**_fSection).kind != stPublisher )
  395.                 THROW(kODErrCorruptLink);
  396.         
  397.             storageUnit->Focus(ev, kODPropEditionAlias, kODPosUndefined, kODApplealis, (ODValueIndex)0, kODPosUndefined);
  398.             ODULong size = storageUnit->GetSize(ev);
  399.         
  400.             if ( size < sizeof(AliasRecord) )
  401.                 THROW(kODErrCorruptLink);
  402.         
  403.             alias = (AliasHandle) ODNewHandle(size);
  404.             ODValue theAliasPtr = ODLockHandle((ODHandle) alias);
  405.             StorageUnitGetValue(storageUnit, ev, size, theAliasPtr);
  406.             ODUnlockHandle((ODHandle) alias);
  407.         CATCH_ALL
  408.             ODDisposeHandle((ODHandle) _fSection);
  409.             _fSection = (SectionHandle) kODNULL;
  410.             ODDisposeHandle((ODHandle) alias);
  411.             RERAISE;
  412.         ENDTRY
  413.  
  414.         (**_fSection).alias = alias;
  415.         (**_fSection).refCon = (long) somSelf;
  416.  
  417.         if ( IsTopDraft(ev, storageUnit->GetDraft(ev)) )
  418.         {
  419.             if ( IsRegisteredSection(_fSection) != noErr )
  420.             {
  421.                 ODBoolean aliasWasUpdated;
  422.  
  423.                 ODContainer* container = storageUnit->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);;
  424.                 ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  425.  
  426.                 OSErr error = RegisterSection(&documentSpec, _fSection, &aliasWasUpdated);
  427.                 
  428.                 // For now, ignore any error returned by RegisterSection.  The most likely errors are:
  429.                 //    multiplePublisherWrn = -460,        A Publisher is already registered for that container
  430.                 //    containerNotFoundWrn = -461,        Could not find editionContainer at this time
  431.                 //    containerAlreadyOpenWrn = -462,        Container already opened by this section
  432.                 //    notThePublisherWrn = -463,            Not the first registered publisher for that container
  433.     
  434.                 if ( IsRegisteredSection(_fSection) == noErr )
  435.                     somSelf->Acquire(ev);    // Link must not be deleted untill its section is unregistered!
  436.             }
  437.         }
  438.     }
  439. }
  440.  
  441. //------------------------------------------------------------------------------
  442. // ODLink: Release (OVERRIDE)
  443. //------------------------------------------------------------------------------
  444.  
  445. SOM_Scope void  SOMLINK ODLinkRelease(ODLink *somSelf, Environment *ev)
  446. {
  447.     ODLinkData *somThis = ODLinkGetData(somSelf);
  448.     ODLinkMethodDebug("ODLink","Release");
  449.  
  450.     SOM_CATCH return;
  451.  
  452.     parent_Release(somSelf, ev);
  453.  
  454. #if ODDebugLink
  455.     somPrintf("ODLink %d::Release: Ref count is %d\n", somSelf->GetID(ev), somSelf->GetRefCount(ev));
  456. #endif
  457.  
  458.     if (somSelf->GetRefCount(ev) == 0)
  459.         somSelf->GetStorageUnit(ev)->GetDraft(ev)->ReleaseLink(ev, somSelf);
  460. }
  461.  
  462. //------------------------------------------------------------------------------
  463. // ODLink: Externalize (OVERRIDE)
  464. //------------------------------------------------------------------------------
  465.  
  466. SOM_Scope void  SOMLINK ODLinkExternalize(ODLink *somSelf, Environment *ev)
  467. {
  468.     ODLinkData *somThis = ODLinkGetData(somSelf);
  469.     ODLinkMethodDebug("ODLink","Externalize");
  470.  
  471.     SOM_CATCH return;
  472.  
  473.     parent_Externalize(somSelf,ev);
  474.  
  475.     ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  476.  
  477.     if ( _fDirty )
  478.     {
  479.         if ( _fSection == (SectionHandle) kODNULL ) 
  480.         {
  481.             ODSURemoveProperty(ev, su, kODPropLinkSection);
  482.             ODSURemoveProperty(ev, su, kODPropEditionAlias);
  483.         }
  484.         else 
  485.         {
  486.             SectionPtr theSectionPtr = (SectionPtr) ODLockHandle((ODHandle) _fSection);
  487.     
  488.             ODSUForceFocus(ev, su, kODPropLinkSection, kODApplesect);
  489.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) _fSection), (ODValue) theSectionPtr);
  490.             
  491.             ODValue theAliasPtr = ODLockHandle((ODHandle) theSectionPtr->alias);
  492.             ODSUForceFocus(ev, su, kODPropEditionAlias, kODApplealis);
  493.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) theSectionPtr->alias), theAliasPtr);
  494.             
  495.             ODUnlockHandle((ODHandle) theSectionPtr->alias);
  496.             ODUnlockHandle((ODHandle) _fSection);
  497.         }
  498.         _fDirty = kODFalse;
  499.     }
  500. }
  501.  
  502. //------------------------------------------------------------------------------
  503. // ODLink: CloneInto (OVERRIDE)
  504. //------------------------------------------------------------------------------
  505. // We don't clone the cross-document link info, so a second publisher can't be created.
  506. // This depends on this method being called rather than ODStorageUnit::CloneInto().
  507. // Currently, all link objects are internalized when a draft is opened, so this is true.
  508.  
  509. SOM_Scope void  SOMLINK ODLinkCloneInto(ODLink *somSelf, Environment *ev,
  510.         ODDraftKey key,
  511.         ODStorageUnit* toSU,
  512.         ODFrame* scopeFrame)
  513. {
  514.     ODLinkData *somThis = ODLinkGetData(somSelf);
  515.     ODLinkMethodDebug("ODLink","CloneInto");
  516.  
  517.     SOM_CATCH return;
  518.     
  519.     // If one of our properties already exists, this object has been cloned already
  520.     if ( toSU->Exists(ev, kODPropLinkSection, kODApplesect, 0) )
  521.         return;
  522.  
  523.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  524. }
  525.  
  526. //------------------------------------------------------------------------------
  527. // ODLink: ReleaseAll (OVERRIDE)
  528. //------------------------------------------------------------------------------
  529.  
  530. SOM_Scope void  SOMLINK ODLinkReleaseAll(ODLink *somSelf, Environment *ev)
  531. {
  532.     ODLinkData *somThis = ODLinkGetData(somSelf);
  533.     ODLinkMethodDebug("ODLink","ReleaseAll");
  534.  
  535.     SOM_CATCH return;
  536.  
  537.     parent_ReleaseAll(somSelf,ev);
  538.  
  539.     if ( _fSection != (SectionHandle) kODNULL ) 
  540.     {
  541.         if ( IsTopDraft(ev, somSelf->GetStorageUnit(ev)->GetDraft(ev)) )
  542.         {
  543.             if ( IsRegisteredSection(_fSection) == noErr )
  544.             {
  545.                 OSErr error = UnRegisterSection(_fSection);
  546.                 somSelf->Release(ev);    // RefCount incremented when section was registered
  547.             }
  548.         }
  549.  
  550.         ODDisposeHandle((ODHandle) (**_fSection).alias);
  551.         ODDisposeHandle((ODHandle) _fSection);
  552.         _fSection = (SectionHandle) kODNULL;
  553.     }
  554. }
  555.  
  556. //------------------------------------------------------------------------------
  557. // ODBaseLink: UpdateDependents (OVERRIDE)
  558. //------------------------------------------------------------------------------
  559.  
  560. SOM_Scope void  SOMLINK ODLinkUpdateDependents(ODLink *somSelf, Environment *ev)
  561. {
  562.     ODLinkData *somThis = ODLinkGetData(somSelf);
  563.     ODLinkMethodDebug("ODLink","UpdateDependents");
  564.  
  565.     SOM_CATCH return;
  566.  
  567.     parent_UpdateDependents(somSelf, ev);
  568.  
  569.     if ( (_fSection != (SectionHandle) kODNULL) )
  570.     {
  571.         ODBoolean autoUpdate = somSelf->GetLinkSource(ev)->IsAutoUpdate(ev);
  572.         if ( autoUpdate )
  573.         {
  574.             ODLinkManager*    linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  575.             linkManager->ExportOnSave(ev, somSelf, kODTrue);
  576.         }
  577.         else
  578.         {
  579.             ODLinkKey key;
  580.             ODVolatile(key);
  581.             if ( somSelf->Lock(ev, 0, &key) ) 
  582.             {
  583.                 TRY
  584.                     somSelf->UpdateLinkEdition(ev, key);
  585.                 CATCH_ALL
  586.                     somSelf->Unlock(ev, key);
  587.                     RERAISE;
  588.                 ENDTRY
  589.                 somSelf->Unlock(ev, key);
  590.             }
  591.         }
  592.     }
  593. }
  594.  
  595. //------------------------------------------------------------------------------
  596. // ODLink::ShowLinkDestinationInfo (OVERRIDE)
  597. //------------------------------------------------------------------------------
  598.  
  599. SOM_Scope ODBoolean  SOMLINK ODLinkShowLinkDestinationInfo(ODLink *somSelf, Environment *ev,
  600.         ODFacet* facet,
  601.         ODLinkInfo* info,
  602.         ODBoolean changesAllowed,
  603.         ODLinkInfoResult* infoResult)
  604. {
  605.     ODLinkData *somThis = ODLinkGetData(somSelf);
  606.     ODLinkMethodDebug("ODLink","ShowLinkDestinationInfo");
  607.  
  608.     SOM_CATCH return kODFalse;
  609.     
  610.     ODLinkSource* linkSource = somSelf->GetLinkSource(ev);
  611.     
  612.     ODError error = linkSource->GetStatus(ev);
  613.  
  614.     if ( error )
  615.         ShowLinkStatusAlert(error);
  616.  
  617.     return parent_ShowLinkDestinationInfo(somSelf, ev, facet, info, changesAllowed, infoResult);
  618. }
  619.  
  620. //------------------------------------------------------------------------------
  621. // ODLink: SetLinkDirty
  622. //------------------------------------------------------------------------------
  623.  
  624. SOM_Scope void  SOMLINK ODLinkSetLinkDirty(ODLink *somSelf, Environment *ev)
  625. {
  626.     ODLinkData *somThis = ODLinkGetData(somSelf);
  627.     ODLinkMethodDebug("ODLink","SetLinkDirty");
  628.  
  629.     SOM_TRY    
  630.         _fDirty = kODTrue;
  631.  
  632.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  633.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  634.             draft->SetChangedFromPrev(ev);
  635.     SOM_CATCH_ALL
  636.     SOM_ENDTRY
  637. }
  638.  
  639. //------------------------------------------------------------------------------
  640. // ODLink: CreateLinkEdition
  641. //------------------------------------------------------------------------------
  642.  
  643. SOM_Scope void  SOMLINK ODLinkCreateLinkEdition(ODLink *somSelf, Environment *ev,
  644.         EditionContainerSpec editionContainer,
  645.         ODFileSpec* documentSpec,
  646.         ODULong sectionID,
  647.         ODLinkKey key,
  648.         ODByteArray* aliasData)
  649. {
  650.     ODLinkData *somThis = ODLinkGetData(somSelf);
  651.     ODLinkMethodDebug("ODLink","CreateLinkEdition");
  652.  
  653.     OSErr error;
  654.     OSErr createError = mFulErr;    // Anything but noErr
  655.     SectionHandle tempSection = kODNULL;
  656.     
  657.     ODVolatile(createError);
  658.     ODVolatile(tempSection);
  659.     ODVolatile(editionContainer);
  660.  
  661.     SOM_TRY
  662.     
  663.         somSelf->KeyValid(ev, key);
  664.     
  665.         // Should throw kODErrCannotCreateLink if linkSource imports
  666.         
  667.         if ( _fSection != kODNULL)
  668.             THROW(kODErrLinkAlreadyExported);    // Internal error
  669.         
  670.         FInfo documentFInfo;
  671.         error = FSpGetFInfo((FSSpecPtr) documentSpec, &documentFInfo);
  672.         THROW_IF_ERROR(error);
  673.     
  674.         createError = CreateEditionContainerFile(&editionContainer.theFile, 
  675.                     documentFInfo.fdCreator, editionContainer.theFileScript);
  676.         THROW_IF_ERROR(createError);
  677.     
  678.         error = NewSection(&editionContainer, (FSSpecPtr) documentSpec, stPublisher, sectionID, pumOnSave, &tempSection);
  679.         if ( (error != noErr) && 
  680.              (error != multiplePublisherWrn) &&
  681.              (error != notThePublisherWrn) ) 
  682.         {
  683.             THROW(error);
  684.         }
  685.     
  686.         (**tempSection).mdDate = (TimeStamp) somSelf->GetChangeTime(ev);
  687.         (**tempSection).refCon = (long) somSelf;
  688.     
  689.         somSelf->WriteLinkEdition(ev, tempSection, (FSSpecPtr) documentSpec, key);
  690.  
  691.         // Edition file was successfully created and written, so add section to persistent state.
  692.         // This Link must not be deleted until its section is unregistered!
  693.         _fSection = tempSection;
  694.         somSelf->Acquire(ev);
  695.  
  696.         somSelf->SetLinkDirty(ev);
  697.     
  698.         TempODHandleLock aHandle((ODHandle) (**_fSection).alias);
  699.         if ( (ODHandle) aHandle )
  700.             *aliasData = CreateByteArrayStruct(*(ODHandle) aHandle, ODGetHandleSize(aHandle));
  701.         
  702.     SOM_CATCH_ALL
  703.  
  704.         if ( createError == noErr )
  705.             DeleteEditionContainerFile(&editionContainer.theFile);
  706.  
  707.         if ( tempSection ) 
  708.         {
  709.             UnRegisterSection(tempSection);
  710.             ODDisposeHandle((ODHandle) (**tempSection).alias);
  711.             ODDisposeHandle((ODHandle) tempSection);
  712.         }
  713.  
  714.     SOM_ENDTRY
  715. }
  716.  
  717. //------------------------------------------------------------------------------
  718. // ODLink: GetLinkEdition
  719. //------------------------------------------------------------------------------
  720.  
  721. SOM_Scope ODBoolean  SOMLINK ODLinkGetLinkEdition(ODLink *somSelf, Environment *ev,
  722.         ODLinkKey key,
  723.         ODByteArray* aliasData)
  724. {
  725.     ODLinkData *somThis = ODLinkGetData(somSelf);
  726.     ODLinkMethodDebug("ODLink","GetLinkEdition");
  727.  
  728.     ODBoolean result = kODFalse;
  729.     
  730.     SOM_TRY
  731.  
  732.         somSelf->KeyValid(ev, key);
  733.     
  734.         if ( _fSection != (SectionHandle) kODNULL )
  735.         {
  736.             TempODHandleLock aHandle((ODHandle) (**_fSection).alias);
  737.             if ( (ODHandle) aHandle )
  738.             {
  739.                 *aliasData = CreateByteArrayStruct(*(ODHandle) aHandle, ODGetHandleSize(aHandle));
  740.                 result = kODTrue;
  741.             }
  742.         }
  743.  
  744.     SOM_CATCH_ALL
  745.     SOM_ENDTRY
  746.  
  747.     return result;
  748. }
  749.  
  750. //------------------------------------------------------------------------------
  751. // ODLink: DeleteLinkEdition
  752. //------------------------------------------------------------------------------
  753.  
  754. SOM_Scope void  SOMLINK ODLinkDeleteLinkEdition(ODLink *somSelf, Environment *ev,
  755.         ODLinkKey key)
  756. {
  757.     ODLinkData *somThis = ODLinkGetData(somSelf);
  758.     ODLinkMethodDebug("ODLink","DeleteLinkEdition");
  759.  
  760.     SOM_CATCH return;
  761.  
  762.     somSelf->KeyValid(ev, key);
  763.  
  764.     if ( _fSection != (SectionHandle) kODNULL )
  765.     {
  766.         if ( IsTopDraft(ev, somSelf->GetStorageUnit(ev)->GetDraft(ev)) )
  767.         {
  768.             FSSpec editionFile;
  769.             ODBoolean wasChanged;
  770.     
  771.             OSErr error = ResolveAlias(nil, (**_fSection).alias, &editionFile, &wasChanged);
  772.             THROW_IF_ERROR(error);
  773.  
  774.             if ( IsRegisteredSection(_fSection) == noErr )
  775.             {
  776.                 error = UnRegisterSection(_fSection);
  777.                 if ( error == noErr )
  778.                     somSelf->Release(ev);    // RefCount incremented when section was registered
  779.             }
  780.  
  781.             error = DeleteEditionContainerFile(&editionFile);
  782.             THROW_IF_ERROR(error);
  783.  
  784.             ODDisposeHandle((ODHandle) (**_fSection).alias);
  785.             ODDisposeHandle((ODHandle) _fSection);
  786.             _fSection = (SectionHandle) kODNULL;
  787.             
  788.             somSelf->SetLinkDirty(ev);
  789.         }
  790.     }
  791. }
  792.  
  793. //------------------------------------------------------------------------------
  794. // ODLink: UpdateLinkEdition
  795. //------------------------------------------------------------------------------
  796.  
  797. SOM_Scope void  SOMLINK ODLinkUpdateLinkEdition(ODLink *somSelf, Environment *ev,
  798.         ODLinkKey key)
  799. {
  800.     ODLinkData *somThis = ODLinkGetData(somSelf);
  801.     ODLinkMethodDebug("ODLink","UpdateLinkEdition");
  802.  
  803.     SOM_CATCH return;
  804.  
  805.     if (_fSection != (SectionHandle) kODNULL) 
  806.     {
  807.         ODTime changeTime = somSelf->GetChangeTime(ev);
  808.         if ((TimeStamp) changeTime != (**_fSection).mdDate) 
  809.         {
  810.             ODStorageUnit* storageUnit = somSelf->GetStorageUnit(ev);
  811.             ODContainer* container = storageUnit->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);;
  812.             ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  813.  
  814.             (**_fSection).mdDate = (TimeStamp) changeTime;
  815.             somSelf->WriteLinkEdition(ev, _fSection, &documentSpec, key);
  816.         }
  817.     }
  818. }
  819.  
  820. //------------------------------------------------------------------------------
  821. // ODLink: GetPlatformValue
  822. //------------------------------------------------------------------------------
  823.  
  824. SOM_Scope ODHandle  SOMLINK ODLinkGetPlatformValue(ODLink *somSelf, Environment *ev,
  825.         ODPlatformType platformType,
  826.         ODLinkKey key)
  827. {
  828.     ODLinkData *somThis = ODLinkGetData(somSelf);
  829.     ODLinkMethodDebug("ODLink","GetPlatformValue");
  830.  
  831.     ODHandle        dataHandle = (ODHandle) kODNULL;
  832.     
  833.     SOM_TRY
  834.     
  835.     ODULong            dataSize;
  836.     ODStorageUnit*    contentSU = somSelf->GetContentStorageUnit(ev, key);
  837.     ODValueType        isoType = kODNULL;
  838.  
  839.     ODVolatile(isoType);
  840.     ODVolatile(dataHandle);
  841.     TRY
  842.         ODTranslation* translation = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetTranslation(ev);
  843.         isoType = translation->GetISOTypeFromPlatformType(ev, platformType, kODPlatformDataType);
  844.  
  845.         if ( ODSUExistsThenFocus(ev, contentSU, kODPropContents, isoType) )
  846.         {
  847.             dataSize = contentSU->GetSize(ev);
  848.             dataHandle = ODNewHandle(dataSize);
  849.             ODValue dataPtr = ODLockHandle(dataHandle);
  850.             StorageUnitGetValue(contentSU, ev, dataSize, dataPtr);
  851.             ODUnlockHandle(dataHandle);
  852.         }
  853.     CATCH_ALL
  854.         ODDisposeHandle(dataHandle);
  855.         dataHandle = (ODHandle) kODNULL;
  856.     ENDTRY
  857.  
  858.     ODDisposePtr(isoType);
  859.     
  860.     SOM_CATCH_ALL
  861.         dataHandle = kODNULL;
  862.     SOM_ENDTRY
  863.  
  864.     return dataHandle;
  865. }
  866.  
  867. //------------------------------------------------------------------------------
  868. // ODLink: CloneToMemoryContainer
  869. //------------------------------------------------------------------------------
  870.  
  871. SOM_Scope ODHandle  SOMLINK ODLinkCloneToMemoryContainer(ODLink *somSelf, Environment *ev,
  872.         ODLinkKey key)
  873. {
  874.     ODLinkData *somThis = ODLinkGetData(somSelf);
  875.     ODLinkMethodDebug("ODLink","CloneToMemoryContainer");
  876.  
  877.     SOM_CATCH return (ODHandle) kODNULL;
  878.  
  879.     ODHandle            containerHandle;
  880.     ODContainer*        container = (ODContainer*) kODNULL;
  881.     ODDocument*            document = (ODDocument*) kODNULL;
  882.     ODDraft*            draft = (ODDraft*) kODNULL;
  883.     ODStorageUnit*        draftProperties = (ODStorageUnit*) kODNULL;
  884.     ODStorageUnit*        contentSU = (ODStorageUnit*) kODNULL;
  885.     ODDraft*            myDraft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  886.     ODSession*            session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  887.     ODStorageUnitID        rootSUID = 0;
  888.  
  889.     ODVolatile(draft);
  890.     ODVolatile(draftProperties);
  891.     ODVolatile(document);
  892.     ODVolatile(container);
  893.     ODVolatile(containerHandle);
  894.     ODVolatile(myDraft);
  895.     
  896.     contentSU = somSelf->GetContentStorageUnit(ev, key);
  897.  
  898.     // Externalize contentSU to force resolution of promises before the
  899.     // clone into the memory container is begun.
  900.     contentSU->Externalize(ev);
  901.  
  902.     containerHandle = ODNewHandle(0);
  903.     TRY
  904.         container = CreateMemoryContainer(ev, session, containerHandle, kODBentoMemoryContainer);
  905.         
  906.         document = container->AcquireDocument(ev, kODDefaultDocument);
  907.             
  908.         draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  909.         
  910.         ODDraftKey draftKey = myDraft->BeginClone(ev, draft, kODNULL, kODCloneAll);
  911.         ODVolatile(draftKey);
  912.         TRY
  913.             rootSUID = myDraft->Clone(ev, draftKey, contentSU->GetID(ev), kODNULLID, 0);    
  914.  
  915.             if ( ODSUExistsThenFocus(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef) )
  916.             {
  917.                 ODID contentFrameID = ODGetWeakSURefProp(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef);
  918.                 myDraft->Clone(ev, draftKey, contentFrameID, kODNULLID, 0);                
  919.             }        
  920.         CATCH_ALL
  921.             myDraft->AbortClone(ev, draftKey);
  922.             RERAISE;
  923.         ENDTRY
  924.         
  925.         myDraft->EndClone(ev, draftKey);
  926.  
  927.         draftProperties = draft->AcquireDraftProperties(ev);
  928.         ODSetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef, rootSUID);
  929.         draftProperties->Release(ev);
  930.         draftProperties = kODNULL;
  931.  
  932.         draft->Externalize(ev);
  933.         draft->Release(ev);
  934.         document->Release(ev);
  935.         container->Release(ev);
  936.  
  937.     CATCH_ALL
  938.         ODReleaseObject(ev, draftProperties);
  939.         ODReleaseObject(ev, draft);
  940.         ODReleaseObject(ev, document);
  941.         ODReleaseObject(ev, container);
  942.         
  943.         ODDisposeHandle(containerHandle);
  944.         RERAISE;
  945.     ENDTRY
  946.  
  947.     return containerHandle;
  948. }
  949.  
  950. //------------------------------------------------------------------------------
  951. // ODLink: WriteLinkEdition
  952. //------------------------------------------------------------------------------
  953.  
  954. SOM_Scope void  SOMLINK ODLinkWriteLinkEdition(ODLink *somSelf, Environment *ev,
  955.         SectionHandle section,
  956.         ODFileSpec* documentSpec,
  957.         ODLinkKey key)
  958. {
  959.     ODLinkData *somThis = ODLinkGetData(somSelf);
  960.     ODLinkMethodDebug("ODLink","WriteLinkEdition");
  961.  
  962.     OSErr            infoError;
  963.     OSErr            openError;
  964.     OSErr            writeError = noErr;
  965.     EditionRefNum    edRefNum = 0;
  966.     ODHandle        dataHandle = (ODHandle) kODNULL;
  967.     ODBoolean        successful = kODTrue;
  968.  
  969.     ODVolatile(dataHandle);
  970.     ODVolatile(successful);
  971.     
  972.     SOM_TRY 
  973.  
  974.         if ( section == (SectionHandle) kODNULL ) 
  975.             THROW(kODErrNotExportedLink);
  976.     
  977.         FInfo documentFInfo;
  978.         infoError = FSpGetFInfo((FSSpecPtr) documentSpec, &documentFInfo);
  979.         THROW_IF_ERROR(infoError);
  980.     
  981.         openError = OpenNewEdition(section, documentFInfo.fdCreator, documentSpec, &edRefNum);
  982.         THROW_IF_ERROR(openError);
  983.     
  984.         dataHandle = somSelf->CloneToMemoryContainer(ev, key);
  985.         if ( dataHandle != (ODHandle) kODNULL ) 
  986.         {
  987.             ODPtr dataPtr = ODLockHandle(dataHandle);
  988.             writeError = WriteEdition(edRefNum, kODScrapTypeODBentoContainer, dataPtr, ODGetHandleSize(dataHandle));
  989.             ODDisposeHandle(dataHandle);
  990.             dataHandle = kODNULL;
  991.         }
  992.         THROW_IF_ERROR(writeError);
  993.     
  994.         // Also write out any text content property (unnecessary for OpenDoc, but allows
  995.         // subscribing by non-OpenDoc applications, and allows the Edition Manager to display
  996.         // content in the GetInfo dialog.
  997.         dataHandle = somSelf->GetPlatformValue(ev, 'TEXT', key);
  998.         if ( dataHandle != (ODHandle) kODNULL ) 
  999.         {
  1000.             ODPtr dataPtr = ODLockHandle(dataHandle);
  1001.             writeError = WriteEdition(edRefNum, 'TEXT', dataPtr, ODGetHandleSize(dataHandle));
  1002.             ODUnlockHandle(dataHandle);
  1003.             ODDisposeHandle(dataHandle);
  1004.             dataHandle = kODNULL;
  1005.         }
  1006.         THROW_IF_ERROR(writeError);
  1007.  
  1008.         dataHandle = somSelf->GetPlatformValue(ev, 'PICT', key);
  1009.         if ( dataHandle != (ODHandle) kODNULL ) 
  1010.         {
  1011.             ODPtr dataPtr = ODLockHandle(dataHandle);
  1012.             writeError = WriteEdition(edRefNum, 'PICT', dataPtr, ODGetHandleSize(dataHandle));
  1013.             ODUnlockHandle(dataHandle);
  1014.             ODDisposeHandle(dataHandle);
  1015.             dataHandle = kODNULL;
  1016.         }
  1017.         THROW_IF_ERROR(writeError);
  1018.  
  1019.  
  1020.     SOM_CATCH_ALL
  1021.  
  1022.         ODDisposeHandle(dataHandle);
  1023.         successful = kODFalse;
  1024.  
  1025.     SOM_ENDTRY;
  1026.  
  1027.     if ( edRefNum != 0 )
  1028.         CloseEdition(edRefNum, successful);
  1029. }
  1030.