home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osr1.exe / src / iavlsvr.cpp < prev    next >
C/C++ Source or Header  |  1997-03-21  |  131KB  |  4,352 lines

  1. /* @(#)Z 1.6 os2/src/storage/iavlsvr.cpp, oddataxfer, od96os2, odos29712d 97/03/21 17:38:26 (96/10/04 16:05:30) */
  2. //====START_GENERATED_PROLOG======================================
  3. //
  4. //
  5. //   COMPONENT_NAME: oddataxfer
  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. #ifdef _PLATFORM_OS2_
  30.  
  31. /*
  32. 1. Change _interrupt(3) to raise exception.
  33. 2. NOTE: If AS failed and restarted, all registered documents will be marked
  34. *        as closed and all links are marked as UNLOADED.
  35. */
  36.  
  37. #ifndef SOM_Module_iavlsvr_Source
  38. #define SOM_Module_iavlsvr_Source
  39. #endif
  40. #define IODAvailServer_Class_Source
  41.  
  42. #define METHOD_MACROS
  43. #define VARIABLE_MACROS
  44.  
  45. #define INCL_WIN
  46. #define INCL_ODAPI
  47. #include <os2.h>
  48.  
  49. #include <Builtin.h>
  50. #include <barray.h>
  51. #include <storutil.h>
  52. #include <stdtypio.h>
  53. #include <ODMemory.h>
  54. #include <ISOStr.h>
  55. #include <IODDefs.xh>
  56. #include <somd.xh>
  57. #include <IAS2LSv.xh>
  58. #include <link.xh>
  59. #include <iciditr.xh>
  60. #include <ILinkSrc.xh>
  61. #include <StdTypes.xh>
  62. #include <lmgrdefs.h>
  63. #include <IODMutex.xh>
  64. #include <ILnkSrvc.xh>
  65. #include <CMDraft.xh>
  66. #include <lmgrdefs.h>
  67.  
  68.  
  69. /*
  70. #ifndef _AEHSHTBL_
  71. #include "AEHshTbl.h"
  72. #endif
  73. */
  74.  
  75. #ifndef _OPENHASH_
  76. #include "OpenHash.h"
  77. #endif
  78.  
  79. #ifndef _EXCEPT_
  80. #include "Except.h"
  81. #endif
  82.  
  83. #include "StorageU.xh"
  84. #include "Draft.xh"
  85. #include "AvsShell.h"
  86.  
  87. #include "IAvlSvr.xih"
  88.  
  89. const ODULong  kODInitialNumEntries = 8;
  90.  
  91. enum LinkSrcState
  92. {
  93.   UNLOADED,
  94.   INDOC,
  95.   INAS,
  96.   INBOTH,
  97.   REMOVED
  98. };
  99.  
  100. typedef struct LinkIDNode
  101. {
  102.   ODLinkID    linkID;
  103.   LinkIDNode* next;
  104. } LinkIDNode;
  105.  
  106. typedef struct DocInfo
  107. {
  108.   ODISOStr                     pathName;
  109.   LinkIDNode*                  linkIDs;
  110.   IODAvailServerToLinkService* linkSrvc;
  111. } DocInfo;
  112.  
  113. typedef struct LinkSrcInfo
  114. {
  115.   LinkSrcState               state;
  116.   IODDocumentID              docID;
  117.   ODStorageUnitID            auxStateSUID;
  118.   ODBoolean                  isLocked;
  119.   IODLinkTargetToLinkSource* asLinkSrc;
  120.   IODLinkTargetToLinkSource* docLinkSrc;
  121. } LinkSrcInfo;
  122.  
  123. /*
  124.  *=============================================================================
  125.  * CleanupDocInfo
  126.  *
  127.  * <1>  Delete pathName
  128.  * <2>  Iterate through the list of linkIDs and delete each LinkIDNode entry.
  129.  * <3>  Release the LinkService proxy.
  130.  *=============================================================================
  131.  */
  132.  
  133. void CleanupDocInfo(Environment* ev,
  134.                     DocInfo* docInfo)
  135. {
  136.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  137.     LinkIDNode* nptr;
  138.  
  139.     //---<1>
  140.     if (docInfo->pathName != (ODISOStr)kODNULL)
  141.     {
  142.       ODDisposePtr(docInfo->pathName);
  143.     }
  144.  
  145.     //---<2>
  146.     while (docInfo->linkIDs != (LinkIDNode*)kODNULL)
  147.     {
  148.       nptr = docInfo->linkIDs;
  149.       docInfo->linkIDs = docInfo->linkIDs->next;
  150.       nptr->next = (LinkIDNode*)kODNULL;
  151.       delete nptr;
  152.     }
  153.  
  154.     //---<3>
  155.     if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  156.     {
  157.       if (((SOMDObject*)docInfo->linkSrvc)->is_proxy(ev))
  158.       {
  159.         SOMD_ObjectMgr->somdReleaseObject(ev, docInfo->linkSrvc);
  160.       }
  161.       else
  162.       {
  163.       }
  164.     }
  165. }
  166.  
  167. /*
  168.  *=============================================================================
  169.  * CleanupLinkSrcInfo
  170.  *
  171.  * <1>  Release LinkSource surrogate.
  172.  * <2>  Release the LinkSource proxy.
  173.  *=============================================================================
  174.  */
  175.  
  176. void CleanupLinkSrcInfo(Environment* ev,
  177.                         ODDraft* fSurrogateDraft,
  178.                         LinkSrcInfo* lsInfo)
  179. {
  180.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  181.  
  182.     //---<1>
  183.     if (lsInfo->asLinkSrc != (IODLinkTargetToLinkSource*)kODNULL)
  184.     {
  185.       TRY
  186.         ((CMDraft*)fSurrogateDraft)->
  187.           RemoveLinkSource(ev, (ODLinkSource*)lsInfo->asLinkSrc);
  188.       CATCH_ALL
  189.       ENDTRY
  190.     }
  191.  
  192.     //---<2>
  193.     if (lsInfo->docLinkSrc != (IODLinkTargetToLinkSource*)kODNULL)
  194.     {
  195.       if (((SOMDObject*)lsInfo->docLinkSrc)->is_proxy(ev))
  196.       {
  197.          SOMD_ObjectMgr->somdReleaseObject(ev, lsInfo->docLinkSrc);
  198.       }
  199.       else
  200.       {
  201.       }
  202.     }
  203. }
  204.  
  205. /*
  206.  *=============================================================================
  207.  * ReleaseDocLinkSource
  208.  *=============================================================================
  209.  */
  210.  
  211. void ReleaseDocLinkSource(Environment* ev,
  212.                           IODLinkTargetToLinkSource* linkSrc)
  213. {
  214.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  215.  
  216.     if (linkSrc != (IODLinkTargetToLinkSource*)kODNULL)
  217.     {
  218.       if (((SOMDObject*)linkSrc)->is_proxy(ev))
  219.       {
  220.          SOMD_ObjectMgr->somdReleaseObject(ev, linkSrc);
  221.  
  222.       }
  223.       else
  224.       {
  225.       }
  226.     }
  227. }
  228.  
  229. /*
  230.  *=============================================================================
  231.  * ReleaseLinkService
  232.  *=============================================================================
  233.  */
  234.  
  235. void ReleaseLinkService(Environment *ev,
  236.                         IODAvailServerToLinkService* linkSrvc)
  237. {
  238.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  239.  
  240.     if (linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  241.     {
  242.       if (((SOMDObject*)linkSrvc)->is_proxy(ev))
  243.       {
  244.          SOMD_ObjectMgr->somdReleaseObject(ev, linkSrvc);
  245.       }
  246.       else
  247.       {
  248.       }
  249.     }
  250. }
  251.  
  252. /*
  253.  *=============================================================================
  254.  * SetDocumentsProp
  255.  *
  256.  * <1>  Focus to the given property and value.
  257.  * <2>  Reserve space to write the total number of entries in the hashtable.
  258.  * <3>  Iterate through each DocInfo entry of the hashtable.
  259.  *      For each DocInfo entry, we are going to save the key, the pathName, and
  260.  *        the list of linkIDs.
  261.  * <4>  Write docID which is the key of the entry.
  262.  * <5>  Get string length of pathName.
  263.  *      Write string length of pathName.
  264.  *      Write pathName.
  265.  * <6>  Count the number of entries in the list of linkIDs.
  266.  * <7>  Write the number of entries in the list of linkIDs.
  267.  * <8>  Iterate through each entry of the list of linkIDs and write each
  268.  *        linkID.
  269.  * <9>  Count the number of entries in the hashtable.
  270.  * <10> After iterating thru the hashtable, refocus to the given property and
  271.  *      value.
  272.  *      Write the total number of entries in the hashtable in the space
  273.  *      reseved at <2>.
  274.  *=============================================================================
  275.  */
  276.  
  277. void SetDocumentsProp(Environment* ev,
  278.                       ODStorageUnit* su,
  279.                       ODPropertyName prop,
  280. //                      AEHashTable &documents)
  281.                       OpenHashTable &documents)
  282. {
  283.     ODULong       numOfEntries = 0;
  284.     IODDocumentID docID;
  285.     DocInfo*      docInfo;
  286.     LinkIDNode*   nptr;
  287.     ODULong       strLength;
  288.  
  289.     //---<1>
  290.     ODSUForceFocus(ev, su, prop, kODHashTable);
  291.  
  292.     //---<2>
  293.     StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfEntries);
  294.  
  295.     //---<3>
  296. //    AEHashTableIterator iter(&documents);
  297. //    for (iter.First(&docID, &docInfo);
  298. //         iter.IsNotComplete();
  299. //         iter.Next(&docID, &docInfo))
  300.  
  301.     OpenHashTableIterator iter(&documents);
  302.     for (iter.First(&docID, &docInfo);
  303.         iter.IsNotComplete();
  304.         iter.Next(&docID, &docInfo))
  305.     {
  306.       ODULong       numOfLinkIDs = 0;
  307.       //---<4>
  308.       StorageUnitSetValue(su, ev, sizeof(IODDocumentID), (ODValue)&docID);
  309.  
  310.       //---<5>
  311.       strLength = ODISOStrLength(docInfo->pathName);
  312.       StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&strLength);
  313.       StorageUnitSetValue(su, ev, strLength+1, (ODValue)docInfo->pathName);
  314.  
  315.       //---<6>
  316.       for (nptr = docInfo->linkIDs;
  317.            nptr != (LinkIDNode*)kODNULL;
  318.            nptr = nptr->next)
  319.       {
  320.         numOfLinkIDs++;
  321.       }
  322.  
  323.       //---<7>
  324.       StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfLinkIDs);
  325.  
  326.       //---<8>
  327.       for (nptr = docInfo->linkIDs;
  328.            nptr != (LinkIDNode*)kODNULL;
  329.            nptr = nptr->next)
  330.       {
  331.         StorageUnitSetValue(su,
  332.                             ev,
  333.                             sizeof(ODLinkID),
  334.                             (ODValue)&(nptr->linkID));
  335.       }
  336.  
  337.       //---<9>
  338.       numOfEntries++;
  339.     }
  340.  
  341.     //---<10>
  342.     su->Focus(ev, prop, kODPosSame, kODHashTable, 0, kODPosSame);
  343.     StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfEntries);
  344. }
  345.  
  346. /*
  347.  *=============================================================================
  348.  * GetDocumentsProp
  349.  *
  350.  * <1>  Focus to the given property and value.
  351.  * <2>  Read in the total number of entries in the hashtable.
  352.  * <3>  Loop to read in each entry of the hashtable.
  353.  * <4>  Read in docID which will be used as the key of the entry in the
  354.  *        hashtable.
  355.  * <5>  Create a DocInfo entry.
  356.  * <6>  Initilize linkIDs and linkSrvc fields of the DocInfo entry.
  357.  * <7>  Read in the length of pathName.
  358.  *      Allocate memory for pathName in the DocInfo entry.
  359.  *      Read in pathName.
  360.  * <8>  Read in the total number of entries in the list of linkIDs.
  361.  * <9>  Loop to read in each entry of the list of linkIDs.
  362.  * <10> Create a LinkIDNode entry.
  363.  * <11> Read in the linkID.
  364.  * <12> Insert the LinkIDNode entry into the list of linkIDs in DocInfo entry.
  365.  * <13> Add the DocInfo entry to the hashtable.
  366.  *=============================================================================
  367.  */
  368.  
  369. void GetDocumentsProp(Environment* ev,
  370.                       ODStorageUnit* su,
  371.                       ODPropertyName prop,
  372. //                      AEHashTable &documents)
  373.                       OpenHashTable &documents)
  374. {
  375.     IODDocumentID docID;
  376.     DocInfo*      docInfo;
  377.     ODULong       i;
  378.     ODULong       j;
  379.     LinkIDNode*   linkIDNode;
  380.     ODULong       numOfEntries;
  381.     ODULong       numOfLinkIDs;
  382.     ODULong       strLength;
  383.  
  384.     //---<1>
  385.     if (ODSUExistsThenFocus(ev, su, prop, kODHashTable))
  386.     {
  387.       //---<2>
  388.       StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue)&numOfEntries);
  389.  
  390.       //---<3>
  391.       for (i = 0; i < numOfEntries; i++)
  392.       {
  393.         //---<4>
  394.         StorageUnitGetValue(su, ev, sizeof(IODDocumentID), (ODValue)&docID);
  395.  
  396.         //---<5>
  397.         docInfo = new DocInfo;
  398.  
  399.         //---<6>
  400.         docInfo->linkIDs = (LinkIDNode*)kODNULL;
  401.         docInfo->linkSrvc = (IODAvailServerToLinkService*)kODNULL;
  402.  
  403.         //---<7>
  404.         StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue)&strLength);
  405.         docInfo->pathName = (ODISOStr)ODNewPtr(strLength+1, kDefaultHeapID);
  406.         StorageUnitGetValue(su,
  407.                             ev,
  408.                             strLength+1,
  409.                             (ODValue)docInfo->pathName);
  410.  
  411.         //---<8>
  412.         StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue)&numOfLinkIDs);
  413.  
  414.         //---<9>
  415.         for (j = 0; j < numOfLinkIDs; j++)
  416.         {
  417.           //---<10>
  418.           linkIDNode = new LinkIDNode;
  419.           linkIDNode->next = (LinkIDNode*)kODNULL;
  420.  
  421.           //---<11>
  422.           StorageUnitGetValue(su,
  423.                               ev,
  424.                               sizeof(ODLinkID),
  425.                               (ODValue)&(linkIDNode->linkID));
  426.  
  427.           //---<12>
  428.           if (docInfo->linkIDs == (LinkIDNode*)kODNULL)
  429.           {
  430.             docInfo->linkIDs = linkIDNode;
  431.           }
  432.           else
  433.           {
  434.             linkIDNode->next = docInfo->linkIDs;
  435.             docInfo->linkIDs = linkIDNode;
  436.           }
  437.         }
  438.  
  439.         //---<13>
  440.         documents.ReplaceEntry(&docID, &docInfo);
  441.       }
  442.     }
  443. }
  444.  
  445. /*
  446.  *=============================================================================
  447.  * SetLinksProp
  448.  *
  449.  * <1>  Focus to the given property and value.
  450.  * <2>  Reserve space to write the total number of entries in the hashtable.
  451.  * <3>  Iterate through each LinkSrcInfo entry of the hashtable.
  452.  *      For each LinkSrcInfo entry, we are going to save the key, docID and
  453.  *        auxStateSUID.
  454.  * <4>  Write linkID which is the key of the entry.
  455.  * <5>  Write docID.
  456.  * <6>  Get a weak reference from auxStateSUID.
  457.  *      Write the weak reference.
  458.  * <7>  Count the number of entries in the hashtable.
  459.  * <8>  After iterating thru the hashtable, refocus to the given property and
  460.  *      value.
  461.  *      Write the total number of entries in the hashtable in the space
  462.  *      reseved at <2>.
  463.  *=============================================================================
  464.  */
  465.  
  466. void SetLinksProp(Environment* ev,
  467.                   ODStorageUnit* su,
  468.                   ODPropertyName prop,
  469. //                  AEHashTable &links)
  470.                   OpenHashTable &links)
  471. {
  472.     ODULong          numOfEntries = 0;
  473.     ODLinkID         linkID;
  474.     LinkSrcInfo*     lsInfo;
  475.     ODStorageUnitRef suRef;
  476.  
  477.     //---<1>
  478.     ODSUForceFocus(ev, su, prop, kODHashTable);
  479.  
  480.     //---<2>
  481.     StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfEntries);
  482.  
  483.     //---<3>
  484. //    AEHashTableIterator iter(&links);
  485. //    for (iter.First(&linkID, &lsInfo);
  486. //         iter.IsNotComplete();
  487. //         iter.Next(&linkID, &lsInfo))
  488.  
  489.     OpenHashTableIterator iter(&links);
  490.     for (iter.First(&linkID, &lsInfo);
  491.         iter.IsNotComplete();
  492.         iter.Next(&linkID, &lsInfo))
  493.     {
  494.       if (lsInfo->state != REMOVED)
  495.       {
  496.         //---<4>
  497.         StorageUnitSetValue(su, ev, sizeof(ODLinkID), (ODValue)&linkID);
  498.  
  499.         //---<5>
  500.         StorageUnitSetValue(su,
  501.                             ev,
  502.                             sizeof(IODDocumentID),
  503.                             (ODValue)&(lsInfo->docID));
  504.  
  505.         //---<6>
  506.         su->GetWeakStorageUnitRef(ev, lsInfo->auxStateSUID, suRef);
  507.         StorageUnitSetValue(su, ev, sizeof(ODStorageUnitRef), (ODValue)&suRef);
  508.  
  509.         //---<7>
  510.         numOfEntries++;
  511.       }
  512.     }
  513.  
  514.     //---<8>
  515.     su->Focus(ev, prop, kODPosSame, kODHashTable, 0, kODPosSame);
  516.     StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfEntries);
  517. }
  518.  
  519. /*
  520.  *=============================================================================
  521.  * GetLinksProp
  522.  *
  523.  * <1>  Focus to the given property and value.
  524.  * <2>  Read in the total number of entries in the hashtable.
  525.  * <3>  Loop to read in each entry of the hashtable.
  526.  * <4>  Read in linkID which will be used as the key of the entry in the
  527.  *        hashtable.
  528.  * <5>  Create a LinkSrcInfo entry.
  529.  * <6>  Initiliize the LinkSrcInfo entry as
  530.  *        <UNLOADED, _____, _____, false, null, null>
  531.  * <7>  Read in docID.
  532.  * <8>  Read in the auxiliary state's SU reference.
  533.  * <9>  Retrieve the SU ID of the auxiliary state's SU reference.
  534.  *      The LinkSrcInfo entry now becomes
  535.  *        <UNLOADED, docID, auxStateSUID, false, null, null>
  536.  * <10> Add the LinkSrcInfo entry to the hashtable.
  537.  *=============================================================================
  538.  */
  539.  
  540. void GetLinksProp(Environment* ev,
  541.                   ODStorageUnit* su,
  542.                   ODPropertyName prop,
  543. //                  AEHashTable &links)
  544.                   OpenHashTable &links)
  545. {
  546.     IODDocumentID    docID;
  547.     ODULong          i;
  548.     ODLinkID         linkID;
  549.     LinkSrcInfo*     lsInfo;
  550.     ODULong          numOfEntries;
  551.     ODStorageUnitRef suRef;
  552.  
  553.     //---<1>
  554.     if (ODSUExistsThenFocus(ev, su, prop, kODHashTable))
  555.     {
  556.       //---<2>
  557.       StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue)&numOfEntries);
  558.  
  559.       //---<3>
  560.       for (i = 0; i < numOfEntries; i++)
  561.       {
  562.         //---<4>
  563.         StorageUnitGetValue(su, ev, sizeof(ODLinkID), (ODValue)&linkID);
  564.  
  565.         //---<5>
  566.         lsInfo = new LinkSrcInfo;
  567.  
  568.         //---<6>
  569.         lsInfo->state = UNLOADED;
  570.         lsInfo->isLocked = kODFalse;
  571.         lsInfo->asLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  572.         lsInfo->docLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  573.  
  574.         //---<7>
  575.         StorageUnitGetValue(su,
  576.                             ev,
  577.                             sizeof(IODDocumentID),
  578.                             (ODValue)&(lsInfo->docID));
  579.  
  580.         //---<8>
  581.         StorageUnitGetValue(su,
  582.                             ev,
  583.                             sizeof(ODStorageUnitRef),
  584.                             (ODValue)&suRef);
  585.  
  586.         //---<9>
  587.         if (su->IsValidStorageUnitRef(ev, suRef))
  588.         {
  589.           lsInfo->auxStateSUID = su->GetIDFromStorageUnitRef(ev, suRef);
  590.         }
  591.         else
  592.         {
  593.         }
  594.  
  595.         //---<10>
  596.         links.ReplaceEntry(&linkID, &lsInfo);
  597.       }
  598.     }
  599. }
  600.  
  601. /*
  602.  *=============================================================================
  603.  * SetAuxStateToSU
  604.  *
  605.  * <1>  Write the version number.
  606.  * <2>  Write idCounter (LinkID counter).
  607.  * <3>  Write the remoteLinkInfos as a BArray.
  608.  * <4>  If the new size is smaller than the old size, delete excess
  609.  *=============================================================================
  610.  */
  611.  
  612. void SetAuxStateToSU (Environment *ev,
  613.                       ODStorageUnit *su,
  614.                       IODAuxiliaryState& auxState)
  615. {
  616.     //---<1>
  617.     ODSetULongProp(ev, su, kODPropVersion, kODULong, auxState.version);
  618.  
  619.     //---<2>
  620.     ODSetULongProp(ev, su, kODPropIDCounter, kODULong, auxState.idCounter);
  621.  
  622.     //---<3>
  623.     ODSUForceFocus(ev, su, kODPropRemoteLinkInfos, kODHashTable);
  624.     ODULong oldsize = su->GetSize(ev);
  625.     su->SetValue(ev, &(auxState.remoteLinkInfos));
  626.  
  627.     //---<4>
  628.    if (oldsize - auxState.remoteLinkInfos._length > 0) {
  629.       su->DeleteValue(ev, oldsize - auxState.remoteLinkInfos._length);
  630.     }
  631. }
  632.  
  633. /*
  634.  *=============================================================================
  635.  * GetAuxStateFromSU
  636.  *
  637.  * <1>  Read in version number.
  638.  * <2>  Read in LinkID counter.
  639.  * <3>  Read in remoteLinkInfos as a BArray.
  640.  *=============================================================================
  641.  */
  642.  
  643. void GetAuxStateFromSU (Environment *ev,
  644.                         ODStorageUnit *su,
  645.                         IODAuxiliaryState& auxState)
  646. {
  647.     TRY
  648.       //---<1>
  649.       if (ODSUExistsThenFocus(ev, su, kODPropVersion, kODULong))
  650.       {
  651.          StorageUnitGetValue(su,
  652.                              ev,
  653.                              sizeof(ODULong),
  654.                              (ODValue)&auxState.version);
  655.       }
  656.       else
  657.       {
  658.          auxState.version = 0;
  659.       }
  660.  
  661.       //---<2>
  662.       if (ODSUExistsThenFocus(ev, su, kODPropIDCounter, kODULong))
  663.       {
  664.          StorageUnitGetValue(su,
  665.                              ev,
  666.                              sizeof(ODULong),
  667.                              (ODValue)&auxState.idCounter);
  668.       }
  669.       else
  670.       {
  671.          auxState.idCounter = 0;
  672.       }
  673.  
  674.       //---<3>
  675.       if (ODSUExistsThenFocus(ev, su, kODPropRemoteLinkInfos, kODHashTable))
  676.       {
  677.         long size = su->GetSize(ev);
  678.         auxState.remoteLinkInfos = CreateEmptyByteArrayStruct(size);
  679.         auxState.remoteLinkInfos._length = size;
  680.         su->GetValue(ev, size, &(auxState.remoteLinkInfos));
  681.       }
  682.       else
  683.       {
  684.         auxState.remoteLinkInfos = CreateEmptyByteArrayStruct(0);
  685.       }
  686.     CATCH_ALL
  687.       RERAISE;
  688.     ENDTRY
  689. }
  690.  
  691. /*
  692.  *=============================================================================
  693.  *=============================================================================
  694.  */
  695.  
  696. void SaveAuxState(Environment* ev,
  697.                   AvsShell* shell,
  698.                   ODDraft* asDraft,
  699.                   LinkSrcInfo* lsInfo)
  700. {
  701.     IODAuxiliaryState* auxState = new IODAuxiliaryState;
  702.     ((IODLinkSource*)lsInfo->asLinkSrc)->GetAuxState(ev, &auxState);
  703.     ODStorageUnit* su = asDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  704.     SetAuxStateToSU(ev, su, *auxState);
  705.     delete auxState;
  706. //    shell->SaveDraft();
  707. }
  708.  
  709.  
  710. /*
  711.  *=============================================================================
  712.  *=============================================================================
  713.  */
  714. void SaveToAsDraft (Environment* ev,
  715.                     AvsShell* shell,
  716.                     ODDraft* asDraft,
  717.                     ODULong docIDCounter,
  718.                     ODULong linkIDCounter,
  719. //                    AEHashTable* documents,
  720. //                    AEHashTable* links)
  721.                     OpenHashTable* documents,
  722.                     OpenHashTable* links)
  723. {
  724.     TRY
  725.       ODStorageUnit* su = asDraft->AcquireDraftProperties(ev);
  726.       if (docIDCounter > 0)
  727.       {
  728.         ODSetULongProp(ev, su, kODPropDocIDCounter, kODULong, docIDCounter);
  729.       }
  730.       if (linkIDCounter > 0)
  731.       {
  732.         ODSetULongProp(ev, su, kODPropLinkIDCounter, kODULong, linkIDCounter);
  733.       }
  734. //      if (documents != (AEHashTable*)kODNULL)
  735.       if (documents != (OpenHashTable*)kODNULL)
  736.       {
  737.         SetDocumentsProp(ev, su, kODPropDocuments, *documents);
  738.       }
  739. //      if (links != (AEHashTable*)kODNULL)
  740.       if (links != (OpenHashTable*)kODNULL)
  741.       {
  742.         SetLinksProp(ev, su, kODPropLinks, *links);
  743.       }
  744.       su->Release(ev);
  745.     CATCH_ALL
  746.       RERAISE;
  747.     ENDTRY
  748. }
  749.  
  750. /*
  751.  *=============================================================================
  752.  * IODAvailServer::InitAvailServer
  753.  *
  754.  * InitAvailServer is called by the AS Shell to initialize the AS.
  755.  * It supplies
  756.  * the AS with 2 drafts.  asDraft contains the persistent storage used
  757.  * by the AS: it contains the AS manager tables and the
  758.  * SurrogateWriteableState for each LinkSource registered with this AS.
  759.  * surrogateDraft is a temporary (in-memory) draft containing the
  760.  * opened LinkSourceSurrogates and their referenced contentSUs.
  761.  *
  762.  * This method doesn't need to use a semaphore..
  763.  * Unless otherwise noted, all methods need to seize a semaphore on entry,
  764.  * and release it on exit, since we want to serialize access to the tables.
  765.  *
  766.  * <1>  Verify that input shell is non-null.
  767.  * <2>  Verify that input drafts are non-null.
  768.  * <3>  Save input shell and drafts.
  769.  * <4>  Init fDocIDCounter and fLinkIDCounter to 0.
  770.  * <5>  Create fMutex.
  771.  * <6>  Create fDocuments.
  772.  * <7>  Create fLinks.
  773.  * <8>  Obtain properties of fAsDraft.
  774.  * <9>  AvailServer is new.
  775.  *      Add PropDocuments to fAsDraft's properties.
  776.  *      Add PropLinks to fAsDraft's properties.
  777.  *      Add PropDocIDCounter to fAsDraft's properties.
  778.  *      Add PropLinkIDCounter to fAsDraft's properties.
  779.  * <10> AvailServer is not new.
  780.  *      Internalize fDocuments from fAsDraft's PropDocuments.
  781.  *      Internalize fLinks from fAsDraft's PropLinks.
  782.  *      Internalize fDocIDCounter from fAsDraft's PropDocIDCounter.
  783.  *      Internalize fLinkIDCounter from fAsDraft's PropLinkIDCounter.
  784.  * <11> Release properties of fAsDraft.
  785.  *      Return.
  786.  * <12>  An exception is caught!
  787.  *      Delete fMutex.
  788.  * <13> Cleanup and delete fDocuments.
  789.  * <14> Cleanup and delete fLinks.
  790.  * <15> Reset fShell, fAsDraft, fSurrogateDraft, fDocIDCounter and
  791.  *        fLinkIDCounter.
  792.  * <16> Release properties of fAsDraft.
  793.  * <17> Set SOM ev to ODError.
  794.  *      Return.
  795.  *=============================================================================
  796.  */
  797.  
  798. SOM_Scope void
  799. SOMLINK InitAvailServer(IODAvailServer *somSelf,
  800.                         Environment *ev,
  801.                         ODBoolean isNew,
  802.                         AvsShell* shell,
  803.                         ODDraft* asDraft,
  804.                         ODDraft* surrogateDraft)
  805. {
  806.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  807.     IODAvailServerMethodDebug("IODAvailServer","InitAvailServer");
  808.  
  809.     IODDocumentID  docID;
  810.     DocInfo*       docInfo;
  811.     ODLinkID       linkID;
  812.     LinkSrcInfo*   lsInfo;
  813.     ODStorageUnit* su;
  814.  
  815.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  816.  
  817.     //---<1>
  818.     if (shell == (AvsShell*)kODNULL)
  819.     {
  820.       ODSetSOMException(ev, kODErrInvalidShell);
  821.       return;
  822.     }
  823.  
  824.     //---<2>
  825.     if ((asDraft == (ODDraft*)kODNULL) ||
  826.         (surrogateDraft == (ODDraft*)kODNULL))
  827.     {
  828.       ODSetSOMException(ev, kODErrInvalidDraft);
  829.       return;
  830.     }
  831.  
  832.     SOM_TRY
  833.  
  834.       //---<3>
  835.       _fShell          = shell;
  836.       _fAsDraft        = asDraft;
  837.       _fSurrogateDraft = surrogateDraft;
  838.  
  839.       //---<4>
  840.       _fDocIDCounter = 0;
  841.       _fLinkIDCounter = 0;
  842.  
  843.       //---<5>
  844.       _fMutex = new IODMutex;
  845.       THROW_IF_NULL(_fMutex);
  846.  
  847.       //---<6>
  848. //      _fDocuments = new AEHashTable;
  849. //      THROW_IF_NULL(_fDocuments);
  850. //      _fDocuments->Initialize(kODInitialNumEntries,
  851. //                              sizeof(IODDocumentID),
  852. //                              sizeof(DocInfo*),
  853. //                              kODFalse);
  854. //
  855.       _fDocuments = new OpenHashTable;
  856.       THROW_IF_NULL(_fDocuments);
  857.       _fDocuments->Initialize(kODInitialNumEntries,
  858.                               sizeof(IODDocumentID),
  859.                               sizeof(DocInfo*),
  860.                               kODFalse);
  861.  
  862.       //---<7>
  863. //      _fLinks = new AEHashTable;
  864. //      THROW_IF_NULL(_fLinks);
  865. //      _fLinks->Initialize(kODInitialNumEntries,
  866. //                          sizeof(ODLinkID),
  867. //                          sizeof(LinkSrcInfo*),
  868. //                          kODFalse);
  869.  
  870.       _fLinks = new OpenHashTable;
  871.       THROW_IF_NULL(_fLinks);
  872.       _fLinks->Initialize(kODInitialNumEntries,
  873.                           sizeof(ODLinkID),
  874.                           sizeof(LinkSrcInfo*),
  875.                           kODFalse);
  876.       //---<8>
  877.       su = _fAsDraft->AcquireDraftProperties(ev);
  878.  
  879.       if (isNew)
  880.       {
  881.         //---<9>
  882.         ODSUAddPropValue(ev, su, kODPropDocuments, kODHashTable);
  883.         ODSUAddPropValue(ev, su, kODPropLinks, kODHashTable);
  884.         ODSUAddPropValue(ev, su, kODPropDocIDCounter, kODULong);
  885.         ODSUAddPropValue(ev, su, kODPropLinkIDCounter, kODULong);
  886.         ODSetULongProp(ev, su, kODPropDocIDCounter, kODULong, _fDocIDCounter);
  887.         ODSetULongProp(ev, su, kODPropLinkIDCounter, kODULong, _fLinkIDCounter);
  888.         SetDocumentsProp(ev, su, kODPropDocuments, *_fDocuments);
  889.         SetLinksProp(ev, su, kODPropLinks, *_fLinks);
  890.       }
  891.       else
  892.       {
  893.         //---<10>
  894.         GetDocumentsProp(ev, su, kODPropDocuments, *_fDocuments);
  895.         GetLinksProp(ev, su, kODPropLinks, *_fLinks);
  896.         _fDocIDCounter = ODGetULongProp(ev, su, kODPropDocIDCounter, kODULong);
  897.         _fLinkIDCounter = ODGetULongProp(ev, su, kODPropLinkIDCounter, kODULong);
  898.       }
  899.  
  900.       //---<11>
  901.       su->Release(ev);
  902.       return;
  903.  
  904.     SOM_CATCH_ALL
  905.       ODError exception = ODGetSOMException(ev);
  906.  
  907.       //---<12>
  908.       if (_fMutex != kODNULL)
  909.       {
  910.         delete _fMutex;
  911.         _fMutex = (IODMutex*)kODNULL;
  912.       }
  913.  
  914.       //---<13>
  915. //      if (_fDocuments != (AEHashTable*)kODNULL)
  916.       if (_fDocuments != (OpenHashTable*)kODNULL)
  917.       {
  918. //        AEHashTableIterator iter(_fDocuments);
  919.         OpenHashTableIterator iter(_fDocuments);
  920.         for (iter.First(&docID, &docInfo);
  921.              iter.IsNotComplete();
  922.              iter.Next(&docID, &docInfo))
  923.         {
  924.           CleanupDocInfo(ev, docInfo);
  925.           delete docInfo;
  926.         }
  927.  
  928.         delete _fDocuments;
  929. //        _fDocuments = (AEHashTable*)kODNULL;
  930.         _fDocuments = (OpenHashTable*)kODNULL;
  931.       }
  932.  
  933.       //---<14>
  934. //      if (_fLinks != (*AEHashTable*)kODNULL)
  935.       if (_fLinks != (OpenHashTable*)kODNULL)
  936.       {
  937. //        AEHashTableIterator iter(_fLinks);
  938.         OpenHashTableIterator iter(_fLinks);
  939.         for (iter.First(&linkID, &lsInfo);
  940.              iter.IsNotComplete();
  941.              iter.Next(&linkID, &lsInfo))
  942.         {
  943.           CleanupLinkSrcInfo(ev, _fSurrogateDraft, lsInfo);
  944.           delete lsInfo;
  945.         }
  946.  
  947.         delete _fLinks;
  948. //        _fLinks = (AEHashTable*)kODNULL;
  949.         _fLinks = (OpenHashTable*)kODNULL;
  950.       }
  951.  
  952.       //---<15>
  953.       _fShell = (AvsShell*)kODNULL;
  954.       _fAsDraft = (ODDraft*)kODNULL;
  955.       _fSurrogateDraft = (ODDraft*)kODNULL;
  956.       _fDocIDCounter = 0;
  957.       _fLinkIDCounter = 0;
  958.  
  959.       //--<16>
  960.       if (su != (ODStorageUnit*)kODNULL)
  961.       {
  962.         su->Release(ev);
  963.       }
  964.  
  965.       //---<17>
  966.       ODSetSOMException(ev, exception);
  967.       return;
  968.  
  969.     SOM_ENDTRY
  970. }
  971.  
  972. /*
  973.  *=============================================================================
  974.  * IODAvailServer::IODAvailServer
  975.  
  976.     //- Initialize all dynamic storage to NULL.
  977.     //- This method doesn't need to use a semaphore.
  978.  
  979.  * <1> Initialize the following private variables:
  980.  *       IODMutex      fMutex;
  981.  *       AEHashTable*  fDocuments;
  982.  *       AEHashTable*  fLinks;
  983.  *       IODDocumentID fDocIDCounter;
  984.  *       ODLinkID      fLinkIDCounter;
  985.  *       AvsShell*      fShell;
  986.  *       ODDraft*      fAsDraft;
  987.  *       ODDraft*      fSurrogateDraft;
  988.  *=============================================================================
  989.  */
  990.  
  991. SOM_Scope void
  992. SOMLINK somInit(IODAvailServer *somSelf)
  993. {
  994.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  995.     IODAvailServerMethodDebug("IODAvailServer","somInit");
  996.  
  997.     IODAvailServer_parent_IODLinkServiceToAvailServer_somInit(somSelf);
  998.     IODAvailServer_parent_IODLinkTargetToLinkSource_somInit(somSelf);
  999.  
  1000.     //---<1>
  1001.     _fMutex          = (IODMutex*)kODNULL;
  1002. //    _fDocuments      = (AEHashTable*)kODNULL;
  1003. //    _fLinks          = (AEHashTable*)kODNULL;
  1004.     _fDocuments      = (OpenHashTable*)kODNULL;
  1005.     _fLinks          = (OpenHashTable*)kODNULL;
  1006.     _fDocIDCounter   = 0;
  1007.     _fLinkIDCounter  = 0;
  1008.     _fShell          = (AvsShell*)kODNULL;
  1009.     _fAsDraft        = (ODDraft*)kODNULL;
  1010.     _fSurrogateDraft = (ODDraft*)kODNULL;
  1011. }
  1012.  
  1013. /*
  1014.  *=============================================================================
  1015.  * IODAvailServer::~IODAvailServer
  1016.  *
  1017.  * <1>  Delete fMutex.
  1018.  * <2>  Delete fDocuments.
  1019.  * <3>  Delete fLinks.
  1020.  * <4>  Reset fDocIDCounter and fLinkIDCounter.
  1021.  * <5>  Reset fShell, fAsDraft and fSurrogateDraft.
  1022.  *=============================================================================
  1023.  */
  1024.  
  1025. SOM_Scope void
  1026. SOMLINK somUninit(IODAvailServer *somSelf)
  1027. {
  1028.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1029.     IODAvailServerMethodDebug("IODAvailServer","somUninit");
  1030.  
  1031.     IODDocumentID docID;
  1032.     DocInfo*      docInfo;
  1033.     ODLinkID      linkID;
  1034.     LinkSrcInfo*  lsInfo;
  1035.  
  1036.     //---<1>
  1037.     if (_fMutex != kODNULL)
  1038.     {
  1039.       delete _fMutex;
  1040.       _fMutex = (IODMutex*)kODNULL;
  1041.     }
  1042.  
  1043.     //---<2>
  1044. //    if (_fDocuments != (AEHashTable*)kODNULL)
  1045.     if (_fDocuments != (OpenHashTable*)kODNULL)
  1046.     {
  1047. //      AEHashTableIterator iter(_fDocuments);
  1048.       OpenHashTableIterator iter(_fDocuments);
  1049.       for (iter.First(&docID, &docInfo);
  1050.            iter.IsNotComplete();
  1051.            iter.Next(&docID, &docInfo))
  1052.       {
  1053.         CleanupDocInfo(somGetGlobalEnvironment(), docInfo);
  1054.         delete docInfo;
  1055.       }
  1056.       delete _fDocuments;
  1057. //      _fDocuments = (AEHashTable*)kODNULL;
  1058.       _fDocuments = (OpenHashTable*)kODNULL;
  1059.     }
  1060.  
  1061.     //---<3>
  1062. //     if (_fLinks != (AEHashTable*)kODNULL)
  1063.      if (_fLinks != (OpenHashTable*)kODNULL)
  1064.     {
  1065. //      AEHashTableIterator iter(_fLinks);
  1066.       OpenHashTableIterator iter(_fLinks);
  1067.       for (iter.First(&linkID, &lsInfo);
  1068.            iter.IsNotComplete();
  1069.            iter.Next(&linkID, &lsInfo))
  1070.       {
  1071.         CleanupLinkSrcInfo(somGetGlobalEnvironment(), _fSurrogateDraft, lsInfo);
  1072.         delete lsInfo;
  1073.       }
  1074.        delete _fLinks;
  1075. //      _fLinks = (AEHashTable*)kODNULL;
  1076.       _fLinks = (OpenHashTable*)kODNULL;
  1077.     }
  1078.  
  1079.     //---<4>
  1080.     _fDocIDCounter = 0;
  1081.     _fLinkIDCounter = 0;
  1082.  
  1083.     //---<5>
  1084.     _fShell          = (AvsShell*)kODNULL;
  1085.     _fAsDraft        = (ODDraft*)kODNULL;
  1086.     _fSurrogateDraft = (ODDraft*)kODNULL;
  1087.  
  1088.     IODAvailServer_parent_IODLinkServiceToAvailServer_somUninit(somSelf);
  1089.     IODAvailServer_parent_IODLinkTargetToLinkSource_somUninit(somSelf);
  1090. }
  1091.  
  1092. /*
  1093.  *=============================================================================
  1094.  * IODAvailServer::RegisterDoc
  1095.  *
  1096.  * RegisterDoc is called when a new document is opened.
  1097.  *
  1098.  * <1>  Acquire fMutex before accessing fDocIDCounter and fDocuments.
  1099.  * <2>  Generate new document ID and update fDocIDCounter.
  1100.  * <3>  Create a DocInfo entry.
  1101.  * <4>  Initialize the entry as <docPathName, null, linkService>.
  1102.  * <5>  Add that entry to fDocuments.
  1103.  * <5.1> Save fDocIDCounter and fDocuments to fASDraft.
  1104.  * <6>  Release fMutex.
  1105.  *      Return the new document ID.
  1106.  * <7>  An exception is caught!
  1107.  *      Remove the newly added entry from fDocuments.
  1108.  *      Cleanup and delete that entry.
  1109.  * <8>  Release fMutex.
  1110.  * <9>  Set SOM ev to ODError.
  1111.  *      Return 0 as the document ID.
  1112.  *=============================================================================
  1113.  */
  1114.  
  1115. SOM_Scope IODDocumentID
  1116. SOMLINK RegisterDoc(IODAvailServer *somSelf,
  1117.                     Environment *ev,
  1118.                     IODFileName docPathName,
  1119.                     IODAvailServerToLinkService* linkService)
  1120. {
  1121.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1122.     IODAvailServerMethodDebug("IODAvailServer","RegisterDoc");
  1123.  
  1124.     IODDocumentID docID;
  1125.     DocInfo*      docInfo;
  1126.  
  1127.     //---<1>
  1128.     SOM_TRY
  1129.       _fMutex->Acquire(ev);
  1130.     SOM_CATCH_ALL
  1131.       return 0;
  1132.     SOM_ENDTRY
  1133.  
  1134.     //---<2>
  1135.     docID = ++_fDocIDCounter;
  1136.  
  1137.     SOM_TRY
  1138.       //---<3>
  1139.       docInfo = new DocInfo;
  1140.       THROW_IF_NULL(docInfo);
  1141.  
  1142.       //---<4>
  1143.       docInfo->pathName = ODISOStrFromCStr(docPathName);
  1144.       docInfo->linkIDs = kODNULL;
  1145.       docInfo->linkSrvc = linkService;
  1146.  
  1147.       //---<5>
  1148.       _fDocuments->ReplaceEntry(&docID, &docInfo);
  1149.  
  1150.       //---<5.1>
  1151.       SaveToAsDraft(ev,
  1152.                     _fShell,
  1153.                     _fAsDraft,
  1154.                     _fDocIDCounter,
  1155.                     0,
  1156.                     _fDocuments,
  1157. //                    (AEHashTable*)kODNULL);
  1158.                     (OpenHashTable*)kODNULL);
  1159.  
  1160.       _fShell->UpdateDocList(_fDocIDCounter, docPathName, 'o');
  1161.  
  1162.       //---<6>
  1163.       TRY
  1164.         _fMutex->Release(ev);
  1165.       CATCH_ALL
  1166.       ENDTRY
  1167.  
  1168.       return docID;
  1169.  
  1170.     SOM_CATCH_ALL
  1171.       ODError exception = ODGetSOMException(ev);
  1172.  
  1173.       TRY
  1174.         //---<7>
  1175.         if (docInfo != (DocInfo*)kODNULL)
  1176.         {
  1177.           _fDocuments->RemoveEntry(&docID);
  1178.           CleanupDocInfo(ev, docInfo);
  1179.           delete docInfo;
  1180.         }
  1181.  
  1182.         //---<8>
  1183.         _fMutex->Release(ev);
  1184.       CATCH_ALL
  1185.       ENDTRY
  1186.  
  1187.       //---<9>
  1188.       ODSetSOMException(ev, exception);
  1189.       return 0;
  1190.     SOM_ENDTRY
  1191. }
  1192.  
  1193. /*
  1194.  *=============================================================================
  1195.  * IODAvailServer::UnregisterDoc
  1196.  *
  1197.  * UnregisterDoc is called when a document is destroyed.
  1198.  *
  1199.  * <1>  Acquire fMutex before accessing fDocuments and fLinks.
  1200.  * <2>  Check if docID is associated with a registered document.
  1201.  *      If true retrieve and remove the DocInfo entry of docID from
  1202.  *      fDocuments.
  1203.  * <3>  Iterate through the list of linkID's in the DocInfo entry.
  1204.  * <4>  Retrieve the LinkSrcInfo entry of each linkID from fLinks.
  1205.  * <5>  Check the state of the LinkSrcInfo entry.
  1206.  * <6>  If state is UNLOADED:
  1207.  *        Remove the storage unit of the auxiliary state.
  1208.  * <7>  If state is INDOC:
  1209.  *        Remove the storage unit of the auxiliary state.
  1210.  *        Release LinkSource proxy.
  1211.  * <8>  If state is INAS:
  1212.  *        Remove the storage unit of the auxiliary state.
  1213.  *        Release LinkSource surrogate.
  1214.  * <9>  If state is INBOTH:
  1215.  *        Change state to REMOVED.
  1216.  *        Remove the storage unit of the auxiliary state.
  1217.  *        Release LinkSource proxy.
  1218.  *      NOTE: When the content SU is unlocked by the LinkTarget, the
  1219.  *            LinkSource surrogate will be released and the LinkSrcInfo
  1220.  *            entry will be deleted.
  1221.  * <10> If state of LinkSrcInfo entry is not REMOVED
  1222.  *        Remove the LinkSrcInfo entry from fLinks.
  1223.  *        Delete the LinkSrcInfo entry.
  1224.  * <11> Done interating through the list of linkID's in the DocInfo entry.
  1225.  *      Cleanup and delete the DocInfo entry.
  1226.  * <11.1> Save fDocuments and fLinks to AsDraft.
  1227.  * <12> Release fMutex.
  1228.  *      Return.
  1229.  * <13> Fail testing in <2>: docID is invalid.
  1230.  *      Release fMutex.
  1231.  *      Raise exception.
  1232.  *      Return.
  1233.  *=============================================================================
  1234.  */
  1235.  
  1236. SOM_Scope void
  1237. SOMLINK UnregisterDoc(IODAvailServer *somSelf,
  1238.                       Environment *ev,
  1239.                       IODDocumentID docID)
  1240. {
  1241.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1242.     IODAvailServerMethodDebug("IODAvailServer","UnregisterDoc");
  1243.  
  1244.     DocInfo*       docInfo;
  1245.     ODLinkID       linkID;
  1246.     LinkSrcInfo*   lsInfo;
  1247.     LinkIDNode*    nptr;
  1248.     ODStorageUnit* su;
  1249.  
  1250.     //---<1>
  1251.     SOM_TRY
  1252.       _fMutex->Acquire(ev);
  1253.     SOM_CATCH_ALL
  1254.       return;
  1255.     SOM_ENDTRY
  1256.  
  1257.     //---<2>
  1258.     if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  1259.     {
  1260.       _fDocuments->RemoveEntry(&docID);
  1261.  
  1262.       //---<3>
  1263.       for (nptr = docInfo->linkIDs;
  1264.            nptr != (LinkIDNode*)kODNULL;
  1265.            nptr = nptr->next)
  1266.       {
  1267.         //---<4>
  1268.         linkID = nptr->linkID;
  1269.         if (_fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  1270.         {
  1271.           TRY
  1272.             //---<5>
  1273.             switch (lsInfo->state)
  1274.             {
  1275.               case UNLOADED:
  1276.                 //---<6>
  1277.                 //Before:<UNLOADED, docID, suID, false, null, null>
  1278.                 //After :<UNLOADED, docID, ____, false, null, null>
  1279.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  1280.                 _fAsDraft->RemoveStorageUnit(ev, su);
  1281.                 break;
  1282.  
  1283.               case INDOC:
  1284.                 //---<7>
  1285.                 //Before:<INDOC, docID, suID, false, null, docLS>
  1286.                 //After :<INDOC, docID, ____, false, null, _____>
  1287.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  1288.                 _fAsDraft->RemoveStorageUnit(ev, su);
  1289.                 ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  1290.                 break;
  1291.  
  1292.               case INAS:
  1293.                 //---<8>
  1294.                 //Before:<INAS, docID, suID, false, asLS, null>
  1295.                 //After :<INAS, docID, ____, false, ____, null>
  1296.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  1297.                 _fAsDraft->RemoveStorageUnit(ev, su);
  1298.                 TRY
  1299.                   ((CMDraft*)_fSurrogateDraft)->
  1300.                     RemoveLinkSource(ev, (ODLinkSource*)lsInfo->asLinkSrc);
  1301.                 CATCH_ALL
  1302.                 ENDTRY
  1303.                 break;
  1304.  
  1305.               case INBOTH:
  1306.                 //---<9>
  1307.                 //Before:<INBOTH,  docID, suID, true, asLS, docLS>
  1308.                 //After :<REMOVED, docID, ____, true, asLS, _____>
  1309.                 lsInfo->state = REMOVED;
  1310.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  1311.                 _fAsDraft->RemoveStorageUnit(ev, su);
  1312.                 ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  1313.                 break;
  1314.             }
  1315.           CATCH_ALL
  1316.             // ignore exceptions caught when making calls on _fAsDraft
  1317.           ENDTRY
  1318.  
  1319.           //---<10>
  1320.           if (lsInfo->state != REMOVED)
  1321.           {
  1322.             _fLinks->RemoveEntry(&linkID);
  1323.             delete lsInfo;
  1324.           }
  1325.         }
  1326.       }
  1327.  
  1328.       TRY
  1329.         //---<11>
  1330.         CleanupDocInfo(ev, docInfo);
  1331.         delete docInfo;
  1332.  
  1333.         //---<11.1>
  1334.         SaveToAsDraft(ev, _fShell, _fAsDraft, 0, 0, _fDocuments, _fLinks);
  1335.  
  1336.         //---<12>
  1337.         _fMutex->Release(ev);
  1338.       CATCH_ALL
  1339.       ENDTRY
  1340.  
  1341.       return;
  1342.     }
  1343.     else
  1344.     {
  1345.       //---<13>
  1346.       TRY
  1347.         _fMutex->Release(ev);
  1348.       CATCH_ALL
  1349.       ENDTRY
  1350.       ODSetSOMException(ev, kODErrInvalidDocID);
  1351.       return;
  1352.     }
  1353. }
  1354.  
  1355. /*
  1356.  *=============================================================================
  1357.  * IODAvailServer::DocOpened
  1358.  *
  1359.  * DocOpened is called when a document already registered with the AS
  1360.  * is opened.  If the path name does not match the path name registered
  1361.  * with that document id, then an exception is returned and the document
  1362.  * is not opened.
  1363.  *
  1364.  * <1>  Acquire fMutex before accessing fDocuments and fLinks.
  1365.  * <2>  Check if docID is associated with a registered document.
  1366.  *      If true retrieve the DocInfo entry of docID from fDocuments.
  1367.  * <3>  Check if given path name of document matches the one given at register
  1368.  *      time.
  1369.  * <4>  Check if document is closed.
  1370.  * <5>  Normal case: document is just opened.
  1371.  *      Save given LinkService.
  1372.  *      Release fMutex.
  1373.  *      Return true.
  1374.  *XXXXX <6>  Fail testing in <4>: document is already opened.
  1375.  *XXXXX      Check if document is crashed and restarted (by comparing given
  1376.  *XXXXX      LinkService with the existing one).
  1377.  * <7>  Document is crashed and restarted.
  1378.  *      Release the proxy of old LinkService.
  1379.  *      Save given LinkService.
  1380.  * <8>  Iterate through the list of linkID's in the DocInfo entry.
  1381.  * <9>  Retrieve the LinkSrcInfo entry of each linkID from fLinks.
  1382.  * <10> Check the state of the LinkSrcInfo entry.
  1383.  * <11> If state is UNLOADED:
  1384.  *        No change.
  1385.  * <12> If state is INDOC:
  1386.  *        Change state to UNLOADED.
  1387.  *        Release LinkSource proxy.
  1388.  *        Reset docLinkSrc in LinkSrcInfo entry to null.
  1389.  * <13> If state is INAS:
  1390.  *        No change.
  1391.  * <14> If state is INBOTH:
  1392.  *        Change state to INAS.
  1393.  *        Release LinkSource proxy.
  1394.  *        Reset docLinkSrc in LinkSrcInfo entry to null.
  1395.  * <15> Done iterating through the list of linkID's in DocInfo entry.
  1396.  *      Release fMutex.
  1397.  *      Return true.
  1398.  * <16> Fail testing in <6>: document is opened more than once
  1399.  *        (Nothing has changed)
  1400.  *      Release fMutex.
  1401.  *      Return true.
  1402.  * <17> Fail testing in <3>: given path name of document does not match the
  1403.  *        one given at register time.
  1404.  *      Release fMutex.
  1405.  *      Raise exception.
  1406.  *      Return false.
  1407.  * <18> Fail testing in <2>: docID is invalid. Automatically register the
  1408.  *      document and reuse docID.
  1409.  *      Increase _fDocIDCounter if it is not already greater than or equal to
  1410.  *      docID.
  1411.  *      The logic of the codes is identical to RegisterDoc except here returns
  1412.  *      a boolean rather than the docID.
  1413.  *=============================================================================
  1414.  */
  1415.  
  1416. SOM_Scope ODBoolean
  1417. SOMLINK DocOpened(IODAvailServer *somSelf,
  1418.                   Environment *ev,
  1419.                   IODDocumentID docID,
  1420.                   IODFileName docPathName,
  1421.                   IODAvailServerToLinkService* linkService,
  1422.                   IODFileName* oldDocPathName)
  1423. {
  1424.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1425.     IODAvailServerMethodDebug("IODAvailServer","DocOpened");
  1426.  
  1427.     DocInfo*       docInfo;
  1428.     ODLinkID       linkID;
  1429.     LinkSrcInfo*   lsInfo;
  1430.     LinkIDNode*    nptr;
  1431.     ODStorageUnit* su;
  1432.  
  1433.     //---<1>
  1434.     SOM_TRY
  1435.       _fMutex->Acquire(ev);
  1436.     SOM_CATCH_ALL
  1437.       return kODFalse;
  1438.     SOM_ENDTRY
  1439.  
  1440.     //---<2>
  1441.     if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  1442.     {
  1443.       //---<3>
  1444.       if (ODISOStrCompare(docInfo->pathName, docPathName) == 0)
  1445.       {
  1446.         //---<4>
  1447.         if (docInfo->linkSrvc == (IODAvailServerToLinkService*)kODNULL)
  1448.         {
  1449.           //---<5>
  1450.           docInfo->linkSrvc = linkService;
  1451.  
  1452.           _fShell->UpdateDocList(docID, docPathName, 'o');
  1453.  
  1454.           TRY
  1455.             _fMutex->Release(ev);
  1456.           CATCH_ALL
  1457.           ENDTRY
  1458.  
  1459.           return kODTrue;
  1460.         }
  1461.         else
  1462.         {
  1463.           //---<6>
  1464.           if (docInfo->linkSrvc != linkService)
  1465.           {
  1466.             //---<7>
  1467.             ReleaseLinkService(ev, docInfo->linkSrvc);
  1468.             docInfo->linkSrvc = linkService;
  1469.  
  1470.             //---<8>
  1471.             for (nptr = docInfo->linkIDs;
  1472.                  nptr != (LinkIDNode*)kODNULL;
  1473.                  nptr = nptr->next)
  1474.             {
  1475.               //---<9>
  1476.               linkID = nptr->linkID;
  1477.               if (_fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  1478.               {
  1479.                 //---<10>
  1480.                 switch (lsInfo->state)
  1481.                 {
  1482.                   case UNLOADED:
  1483.                     //---<11>
  1484.                     // Before:<UNLOADED, docID, suID, false, null, null>
  1485.                     // After :<UNLOADED, docID, suID, false, null, null>
  1486.                     // NO CHANGE
  1487.                     break;
  1488.  
  1489.                   case INDOC:
  1490.                     //---<12>
  1491.                     // Before:<INDOC,    docID, suID, false, null, docLS>
  1492.                     // After :<UNLOADED, docID, suID, false, null, null>
  1493.                     lsInfo->state = UNLOADED;
  1494.                     ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  1495.                     lsInfo->docLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  1496.  
  1497.                     _fShell->UpdateLinkList(linkID, docID, UNLOADED);
  1498.  
  1499.                     break;
  1500.  
  1501.                   case INAS:
  1502.                     //---<13>
  1503.                     // Before:<INAS, docID, suID, true/false, asLS, null>
  1504.                     // After :<INAS, docID, suID, true/false, asLS, null>
  1505.                     // NO CHANGE
  1506.                     break;
  1507.  
  1508.                   case INBOTH:
  1509.                     //---<14>
  1510.                     // Before:<INBOTH, docID, suID, true, asLS, docLS>
  1511.                     // After :<INAS,   docID, suID, true, asLS, null>
  1512.                     lsInfo->state = INAS;
  1513.                     ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  1514.                     lsInfo->docLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  1515.  
  1516.                     _fShell->UpdateLinkList(linkID, docID, INAS);
  1517.  
  1518.                     break;
  1519.                 }
  1520.               }
  1521.             }
  1522.             //---<15>
  1523.             _fShell->UpdateDocList(docID, docPathName, 'o');
  1524.  
  1525.             TRY
  1526.               _fMutex->Release(ev);
  1527.             CATCH_ALL
  1528.             ENDTRY
  1529.  
  1530.             return kODTrue;
  1531.           }
  1532.           else
  1533.           {
  1534.             //---<16>
  1535.             TRY
  1536.               _fMutex->Release(ev);
  1537.             CATCH_ALL
  1538.             ENDTRY
  1539.  
  1540.             return kODTrue;
  1541.           }
  1542.         }
  1543.       }
  1544.       else
  1545.       {
  1546.         //---<17>
  1547.         *oldDocPathName = ODISOStrFromCStr(docInfo->pathName);
  1548.  
  1549.         TRY
  1550.           _fMutex->Release(ev);
  1551.         CATCH_ALL
  1552.         ENDTRY
  1553.  
  1554.         ODSetSOMException(ev, kODErrInvalidDocPathName);
  1555.         return kODFalse;
  1556.       }
  1557.     }
  1558.     else
  1559.     {
  1560.       //---<18>
  1561.       if (docID > _fDocIDCounter)
  1562.       {
  1563.         _fDocIDCounter++;
  1564.       }
  1565.  
  1566.       SOM_TRY
  1567.         docInfo = new DocInfo;
  1568.         THROW_IF_NULL(docInfo);
  1569.  
  1570.         docInfo->pathName = ODISOStrFromCStr(docPathName);
  1571.         docInfo->linkIDs = kODNULL;
  1572.         docInfo->linkSrvc = linkService;
  1573.  
  1574.         _fDocuments->ReplaceEntry(&docID, &docInfo);
  1575.  
  1576.         SaveToAsDraft(ev,
  1577.                       _fShell,
  1578.                       _fAsDraft,
  1579.                       _fDocIDCounter,
  1580.                       0,
  1581.                       _fDocuments,
  1582. //                      (AEHashTable*)kODNULL);
  1583.                       (OpenHashTable*)kODNULL);
  1584.  
  1585.         _fShell->UpdateDocList(_fDocIDCounter, docPathName, 'o');
  1586.  
  1587.         TRY
  1588.           _fMutex->Release(ev);
  1589.         CATCH_ALL
  1590.         ENDTRY
  1591.  
  1592.         return kODTrue;
  1593.  
  1594.       SOM_CATCH_ALL
  1595.         ODError exception = ODGetSOMException(ev);
  1596.  
  1597.         TRY
  1598.           if (docInfo != (DocInfo*)kODNULL)
  1599.           {
  1600.             _fDocuments->RemoveEntry(&docID);
  1601.             CleanupDocInfo(ev, docInfo);
  1602.             delete docInfo;
  1603.           }
  1604.  
  1605.           _fMutex->Release(ev);
  1606.         CATCH_ALL
  1607.         ENDTRY
  1608.  
  1609.         ODSetSOMException(ev, exception);
  1610.         return kODFalse;
  1611.       SOM_ENDTRY
  1612.     }
  1613. }
  1614.  
  1615. /*
  1616.  *=============================================================================
  1617.  * IODAvailServer::DocClosed
  1618.  *
  1619.  * DocClosed is called when an opened document is closed.
  1620.  *
  1621.  * [NOTE:  We assume that before this call is issued, each link that was
  1622.  * opened has been called.  Otherwise we would need to:
  1623.  * For each link associated with this document (in its fDocument entry)
  1624.  * make sure that it is not in fLoadedLinks or that its status (in
  1625.  * fLoadedLinks) is not InDoc or InBoth.
  1626.  *
  1627.  * <1>  Acquire fMutex before accessing fDocuments.
  1628.  * <2>  Check if docID is associated with a registered document.
  1629.  *      If true retrieve the DocInfo entry of docID from fDocuments.
  1630.  * <3>  Check if document is opened.
  1631.  * <4>  Document is opened.
  1632.  *      Release LinkService proxy saved in the DocInfo entry.
  1633.  *      Set linkSrvc in DocInfo entry to null.
  1634.  *      Release fMutex.
  1635.  *      Return.
  1636.  * <5>  Fail testing in <3>: document is not opened.
  1637.  *      Release fMutex.
  1638.  *      Raise exception.
  1639.  *      Return.
  1640.  * <6>  Fail testing in <2>: docID is invalid.
  1641.  *      Release fMutex.
  1642.  *      Raise exception.
  1643.  *      Return.
  1644.  *=============================================================================
  1645.  */
  1646.  
  1647. SOM_Scope void
  1648. SOMLINK DocClosed(IODAvailServer *somSelf,
  1649.                   Environment *ev,
  1650.                   IODDocumentID docID)
  1651. {
  1652.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1653.     IODAvailServerMethodDebug("IODAvailServer","DocClosed");
  1654.  
  1655.     DocInfo* docInfo;
  1656.  
  1657.     //---<1>
  1658.     SOM_TRY
  1659.       _fMutex->Acquire(ev);
  1660.     SOM_CATCH_ALL
  1661.       return;
  1662.     SOM_ENDTRY
  1663.  
  1664.     //---<2>
  1665.     if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  1666.     {
  1667.       //---<3>
  1668.       if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  1669.       {
  1670.         //---<4>
  1671.         ReleaseLinkService(ev, docInfo->linkSrvc);
  1672.         docInfo->linkSrvc = (IODAvailServerToLinkService*)kODNULL;
  1673.  
  1674.         _fShell->UpdateDocList(docID, docInfo->pathName, 'c');
  1675.  
  1676.         TRY
  1677.           _fMutex->Release(ev);
  1678.         CATCH_ALL
  1679.         ENDTRY
  1680.  
  1681.         return;
  1682.       }
  1683.       else
  1684.       {
  1685.         //---<5>
  1686.         TRY
  1687.           _fMutex->Release(ev);
  1688.         CATCH_ALL
  1689.         ENDTRY
  1690.  
  1691. //        ODSetSOMException(ev, kODErrDocNotOpened);
  1692.         return;
  1693.       }
  1694.     }
  1695.     else
  1696.     {
  1697.       //---<6>
  1698.       TRY
  1699.         _fMutex->Release(ev);
  1700.       CATCH_ALL
  1701.       ENDTRY
  1702.  
  1703.       ODSetSOMException(ev, kODErrInvalidDocID);
  1704.       return;
  1705.     }
  1706. }
  1707.  
  1708. /*
  1709.  *=============================================================================
  1710.  * IODAvailServer::DocMoved
  1711.  *
  1712.  * DocMoved is called when a registered document's persistent storage
  1713.  * changes from oldPathName to newPathName.
  1714.  *
  1715.  * <1>  Acquire fMutex before accessing fDocuments.
  1716.  * <2>  Check if docID is associated with a registered document.
  1717.  *      If true retrieve the DocInfo entry of docID from fDocuments.
  1718.  * <3>  Check if given old path name of document matches the one given at
  1719.  *      register time.
  1720.  * <4>  Document path name matched.
  1721.  *      Delete old path name in the DocInfo entry.
  1722.  *      Save new path name.
  1723.  *      Save fDocuments to AsDraft.
  1724.  *      Release fMutex.
  1725.  *      Return.
  1726.  * <5>  Fail testing in <3>: old path name does not match.
  1727.  *      Release fMutex.
  1728.  *      Raise exception.
  1729.  *      Return.
  1730.  * <6>  Fail testing in <2>: docID is invalid.
  1731.  *      Release fMutex.
  1732.  *      Raise exception.
  1733.  *      Return.
  1734.  *=============================================================================
  1735.  */
  1736.  
  1737. SOM_Scope void
  1738. SOMLINK DocMoved(IODAvailServer *somSelf,
  1739.                  Environment *ev,
  1740.                  IODDocumentID docID,
  1741.                  IODFileName oldPathName,
  1742.                  IODFileName newPathName)
  1743. {
  1744.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1745.     IODAvailServerMethodDebug("IODAvailServer","DocMoved");
  1746.  
  1747.     DocInfo* docInfo;
  1748.  
  1749.     //---<1>
  1750.     SOM_TRY
  1751.       _fMutex->Acquire(ev);
  1752.     SOM_CATCH_ALL
  1753.       return;
  1754.     SOM_ENDTRY
  1755.  
  1756.     //---<2>
  1757.     if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  1758.     {
  1759.       //---<3>
  1760.       if (ODISOStrCompare(docInfo->pathName, oldPathName) == 0)
  1761.       {
  1762.         SOM_TRY
  1763.           //---<4>
  1764.           ODDisposePtr(docInfo->pathName);
  1765.           docInfo->pathName = ODISOStrFromCStr(newPathName);
  1766.  
  1767.           SaveToAsDraft(ev,
  1768.                         _fShell,
  1769.                         _fAsDraft,
  1770.                         0,
  1771.                         0,
  1772.                         _fDocuments,
  1773. //                        (AEHashTable*)kODNULL);
  1774.                         (OpenHashTable*)kODNULL);
  1775.  
  1776.           TRY
  1777.             _fMutex->Release(ev);
  1778.           CATCH_ALL
  1779.           ENDTRY
  1780.  
  1781.           return;
  1782.  
  1783.         SOM_CATCH_ALL
  1784.           ODError exception = ODGetSOMException(ev);
  1785.  
  1786.           TRY
  1787.             _fMutex->Release(ev);
  1788.           CATCH_ALL
  1789.           ENDTRY
  1790.  
  1791.           ODSetSOMException(ev, exception);
  1792.           return;
  1793.         SOM_ENDTRY
  1794.       }
  1795.       else
  1796.       {
  1797.         //---<5>
  1798.         TRY
  1799.           _fMutex->Release(ev);
  1800.         CATCH_ALL
  1801.         ENDTRY
  1802.  
  1803.         ODSetSOMException(ev, kODErrInvalidDocPathName);
  1804.         return;
  1805.       }
  1806.     }
  1807.     else
  1808.     {
  1809.       //---<6>
  1810.       TRY
  1811.         _fMutex->Release(ev);
  1812.       CATCH_ALL
  1813.       ENDTRY
  1814.  
  1815.       ODSetSOMException(ev, kODErrInvalidDocID);
  1816.       return;
  1817.     }
  1818. }
  1819.  
  1820. /*
  1821.  *=============================================================================
  1822.  * IODAvailServer::RegisterLink
  1823.  *
  1824.  * RegisterLink is called when a new LinkSource has been
  1825.  * created in the document.  It provides a pointer to the LinkSource so
  1826.  * the AS may forward calls to it.  The AS returns a unique (within the
  1827.  * AS) ID for this LinkSource.  (LinkOpened need not be called).
  1828.  
  1829.     // 1. Check that the document is open.
  1830.     //    If not, this could be either a caller error
  1831.     //    or an indication that the AS has crashed and restarted
  1832.     //    losing the opening of the document. The LinkService
  1833.     //    has the obligation to recover from this condition.
  1834.     //    (by calling DocOpened, and asking each link source to
  1835.     //    re-issue LinkOpened, then finally re-issuing RegisterLink.)
  1836.     // 2. Create a new LinkId.
  1837.     // 3. Ask the AsDraft to create a new SU for this LinkId.
  1838.     // 4. Initialize the SU to version 0, empty Auxiliary State.
  1839.     // 5. Insert a new entry in fLinks.
  1840.     // 6. Insert a new entry in fLoadedLinks, with status inDoc.
  1841.     // 7. Optionally save the AsDraft.
  1842.     // 8. Return the LinkId.
  1843.  
  1844.  * <1>  Acquire fMutex before accessing fDocuments and fLinks.
  1845.  * <2>  Check if docID is associated with a registered document.
  1846.  *      If true retrieve the DocInfo entry of docID from fDocuments.
  1847.  * <3>  Check if document is opened.
  1848.  * <4>  Document is opened.
  1849.  *      Generate new linkID and update fLinkIDCounter.
  1850.  * <5>  Ask fAsDraft to create a new SU to store the auxiliary state.
  1851.  *      Add PropVersion to SU.
  1852.  *      Add PropIDCounter to SU.
  1853.  *      Add PropRemoteLinkInfos to SU.
  1854.  * <6>  Create a LinkSrcInfo entry.
  1855.  * <7>  Initialize the entry as <INDOC, docID, su->GetID, false, null, linkSrc>
  1856.  * <8>  Add that entry to fLinks.
  1857.  * <9>  Create a LinkIDNode entry.
  1858.  * <10> Initialize the entry with the linkID.
  1859.  * <11> Insert that entry to the list of link IDs in docInfo.
  1860.  * <11.1> Save fLinkIDCounter, fDocuments and fLinks to AsDraft.
  1861.  * <12> Relase fMutex.
  1862.  *      Return linkID.
  1863.  * <13> An exception is caught!
  1864.  *      Ask fAsDraft to remove the SU created earlier for the auxiliary state.
  1865.  * <14> Remove the newly added LinkSrcInfo entry from fLinks.
  1866.  *      Cleanup that entry.
  1867.  *      Delete that entry.
  1868.  * <15> Release fMutex.
  1869.  * <16> Set SOM ev to ODError.
  1870.  *      Return 0 as linkID.
  1871.  * <17> Fail testing in <3>: document is not opened.
  1872.  *      Release fMutex.
  1873.  *      Raise exception
  1874.  *      Return 0 as linkID
  1875.  * <18> Fail testing in <2>: docID is invalid.
  1876.  *      Release fMutex.
  1877.  *      Raise exception
  1878.  *      Return 0 as linkID
  1879.  *=============================================================================
  1880.  */
  1881.  
  1882. SOM_Scope ODLinkID
  1883. SOMLINK RegisterLink(IODAvailServer *somSelf,
  1884.                      Environment *ev,
  1885.                      IODDocumentID docID,
  1886.                      IODLinkTargetToLinkSource* linkSrc)
  1887. {
  1888.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  1889.     IODAvailServerMethodDebug("IODAvailServer","RegisterLink");
  1890.  
  1891.     DocInfo*       docInfo;
  1892.     ODLinkID       linkID;
  1893.     LinkIDNode*    linkIDNode;
  1894.     LinkSrcInfo*   lsInfo;
  1895.     ODStorageUnit* su;
  1896.  
  1897.     //---<1>
  1898.     SOM_TRY
  1899.       _fMutex->Acquire(ev);
  1900.     SOM_CATCH_ALL
  1901.       return 0;
  1902.     SOM_ENDTRY
  1903.  
  1904.     //---<2>
  1905.     if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  1906.     {
  1907.       //---<3>
  1908.       if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  1909.       {
  1910.         //---<4>
  1911.         linkID = ++_fLinkIDCounter;
  1912.  
  1913.         SOM_TRY
  1914.           //---<5>
  1915.           su = _fAsDraft->CreateStorageUnit(ev);
  1916.           ODSUAddPropValue(ev, su, kODPropVersion, kODULong);
  1917.           ODSUAddPropValue(ev, su, kODPropIDCounter, kODULong);
  1918.           ODSUAddPropValue(ev, su, kODPropRemoteLinkInfos, kODHashTable);
  1919.  
  1920.           //---<6>
  1921.           lsInfo = new LinkSrcInfo;
  1922.           THROW_IF_NULL(lsInfo);
  1923.  
  1924.           //---<7>
  1925.           lsInfo->state = INDOC;
  1926.           lsInfo->docID = docID;
  1927.           lsInfo->auxStateSUID = su->GetID(ev);
  1928.           lsInfo->isLocked = kODFalse;
  1929.           lsInfo->asLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  1930.           lsInfo->docLinkSrc = linkSrc;
  1931.  
  1932.           //---<8>
  1933.           _fLinks->ReplaceEntry(&linkID, &lsInfo);
  1934.  
  1935.           //---<9>
  1936.           linkIDNode = new LinkIDNode;
  1937.           THROW_IF_NULL(linkIDNode);
  1938.  
  1939.           //---<10>
  1940.           linkIDNode->linkID = linkID;
  1941.           linkIDNode->next = (LinkIDNode*)kODNULL;
  1942.  
  1943.           //---<11>
  1944.           if (docInfo->linkIDs == (LinkIDNode*)kODNULL)
  1945.           {
  1946.             docInfo->linkIDs = linkIDNode;
  1947.           }
  1948.           else
  1949.           {
  1950.             linkIDNode->next = docInfo->linkIDs;
  1951.             docInfo->linkIDs = linkIDNode;
  1952.           }
  1953.  
  1954.           //---<11.1>
  1955.           SaveToAsDraft(ev,
  1956.                         _fShell,
  1957.                         _fAsDraft,
  1958.                         0,
  1959.                         _fLinkIDCounter,
  1960.                         _fDocuments,
  1961.                         _fLinks);
  1962.  
  1963.           _fShell->UpdateLinkList(linkID, docID, INDOC);
  1964.  
  1965.           //---<12>
  1966.           TRY
  1967.             _fMutex->Release(ev);
  1968.           CATCH_ALL
  1969.           ENDTRY
  1970.  
  1971.           return linkID;
  1972.  
  1973.         SOM_CATCH_ALL
  1974.           ODError exception = ODGetSOMException(ev);
  1975.  
  1976.           TRY
  1977.             //---<13>
  1978.             if (su != (ODStorageUnit*)kODNULL)
  1979.             {
  1980.               _fAsDraft->RemoveStorageUnit(ev, su);
  1981.             }
  1982.  
  1983.             //---<14>
  1984.             if (lsInfo != (LinkSrcInfo*)kODNULL)
  1985.             {
  1986.               _fLinks->RemoveEntry(&linkID);
  1987.               CleanupLinkSrcInfo(ev, _fSurrogateDraft, lsInfo);
  1988.               delete lsInfo;
  1989.             }
  1990.  
  1991.             //---<15>
  1992.             _fMutex->Release(ev);
  1993.           CATCH_ALL
  1994.           ENDTRY
  1995.  
  1996.           //---<16>
  1997.           ODSetSOMException(ev, exception);
  1998.           return 0;
  1999.  
  2000.           // Note:
  2001.           // No need to cleanup docInfo->linkIDs because if
  2002.           //   linkIDNode = new LinkIDNode;
  2003.           // raises an exception then it will not be added to docInfo->linkIDs
  2004.         SOM_ENDTRY
  2005.       }
  2006.       else
  2007.       {
  2008.         //---<17>
  2009.         TRY
  2010.           _fMutex->Release(ev);
  2011.         CATCH_ALL
  2012.         ENDTRY
  2013.  
  2014.         ODSetSOMException(ev, kODErrDocNotOpened);
  2015.         return 0;
  2016.       }
  2017.     }
  2018.     else
  2019.     {
  2020.       //---<18>
  2021.       TRY
  2022.         _fMutex->Release(ev);
  2023.       CATCH_ALL
  2024.       ENDTRY
  2025.  
  2026.       ODSetSOMException(ev, kODErrInvalidDocID);
  2027.       return 0;
  2028.     }
  2029. }
  2030.  
  2031. /*
  2032.  *=============================================================================
  2033.  * IODAvailServer::LinkOpened
  2034.  *
  2035.  * LinkOpened is called when an existing LinkSource is internalized in
  2036.  * a document.  It provides a pointer to the LinkSource so
  2037.  * the AS may forward calls to it.  The AS returns the current
  2038.  * AuxiliaryState associated with this LinkSource, and whether some
  2039.  * target currently holds a lock on this LinkSource ContentSU.
  2040.  
  2041.     // 1. Find out what docid is associated with this linkid. (fLinks)
  2042.     //    If there is no entry in fLinks, this is either a caller
  2043.     //    error, or the AS crashed and failed to save the registration
  2044.     //    of this linkid.  Either way, return an unregistered exception.
  2045.     //    This is a major disaster,
  2046.     //    so the AS should save early and often.
  2047.     // 2. Check that the document is open (fOpenDocs).  If not, this is
  2048.     //    like step 1. of RegisterLink (see above.)  The caller
  2049.     //    can recover from this error.
  2050.     // 3. Is the linkid is in fLoadedLinks?
  2051.     //    3a. Yes, linkid is loaded. The following cases apply:
  2052.     //    3a.1 InDoc, or InBoth: This shouldn't occur.  Either
  2053.     //         somebody called LinkOpened twice, or else there's
  2054.     //         an implementation bug.
  2055.     //    3a.2 InAS and not IsLocked (IsLocked means the surrogate's ContentSU
  2056.     //                   is locked)
  2057.     //         1. Externalize the ASLinkSrc (i.e. the surrogate).
  2058.     //         2. Retrieve the Auxiliary State
  2059.     //         3. Update this entry in fLoadedLinks to be in state InDoc
  2060.     //            and save the LinkSrc ref (as DocLinkSrc)
  2061.     //         4. Release ASLinkSrc (destroying the surrogate)
  2062.     //         5. (If limitchecking: decrement count of loaded surrogates).
  2063.     //    3a.3 InAS and IsLocked:
  2064.     //         1. Externalize the ASLinkSrc
  2065.     //         2. Retrieve the Auxiliary State
  2066.     //         3. Update this entry in fLoadedLinks to be in state InBoth
  2067.     //            and save the LinkSrc ref (as DocLinkSrc)
  2068.     //    3a  ALL cases:  Move linkid to the top of the LRU list.
  2069. //???? Perhaps not necessary, as policy will be to keep all opened
  2070. //linksources in mem????
  2071.     //    3b  No, linkid is not loaded.
  2072.     //        1. Insert new entry: <InDoc, --, linkSrc, False>.
  2073.     //        2. Retrieve the Auxiliary State
  2074.     //        3. update LRU list (see above query??)
  2075.     //    4. Return AuxiliaryState and locked State
  2076.  
  2077.  * <1>  Acquire fMutex before accessing fDocuments and fLinks.
  2078.  * <2>  Check if linkID is associated with a registered link.
  2079.  *      If true retrieve the LinkSrcInfo entry of linkID from fLinks.
  2080.  * <3>  Check if document containing the link is registered.
  2081.  *      If true retrieve DocInfo of that document from fDocuments.
  2082.  * <4>  Check if document is opened.
  2083.  * <5>  The document is opened.
  2084.  *      Check the state of the LinkSrcInfo entry.
  2085.  * <6>  If state is UNLOADED:
  2086.  *        Change state to INDOC.
  2087.  *        Save LinkSource proxy.
  2088.  *        Assign isLocked to false.
  2089.  *        Allocate memory for auxState.
  2090.  * <6.1>  Retrieve SU of the auxiliary state from fAsDraft.
  2091.  *        Assign auxState with data read from the SU.
  2092.  *      NOTE: <6.1> is necessary because the LinkSource might have been
  2093.  *            internalized in the Avaibility Server and then released.
  2094.  * <7>  If state is INDOC:
  2095.  *        Link already opened!
  2096.  *        Release fMutex.
  2097.  *        Raise exception.
  2098.  *        Return.
  2099.  * <8>  If state is INAS and content SU is locked:
  2100.  *        Change state to INBOTH.
  2101.  *        Save LinkSource proxy.
  2102.  *        Assign isLocked to true.
  2103.  *        Allocate memory for auxState.
  2104.  * <8.1>  Assign auxState from LinkSource surrogate.
  2105.  * <8.2>  Retrieve SU of the auxiliary state from fAsDraft.
  2106.  *        Write auxState to the SU.
  2107.  *      NOTE: a. <8.2> is necessary in order to save the auxiliary state of
  2108.  *               the LinkSource surrogate in the fAsDraft because the surrogate
  2109.  *               itself was created in the fSurrogateDraft.
  2110.  *            b. LinkSource surrogate will be released when the content SU is
  2111.  *               unlocked by the LinkTarget.
  2112.  * <9>  If state is INAS and content SU is not locked:
  2113.  *        Change state to INDOC.
  2114.  *        Save LinkSource proxy.
  2115.  *        Assign isLocked to false.
  2116.  *        Allocate memory for auxState.
  2117.  * <9.1>  Assign auxState from LinkSource surrogate.
  2118.  * <9.2>  Retrieve SU of the auxiliary state from fAsDraft.
  2119.  *        Write auxState to the SU.
  2120.  * <9.3>  Release LinkSource surrogate.
  2121.  *        Reset asLinkSrc in LinkSrcInfo to null.
  2122.  * <10> If state is INBOTH:
  2123.  *        Link already opened!
  2124.  *        Release fMutex.
  2125.  *        Raise exception.
  2126.  *        Return.
  2127.  * <11> Release fMutex.
  2128.  *      Return.
  2129.  * <12> Fail testing in <4>: document is not opened.
  2130.  *      Release fMutex.
  2131.  *      Raise exception.
  2132.  *      Return.
  2133.  * <13> Fail testing in <3>: document is not registered
  2134.  *      Release fMutex.
  2135.  *      Raise exception.
  2136.  *      Return.
  2137.  * <14> Fail testing in <2>: linkID is invalid.
  2138.  *      Release fMutex.
  2139.  *      Raise exception.
  2140.  *      Return.
  2141.  *=============================================================================
  2142.  */
  2143.  
  2144. SOM_Scope void
  2145. SOMLINK LinkOpened(IODAvailServer *somSelf,
  2146.                    Environment *ev,
  2147.                    ODLinkID linkID,
  2148.                    IODLinkTargetToLinkSource* linkSrc,
  2149.                    IODAuxiliaryState** auxState,
  2150.                    ODBoolean* isLocked)
  2151. {
  2152.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  2153.     IODAvailServerMethodDebug("IODAvailServer","LinkOpened");
  2154.  
  2155.     IODDocumentID  docID;
  2156.     DocInfo*       docInfo;
  2157.     LinkSrcInfo*   lsInfo;
  2158.     ODStorageUnit* su;
  2159.  
  2160.     //---<1>
  2161.     SOM_TRY
  2162.       _fMutex->Acquire(ev);
  2163.     SOM_CATCH_ALL
  2164.       return;
  2165.     SOM_ENDTRY
  2166.  
  2167.     //---<2>
  2168.     if (_fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  2169.     {
  2170.       //---<3>
  2171.       docID = lsInfo->docID;
  2172.       if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  2173.       {
  2174.         //---<4>
  2175.         if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  2176.         {
  2177.           SOM_TRY
  2178.             //---<5>
  2179.             switch(lsInfo->state)
  2180.             {
  2181.               case UNLOADED:
  2182.                 //---<6>
  2183.                 // Before:<UNLOADED, docID, suID, false, null, null>
  2184.                 // After :<INDOC,    docID, suID, false, null, linkSrc>
  2185.                 lsInfo->state = INDOC;
  2186.                 lsInfo->docLinkSrc = linkSrc;
  2187.                 *isLocked = kODFalse;
  2188.                 *auxState = new IODAuxiliaryState;
  2189.                 THROW_IF_NULL(*auxState);
  2190.  
  2191.                 //---<6.1>
  2192.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2193.                 GetAuxStateFromSU(ev, su, **auxState);
  2194.  
  2195.                 _fShell->UpdateLinkList(linkID, docID, INDOC);
  2196.  
  2197.                 break;
  2198.  
  2199.               case INDOC:
  2200.                 //---<7>
  2201.                 TRY
  2202.                   _fMutex->Release(ev);
  2203.                 CATCH_ALL
  2204.                 ENDTRY
  2205.  
  2206.                 return;
  2207.  
  2208.               case INAS:
  2209.                 if (lsInfo->isLocked == kODTrue)
  2210.                 {
  2211.                   //---<8>
  2212.                   // Before:<INAS,   docID, suID, true, asLS, null>
  2213.                   // After :<INBOTH, docID, suID, true, asLS, linkSrc>
  2214.                   lsInfo->state = INBOTH;
  2215.                   lsInfo->docLinkSrc = linkSrc;
  2216.                   *isLocked = kODTrue;
  2217.                   *auxState = new IODAuxiliaryState;
  2218.                   THROW_IF_NULL(*auxState);
  2219.  
  2220.                   //---<8.1>
  2221.                   ((IODLinkSource*)lsInfo->asLinkSrc)->GetAuxState(ev,
  2222.                                                                    auxState);
  2223.  
  2224.                   //---<8.2>
  2225.                   su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2226.                   SetAuxStateToSU(ev, su, **auxState);
  2227.  
  2228.                   _fShell->UpdateLinkList(linkID, docID, INBOTH);
  2229.                 }
  2230.                 else
  2231.                 {
  2232.                   //---<9>
  2233.                   // Before:<INAS,  docID, suID, false, asLS, null>
  2234.                   // After :<INDOC, docID, suID, false, null, linkSrc>
  2235.                   lsInfo->state = INDOC;
  2236.                   lsInfo->docLinkSrc = linkSrc;
  2237.                   *isLocked = kODFalse;
  2238.                   *auxState = new IODAuxiliaryState;
  2239.                   THROW_IF_NULL(*auxState);
  2240.  
  2241.                   //---<9.1>
  2242.                   ((IODLinkSource*)lsInfo->asLinkSrc)->GetAuxState(ev,
  2243.                                                                    auxState);
  2244.  
  2245.                   //---<9.2>
  2246.                   su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2247.                   SetAuxStateToSU(ev, su, **auxState);
  2248.  
  2249.                   //---<9.3>
  2250.                   TRY
  2251.                    ((CMDraft*)_fSurrogateDraft)->
  2252.                      RemoveLinkSource(ev, (ODLinkSource*)lsInfo->asLinkSrc);
  2253.                   CATCH_ALL
  2254.                   ENDTRY
  2255.                   lsInfo->asLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  2256.  
  2257.                   _fShell->UpdateLinkList(linkID, docID, INDOC);
  2258.                 }
  2259.                 break;
  2260.  
  2261.               //---<10>
  2262.               case INBOTH:
  2263.                 TRY
  2264.                   _fMutex->Release(ev);
  2265.                 CATCH_ALL
  2266.                 ENDTRY
  2267.  
  2268.                 ODSetSOMException(ev, kODErrLinkAlreadyOpened);
  2269.                 return;
  2270.             }
  2271.  
  2272.             //---<11>
  2273.             TRY
  2274.               _fMutex->Release(ev);
  2275.             CATCH_ALL
  2276.             ENDTRY
  2277.  
  2278.             return;
  2279.  
  2280.           SOM_CATCH_ALL
  2281.             ODError exception = ODGetSOMException(ev);
  2282.  
  2283.             TRY
  2284.               _fMutex->Release(ev);
  2285.             CATCH_ALL
  2286.             ENDTRY
  2287.  
  2288.             ODSetSOMException(ev, exception);
  2289.             return;
  2290.           SOM_ENDTRY
  2291.         }
  2292.         else
  2293.         {
  2294.           //---<12>
  2295.           TRY
  2296.             _fMutex->Release(ev);
  2297.           CATCH_ALL
  2298.           ENDTRY
  2299.  
  2300.           ODSetSOMException(ev, kODErrDocNotOpened);
  2301.           return;
  2302.         }
  2303.       }
  2304.       else
  2305.       {
  2306.         //---<13>
  2307.         TRY
  2308.           _fMutex->Release(ev);
  2309.         CATCH_ALL
  2310.         ENDTRY
  2311.  
  2312.         ODSetSOMException(ev, kODErrDocNotRegistered);
  2313.         return;
  2314.       }
  2315.     }
  2316.     else
  2317.     {
  2318.       //---<14>
  2319.       TRY
  2320.         _fMutex->Release(ev);
  2321.       CATCH_ALL
  2322.       ENDTRY
  2323.  
  2324.       ODSetSOMException(ev, kODErrInvalidLinkID);
  2325.       return;
  2326.     }
  2327. }
  2328.  
  2329. /*
  2330.  *=============================================================================
  2331.  * IODAvailServer::LinkClosed
  2332.  *
  2333.  * LinkClosed is called when a LinkSource is released in a document.
  2334.  * It provides the current AuxiliaryState for this LinkSource.
  2335.  * The AS will now process calls for this LinkSource.
  2336.  * (Note that local LinkTargets will not have a reference any longer to
  2337.  * the LinkSource object in the document.)
  2338.  
  2339.     // 1. Find the docid associated with this linkid. (fLinks)
  2340.     //    If there is no entry, in fLinks, this is a major error,
  2341.     //    as in step 1 of LinkOpened.
  2342.     // 2. Check that the document is open (fOpenDocs). The recovery
  2343.     //    is similar to that of step 1 of RegisterLink, except
  2344.     //    that we will not reissue LinkOpened on the linkID
  2345.     //    which failed.
  2346.     // 3. Is the linkId in fLoadedLinks?
  2347.     //    3a. Yes, linkId is loaded.  The following cases apply:
  2348.     //    3a. InBoth:  This shouldn't occur.  Link Sources should
  2349.     //        not call LinkClosed until the lock is released.
  2350.     //        But perhaps a buggy or malevolent target is holding
  2351.     //        the lock and the linkSource absolutely HAS TO close?
  2352.     //        We may need to require linkSources to break locks
  2353.     //        in which case entering this case is an indication
  2354.     //        that this is what happened.  Set the locked state OFF
  2355.     //        and switch to InAS, after merging the AuxiliaryState
  2356.     //        (i.e. replacing it if it is later, and ignoring it
  2357.     //        if not)
  2358.     //    3a. InDoc:  This is the normal case. Remove the fLoadedLinks
  2359.     //        entry and merge the Auxiliary state.
  2360.     //    3a. InAS: This means that the AS failed and restarted,
  2361.     //        lost the fact that the document and link opened, and now
  2362.     //        the link is being closed.  The document should have
  2363.     //        re-opened in this case, but if it didn't, we may
  2364.     //        have inconsistent auxiliary state (equal version numbers
  2365.     //        with different values.)
  2366.     //    3b. Not loaded:  This also means that the AS failed and
  2367.     //        restarted, as in 3a InAS, but now it's almost certain
  2368.     //        that you should trust the Auxiliary state maintained
  2369.     //        by the document.
  2370.  
  2371.  * <1>  Acquire fMutex before accessing fDocuments and fLinks.
  2372.  * <2>  Check if linkID is associated with a registered link.
  2373.  *      If true retrieve the LinkSrcInfo entry of linkID from fLinks.
  2374.  * <3>  Check if document containing the link is registered.
  2375.  *      If true retrieve the DocInfo entry of that document from fDocuments.
  2376.  * <4>  Check if that document is opened.
  2377.  * <5>  The document is opened.
  2378.  *      Check the state of the LinkSrcInfo entry.
  2379.  * <6>  If state is UNLOADED:
  2380.  *      NOTE: AS failed and restarted, but LinkService already detected this
  2381.  *            and re-issued DocOpened.
  2382.  *        If auxState is non-null
  2383.  *          Get SU of the auxililary state from fAsDraft.
  2384.  *          Write auxState to the SU.
  2385.  * <7>  If state is INDOC:
  2386.  *        Change state to UNLOADED.
  2387.  *        Release LinkSource proxy.
  2388.  *        Reset docLinkSrc in LinkSrcInfo entry to null.
  2389.  *        If auxState is non-null
  2390.  *          Get SU of the auxililary state from fAsDraft.
  2391.  *          Write auxState to the SU.
  2392.  * <8>  If state is INAS:
  2393.  *        XXXXX Should not happen!
  2394.  *      NOTE: The reason that the state of LinkSrcInfo may be INAS is that
  2395.  *            AS failed and restarted and a LinkTarget invokes a method on
  2396.  *            LinkSource before LinkService re-issue DocOpened.
  2397.  *            However once LinkService re-issue DocOpened and LinkOpened
  2398.  *            the state of LinkSrcInfo should either be INDOC or INBOTH.
  2399.  * <9>  If state is INBOTH:
  2400.  *      NOTE: A LinkTarget still holding the lock of the content SU of the
  2401.  *            LinkSource surrogate since LinkOpened was last called.
  2402.  *        Change state to INAS.
  2403.  *        Release LinkSource proxy.
  2404.  *        Reset docLinkSrc in LinkSrcInfo entry to null.
  2405.  *        If auxState is non-null
  2406.  *          Get SU of the auxililary state from fAsDraft.
  2407.  *          Write auxState to the SU.
  2408.  *          Reset the auxiliary state of LinkSource surrogate.
  2409.  * <10> Release fMutex.
  2410.  *      Return.
  2411.  * <11> Fail testing in <4>: document is not opened.
  2412.  *      Release fMutex.
  2413.  *      Raise exception.
  2414.  *      Return.
  2415.  * <12> Fail testing in <3>: document is not registered
  2416.  *      Release fMutex.
  2417.  *      Raise exception.
  2418.  *      Return.
  2419.  * <13> Fail testing in <2>: linkID is invalid.
  2420.  *      Release fMutex.
  2421.  *      Raise exception.
  2422.  *      Return.
  2423.  *=============================================================================
  2424.  */
  2425.  
  2426. SOM_Scope void
  2427. SOMLINK LinkClosed(IODAvailServer *somSelf,
  2428.                    Environment *ev,
  2429.                    ODLinkID linkID,
  2430.                    IODAuxiliaryState* auxState)
  2431. {
  2432.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  2433.     IODAvailServerMethodDebug("IODAvailServer","LinkClosed");
  2434.  
  2435.     IODDocumentID  docID;
  2436.     DocInfo*       docInfo;
  2437.     LinkSrcInfo*   lsInfo;
  2438.     ODStorageUnit* su;
  2439.  
  2440.     //---<1>
  2441.     SOM_TRY
  2442.       _fMutex->Acquire(ev);
  2443.     SOM_CATCH_ALL
  2444.       return;
  2445.     SOM_ENDTRY
  2446.  
  2447.     //---<2>
  2448.     if (_fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  2449.     {
  2450.       //---<3>
  2451.       docID = lsInfo->docID;
  2452.       if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  2453.       {
  2454.         //---<4>
  2455.         if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  2456.         {
  2457.           SOM_TRY
  2458.             //---<5>
  2459.             switch(lsInfo->state)
  2460.             {
  2461.               case UNLOADED:
  2462.                 //---<6>
  2463.                 // Before:<UNLOADED, docID, suID, false, null, null>
  2464.                 // After :<UNLOADED, docID, suID, false, null, null>
  2465.                 if (auxState != (IODAuxiliaryState*)kODNULL)
  2466.                 {
  2467.                   su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2468.                   SetAuxStateToSU(ev, su, *auxState);
  2469.                 }
  2470.                 break;
  2471.  
  2472.               case INDOC:
  2473.                 //---<7>
  2474.                 // Before:<INDOC,    docID, suID, false, null, docLS>
  2475.                 // After :<UNLOADED, docID, suID, false, null, null>
  2476.                 lsInfo->state = UNLOADED;
  2477.                 ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  2478.                 lsInfo->docLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  2479.                 if (auxState != (IODAuxiliaryState*)kODNULL)
  2480.                 {
  2481.                   su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2482.                   SetAuxStateToSU(ev, su, *auxState);
  2483.                 }
  2484.  
  2485.                 _fShell->UpdateLinkList(linkID, docID, UNLOADED);
  2486.  
  2487.                 break;
  2488.  
  2489.               case INAS:
  2490.                 //---<9>
  2491.                 break;
  2492.  
  2493.               case INBOTH:
  2494.                 //---<8>
  2495.                 // Before:<INBOTH, docID, suID, true, asLS, docLS>
  2496.                 // After :<INAS,   docID, suID, true, asLS, null>
  2497.                 lsInfo->state = INAS;
  2498.                 ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  2499.                 lsInfo->docLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  2500.                 if (auxState != (IODAuxiliaryState*)kODNULL)
  2501.                 {
  2502.                   su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2503.                   SetAuxStateToSU(ev, su, *auxState);
  2504.                   ((IODLinkSource*)lsInfo->asLinkSrc)->ResetAuxState(ev,
  2505.                                                                      auxState);
  2506.                 }
  2507.  
  2508.                 _fShell->UpdateLinkList(linkID, docID, INAS);
  2509.  
  2510.                 break;
  2511.             }
  2512.  
  2513.             //---<10>
  2514.             TRY
  2515.               _fMutex->Release(ev);
  2516.             CATCH_ALL
  2517.             ENDTRY
  2518.  
  2519.             return;
  2520.  
  2521.           SOM_CATCH_ALL
  2522.             ODError exception = ODGetSOMException(ev);
  2523.  
  2524.             TRY
  2525.               _fMutex->Release(ev);
  2526.             CATCH_ALL
  2527.             ENDTRY
  2528.  
  2529.             ODSetSOMException(ev, exception);
  2530.             return;
  2531.           SOM_ENDTRY
  2532.         }
  2533.         else
  2534.         {
  2535.           //---<11>
  2536.           TRY
  2537.             _fMutex->Release(ev);
  2538.           CATCH_ALL
  2539.           ENDTRY
  2540.  
  2541.           ODSetSOMException(ev, kODErrDocNotOpened);
  2542.           return;
  2543.         }
  2544.       }
  2545.       else
  2546.       {
  2547.         //---<12>
  2548.         TRY
  2549.           _fMutex->Release(ev);
  2550.         CATCH_ALL
  2551.         ENDTRY
  2552.  
  2553.         ODSetSOMException(ev, kODErrDocNotRegistered);
  2554.         return;
  2555.       }
  2556.     }
  2557.     else
  2558.     {
  2559.       //---<13>
  2560.       TRY
  2561.         _fMutex->Release(ev);
  2562.       CATCH_ALL
  2563.       ENDTRY
  2564.  
  2565.       ODSetSOMException(ev, kODErrInvalidLinkID);
  2566.       return;
  2567.     }
  2568. }
  2569.  
  2570. /*
  2571.  *=============================================================================
  2572.  * IODAvailServer::RemoveLink
  2573.  *
  2574.  * RemoveLink is called when a LinkSource is removed from a document.
  2575.  
  2576.     // 1. Exactly like linkClosed except,
  2577.     //    a.instead of merging auxiliary state,
  2578.     //      discard entry in fLinks table, and remove SU.
  2579.     //    b.never end up in InAS state.  It's the LinkSource's
  2580.     //      responsibility to break locks (for example, to
  2581.     //      notify the lock holder.  This may be done anyway if we always
  2582.     //      notify registered targets when a remove occurs.) if necessary befor
  2583.     //      calling this method.  The AS will
  2584.     //      release the surrogate, and remove fLoadedLinks entry.
  2585.  
  2586.  * <1>  Acquire fMutex before accessing fDocuments and fLinks.
  2587.  * <2>  Check if linkID is associated with a registered link.
  2588.  *      If true retrieve the LinkSrcInfo entry of linkID from fLinks.
  2589.  * <3>  Check if document containing the link is registered.
  2590.  *      If true retrieve the DocInfo entry of that document from fDocuments.
  2591.  * <4>  Check if that document is opened.
  2592.  * <5>  The document is opened.
  2593.  *      Check the state of the LinkSrcInfo entry.
  2594.  * <6>  If state is UNLOADED:
  2595.  *        Get SU of the auxiliary state from fAsDraft.
  2596.  *        Ask fAsDraft to remove that SU.
  2597.  * <7>  If state is INDOC:
  2598.  *        Get SU of the auxiliary state from fAsDraft.
  2599.  *        Ask fAsDraft to remove that SU.
  2600.  *        Release LinkSource proxy.
  2601.  * <8>  If state is INAS:
  2602.  *        XXXXX Should not happen!
  2603.  *      NOTE: The reason that the state of LinkSrcInfo may be INAS is that
  2604.  *            AS failed and restarted and a LinkTarget invokes a method on
  2605.  *            LinkSource before LinkService re-issue DocOpened.
  2606.  *            However once LinkService re-issue DocOpened and LinkOpened
  2607.  *            the state of LinkSrcInfo should either be INDOC or INBOTH.
  2608.  * <9>  If state is INBOTH:
  2609.  *        Change state to REMOVED.
  2610.  *        Remove the storage unit of the auxiliary state.
  2611.  *        Release LinkSource proxy.
  2612.  *      NOTE: When the content SU is unlocked by the LinkTarget, the
  2613.  *            LinkSource surrogate will be released and the LinkSrcInfo
  2614.  *            entry will be deleted.
  2615.  * <10> Delete linkID from the list of linkIDs in the docInfo entry.
  2616.  * <10.1>
  2617.  *      If state of the LinkSrcInfo entry is not REMOVED
  2618.  *        Remove the LinkSrcInfo from fLinks.
  2619.  *        Delete the LinkSrcInfo entry.
  2620.  *      Save fDocuments and fLinks to AsDraft.
  2621.  *      Release fMutex.
  2622.  *      Return.
  2623.  * <11> Fail testing in <4>: document is not opened.
  2624.  *      Release fMutex.
  2625.  *      Raise exception.
  2626.  *      Return.
  2627.  * <12> Fail testing in <3>: document is not registered
  2628.  *      Release fMutex.
  2629.  *      Raise exception.
  2630.  *      Return.
  2631.  * <13> Fail testing in <2>: linkID is invalid.
  2632.  *      Release fMutex.
  2633.  *      Raise exception.
  2634.  *      Return.
  2635.  *=============================================================================
  2636.  */
  2637.  
  2638. SOM_Scope void
  2639. SOMLINK RemoveLink(IODAvailServer *somSelf,
  2640.                    Environment *ev,
  2641.                    ODLinkID linkID)
  2642. {
  2643.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  2644.     IODAvailServerMethodDebug("IODAvailServer","RemoveLink");
  2645.  
  2646.     IODDocumentID  docID;
  2647.     DocInfo*       docInfo;
  2648.     LinkSrcInfo*   lsInfo;
  2649.     ODStorageUnit* su;
  2650.  
  2651.     //---<1>
  2652.     SOM_TRY
  2653.       _fMutex->Acquire(ev);
  2654.     SOM_CATCH_ALL
  2655.       return;
  2656.     SOM_ENDTRY
  2657.  
  2658.     //---<2>
  2659.     if (_fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  2660.     {
  2661.       //---<3>
  2662.       docID = lsInfo->docID;
  2663.       if (_fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  2664.       {
  2665.         //---<4>
  2666.         if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  2667.         {
  2668.           TRY
  2669.             //---<5>
  2670.             switch(lsInfo->state)
  2671.             {
  2672.               case UNLOADED:
  2673.                 //---<6>
  2674.                 //Before:<UNLOADED, docID, suID, false, null, null>
  2675.                 //After :<UNLOADED, docID, ____, false, null, null>
  2676.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2677.                 _fAsDraft->RemoveStorageUnit(ev, su);
  2678.                 break;
  2679.  
  2680.               case INDOC:
  2681.                 //---<7>
  2682.                 //Before:<INDOC, docID, suID, false, null, docLS>
  2683.                 //After :<INDOC, docID, ____, false, null, _____>
  2684.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2685.                 _fAsDraft->RemoveStorageUnit(ev, su);
  2686.                 ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  2687.                 break;
  2688.  
  2689.               case INAS:
  2690.                 //---<9>
  2691.                 break;
  2692.  
  2693.               case INBOTH:
  2694.                 //---<8>
  2695.                 //Before:<INBOTH,  docID, suID, true, asLS, docLS>
  2696.                 //After :<REMOVED, docID, ____, true, asLS, _____>
  2697.                 lsInfo->state = REMOVED;
  2698.                 su = _fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2699.                 _fAsDraft->RemoveStorageUnit(ev, su);
  2700.                 ReleaseDocLinkSource(ev, lsInfo->docLinkSrc);
  2701.                 break;
  2702.             }
  2703.           CATCH_ALL
  2704.             // ignore exceptions caught when making calls on _fAsDraft
  2705.           ENDTRY
  2706.  
  2707.           //---<10>
  2708.           LinkIDNode *hd, *nptr;
  2709.           hd = nptr = docInfo->linkIDs;
  2710.           while(nptr != (LinkIDNode*)kODNULL)
  2711.           {
  2712.             if (nptr->linkID = linkID)
  2713.             {
  2714.               if (hd == nptr)
  2715.               {
  2716.                 docInfo->linkIDs = nptr->next;
  2717.               }
  2718.               else
  2719.               {
  2720.                 hd->next = nptr->next;
  2721.               }
  2722.               nptr->next = kODNULL;
  2723.               delete nptr;
  2724.               break;
  2725.             }
  2726.             hd = nptr;
  2727.             nptr = nptr->next;
  2728.           }
  2729.  
  2730.           //---<10.1>
  2731.           if (lsInfo->state != REMOVED)
  2732.           {
  2733.             _fLinks->RemoveEntry(&linkID);
  2734.             delete lsInfo;
  2735.           }
  2736.  
  2737.           TRY
  2738.             SaveToAsDraft(ev, _fShell, _fAsDraft, 0, 0, _fDocuments, _fLinks);
  2739.             _fMutex->Release(ev);
  2740.           CATCH_ALL
  2741.           ENDTRY
  2742.  
  2743.           return;
  2744.         }
  2745.         else
  2746.         {
  2747.           //---<11>
  2748.           TRY
  2749.             _fMutex->Release(ev);
  2750.           CATCH_ALL
  2751.           ENDTRY
  2752.  
  2753.           ODSetSOMException(ev, kODErrDocNotOpened);
  2754.           return;
  2755.         }
  2756.       }
  2757.       else
  2758.       {
  2759.         //---<12>
  2760.         TRY
  2761.           _fMutex->Release(ev);
  2762.         CATCH_ALL
  2763.         ENDTRY
  2764.  
  2765.         ODSetSOMException(ev, kODErrDocNotRegistered);
  2766.         return;
  2767.       }
  2768.     }
  2769.     else
  2770.     {
  2771.       //---<13>
  2772.       TRY
  2773.         _fMutex->Release(ev);
  2774.       CATCH_ALL
  2775.       ENDTRY
  2776.  
  2777.       ODSetSOMException(ev, kODErrInvalidLinkID);
  2778.       return;
  2779.     }
  2780. }
  2781.  
  2782.  
  2783. /*
  2784.  *=============================================================================
  2785. // The GetDispatch does the following:
  2786. // 1. If the linkId is loaded, find its LoadedLinks entry.
  2787. //   1.1   If it's InAS, make it 'most recently used' if not already,
  2788. //          and return the ASLinkSrc.
  2789. //   1.2.  If it's InDoc or InBoth, return the DocLinkSrc
  2790. // 2. If the linkId isn't loaded,
  2791. //   2.1. If the link's document (see fLinks) is open (see OpenDocs),
  2792. //         2.1.1. ask the documents AS to open the LinkSource,
  2793. //         2.1.2. insert loadedLinks entry in state InDoc
  2794. //         2.1.3. If this fails, assume the document crashed. Close it.
  2795. //   2.2. If the link's document is closed (or was made closed by step 2.1.3)
  2796. //         2.2.1. Open up a read-only document using the document's pathname.
  2797. //         2.2.2. Locate that document's draft's LinkSource table.
  2798. //         2.2.3. Clone the LinkSource into the SurrogateDraft.
  2799. //         2.2.4. Ask the surrogate draft to create a surrogate
  2800. //                and give the new surrogate access to the auxiliary state
  2801. //                retrieved from the AsDraft. The surrogate linkSource
  2802. //                will merge the auxiliary state from the document
  2803. //                with the one retrieved from the AsDraft.  It will
  2804. //                write it into the ASDraft.
  2805. //         2.2.5. Save the ASDraft.
  2806. //         2.2.6. insert loadedLinks entry in state InAS.
  2807.  
  2808.  * <1>  Check if linkID is associated with a registered link.
  2809.  *      If true retrieve the LinkSrcInfo entry of linkID from fLinks.
  2810.  * <2>  Check if the state of LinkSrcInfo entry is UNLOADED.
  2811.  * <3>  Check if document containing the link is registered.
  2812.  *      If true retrieve the DocInfo entry of that document from fDocuments.
  2813.  * <4>  Allocate memory for auxState.
  2814.  *      Ask fAsDraft to get the SU of the auxiliary state.
  2815.  *      Assign auxState to the data retrieved from the SU.
  2816.  * <5>  Check if document is opened.
  2817.  * <6>  The document is opened.
  2818.  *      Release fMutex so it will not block call incoming call
  2819.  *        while making remote call.
  2820.  * <7>  Ask LinkService of the document to internalize the LinkSource and
  2821.  *        obtain its proxy.
  2822.  * <8>  Exception caught on remote call to LinkService to internalize the
  2823.  *        LinkSource, may be the document crashed.
  2824.  *      Acquire fMutex again in order to access fLinks.
  2825.  * <9> Check if linkID is still associated with a registered link.
  2826.  *     If true retrieve the LinkSrcInfo entry of linkID from fLinks.
  2827.  * <10> Ask fShell to clone LinkSource from document draft to fSurrogateDraft.
  2828.  *      Ask fSurrogateDraft to create the surrogate and save it in LinkSrcInfo
  2829.  *        entry.
  2830.  *      Change state to INAS.
  2831.  *      Cleanup and delete auxState.
  2832.  *      Return the LinkSrcInfo entry.
  2833.  * <11> Fail testing in <9>: LinkService called RemoveLink and destroy
  2834.  *        LinkSrcInfo entry while fMutex was released at <6>.
  2835.  *      Raise exception.
  2836.  * <12> No exception caught on remote call to LinkService to internalize the
  2837.  *        LinkSource.
  2838.  *      Acquire fMutex again to access fLinks.
  2839.  * <13> Check if linkID is still associated with a registered link.
  2840.  *      If true retrieve the LinkSrcInfo entry of linkID from fLinks.
  2841.  * <14> If state of LinkSrcInfo remains UNLOADED
  2842.  *        Change state to INDOC.
  2843.  *        Save the LinkSource proxy obtained in <7>.
  2844.  *        Cleanup and delete auxState.
  2845.  *        Return the LinkSrcInfo entry.
  2846.  *      NOTE: If LinkService called LinkOpen while fMutex was released at <6>
  2847.  *            the state of LinkSrcInfo becomes INDOC and it will have the
  2848.  *            LinkSource proxy already.
  2849.  *            However the state can never be INAS, INBOTH or REMOVED.
  2850.  * <15> Fail testing in <13>: LinkService called RemoveLink and destroy
  2851.  *        LinkSrcInfo entry while fMutex was released at <6>.
  2852.  *      Raise exception.
  2853.  
  2854.  * <16> Fail testing in <5>: document is closed.
  2855.  *      Ask fShell to clone LinkSource from document draft to fSurrogateDraft.
  2856.  *      Ask fSurrogateDraft to create the surrogate and save it in LinkSrcInfo
  2857.  *        entry.
  2858.  *      Change state to INAS.
  2859.  *      Cleanup and delete auxState.
  2860.  *      Return the LinkSrcInfo entry.
  2861.  * <17> Fail testing in <3>: document is not registered.
  2862.  *      Raise exception.
  2863.  * <18> The state of  LinkSrcInfo entry is either INDOC, INBOTH or  REMOVED.
  2864.  *      Return the LinkSrcInfo entry.
  2865.  * <19> Fail testing in <1>: invalid linkID.
  2866.  *      Raise exception.
  2867.  *=============================================================================
  2868.  */
  2869.  
  2870. LinkSrcInfo* GetDispatch(Environment* ev,
  2871.                          IODMutex* fMutex,
  2872. //                         AEHashTable* fDocuments,
  2873. //                         AEHashTable* fLinks,
  2874.                          OpenHashTable* fDocuments,
  2875.                          OpenHashTable* fLinks,
  2876.                          AvsShell* fShell,
  2877.                          ODDraft* fAsDraft,
  2878.                          ODDraft* fSurrogateDraft,
  2879.                          ODLinkID linkID)
  2880. {
  2881.     IODAuxiliaryState*         auxState;
  2882.     IODDocumentID              docID;
  2883.     DocInfo*                   docInfo;
  2884.     IODLinkTargetToLinkSource* linkSrc;
  2885.     LinkSrcInfo*               lsInfo;
  2886.     ODStorageUnit*             su;
  2887.     ODStorageUnitID            suID;
  2888.  
  2889.     //---<1>
  2890.     if (fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  2891.     {
  2892.       //---<2>
  2893.       if (lsInfo->state == UNLOADED)
  2894.       {
  2895.         //---<3>
  2896.         docID = lsInfo->docID;
  2897.         if (fDocuments->GetValue(&docID, &docInfo) == kODTrue)
  2898.         {
  2899.           TRY
  2900.             //---<4>
  2901.             auxState = new IODAuxiliaryState;
  2902.             THROW_IF_NULL(auxState);
  2903.  
  2904.             su = fAsDraft->AcquireStorageUnit(ev, lsInfo->auxStateSUID);
  2905.             GetAuxStateFromSU(ev, su, *auxState);
  2906.  
  2907.           CATCH_ALL
  2908.             RERAISE;
  2909.           ENDTRY
  2910.  
  2911.           //---<5>
  2912.           if (docInfo->linkSrvc != (IODAvailServerToLinkService*)kODNULL)
  2913.           {
  2914.             //---<6>
  2915.             IODLinkService* linkSrvc = (IODLinkService*)docInfo->linkSrvc;
  2916.  
  2917.             TRY
  2918.               fMutex->Release(ev);
  2919.             CATCH_ALL
  2920.               RERAISE;
  2921.             ENDTRY
  2922.  
  2923.             TRY
  2924.               //---<7>
  2925.               linkSrc = (IODLinkTargetToLinkSource*)
  2926.                         linkSrvc->InternalizeLinkSource(ev, linkID, auxState);
  2927.             CATCH_ALL
  2928.               //---<8>
  2929.               TRY
  2930.                 fMutex->Acquire(ev);
  2931.               CATCH_ALL
  2932.                 RERAISE;
  2933.               ENDTRY
  2934.  
  2935.               //---<9>
  2936.               if (fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  2937.               {
  2938.                 TRY
  2939.                   //---<10>
  2940.                   suID = fShell->CloneLinkSource(linkID, docInfo->pathName);
  2941.                   lsInfo->asLinkSrc = (IODLinkTargetToLinkSource*)
  2942.                                       ((CMDraft*)fSurrogateDraft)->
  2943.                                                    GetLinkSrcForAvlSvr(
  2944.                                                      ev,
  2945.                                                      suID,
  2946.                                                      auxState);
  2947.                   lsInfo->state = INAS;
  2948.  
  2949.                   fShell->UpdateLinkList(linkID, docID, INAS);
  2950.  
  2951.                   ODDisposePtr(auxState->remoteLinkInfos._buffer);
  2952.                   delete auxState;
  2953.                   return lsInfo;
  2954.  
  2955.                 CATCH_ALL
  2956.                   ODDisposePtr(auxState->remoteLinkInfos._buffer);
  2957.                   delete auxState;
  2958.                   RERAISE;
  2959.                 ENDTRY
  2960.               }
  2961.               else
  2962.               {
  2963.                 //---<11>
  2964.                 ODDisposePtr(auxState->remoteLinkInfos._buffer);
  2965.                 delete auxState;
  2966.                 THROW(kODErrInvalidLinkID);
  2967.               }
  2968.             ENDTRY
  2969.  
  2970.             //---<12>
  2971.             TRY
  2972.               fMutex->Acquire(ev);
  2973.             CATCH_ALL
  2974.               RERAISE;
  2975.             ENDTRY
  2976.  
  2977.             //---<13>
  2978.             if (fLinks->GetValue(&linkID, &lsInfo) == kODTrue)
  2979.             {
  2980.               //---<14>
  2981.               if (lsInfo->state == UNLOADED)
  2982.               {
  2983.                 lsInfo->state = INDOC;
  2984.                 lsInfo->docLinkSrc = linkSrc;
  2985.  
  2986.                 fShell->UpdateLinkList(linkID, docID, INDOC);
  2987.               }
  2988.  
  2989.               ODDisposePtr(auxState->remoteLinkInfos._buffer);
  2990.               delete auxState;
  2991.               return lsInfo;
  2992.             }
  2993.             else
  2994.             {
  2995.               //---<15>
  2996.               ODDisposePtr(auxState->remoteLinkInfos._buffer);
  2997.               delete auxState;
  2998.               THROW(kODErrInvalidLinkID);
  2999.             }
  3000.           }
  3001.           else
  3002.           {
  3003.             //---<16>
  3004.             TRY
  3005.               suID = fShell->CloneLinkSource(linkID, docInfo->pathName);
  3006.               lsInfo->asLinkSrc = (IODLinkTargetToLinkSource*)
  3007.                                   ((CMDraft*)fSurrogateDraft)->
  3008.                                                GetLinkSrcForAvlSvr(ev,
  3009.                                                                    suID,
  3010.                                                                    auxState);
  3011.               lsInfo->state = INAS;
  3012.  
  3013.               fShell->UpdateLinkList(linkID, docID, INAS);
  3014.  
  3015.               ODDisposePtr(auxState->remoteLinkInfos._buffer);
  3016.               delete auxState;
  3017.               return lsInfo;
  3018.  
  3019.             CATCH_ALL
  3020.               ODDisposePtr(auxState->remoteLinkInfos._buffer);
  3021.               delete auxState;
  3022.               RERAISE;
  3023.             ENDTRY
  3024.           }
  3025.         }
  3026.         else
  3027.         {
  3028.           //---<17>
  3029.           THROW(kODErrDocNotRegistered);
  3030.         }
  3031.       }
  3032.       else
  3033.       {
  3034.         //---<18>
  3035.         return lsInfo;
  3036.       }
  3037.     }
  3038.     else
  3039.     {
  3040.       //---<19>
  3041.       THROW(kODErrInvalidLinkID);
  3042.     }
  3043. }
  3044.  
  3045.  
  3046.  
  3047. // All of the following have the same form:
  3048. // 1. Grab a semaphore.
  3049. // 2. Call GetDispatch to locate the loadedLinks entry and linkSource
  3050. // 3. Call the corresponding LinkSource method (either in doc or surrogate)
  3051. // 4. If this was Lock or Unlock and not InDoc,
  3052. //    record state in loadedLinks entry.
  3053. // 5. If an InBoth entry became unlocked, release surrogate, go to InDoc.
  3054. //    (decrementing the count if limitchecking)
  3055. // 6. Release the semaphore.
  3056.  
  3057.  
  3058.  
  3059. /*
  3060.  *=============================================================================
  3061.  * IODAvailServer::ForwardLock
  3062.  *=============================================================================
  3063.  */
  3064.  
  3065. SOM_Scope ODBoolean
  3066. SOMLINK ForwardLock(IODAvailServer *somSelf,
  3067.                     Environment *ev,
  3068.                     ODLinkID linkID,
  3069.                     ODULong wait,
  3070.                     ODLinkKey* key)
  3071. {
  3072.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3073.     IODAvailServerMethodDebug("IODAvailServer","ForwardLock");
  3074.  
  3075.     IODLinkTargetToLinkSource* linkSrc;
  3076.     LinkSrcInfo*               lsInfo;
  3077.     ODBoolean                  rc;
  3078.  
  3079.     SOM_TRY
  3080.       _fMutex->Acquire(ev);
  3081.     SOM_CATCH_ALL
  3082.       return kODFalse;
  3083.     SOM_ENDTRY
  3084.  
  3085.     SOM_TRY
  3086.       lsInfo = GetDispatch(ev,
  3087.                            _fMutex,
  3088.                            _fDocuments,
  3089.                            _fLinks,
  3090.                            _fShell,
  3091.                            _fAsDraft,
  3092.                            _fSurrogateDraft,
  3093.                            linkID);
  3094.  
  3095.       switch(lsInfo->state)
  3096.       {
  3097.         case INDOC:
  3098.           linkSrc = lsInfo->docLinkSrc;
  3099.           break;
  3100.  
  3101.         case INAS:
  3102.           linkSrc = lsInfo->asLinkSrc;
  3103.           break;
  3104.  
  3105.         case INBOTH:
  3106.           TRY
  3107.             _fMutex->Release(ev);
  3108.           CATCH_ALL
  3109.           ENDTRY
  3110.  
  3111.           return kODFalse;
  3112.  
  3113.         case REMOVED:
  3114.           TRY
  3115.             _fMutex->Release(ev);
  3116.           CATCH_ALL
  3117.           ENDTRY
  3118.  
  3119.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3120.           return kODFalse;
  3121.       }
  3122.  
  3123.       rc = linkSrc->ForwardLock(ev, linkID, wait, key);
  3124.  
  3125.       if ((lsInfo->state == INAS) && (rc == kODTrue))
  3126.       {
  3127.         lsInfo->isLocked = kODTrue;
  3128.       }
  3129.  
  3130.       TRY
  3131.         _fMutex->Release(ev);
  3132.       CATCH_ALL
  3133.       ENDTRY
  3134.  
  3135.       return rc;
  3136.  
  3137.     SOM_CATCH_ALL
  3138.       ODError exception = ODGetSOMException(ev);
  3139.  
  3140.       TRY
  3141.         _fMutex->Release(ev);
  3142.       CATCH_ALL
  3143.       ENDTRY
  3144.  
  3145.       ODSetSOMException(ev, exception);
  3146.       return kODFalse;
  3147.     SOM_ENDTRY
  3148. }
  3149.  
  3150. /*
  3151.  *=============================================================================
  3152.  * IODAvailServer::ForwardUnlock
  3153.  *=============================================================================
  3154.  */
  3155.  
  3156. SOM_Scope void
  3157. SOMLINK ForwardUnlock(IODAvailServer *somSelf,
  3158.                       Environment *ev,
  3159.                       ODLinkID linkID,
  3160.                       ODLinkKey key,
  3161.                       ODBoolean isLocal)
  3162. {
  3163.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3164.     IODAvailServerMethodDebug("IODAvailServer","ForwardUnlock");
  3165.  
  3166.     IODLinkTargetToLinkSource* linkSrc;
  3167.     LinkSrcInfo*               lsInfo;
  3168.  
  3169.     SOM_TRY
  3170.       _fMutex->Acquire(ev);
  3171.     SOM_CATCH_ALL
  3172.       return;
  3173.     SOM_ENDTRY
  3174.  
  3175.     SOM_TRY
  3176.       lsInfo = GetDispatch(ev,
  3177.                            _fMutex,
  3178.                            _fDocuments,
  3179.                            _fLinks,
  3180.                            _fShell,
  3181.                            _fAsDraft,
  3182.                            _fSurrogateDraft,
  3183.                            linkID);
  3184.  
  3185.       switch(lsInfo->state)
  3186.       {
  3187.         case INDOC:
  3188.           linkSrc = lsInfo->docLinkSrc;
  3189.           break;
  3190.  
  3191.         case INAS:
  3192.         case INBOTH:
  3193.         case REMOVED:
  3194.           linkSrc = lsInfo->asLinkSrc;
  3195.           break;
  3196.       }
  3197.  
  3198.       linkSrc->ForwardUnlock(ev, linkID, key, isLocal);
  3199.  
  3200.       switch(lsInfo->state)
  3201.       {
  3202.         case INAS:
  3203.           lsInfo->isLocked = kODFalse;
  3204.           break;
  3205.  
  3206.         case INBOTH:
  3207.           lsInfo->state = INDOC;
  3208.           lsInfo->isLocked = kODFalse;
  3209.           TRY
  3210.             ((CMDraft*)_fSurrogateDraft)->
  3211.               RemoveLinkSource(ev, (ODLinkSource*)lsInfo->asLinkSrc);
  3212.           CATCH_ALL
  3213.           ENDTRY
  3214.           lsInfo->asLinkSrc = (IODLinkTargetToLinkSource*)kODNULL;
  3215.           lsInfo->docLinkSrc->ForwardUnlock(ev, linkID, key, isLocal);
  3216.           break;
  3217.  
  3218.         case REMOVED:
  3219.           _fLinks->RemoveEntry(&linkID);
  3220.           TRY
  3221.             ((CMDraft*)_fSurrogateDraft)->
  3222.               RemoveLinkSource(ev, (ODLinkSource*)lsInfo->asLinkSrc);
  3223.           CATCH_ALL
  3224.           ENDTRY
  3225.           delete lsInfo;
  3226.           break;
  3227.       }
  3228.  
  3229.       TRY
  3230.         _fMutex->Release(ev);
  3231.       CATCH_ALL
  3232.       ENDTRY
  3233.  
  3234.       return;
  3235.  
  3236.     SOM_CATCH_ALL
  3237.       ODError exception = ODGetSOMException(ev);
  3238.  
  3239.       TRY
  3240.         _fMutex->Release(ev);
  3241.       CATCH_ALL
  3242.       ENDTRY
  3243.  
  3244.       ODSetSOMException(ev, exception);
  3245.       return;
  3246.     SOM_ENDTRY
  3247. }
  3248.  
  3249. /*
  3250.  *=============================================================================
  3251.  * IODAvailServer::ForwardGetContentStorageUnit
  3252.  *=============================================================================
  3253.  */
  3254.  
  3255. SOM_Scope ODStorageUnit*
  3256. SOMLINK ForwardGetContentStorageUnit(IODAvailServer *somSelf,
  3257.                                      Environment *ev,
  3258.                                      ODLinkID linkID,
  3259.                                      ODLinkKey key)
  3260. {
  3261.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3262.     IODAvailServerMethodDebug("IODAvailServer","ForwardGetContentStorageUnit");
  3263.  
  3264.     IODLinkTargetToLinkSource* linkSrc;
  3265.     LinkSrcInfo*               lsInfo;
  3266.     ODStorageUnit*             su;
  3267.  
  3268.     SOM_TRY
  3269.       _fMutex->Acquire(ev);
  3270.     SOM_CATCH_ALL
  3271.       return kODNULL;
  3272.     SOM_ENDTRY
  3273.  
  3274.     SOM_TRY
  3275.       lsInfo = GetDispatch(ev,
  3276.                            _fMutex,
  3277.                            _fDocuments,
  3278.                            _fLinks,
  3279.                            _fShell,
  3280.                            _fAsDraft,
  3281.                            _fSurrogateDraft,
  3282.                            linkID);
  3283.  
  3284.       switch(lsInfo->state)
  3285.       {
  3286.         case INDOC:
  3287.           linkSrc = lsInfo->docLinkSrc;
  3288.           break;
  3289.  
  3290.         case INAS:
  3291.         case INBOTH:
  3292.           linkSrc = lsInfo->asLinkSrc;
  3293.           break;
  3294.  
  3295.         case REMOVED:
  3296.           TRY
  3297.             _fMutex->Release(ev);
  3298.           CATCH_ALL
  3299.           ENDTRY
  3300.  
  3301.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3302.           return kODNULL;
  3303.       }
  3304.  
  3305.       su = linkSrc->ForwardGetContentStorageUnit(ev, linkID, key);
  3306.  
  3307.       TRY
  3308.         _fMutex->Release(ev);
  3309.       CATCH_ALL
  3310.       ENDTRY
  3311.  
  3312.       return su;
  3313.  
  3314.     SOM_CATCH_ALL
  3315.       ODError exception = ODGetSOMException(ev);
  3316.  
  3317.       TRY
  3318.         _fMutex->Release(ev);
  3319.       CATCH_ALL
  3320.       ENDTRY
  3321.  
  3322.       ODSetSOMException(ev, exception);
  3323.       return kODNULL;
  3324.     SOM_ENDTRY
  3325. }
  3326.  
  3327. /*
  3328.  *=============================================================================
  3329.  * IODAvailServer::AddLinkTarget
  3330.  *=============================================================================
  3331.  */
  3332.  
  3333. SOM_Scope void
  3334. SOMLINK AddLinkTarget(IODAvailServer *somSelf,
  3335.                       Environment *ev,
  3336.                       ODLinkID linkid,
  3337.                       ODULong pid,
  3338.                       ODLinkConnectionData* trgtPartDesc,
  3339.                       IODLinkTarget* linkTrgt,
  3340.                       ODStorageUnitID* sourceSUID,
  3341.                       ODLinkConnectionID* trgtID,
  3342.                       ODBoolean* isLocal,
  3343.                       ODBoolean* trackTrgt)
  3344. {
  3345.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3346.     IODAvailServerMethodDebug("IODAvailServer","AddLinkTarget");
  3347.  
  3348.     IODLinkTargetToLinkSource* linkSrc;
  3349.     LinkSrcInfo*               lsInfo;
  3350.  
  3351.     SOM_TRY
  3352.       _fMutex->Acquire(ev);
  3353.     SOM_CATCH_ALL
  3354.       return;
  3355.     SOM_ENDTRY
  3356.  
  3357.     SOM_TRY
  3358.       lsInfo = GetDispatch(ev,
  3359.                            _fMutex,
  3360.                            _fDocuments,
  3361.                            _fLinks,
  3362.                            _fShell,
  3363.                            _fAsDraft,
  3364.                            _fSurrogateDraft,
  3365.                            linkid);
  3366.  
  3367.       switch(lsInfo->state)
  3368.       {
  3369.         case INDOC:
  3370.         case INBOTH:
  3371.           linkSrc = lsInfo->docLinkSrc;
  3372.           break;
  3373.  
  3374.         case INAS:
  3375.           linkSrc = lsInfo->asLinkSrc;
  3376.           break;
  3377.  
  3378.         case REMOVED:
  3379.           TRY
  3380.             _fMutex->Release(ev);
  3381.           CATCH_ALL
  3382.           ENDTRY
  3383.  
  3384.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3385.           return;
  3386.       }
  3387.  
  3388.       linkSrc->AddLinkTarget(ev,
  3389.                              linkid,
  3390.                              pid,
  3391.                              trgtPartDesc,
  3392.                              linkTrgt,
  3393.                              sourceSUID,
  3394.                              trgtID,
  3395.                              isLocal,
  3396.                              trackTrgt);
  3397.  
  3398.       TRY
  3399.         _fMutex->Release(ev);
  3400.       CATCH_ALL
  3401.       ENDTRY
  3402.  
  3403.       return;
  3404.  
  3405.     SOM_CATCH_ALL
  3406.       ODError exception = ODGetSOMException(ev);
  3407.  
  3408.       TRY
  3409.         _fMutex->Release(ev);
  3410.       CATCH_ALL
  3411.       ENDTRY
  3412.  
  3413.       ODSetSOMException(ev, exception);
  3414.       return;
  3415.     SOM_ENDTRY
  3416. }
  3417. /*
  3418.  *=============================================================================
  3419.  * IODAvailServer::ForwardGetUpdateID
  3420.  *=============================================================================
  3421.  */
  3422.  
  3423. SOM_Scope ODUpdateID
  3424. SOMLINK ForwardGetUpdateID(IODAvailServer *somSelf,
  3425.                            Environment *ev,
  3426.                            ODLinkID linkID)
  3427. {
  3428.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3429.     IODAvailServerMethodDebug("IODAvailServer","ForwardGetUpdateID");
  3430.  
  3431.     IODLinkTargetToLinkSource* linkSrc;
  3432.     LinkSrcInfo*               lsInfo;
  3433.     ODUpdateID                 changeID;
  3434.  
  3435.     SOM_TRY
  3436.       _fMutex->Acquire(ev);
  3437.     SOM_CATCH_ALL
  3438.       return kODUnknownUpdate;
  3439.     SOM_ENDTRY
  3440.  
  3441.     SOM_TRY
  3442.       lsInfo = GetDispatch(ev,
  3443.                            _fMutex,
  3444.                            _fDocuments,
  3445.                            _fLinks,
  3446.                            _fShell,
  3447.                            _fAsDraft,
  3448.                            _fSurrogateDraft,
  3449.                            linkID);
  3450.  
  3451.       switch(lsInfo->state)
  3452.       {
  3453.         case INDOC:
  3454.         case INBOTH:
  3455.           linkSrc = lsInfo->docLinkSrc;
  3456.           break;
  3457.  
  3458.         case INAS:
  3459.           linkSrc = lsInfo->asLinkSrc;
  3460.           break;
  3461.  
  3462.         case REMOVED:
  3463.           TRY
  3464.             _fMutex->Release(ev);
  3465.           CATCH_ALL
  3466.           ENDTRY
  3467.  
  3468.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3469.           return kODUnknownUpdate;
  3470.       }
  3471.  
  3472.       changeID = linkSrc->ForwardGetUpdateID(ev, linkID);
  3473.  
  3474.       TRY
  3475.         _fMutex->Release(ev);
  3476.       CATCH_ALL
  3477.       ENDTRY
  3478.  
  3479.       return changeID;
  3480.  
  3481.     SOM_CATCH_ALL
  3482.       ODError exception = ODGetSOMException(ev);
  3483.  
  3484.       TRY
  3485.         _fMutex->Release(ev);
  3486.       CATCH_ALL
  3487.       ENDTRY
  3488.  
  3489.       ODSetSOMException(ev, exception);
  3490.       return kODUnknownUpdate;
  3491.     SOM_ENDTRY
  3492. }
  3493.  
  3494. /*
  3495.  *=============================================================================
  3496.  * IODAvailServer::ForwardGetChangeTime
  3497.  *=============================================================================
  3498.  */
  3499.  
  3500. SOM_Scope ODTime
  3501. SOMLINK ForwardGetChangeTime(IODAvailServer *somSelf,
  3502.                              Environment *ev,
  3503.                              ODLinkID linkID)
  3504. {
  3505.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3506.     IODAvailServerMethodDebug("IODAvailServer","ForwardGetChangeTime");
  3507.  
  3508.     IODLinkTargetToLinkSource* linkSrc;
  3509.     LinkSrcInfo*               lsInfo;
  3510.     ODTime                     changeTime;
  3511.  
  3512.     SOM_TRY
  3513.       _fMutex->Acquire(ev);
  3514.     SOM_CATCH_ALL
  3515.       return 0;
  3516.     SOM_ENDTRY
  3517.  
  3518.     SOM_TRY
  3519.       lsInfo = GetDispatch(ev,
  3520.                            _fMutex,
  3521.                            _fDocuments,
  3522.                            _fLinks,
  3523.                            _fShell,
  3524.                            _fAsDraft,
  3525.                            _fSurrogateDraft,
  3526.                            linkID);
  3527.  
  3528.       switch(lsInfo->state)
  3529.       {
  3530.         case INDOC:
  3531.         case INBOTH:
  3532.           linkSrc = lsInfo->docLinkSrc;
  3533.           break;
  3534.  
  3535.         case INAS:
  3536.           linkSrc = lsInfo->asLinkSrc;
  3537.           break;
  3538.  
  3539.         case REMOVED:
  3540.           TRY
  3541.             _fMutex->Release(ev);
  3542.           CATCH_ALL
  3543.           ENDTRY
  3544.  
  3545.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3546.           return 0;
  3547.       }
  3548.  
  3549.       changeTime = linkSrc->ForwardGetChangeTime(ev, linkID);
  3550.  
  3551.       TRY
  3552.         _fMutex->Release(ev);
  3553.       CATCH_ALL
  3554.       ENDTRY
  3555.  
  3556.       return changeTime;
  3557.  
  3558.     SOM_CATCH_ALL
  3559.       ODError exception = ODGetSOMException(ev);
  3560.  
  3561.       TRY
  3562.         _fMutex->Release(ev);
  3563.       CATCH_ALL
  3564.       ENDTRY
  3565.  
  3566.       ODSetSOMException(ev, exception);
  3567.       return 0;
  3568.     SOM_ENDTRY
  3569. }
  3570.  
  3571. /*
  3572.  *=============================================================================
  3573.  * IODAvailServer::GetSourcePartDescription
  3574.  *=============================================================================
  3575.  */
  3576.  
  3577. SOM_Scope void
  3578. SOMLINK GetSourcePartDescription(IODAvailServer *somSelf,
  3579.                                  Environment *ev,
  3580.                                  ODLinkID linkID,
  3581.                                  ODLinkConnectionData** srcPartDesc)
  3582. {
  3583.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3584.     IODAvailServerMethodDebug("IODAvailServer","GetSourcePartDescription");
  3585.  
  3586.     IODLinkTargetToLinkSource* linkSrc;
  3587.     LinkSrcInfo*               lsInfo;
  3588.  
  3589.     SOM_TRY
  3590.       _fMutex->Acquire(ev);
  3591.     SOM_CATCH_ALL
  3592.       return;
  3593.     SOM_ENDTRY
  3594.  
  3595.     SOM_TRY
  3596.       lsInfo = GetDispatch(ev,
  3597.                            _fMutex,
  3598.                            _fDocuments,
  3599.                            _fLinks,
  3600.                            _fShell,
  3601.                            _fAsDraft,
  3602.                            _fSurrogateDraft,
  3603.                            linkID);
  3604.  
  3605.       switch(lsInfo->state)
  3606.       {
  3607.         case INDOC:
  3608.         case INBOTH:
  3609.           linkSrc = lsInfo->docLinkSrc;
  3610.           break;
  3611.  
  3612.         case INAS:
  3613.           linkSrc = lsInfo->asLinkSrc;
  3614.           break;
  3615.  
  3616.         case REMOVED:
  3617.           TRY
  3618.             _fMutex->Release(ev);
  3619.           CATCH_ALL
  3620.           ENDTRY
  3621.  
  3622.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3623.           return;
  3624.       }
  3625.  
  3626.       linkSrc->GetSourcePartDescription(ev, linkID, srcPartDesc);
  3627.  
  3628.       TRY
  3629.         _fMutex->Release(ev);
  3630.       CATCH_ALL
  3631.       ENDTRY
  3632.  
  3633.       return;
  3634.  
  3635.     SOM_CATCH_ALL
  3636.       ODError exception = ODGetSOMException(ev);
  3637.  
  3638.       TRY
  3639.         _fMutex->Release(ev);
  3640.       CATCH_ALL
  3641.       ENDTRY
  3642.  
  3643.       ODSetSOMException(ev, exception);
  3644.       return;
  3645.     SOM_ENDTRY
  3646. }
  3647.  
  3648. /*
  3649.  *=============================================================================
  3650.  * IODAvailServer::LinkTargetClosed
  3651.  *=============================================================================
  3652.  */
  3653.  
  3654. SOM_Scope void
  3655. SOMLINK LinkTargetClosed(IODAvailServer *somSelf,
  3656.                          Environment *ev,
  3657.                          ODLinkID linkID,
  3658.                          ODLinkConnectionID trgtID,
  3659.                          ODBoolean isLocal)
  3660. {
  3661.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3662.     IODAvailServerMethodDebug("IODAvailServer","LinkTargetClosed");
  3663.  
  3664.     IODLinkTargetToLinkSource* linkSrc;
  3665.     LinkSrcInfo*               lsInfo;
  3666.  
  3667.     SOM_TRY
  3668.       _fMutex->Acquire(ev);
  3669.     SOM_CATCH_ALL
  3670.       return;
  3671.     SOM_ENDTRY
  3672.  
  3673.     SOM_TRY
  3674.       lsInfo = GetDispatch(ev,
  3675.                            _fMutex,
  3676.                            _fDocuments,
  3677.                            _fLinks,
  3678.                            _fShell,
  3679.                            _fAsDraft,
  3680.                            _fSurrogateDraft,
  3681.                            linkID);
  3682.  
  3683.       switch(lsInfo->state)
  3684.       {
  3685.         case INDOC:
  3686.         case INBOTH:
  3687.           linkSrc = lsInfo->docLinkSrc;
  3688.           break;
  3689.  
  3690.         case INAS:
  3691.           linkSrc = lsInfo->asLinkSrc;
  3692.           break;
  3693.  
  3694.         case REMOVED:
  3695.           TRY
  3696.             _fMutex->Release(ev);
  3697.           CATCH_ALL
  3698.           ENDTRY
  3699.  
  3700.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3701.           return;
  3702.       }
  3703.  
  3704.       linkSrc->LinkTargetClosed(ev, linkID, trgtID, isLocal);
  3705.  
  3706.       if (lsInfo->state == INAS)
  3707.       {
  3708.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  3709.       }
  3710.  
  3711.       TRY
  3712.         _fMutex->Release(ev);
  3713.       CATCH_ALL
  3714.       ENDTRY
  3715.  
  3716.       return;
  3717.  
  3718.     SOM_CATCH_ALL
  3719.       ODError exception = ODGetSOMException(ev);
  3720.  
  3721.       TRY
  3722.         _fMutex->Release(ev);
  3723.       CATCH_ALL
  3724.       ENDTRY
  3725.  
  3726.       ODSetSOMException(ev, exception);
  3727.       return;
  3728.     SOM_ENDTRY
  3729. }
  3730.  
  3731. /*
  3732.  *=============================================================================
  3733.  * IODAvailServer::LinkTargetRemoved
  3734.  *=============================================================================
  3735.  */
  3736.  
  3737. SOM_Scope void
  3738. SOMLINK LinkTargetRemoved(IODAvailServer *somSelf,
  3739.                           Environment *ev,
  3740.                           ODLinkID linkID,
  3741.                           ODLinkConnectionID trgtID,
  3742.                           ODBoolean isLocal)
  3743. {
  3744.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3745.     IODAvailServerMethodDebug("IODAvailServer","LinkTargetRemoved");
  3746.  
  3747.     IODLinkTargetToLinkSource* linkSrc;
  3748.     LinkSrcInfo*               lsInfo;
  3749.  
  3750.     SOM_TRY
  3751.       _fMutex->Acquire(ev);
  3752.     SOM_CATCH_ALL
  3753.       return;
  3754.     SOM_ENDTRY
  3755.  
  3756.     SOM_TRY
  3757.       lsInfo = GetDispatch(ev,
  3758.                            _fMutex,
  3759.                            _fDocuments,
  3760.                            _fLinks,
  3761.                            _fShell,
  3762.                            _fAsDraft,
  3763.                            _fSurrogateDraft,
  3764.                            linkID);
  3765.  
  3766.       switch(lsInfo->state)
  3767.       {
  3768.         case INDOC:
  3769.         case INBOTH:
  3770.           linkSrc = lsInfo->docLinkSrc;
  3771.           break;
  3772.  
  3773.         case INAS:
  3774.           linkSrc = lsInfo->asLinkSrc;
  3775.           break;
  3776.  
  3777.         case REMOVED:
  3778.           TRY
  3779.             _fMutex->Release(ev);
  3780.           CATCH_ALL
  3781.           ENDTRY
  3782.  
  3783.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3784.           return;
  3785.       }
  3786.  
  3787.       linkSrc->LinkTargetRemoved(ev, linkID, trgtID, isLocal);
  3788.  
  3789.       if (lsInfo->state == INAS)
  3790.       {
  3791.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  3792.       }
  3793.  
  3794.       TRY
  3795.         _fMutex->Release(ev);
  3796.       CATCH_ALL
  3797.       ENDTRY
  3798.  
  3799.       return;
  3800.  
  3801.     SOM_CATCH_ALL
  3802.       ODError exception = ODGetSOMException(ev);
  3803.  
  3804.       TRY
  3805.         _fMutex->Release(ev);
  3806.       CATCH_ALL
  3807.       ENDTRY
  3808.  
  3809.       ODSetSOMException(ev, exception);
  3810.       return;
  3811.     SOM_ENDTRY
  3812. }
  3813.  
  3814. /*
  3815.  *=============================================================================
  3816.  * IODAvailServer::LinkTargetReopened
  3817.  *=============================================================================
  3818.  */
  3819.  
  3820. SOM_Scope void
  3821. SOMLINK LinkTargetReopened(IODAvailServer *somSelf,
  3822.                            Environment *ev,
  3823.                            ODLinkID linkID,
  3824.                            ODLinkConnectionID trgtID,
  3825.                            ODULong pid,
  3826.                            ODLinkConnectionData* trgtPartDesc,
  3827.                            IODLinkTarget* linkTrgt,
  3828.                            ODBoolean* isLocal)
  3829. {
  3830.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3831.     IODAvailServerMethodDebug("IODAvailServer","LinkTargetReopened");
  3832.  
  3833.     IODLinkTargetToLinkSource* linkSrc;
  3834.     LinkSrcInfo*               lsInfo;
  3835.  
  3836.     SOM_TRY
  3837.       _fMutex->Acquire(ev);
  3838.     SOM_CATCH_ALL
  3839.       return;
  3840.     SOM_ENDTRY
  3841.  
  3842.     SOM_TRY
  3843.       lsInfo = GetDispatch(ev,
  3844.                            _fMutex,
  3845.                            _fDocuments,
  3846.                            _fLinks,
  3847.                            _fShell,
  3848.                            _fAsDraft,
  3849.                            _fSurrogateDraft,
  3850.                            linkID);
  3851.  
  3852.       switch(lsInfo->state)
  3853.       {
  3854.         case INDOC:
  3855.         case INBOTH:
  3856.           linkSrc = lsInfo->docLinkSrc;
  3857.           break;
  3858.  
  3859.         case INAS:
  3860.           linkSrc = lsInfo->asLinkSrc;
  3861.           break;
  3862.  
  3863.         case REMOVED:
  3864.           TRY
  3865.             _fMutex->Release(ev);
  3866.           CATCH_ALL
  3867.           ENDTRY
  3868.  
  3869.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3870.           return;
  3871.       }
  3872.  
  3873.       linkSrc->LinkTargetReopened(ev,
  3874.                                   linkID,
  3875.                                   trgtID,
  3876.                                   pid,
  3877.                                   trgtPartDesc,
  3878.                                   linkTrgt,
  3879.                                   isLocal);
  3880.  
  3881.       if (lsInfo->state == INAS)
  3882.       {
  3883.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  3884.       }
  3885.  
  3886.       TRY
  3887.         _fMutex->Release(ev);
  3888.       CATCH_ALL
  3889.       ENDTRY
  3890.  
  3891.       return;
  3892.  
  3893.     SOM_CATCH_ALL
  3894.       ODError exception = ODGetSOMException(ev);
  3895.  
  3896.       TRY
  3897.         _fMutex->Release(ev);
  3898.       CATCH_ALL
  3899.       ENDTRY
  3900.  
  3901.       ODSetSOMException(ev, exception);
  3902.       return;
  3903.     SOM_ENDTRY
  3904. }
  3905.  
  3906. /*
  3907.  *=============================================================================
  3908.  * IODAvailServer::LockToRead
  3909.  *=============================================================================
  3910.  */
  3911.  
  3912. SOM_Scope void
  3913. SOMLINK LockToRead(IODAvailServer *somSelf,
  3914.                    Environment *ev,
  3915.                    ODLinkID linkID,
  3916.                    ODULong wait,
  3917.                    ODLinkKey* key)
  3918. {
  3919.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3920.     IODAvailServerMethodDebug("IODAvailServer","LockToRead");
  3921.  
  3922.  
  3923. }
  3924.  
  3925. /*
  3926.  *=============================================================================
  3927.  * IODAvailServer::RegisterTrackedLinkTarget
  3928.  *=============================================================================
  3929.  */
  3930.  
  3931. SOM_Scope void
  3932. SOMLINK RegisterTrackedLinkTarget(IODAvailServer *somSelf,
  3933.                                   Environment *ev,
  3934.                                   ODLinkID linkID,
  3935.                                   ODLinkConnectionID trgtID,
  3936.                                   ODBoolean isLocal)
  3937. {
  3938.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  3939.     IODAvailServerMethodDebug("IODAvailServer","RegisterTrackedLinkTarget");
  3940.  
  3941.     IODLinkTargetToLinkSource* linkSrc;
  3942.     LinkSrcInfo*               lsInfo;
  3943.  
  3944.     SOM_TRY
  3945.       _fMutex->Acquire(ev);
  3946.     SOM_CATCH_ALL
  3947.       return;
  3948.     SOM_ENDTRY
  3949.  
  3950.     SOM_TRY
  3951.       lsInfo = GetDispatch(ev,
  3952.                            _fMutex,
  3953.                            _fDocuments,
  3954.                            _fLinks,
  3955.                            _fShell,
  3956.                            _fAsDraft,
  3957.                            _fSurrogateDraft,
  3958.                            linkID);
  3959.  
  3960.       switch(lsInfo->state)
  3961.       {
  3962.         case INDOC:
  3963.         case INBOTH:
  3964.           linkSrc = lsInfo->docLinkSrc;
  3965.           break;
  3966.  
  3967.         case INAS:
  3968.           linkSrc = lsInfo->asLinkSrc;
  3969.           break;
  3970.  
  3971.         case REMOVED:
  3972.           TRY
  3973.             _fMutex->Release(ev);
  3974.           CATCH_ALL
  3975.           ENDTRY
  3976.  
  3977.           ODSetSOMException(ev, kODErrWaitingUnlock);
  3978.           return;
  3979.       }
  3980.  
  3981.       linkSrc->RegisterTrackedLinkTarget(ev, linkID, trgtID, isLocal);
  3982.  
  3983.       if (lsInfo->state == INAS)
  3984.       {
  3985.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  3986.       }
  3987.  
  3988.       TRY
  3989.         _fMutex->Release(ev);
  3990.       CATCH_ALL
  3991.       ENDTRY
  3992.  
  3993.       return;
  3994.  
  3995.     SOM_CATCH_ALL
  3996.       ODError exception = ODGetSOMException(ev);
  3997.  
  3998.       TRY
  3999.         _fMutex->Release(ev);
  4000.       CATCH_ALL
  4001.       ENDTRY
  4002.  
  4003.       ODSetSOMException(ev, exception);
  4004.       return;
  4005.     SOM_ENDTRY
  4006. }
  4007.  
  4008. /*
  4009.  *=============================================================================
  4010.  * IODAvailServer::RegisterUntrackedLinkTarget
  4011.  *=============================================================================
  4012.  */
  4013.  
  4014. SOM_Scope void
  4015. SOMLINK RegisterUntrackedLinkTarget(IODAvailServer *somSelf,
  4016.                                     Environment *ev,
  4017.                                     ODLinkID linkID,
  4018.                                     IODLinkTarget* linkTrgt,
  4019.                                     ODLinkConnectionData* trgtPartDesc,
  4020.                                     ODBoolean isLocal,
  4021.                                     ODLinkConnectionID* trgtID)
  4022. {
  4023.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  4024.     IODAvailServerMethodDebug("IODAvailServer","RegisterUntrackedLinkTarget");
  4025.  
  4026.     IODLinkTargetToLinkSource* linkSrc;
  4027.     LinkSrcInfo*               lsInfo;
  4028.  
  4029.     SOM_TRY
  4030.       _fMutex->Acquire(ev);
  4031.     SOM_CATCH_ALL
  4032.       return;
  4033.     SOM_ENDTRY
  4034.  
  4035.     SOM_TRY
  4036.       lsInfo = GetDispatch(ev,
  4037.                            _fMutex,
  4038.                            _fDocuments,
  4039.                            _fLinks,
  4040.                            _fShell,
  4041.                            _fAsDraft,
  4042.                            _fSurrogateDraft,
  4043.                            linkID);
  4044.  
  4045.       switch(lsInfo->state)
  4046.       {
  4047.         case INDOC:
  4048.         case INBOTH:
  4049.           linkSrc = lsInfo->docLinkSrc;
  4050.           break;
  4051.  
  4052.         case INAS:
  4053.           linkSrc = lsInfo->asLinkSrc;
  4054.           break;
  4055.  
  4056.         case REMOVED:
  4057.           TRY
  4058.             _fMutex->Release(ev);
  4059.           CATCH_ALL
  4060.           ENDTRY
  4061.  
  4062.           ODSetSOMException(ev, kODErrWaitingUnlock);
  4063.           return;
  4064.       }
  4065.  
  4066.       linkSrc->RegisterUntrackedLinkTarget(ev,
  4067.                                            linkID,
  4068.                                            linkTrgt,
  4069.                                            trgtPartDesc,
  4070.                                            isLocal,
  4071.                                            trgtID);
  4072.  
  4073.       if (lsInfo->state == INAS)
  4074.       {
  4075.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  4076.       }
  4077.  
  4078.       TRY
  4079.         _fMutex->Release(ev);
  4080.       CATCH_ALL
  4081.       ENDTRY
  4082.  
  4083.       return;
  4084.  
  4085.     SOM_CATCH_ALL
  4086.       ODError exception = ODGetSOMException(ev);
  4087.  
  4088.       TRY
  4089.         _fMutex->Release(ev);
  4090.       CATCH_ALL
  4091.       ENDTRY
  4092.  
  4093.       ODSetSOMException(ev, exception);
  4094.       return;
  4095.     SOM_ENDTRY
  4096. }
  4097.  
  4098. /*
  4099.  *=============================================================================
  4100.  * IODAvailServer::ShowSourceContentFor
  4101.  *=============================================================================
  4102.  */
  4103.  
  4104. SOM_Scope void
  4105. SOMLINK ShowSourceContentFor(IODAvailServer *somSelf,
  4106.                              Environment *ev,
  4107.                              ODLinkID linkID,
  4108.                              ODISOStr hostName)
  4109. {
  4110.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  4111.     IODAvailServerMethodDebug("IODAvailServer","ShowSourceContentFor");
  4112.  
  4113.     IODLinkTargetToLinkSource* linkSrc;
  4114.     LinkSrcInfo*               lsInfo;
  4115.  
  4116.     SOM_TRY
  4117.       _fMutex->Acquire(ev);
  4118.     SOM_CATCH_ALL
  4119.       return;
  4120.     SOM_ENDTRY
  4121.  
  4122.     SOM_TRY
  4123.       lsInfo = GetDispatch(ev,
  4124.                            _fMutex,
  4125.                            _fDocuments,
  4126.                            _fLinks,
  4127.                            _fShell,
  4128.                            _fAsDraft,
  4129.                            _fSurrogateDraft,
  4130.                            linkID);
  4131.  
  4132.       switch(lsInfo->state)
  4133.       {
  4134.         case INDOC:
  4135.         case INBOTH:
  4136.           linkSrc = lsInfo->docLinkSrc;
  4137.           break;
  4138.  
  4139.         case INAS:
  4140.           TRY
  4141.             _fMutex->Release(ev);
  4142.           CATCH_ALL
  4143.           ENDTRY
  4144.  
  4145.           ODSetSOMException(ev, kODErrSourceDocNotOpen);
  4146.           return;
  4147.  
  4148.         case REMOVED:
  4149.           TRY
  4150.             _fMutex->Release(ev);
  4151.           CATCH_ALL
  4152.           ENDTRY
  4153.  
  4154.           ODSetSOMException(ev, kODErrWaitingUnlock);
  4155.           return;
  4156.       }
  4157.  
  4158.       linkSrc->ShowSourceContentFor(ev, linkID, hostName);
  4159.  
  4160.       TRY
  4161.         _fMutex->Release(ev);
  4162.       CATCH_ALL
  4163.       ENDTRY
  4164.  
  4165.       return;
  4166.  
  4167.     SOM_CATCH_ALL
  4168.       ODError exception = ODGetSOMException(ev);
  4169.  
  4170.       TRY
  4171.         _fMutex->Release(ev);
  4172.       CATCH_ALL
  4173.       ENDTRY
  4174.  
  4175.       ODSetSOMException(ev, exception);
  4176.       return;
  4177.     SOM_ENDTRY
  4178. }
  4179.  
  4180. /*
  4181.  *=============================================================================
  4182.  * IODAvailServer::TargetPartDescriptionChanged
  4183.  *=============================================================================
  4184.  */
  4185.  
  4186. SOM_Scope void
  4187. SOMLINK TargetPartDescriptionChanged(IODAvailServer *somSelf,
  4188.                                      Environment *ev,
  4189.                                      ODLinkID linkID,
  4190.                                      ODLinkConnectionID trgtID,
  4191.                                      ODBoolean isLocal,
  4192.                                      ODLinkConnectionData* trgtPartDesc)
  4193. {
  4194.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  4195.     IODAvailServerMethodDebug("IODAvailServer","TargetPartDescriptionChanged");
  4196.  
  4197.     IODLinkTargetToLinkSource* linkSrc;
  4198.     LinkSrcInfo*               lsInfo;
  4199.  
  4200.     SOM_TRY
  4201.       _fMutex->Acquire(ev);
  4202.     SOM_CATCH_ALL
  4203.       return;
  4204.     SOM_ENDTRY
  4205.  
  4206.     SOM_TRY
  4207.       lsInfo = GetDispatch(ev,
  4208.                            _fMutex,
  4209.                            _fDocuments,
  4210.                            _fLinks,
  4211.                            _fShell,
  4212.                            _fAsDraft,
  4213.                            _fSurrogateDraft,
  4214.                            linkID);
  4215.  
  4216.       switch(lsInfo->state)
  4217.       {
  4218.         case INDOC:
  4219.         case INBOTH:
  4220.           linkSrc = lsInfo->docLinkSrc;
  4221.           break;
  4222.  
  4223.         case INAS:
  4224.           linkSrc = lsInfo->asLinkSrc;
  4225.           break;
  4226.  
  4227.         case REMOVED:
  4228.           TRY
  4229.             _fMutex->Release(ev);
  4230.           CATCH_ALL
  4231.           ENDTRY
  4232.  
  4233.           ODSetSOMException(ev, kODErrWaitingUnlock);
  4234.           return;
  4235.       }
  4236.  
  4237.       linkSrc->TargetPartDescriptionChanged(ev,
  4238.                                             linkID,
  4239.                                             trgtID,
  4240.                                             isLocal,
  4241.                                             trgtPartDesc);
  4242.  
  4243.       if (lsInfo->state == INAS)
  4244.       {
  4245.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  4246.       }
  4247.  
  4248.       TRY
  4249.         _fMutex->Release(ev);
  4250.       CATCH_ALL
  4251.       ENDTRY
  4252.  
  4253.       return;
  4254.  
  4255.     SOM_CATCH_ALL
  4256.       ODError exception = ODGetSOMException(ev);
  4257.  
  4258.       TRY
  4259.         _fMutex->Release(ev);
  4260.       CATCH_ALL
  4261.       ENDTRY
  4262.  
  4263.       ODSetSOMException(ev, exception);
  4264.       return;
  4265.     SOM_ENDTRY
  4266. }
  4267.  
  4268. /*
  4269.  *=============================================================================
  4270.  * IODAvailServer::UnregisterLinkTarget
  4271.  *=============================================================================
  4272.  */
  4273.  
  4274. SOM_Scope void
  4275. SOMLINK UnregisterLinkTarget(IODAvailServer *somSelf,
  4276.                              Environment *ev,
  4277.                              ODLinkID linkID,
  4278.                              ODLinkConnectionID trgtID,
  4279.                              ODBoolean isLocal)
  4280. {
  4281.     IODAvailServerData *somThis = IODAvailServerGetData(somSelf);
  4282.     IODAvailServerMethodDebug("IODAvailServer","UnregisterLinkTarget");
  4283.  
  4284.     IODLinkTargetToLinkSource* linkSrc;
  4285.     LinkSrcInfo*               lsInfo;
  4286.  
  4287.     SOM_TRY
  4288.       _fMutex->Acquire(ev);
  4289.     SOM_CATCH_ALL
  4290.       return;
  4291.     SOM_ENDTRY
  4292.  
  4293.     SOM_TRY
  4294.       lsInfo = GetDispatch(ev,
  4295.                            _fMutex,
  4296.                            _fDocuments,
  4297.                            _fLinks,
  4298.                            _fShell,
  4299.                            _fAsDraft,
  4300.                            _fSurrogateDraft,
  4301.                            linkID);
  4302.  
  4303.       switch(lsInfo->state)
  4304.       {
  4305.         case INDOC:
  4306.         case INBOTH:
  4307.           linkSrc = lsInfo->docLinkSrc;
  4308.           break;
  4309.  
  4310.         case INAS:
  4311.           linkSrc = lsInfo->asLinkSrc;
  4312.           break;
  4313.  
  4314.         case REMOVED:
  4315.           TRY
  4316.             _fMutex->Release(ev);
  4317.           CATCH_ALL
  4318.           ENDTRY
  4319.  
  4320.           ODSetSOMException(ev, kODErrWaitingUnlock);
  4321.           return;
  4322.       }
  4323.  
  4324.       linkSrc->UnregisterLinkTarget(ev, linkID, trgtID, isLocal);
  4325.  
  4326.       if (lsInfo->state == INAS)
  4327.       {
  4328.         SaveAuxState(ev, _fShell, _fAsDraft, lsInfo);
  4329.       }
  4330.  
  4331.       TRY
  4332.         _fMutex->Release(ev);
  4333.       CATCH_ALL
  4334.       ENDTRY
  4335.  
  4336.       return;
  4337.  
  4338.     SOM_CATCH_ALL
  4339.       ODError exception = ODGetSOMException(ev);
  4340.  
  4341.       TRY
  4342.         _fMutex->Release(ev);
  4343.       CATCH_ALL
  4344.       ENDTRY
  4345.  
  4346.       ODSetSOMException(ev, exception);
  4347.       return;
  4348.     SOM_ENDTRY
  4349. }
  4350. #endif
  4351.  
  4352.