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

  1. /* @(#)Z 1.14 os2/src/storage/ilnksrvc.cpp, oddataxfer, od96os2, odos29712d 97/03/21 17:40:38 (97/03/20 08:41:05) */
  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. #ifndef SOM_Module_ilnksrvc_Source
  33. #define SOM_Module_ilnksrvc_Source
  34. #endif
  35. #define IODLinkService_Class_Source
  36.  
  37. #define METHOD_MACROS
  38. #define VARIABLE_MACROS
  39.  
  40. #define INCL_DOSERRORS
  41. #define INCL_ERROR_H
  42. #include <bseerr.h>
  43.  
  44. //lsdlgs includes
  45. #define INCL_WIN
  46. #define INCL_DOS
  47. #include <os2.h>
  48. #include <odres.h>       //For Link Servic dialog's resource id's
  49. #include <ODPagtun.h>
  50. #define INCL_DOSMODULEMGR
  51. #include <bsedos.h>
  52. //#include <pmwin.h>
  53.  
  54. #ifndef _ITEXT_
  55. #include <IText.h>
  56. #endif
  57.  
  58. #ifndef _PLFMDEF_
  59. #include "plfmdef.h"
  60. #endif
  61.  
  62. #ifndef _LINKDLGS_
  63. #include "Linkdlgs.h"
  64. #endif
  65.  
  66. #ifndef _EXCEPT_
  67. #include "Except.h"
  68. #endif
  69.  
  70. #ifndef _LINKDEFS_
  71. #include "LinkDefs.h"
  72. #endif
  73.  
  74. #ifndef SOM_Module_OpenDoc_StdProps_defined
  75. #include <StdProps.xh>
  76. #endif
  77.  
  78. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  79. #include <StdTypes.xh>
  80. #endif
  81.  
  82. #ifndef SOM_ODFrame_xh
  83. #include <Frame.xh>
  84. #endif
  85.  
  86. #ifndef SOM_Facet_xh
  87. #include "Facet.xh"
  88. #endif
  89.  
  90. #ifndef SOM_ODWindow_xh
  91. #include <Window.xh>
  92. #endif
  93.  
  94. //#ifndef _INFOUTIL_
  95. //#include "infoutil.h"
  96. //#endif
  97.  
  98.  
  99. #ifndef SOM_ODTypeList_xh
  100. #include <TypeList.xh>
  101. #endif
  102. //end lsdlgs includes
  103. #include <ISOStr.h>
  104. #include <stdtypes.xh>
  105. #include <IODDefs.xh>
  106. #include <Except.h>
  107. #include <AvsShell.h>
  108. #include <barray.h>
  109. #include <IAvlSvr.xh>
  110. #include <cmdraft.xh>
  111. #include <iciditr.xh>
  112. #ifdef WHATISTHIS
  113. #include <lsdlgs.h>
  114. #endif // WHATISTHIS
  115.  
  116. #include <io.h>
  117.  
  118. #ifndef SOM_CMDocument_xh
  119. #include <CMDoc.xh>
  120. #endif
  121. #ifndef SOM_ODContainer_xh
  122. #include <ODCtr.xh>
  123. #endif
  124. #ifndef SOM_ODStorageSystem_xh
  125. #include <ODStor.xh>
  126. #endif
  127. #ifndef SOM_ODSession_xh
  128. #include <ODSessn.xh>
  129. #endif
  130.  
  131.  
  132. #ifndef _OPENHASH_
  133. #include "OpenHash.h"
  134. #endif
  135.  
  136. #ifndef _STDTYPIO_
  137.   #include <StdTypIO.h>
  138. #endif
  139.  
  140. #ifndef _STORUTIL_
  141.   #include <storutil.h>
  142. #endif
  143.  
  144. #ifndef SOM_ODStorageUnit_xh
  145.   #include <StorageU.xh>
  146. #endif
  147.  
  148. #ifndef SOM_ODDraft_xh
  149.   #include <Draft.xh>
  150. #endif
  151.  
  152. #ifndef SOM_ODPart_xh
  153.   #include <part.xh>
  154. #endif
  155.  
  156. #ifndef SOM_IODLinkSource_xh
  157.   #include <ILinkSrc.xh>
  158. #endif
  159.  
  160. #ifndef SOM_IODLinkTargetToLinkSource_xh
  161.   #include <ILTr2LSr.xh>
  162. #endif
  163.  
  164. #include <ilnktrgt.xh>
  165.  
  166. #include <Builtin.h>
  167. #include <somd.xh>
  168. #include <servmgr.xh>
  169. #include "ILnkSrvc.xih"
  170.  
  171. #ifndef SOM_IODMutex_xh
  172.   #include <IODMutex.xh>
  173. #endif
  174.  
  175. #include <cmlksitr.xh>
  176. #include <cmlkitr.xh>
  177.  
  178. #include <lmgrdefs.h>
  179.  
  180. const  ODValueType  kODLengthPrefixStr           = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Type:LengthPrefixStr";
  181. //==============================================================================
  182. // Constants
  183. //==============================================================================
  184. #define kODLinkIDLen         4
  185. #define kODULongLen          4
  186. #define kODStorageUnitRefLen 4
  187. const ODULong kODInitialNumEntries = 8;
  188. #define FILE_LENGTH 256
  189.  
  190.  
  191. typedef struct
  192. {
  193.     ODLinkID           linkID;
  194.     ODStorageUnitRef   linkSrcSURef;
  195.     IODLinkSource*     linkSrc;
  196.     ODBoolean          isOpened;
  197.     ODBoolean          isSaved;
  198.     ODStorageUnitRef   srcPartSURef;
  199. } LinkSrcInfo;
  200. //# Structure of an entry in the fLinkSrcInfos hash table where the key is
  201. //#   the link ID
  202.  
  203. typedef struct
  204. {
  205.   ODID               trgtID;
  206.   IODLinkTarget*     linkTrgt;
  207.   ODStorageUnitRef   linkTrgtSURef;
  208.   ODStorageUnitRef   trgtPartSURef;
  209. } LinkTrgtInfo;
  210. //# Structure of an entry in the fLinkTrgtInfos hash table where the key is
  211. //#   the link target
  212.  
  213. char* GetPathName (char* docName)
  214. {
  215.     char   drive[3] = "::";
  216.     char*  hostName;
  217.     char*  pathName = (char*)kODNULL;
  218.     APIRET rc = NO_ERROR;
  219.     char*  tmp;
  220.     ULONG  ulOrdinal = 0;
  221.  
  222.     // To eliminate the popup for drive not ready
  223.     // defect 25874
  224.     DosError(FERR_DISABLEHARDERR);
  225.  
  226.     if (strstr(docName, "LOCALHOST") == docName)
  227.     {
  228.       pathName = (char*)SOMMalloc(strlen(docName));
  229.       strcpy(pathName, docName+10);
  230.       return pathName;
  231.     }
  232.  
  233.     if (hostName = getenv("HOSTNAME"))
  234.     {
  235.       if (strstr(docName, strupr(hostName)) == docName)
  236.       {
  237.         pathName = (char*)SOMMalloc(strlen(docName));
  238.         strcpy(pathName, docName+strlen(hostName)+1);
  239.         return pathName;
  240.       }
  241.     }
  242.  
  243.     for (char c = 'C'; c <= 'Z'; c++)
  244.     {
  245.       drive[0] = c;
  246.  
  247.       {
  248.         BYTE        fsqBuffer[sizeof(FSQBUFFER2) + (3 * CCHMAXPATH)] = {0};
  249.         PFSQBUFFER2 pfsqBuffer = (PFSQBUFFER2)fsqBuffer;
  250.         ULONG       cbBuffer = sizeof(fsqBuffer);
  251.         PBYTE       prgFSAData = NULL;
  252.         PBYTE       pszFSDName = NULL;
  253.  
  254.         rc = DosQueryFSAttach(drive,
  255.                               ulOrdinal,
  256.                               FSAIL_QUERYNAME,
  257.                               pfsqBuffer,
  258.                               &cbBuffer);
  259.  
  260.         if (rc == NO_ERROR)
  261.         {
  262.           pszFSDName = (BYTE*)(pfsqBuffer->szName + pfsqBuffer->cbName + 1);
  263.           prgFSAData = strupr(pszFSDName + pfsqBuffer->cbFSDName + 1);
  264.  
  265.           // Only consider NFS remote file
  266.           if ((pfsqBuffer->iType == FSAT_REMOTEDRV) &&
  267.               (strcmp(pszFSDName, "NFS") == 0))
  268.           {
  269.             if (strstr(docName, prgFSAData) == docName)
  270.             {
  271.               pathName = (char*)malloc(strlen(docName) + 3);
  272.               pathName[0] = c;
  273.               pathName[1] = ':';
  274.               pathName[2] = '\0';
  275.               strcat(pathName, docName+strlen(prgFSAData));
  276.               return pathName;
  277.             }
  278.           }
  279.         }
  280.       }
  281.     }
  282.  
  283.     // To eliminate the popup for drive not ready
  284.     // defect 25874
  285.     DosError(FERR_ENABLEHARDERR);
  286.  
  287.     return pathName;
  288. }
  289.  
  290. /*
  291.  *=============================================================================
  292.  * Local function for cleaning up LinkService Properties.
  293.  *
  294.  * <1> Clean Up instance variables.
  295.  * <2> Release the local _fAvlServer object(deletes the proxy, but not the
  296.  *                                           remote AvlServer...)
  297.  *=============================================================================
  298.  */
  299.  
  300. SOM_Scope void
  301. SOMLINK CleanupLinkServiceProperties(IODLinkService *somSelf, Environment *ev)
  302. {
  303.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  304.   IODLinkServiceMethodDebug("IODLinkService","CleanUpLinkServicProperties");
  305.   //---<1>
  306.   ODLinkID linkID;
  307.   LinkSrcInfo *linkSrcInfo = kODNULL;
  308.   if (_fLinkSrcInfos != (OpenHashTable*)kODNULL)
  309.   {
  310.    OpenHashTableIterator iter(_fLinkSrcInfos);
  311.    for (iter.First(&linkID, &linkSrcInfo);
  312.         iter.IsNotComplete();
  313.         iter.Next(&linkID, &linkSrcInfo))
  314.     {
  315.      (linkSrcInfo->linkSrc)->Release(ev);
  316.       delete linkSrcInfo;
  317.     }
  318.  
  319.     delete _fLinkSrcInfos;
  320.     _fLinkSrcInfos = (OpenHashTable*)kODNULL;
  321.    }
  322.    ODLinkConnectionID    trgtID;
  323.    LinkTrgtInfo *linkTrgtInfo = kODNULL;
  324.    if (_fLinkTrgtInfos != (OpenHashTable*)kODNULL)
  325.    {
  326.     OpenHashTableIterator iter(_fLinkTrgtInfos);
  327.     for (iter.First(&trgtID, &linkTrgtInfo);
  328.          iter.IsNotComplete();
  329.          iter.Next(&linkID, &linkTrgtInfo))
  330.      {
  331.        delete linkTrgtInfo;
  332.      }
  333.  
  334.      delete _fLinkTrgtInfos;
  335.      _fLinkTrgtInfos = (OpenHashTable*)kODNULL;
  336.     }
  337.    SOMFree(_fDocPathName);
  338.    _fDocPathName  = kODNULL;
  339.    SOMFree(_fASName);
  340.    _fASName       = kODNULL;
  341.    _fDraftOpened  = kODFalse;
  342.    _fDraft = kODNULL;
  343.    _fDraftOpened = kODFalse;
  344.    _fDocumentID   = kODNULL;
  345.    //---<2>
  346.    if (_fAvlSvr != (IODAvailServer*)kODNULL)
  347.    {
  348.      if (((SOMDObject*)_fAvlSvr)->is_proxy(ev))
  349.      {
  350.        SOMD_ObjectMgr->somdReleaseObject(ev, (SOMDObject*)_fAvlSvr);
  351.      }
  352.      else
  353.      {
  354.        _interrupt(3);
  355.      }
  356.    }
  357.    _fAvlSvr       = kODNULL;
  358. }
  359. /*
  360.  *=============================================================================
  361.  * Local function for contacting the availability server
  362.  *
  363.  * <1>  If the availability server already contacted, then nothing to do.
  364.  * <2>  Get a pointer to the Availability Server from its name using
  365.  *      somdFindServerByName. Store it in the _fAvlSvr field.
  366.  * <3>  If this is a moved document, call DocMoved
  367.  * <4A> If this is a new document (one with no ASName property, or DocumentID 0)
  368.  *     <4.A.1.> Call Register Document on the Availability server; get back the
  369.  *              document id.
  370.  * <4B> If this is an old document
  371.  *     <4.B.1.> Call the Availability Server DocOpened.
  372.  *     <4.B.2.> If DocOpened failed - check return code and if it is Invalid
  373.  *          doc name - then this is an original of a copy/move.
  374.  *          Bring up a dialogue to select the dominant document.
  375.  *     <4.B.2.1.> If move, call DocMoved, and
  376.  *                Call the Availability Server DocOpened again.
  377.  *                and it should work; Raise an exception if it doesn't.
  378.  *     <4.B.2.2.> If copy, call the availability server Register,
  379.  *                and empty out the table of source links
  380.  *=============================================================================
  381. */
  382.  
  383. void ContactAvailabilityServer (Environment *ev,
  384.                                 IODLinkService *somSelf,
  385.                                 IODLinkServiceData *somThis,
  386.                                 ODMoveCopyResult *mcResult /* non-null if move-copy dialog has taken place */
  387.                                 )
  388. {
  389.     SOMDServer* server;
  390.     CHAR        LoadError[CCHMAXPATH];
  391.     CHAR        pszTemp[CCHMAXPATH];
  392.     CHAR        pszTemp2[CCHMAXPATH];
  393.     HAB         hab;
  394.     HMODULE     hmodDLL;
  395.  
  396.     HPOINTER waitptr, arrowptr;
  397.     waitptr  = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  398.     arrowptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
  399.     WinSetPointer(HWND_DESKTOP,waitptr);
  400.  
  401. // #ifdef OS2LinkChanges
  402.     _fDraft->
  403.       GetDocument(ev)->
  404.         GetContainer(ev)->
  405.           GetStorageSystem(ev)->
  406.             GetSession(ev)->
  407.               StartServer(ev, (char*)kODNULL);
  408. // #endif // OS2LinkChanges
  409.  
  410.     // 1.
  411.     if (_fAvlSvr != kODNULL) return;
  412.  
  413.     SOMDServerMgr* servMgr;
  414.     servMgr = new SOMDServerMgr;
  415.     servMgr->somdStartServer(ev, _fASName);
  416.  
  417.     if (ev->_major != NO_EXCEPTION) {
  418.        DosLoadModule(LoadError,sizeof(LoadError),"ODRes",&hmodDLL);
  419.        WinLoadString(hab,hmodDLL,IDS_NOSERVER,CCHMAXPATH,pszTemp);
  420.        WinLoadString(hab,hmodDLL,IDS_ERROR,CCHMAXPATH,pszTemp2);
  421.        WinMessageBox(HWND_DESKTOP,
  422.                      HWND_DESKTOP,
  423.                      pszTemp,
  424.                      pszTemp2,
  425.                      0L,
  426.                      MB_OK | MB_ERROR);
  427.     }
  428.  
  429.     // 2.
  430.     server = SOMD_ObjectMgr->somdFindServerByName(ev, _fASName);
  431.  
  432.     if(server == NULL)                   //@SK [124619]
  433.     {                                              //@SK [124619]
  434.       somPrintf("\n Error: Cannot find Availability Server.\n");//@SK [124619]
  435.       WinSetPointer(HWND_DESKTOP,arrowptr);
  436.       DosExit(EXIT_PROCESS, 1);                      //@SK [124619]
  437.     }
  438.  
  439.     if(server)
  440.     {
  441.       _fAvlSvr = (IODAvailServer*)(void*)server->
  442.                                            somdCreateObj(ev,
  443.                                                          "IODAvailServer",
  444.                                                          "");
  445.     }
  446.  
  447.     if (ODGetSOMException(ev) != kODNoError)
  448.     {
  449.       _fAvlSvr = kODNULL;
  450.       THROW(kODErrInvalidAvlSvr);
  451.     }
  452.  
  453.     // 3.
  454.     if ((mcResult != kODNULL) && (mcResult->FileMoved))
  455.     {
  456.       TRY
  457.         somSelf->DraftMoved(ev,
  458.                             _fDraft,
  459.                             mcResult->fOldDocPathName,
  460.                             mcResult->fNewDocPathName);
  461.       CATCH_ALL
  462.         ODMoveCopyResult mcDialog;
  463.         mcDialog.fNewDocPathName = _fDocPathName;
  464.         mcDialog.fOldDocPathName = mcResult->fOldDocPathName;
  465.         do
  466.         {
  467.           ShowMoveCopyDialog(&mcDialog);
  468.           if (mcDialog.FileCopied)
  469.           {
  470.             _fDocumentID = _fAvlSvr->
  471.                              RegisterDoc(ev,
  472.                                          _fDocPathName,
  473.                                          (IODAvailServerToLinkService*)somSelf);
  474.             THROW_IF_NULL((void *)_fDocumentID);
  475.             delete _fLinkSrcInfos;
  476.             _fLinkSrcInfos = new OpenHashTable;
  477.             _fLinkSrcInfos->Initialize(kODInitialNumEntries,
  478.                                        sizeof(ODStorageUnitID),
  479.                                        sizeof(LinkSrcInfo*),
  480.                                        kODFalse);
  481.             delete _fLinkTrgtInfos;
  482.             _fLinkTrgtInfos = new OpenHashTable;
  483.             _fLinkTrgtInfos->Initialize(kODInitialNumEntries,
  484.                                         sizeof(ODStorageUnitID),
  485.                                         sizeof(LinkTrgtInfo*),
  486.                                         kODFalse);
  487.             _fIsNew = kODTrue;
  488.             return;
  489.           }
  490.         } while (mcDialog.FileMoved);
  491.       ENDTRY
  492.     }
  493.  
  494.     // 4.
  495.     if (_fIsNew || _fDocumentID == 0)
  496.     {
  497.       //---<4.A.1.>
  498.       _fDocumentID = _fAvlSvr->
  499.                        RegisterDoc(ev,
  500.                                    _fDocPathName,
  501.                                    (IODAvailServerToLinkService*)somSelf);
  502.       THROW_IF_NULL((void *)_fDocumentID);
  503.     }
  504.     else
  505.     {
  506.       ODISOStr oldDocPathName;
  507.       ODBoolean success;
  508.     SOM_TRY
  509.       //---<4.B.1.>
  510.       success = _fAvlSvr->
  511.                              DocOpened(ev,
  512.                                        _fDocumentID,
  513.                                        _fDocPathName,
  514.                                        (IODAvailServerToLinkService*)somSelf,
  515.                                        &oldDocPathName);
  516.     SOM_CATCH_ALL
  517.       //---<4.B.2.>
  518.       if (!success)
  519.       {
  520.         if (ODGetSOMException(ev) == kODErrInvalidDocPathName)
  521.         {
  522.           ODSetSOMException(ev, kODNoError);
  523.           ODMoveCopyResult mcDialog;
  524.           mcDialog.fNewDocPathName = _fDocPathName;
  525.           mcDialog.fOldDocPathName = oldDocPathName;
  526.           ShowMoveCopyDialog(&mcDialog);
  527.           if (mcDialog.FileMoved == kODTrue)
  528.           {
  529.           TRY
  530.             //---<4.B.2.1.>
  531.             somSelf->DraftMoved(ev,
  532.                                 _fDraft,
  533.                                 mcDialog.fOldDocPathName,
  534.                                 mcDialog.fNewDocPathName);
  535.             if (oldDocPathName != kODNULL)
  536.             {
  537.               SOMFree(oldDocPathName);
  538.               oldDocPathName = kODNULL;
  539.             }
  540.             success = _fAvlSvr->
  541.                         DocOpened(ev,
  542.                                   _fDocumentID,
  543.                                   _fDocPathName,
  544.                                   (IODAvailServerToLinkService*)somSelf,
  545.                                    &oldDocPathName);
  546.             if (oldDocPathName != kODNULL)
  547.             {
  548.               SOMFree(oldDocPathName);
  549.               oldDocPathName = kODNULL;
  550.             }
  551.           CATCH_ALL
  552.             if(!success)
  553.             {
  554.               THROW(kODErrDocOpenedFailed);
  555.             }
  556.           ENDTRY
  557.           } /* if moved */
  558.           else
  559.           {
  560.             //---<4.B.2.2.>
  561.             _fDocumentID = _fAvlSvr->
  562.                              RegisterDoc(ev,
  563.                                          _fDocPathName,
  564.                                          (IODAvailServerToLinkService*)somSelf);
  565.             THROW_IF_NULL((void *)_fDocumentID);
  566.             delete _fLinkSrcInfos;
  567.             _fLinkSrcInfos = new OpenHashTable;
  568.             _fLinkSrcInfos->Initialize(kODInitialNumEntries,
  569.                                        sizeof(ODStorageUnitID),
  570.                                        sizeof(LinkSrcInfo*),
  571.                                        kODFalse);
  572.             delete _fLinkTrgtInfos;
  573.             _fLinkTrgtInfos = new OpenHashTable;
  574.             _fLinkTrgtInfos->Initialize(kODInitialNumEntries,
  575.                                         sizeof(ODStorageUnitID),
  576.                                         sizeof(LinkTrgtInfo*),
  577.                                         kODFalse);
  578.             _fIsNew = kODTrue;
  579.           }/* else */
  580.         } /* if invalidDocId */
  581.       } /* if not success */
  582.     SOM_ENDTRY
  583.       if  (oldDocPathName != kODNULL)
  584.       {
  585.         SOMFree(oldDocPathName);
  586.       }
  587.     } /* if not IsNew */
  588.  
  589.     WinSetPointer(HWND_DESKTOP,arrowptr);
  590. }
  591.  
  592. /*
  593.  *=============================================================================
  594.  * Local function for writing an ODISOStr to a storage unit.
  595.  *
  596.  * <1>  Focus to the given property and value.
  597.  * <2>  Save old size of the focused value in oldSize.
  598.  * <3>  Write the length of the string, followed by the string itself.
  599.  *       Increase newSize by the size of the length counter + lenght bytes.
  600.  * <4>  Delete unused space left from previous write.
  601.  *=============================================================================
  602. */
  603.  
  604. void SetISOStrProp (Environment *ev,
  605.                              ODStorageUnit *su,
  606.                              ODPropertyName prop,
  607.                              ODISOStr myISOStr)
  608. {
  609.     ODULong                      newSize;
  610.     ODULong                      oldSize;
  611.     ODULong                      strLength;/* length of string written to SU */
  612.                                            /* is string length + its null    */
  613.     //---<1>
  614. // defect 27438
  615.     ODSUForceFocus(ev, su, prop, kODLengthPrefixStr);
  616.  
  617.     //---<2>
  618.     oldSize = su->GetSize(ev);
  619.  
  620.     //---<3>
  621.     strLength = strlen(myISOStr) + 1;
  622.     StorageUnitSetValue(su, ev, kODULongLen, (ODValue)&strLength);
  623.     StorageUnitSetValue(su,
  624.                         ev,
  625.                         strLength,
  626.                         (ODValue)myISOStr);
  627.     newSize = (kODULongLen + strLength);
  628.  
  629.     //---<4>
  630.     if (oldSize > newSize)
  631.     {
  632.       su->DeleteValue(ev, oldSize-newSize);
  633.     }
  634.  
  635. } /* end SetISOStrProp */
  636.  
  637. /*
  638.  *=============================================================================
  639.  * Local function for reading an ODISOStr from a storage unit.
  640.  *
  641.  * <1>  Focus to the given property and value.
  642.  * <2>  Read in the string.
  643.  *=============================================================================
  644. */
  645.  
  646. void GetISOStrProp (Environment *ev,
  647.                     ODStorageUnit *su,
  648.                     ODPropertyName prop,
  649.                     ODISOStr *myISOStr)
  650. {
  651.     ODULong                strLength;/* length of string written to SU */
  652.                                      /* is string length + its null    */
  653.     //---<1>
  654. // defect 27438
  655.     if (ODSUExistsThenFocus(ev, su, prop, kODLengthPrefixStr))
  656.     {
  657.         //---<2>
  658.         StorageUnitGetValue(su, ev, kODULongLen, (ODValue)&strLength);
  659.         *myISOStr = (ODISOStr)SOMMalloc(strLength);
  660.         StorageUnitGetValue(su,
  661.                             ev,
  662.                             strLength,
  663.                             (ODValue)*myISOStr);
  664.    }
  665. } /* end GetISOStrProp */
  666.  
  667. /*
  668.  *=============================================================================
  669.  * Local function for writing an ODULong to a storage unit.
  670.  *
  671.  * <1>  Focus to the given property and value.
  672.  * <2>  Write the ULong to storage unit.
  673.  *=============================================================================
  674. */
  675.  
  676. void SetULongProp (Environment *ev,
  677.                    ODStorageUnit *su,
  678.                    ODPropertyName prop,
  679.                    ODULong  &myULong)
  680. {
  681.     //---<1>
  682.     ODSUForceFocus(ev, su, prop, kODULong);
  683.  
  684.     //---<2>
  685.     StorageUnitSetValue(su, ev, kODULongLen, (ODValue)&myULong);
  686.  
  687. } /* end SetISOStrProp */
  688.  
  689. /*
  690.  *=============================================================================
  691.  * Local function for reading an ODULong from a storage unit.
  692.  *
  693.  * <1>  Focus to the given property and value.
  694.  * <2>  Read in the ULong.
  695.  *=============================================================================
  696. */
  697.  
  698. void GetULongProp (Environment *ev,
  699.                     ODStorageUnit *su,
  700.                     ODPropertyName prop,
  701.                     ODULong &myULong)
  702. {
  703.     ODULong                strLength;
  704.  
  705.     //---<1>
  706.     if (ODSUExistsThenFocus(ev, su, prop, kODULong))
  707.     {
  708.         //---<2>
  709.         StorageUnitGetValue(su, ev, kODULongLen, (ODValue)&myULong);
  710.    }
  711. } /* end GetULongProp */
  712.  
  713. /*
  714.  *=============================================================================
  715.  * Local function for writing a hashtable of LinkSrcInfo to the
  716.  * storage unit.
  717.  *
  718.  * <1>  Focus to the given property and value.
  719.  * <2>  Save old size of the focused value in oldSize.
  720.  * <3>  Reserve space to write the number of elements in the hashtable.
  721.  *      Initialize newSize to the size of ulong.
  722.  * <4>  Iterate thru each element of the hash table.
  723.  * <5>  Write the LinkID.
  724.  *      Increase newSize by the size of IODLinkID.
  725.  * <6>  Write the weak SU reference to the linksource storage unit.
  726.  *      Increase newSize by the size of kODStorageUnitRef.
  727.  * <7>  Write the weak SU reference to the source part storage unit.
  728. *      If the source part from the last SetSourcePart is null,
  729.  *      write a zero.
  730.  *      Increase newSize by the size of kODStorageUnitRef.
  731.  * <8>  Count the number of elements in the hashtable.
  732.  * <9>  Delete unused space left from previous write.
  733.  * <10> After iterating through the hashtable, refocus to the given property and
  734.  *      value.
  735.  *      Write the total number of elements in the hashtable in the space
  736.  *      reseved at <3>.
  737.  *=============================================================================
  738. */
  739.  
  740. void SetLinkSrcInfosProp (Environment *ev,
  741.                              ODStorageUnit *su,
  742.                              ODPropertyName prop,
  743.                              ODValueType val,
  744.                              OpenHashTable &LinkSrcInfos)
  745. {
  746.     ODLinkID                     key;
  747.     LinkSrcInfo*                 linkSrcInfo;
  748.     ODULong                      numOfElmnts = 0;
  749.     ODULong                      newSize;
  750.     ODULong                      oldSize;
  751.     ODULong                      strLength;
  752.  
  753.     //---<1>
  754.     ODSUForceFocus(ev, su, prop, val);
  755.  
  756.     //---<2>
  757.     oldSize = su->GetSize(ev);
  758.  
  759.     //---<3>
  760.     StorageUnitSetValue(su, ev, kODULongLen, (ODValue)&numOfElmnts);
  761.     newSize = kODULongLen;
  762.  
  763.     //---<4>
  764.     OpenHashTableIterator infos(&LinkSrcInfos);
  765.     for (infos.First(&key, &linkSrcInfo);
  766.          infos.IsNotComplete();
  767.          infos.Next(&key, &linkSrcInfo))
  768.     {
  769.       //---<5>
  770.       StorageUnitSetValue(su,
  771.                           ev,
  772.                           kODLinkIDLen,
  773.                           (ODValue)&(linkSrcInfo->linkID));
  774.  
  775.       newSize += kODLinkIDLen;
  776.  
  777.       //---<6>
  778.       StorageUnitSetValue(su,
  779.                           ev,
  780.                           kODStorageUnitRefLen,
  781.                           (ODValue)&(linkSrcInfo->linkSrcSURef));
  782.  
  783.       newSize += kODStorageUnitRefLen;
  784.  
  785.       //---<7>
  786.       ODStorageUnit *partSU =  (linkSrcInfo->linkSrc) -> AcquireSourcePart(ev);
  787.       if ( partSU == kODNULL)
  788.         {
  789.            ODStorageUnitRef zero;
  790.            memset(zero, 0, kODStorageUnitRefLen);
  791.            StorageUnitSetValue(su,
  792.                                ev,
  793.                                kODStorageUnitRefLen,
  794.                                (ODValue)kODNULL);
  795.          } else {
  796.            StorageUnitSetValue(su,
  797.                                ev,
  798.                                kODStorageUnitRefLen,
  799.                                (ODValue)&(linkSrcInfo->srcPartSURef));
  800.            partSU -> Release(ev);
  801.          }
  802.  
  803.  
  804.       newSize += kODStorageUnitRefLen;
  805.  
  806.       //---<8>
  807.       numOfElmnts++;
  808.     }
  809.  
  810.     //---<9>
  811.     if (oldSize > newSize)
  812.     {
  813.       su->DeleteValue(ev, oldSize-newSize);
  814.     }
  815.  
  816.     //---<10>
  817.     su->Focus(ev, prop, kODPosUndefined, val, 0, kODPosUndefined);
  818.     StorageUnitSetValue(su, ev, kODULongLen, (ODValue)&numOfElmnts);
  819.  
  820. } /* end SetLinkSrcInfosProp */
  821.  
  822. /*
  823.  *=============================================================================
  824.  * Local function for reading a hashtable of LinkSrcInfo from a
  825.  * storage unit.
  826.  *
  827.  * <1>  Focus to the given property and value.
  828.  * <2>  Read the total number of elements in the hashtable into numOfElemnts.
  829.  * <3>  Loop to read in each element of the hashtable.
  830.  * <4>  Create a new LinkSrcInfo.
  831.  * <5>  Read in the link storage unit ref field of LinkSrcInfo.
  832.  * <6>  Read in the LinkSource's SU reference.
  833.  * <7>  Read in the source parts' SU reference.
  834.  * <8>  Add linkInfo to the hashtable.
  835.  *=============================================================================
  836. */
  837.  
  838. void GetLinkSrcInfosProp (Environment *ev,
  839.                              ODStorageUnit *su,
  840.                              ODPropertyName prop,
  841.                              ODValueType val,
  842.                              OpenHashTable &LinkSrcInfos)
  843. {
  844.     ODULong                i;
  845.     ODLinkID               key;
  846.     LinkSrcInfo*           linkSrcInfo;
  847.     ODULong                numOfElmnts;
  848.     ODID                   linkSUID;
  849.  
  850.     //---<1>
  851.     if (ODSUExistsThenFocus(ev, su, prop, val))
  852.     {
  853.       //---<2>
  854.       StorageUnitGetValue(su, ev, kODULongLen, (ODValue)&numOfElmnts);
  855.  
  856.       //---<3>
  857.       for (i = 0; i < numOfElmnts; i++)
  858.       {
  859.         //---<4>
  860.         linkSrcInfo = new LinkSrcInfo;
  861.  
  862.         //---<5>
  863.         StorageUnitGetValue(su,
  864.                             ev,
  865.                             kODLinkIDLen,
  866.                             (ODValue)&(linkSrcInfo->linkID));
  867.         //---<6>
  868.         StorageUnitGetValue(su,
  869.                             ev,
  870.                             kODStorageUnitRefLen,
  871.                             (ODValue)&linkSrcInfo->linkSrcSURef);
  872.         //---<7>
  873.         StorageUnitGetValue(su,
  874.                             ev,
  875.                             kODStorageUnitRefLen,
  876.                             (ODValue)&(linkSrcInfo->srcPartSURef));
  877.  
  878.         linkSrcInfo->linkSrc  = kODNULL;
  879.         linkSrcInfo->isOpened = kODFalse;
  880.         linkSrcInfo->isSaved  = kODTrue;
  881.         //---<8>
  882.         LinkSrcInfos.ReplaceEntry(&(linkSrcInfo->linkID), &linkSrcInfo);
  883.       }
  884.     }
  885. } /* end GetLinkSrcInfosProp */
  886.  
  887. /*
  888.  *=============================================================================
  889.  * Local function for writing a hashtable of LinkTrgtInfo to the
  890.  * storage unit.
  891.  *
  892.  * <1>  Focus to the given property and value.
  893.  * <2>  Reserve space to write the number of elements in the hashtable.
  894.  * <3>  Iterate thru each element of the hash table.
  895.  * <4>  Write the trgtID field of linkTrgtInfo.
  896.  * <5>  Write the weak SU reference to the linktarget storage unit.
  897.  *      Increase newSize by the size of kODStorageUnitRef.
  898.  * <6>  Write the weak SU reference to the source part storage unit.
  899.  *      Increase newSize by the size of kODStorageUnitRef.
  900.  * <7>  Count the number of elements in the hashtable.
  901.  * <8>  After iterating thru the hashtable, refocus to the given property and
  902.  *      value.
  903.  *      Write the total number of elements in the hashtable in the space
  904.  *      reseved at <2>.
  905.  *=============================================================================
  906. */
  907.  
  908. void SetLinkTrgtInfosProp (Environment *ev,
  909.                        ODStorageUnit *su,
  910.                        ODPropertyName prop,
  911.                        ODValueType val,
  912.                        OpenHashTable &linkTrgtInfos)
  913. {
  914.     ODLinkConnectionID  key;
  915.     LinkTrgtInfo*    linkTrgtInfo;
  916.     ODULong          numOfElmnts = 0;
  917.     ODULong          newSize;
  918.     ODULong          oldSize;
  919.     ODISOStr         remoteTrgtID;
  920.     ODULong          strLength;
  921.     ODID             trgtSUID;
  922.     ODStorageUnitRef trgtSURef;
  923.  
  924.     //---<1>
  925.     ODSUForceFocus(ev, su, prop, val);
  926.  
  927.     //---<2>
  928.     StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfElmnts);
  929.  
  930.     //---<3>
  931.     OpenHashTableIterator infos(&linkTrgtInfos);
  932.     for (infos.First(&key, &linkTrgtInfo);
  933.          infos.IsNotComplete();
  934.          infos.Next(&key, &linkTrgtInfo))
  935.     {
  936.       //---<4>
  937.       StorageUnitSetValue(su,
  938.                           ev,
  939.                           sizeof(ODLinkConnectionID),
  940.                           (ODValue)&(linkTrgtInfo->trgtID));
  941.  
  942.       //---<5>
  943.       StorageUnitSetValue(su,
  944.                           ev,
  945.                           kODStorageUnitRefLen,
  946.                           (ODValue)&(linkTrgtInfo->linkTrgtSURef));
  947.  
  948.       newSize += kODStorageUnitRefLen;
  949.       //---<6>
  950.       StorageUnitSetValue(su,
  951.                           ev,
  952.                           kODStorageUnitRefLen,
  953.                           (ODValue)&(linkTrgtInfo->trgtPartSURef));
  954.  
  955.       newSize += kODStorageUnitRefLen;
  956.       //---<7>
  957.       numOfElmnts++;
  958.     }
  959.  
  960.     //---<8>
  961.     su->Focus(ev, prop, kODPosSame, val, 0, kODPosSame);
  962.     StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue)&numOfElmnts);
  963. }
  964.  
  965. /*
  966.  *=============================================================================
  967.  * Local function for reading a hashtable of LinkTrgtInfo from a
  968.  * storage unit.
  969.  *
  970.  * <1>  Focus to the given property and value.
  971.  * <2>  Read the total number of elements in the hashtable into numOfElemnts.
  972.  * <3>  Loop to read in each element of the hashtable.
  973.  * <4>  Create a new linkTrgtInfo.
  974.  * <5>  Read in the trgtID field of linkTrgtInfo.
  975.  * <6>  Read in the LinkTarget's SU reference.
  976.  * <7>  Read in the source parts' SU reference.
  977.  * <8>  Add linkTrgtInfo to the hashtable.
  978.  *=============================================================================
  979. */
  980.  
  981. void GetLinkTrgtInfosProp (Environment *ev,
  982.                        ODStorageUnit *su,
  983.                        ODPropertyName prop,
  984.                        ODValueType val,
  985.                        OpenHashTable &linkTrgtInfos)
  986. {
  987.     ODULong          i;
  988.     LinkTrgtInfo*    linkTrgtInfo;
  989.     ODULong          numOfElmnts;
  990.     ODISOStr         remoteTrgtID;
  991.     ODULong          strLength;
  992.     ODID             trgtSUID;
  993.     ODStorageUnitRef trgtSURef;
  994.  
  995.     //---<1>
  996.     if (ODSUExistsThenFocus(ev, su, prop, val))
  997.     {
  998.       //---<2>
  999.       StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue)&numOfElmnts);
  1000.  
  1001.       //---<3>
  1002.       for (i = 0; i < numOfElmnts; i++)
  1003.       {
  1004.         //---<4>
  1005.         linkTrgtInfo = new LinkTrgtInfo;
  1006.  
  1007.         //---<5>
  1008.         StorageUnitGetValue(su,
  1009.                             ev,
  1010.                             sizeof(ODLinkConnectionID),
  1011.                             (ODValue)&(linkTrgtInfo->trgtID));
  1012.  
  1013.         //---<6>
  1014.         StorageUnitGetValue(su,
  1015.                             ev,
  1016.                             kODStorageUnitRefLen,
  1017.                             (ODValue)&linkTrgtInfo->linkTrgtSURef);
  1018.         //---<7>
  1019.         StorageUnitGetValue(su,
  1020.                             ev,
  1021.                             kODStorageUnitRefLen,
  1022.                             (ODValue)&(linkTrgtInfo->trgtPartSURef));
  1023.  
  1024.         //---<9>
  1025.         linkTrgtInfos.ReplaceEntry(&(linkTrgtInfo->trgtID), &linkTrgtInfo);
  1026.       }
  1027.     }
  1028. }
  1029.  
  1030. /*
  1031.  *=============================================================================
  1032.  * Local function for browsing an externalized LinkSrcInfos hashtable
  1033.  * in search of an entry matching a given LinkID. If found, the
  1034.  * corresponding storage unit reference is returned.
  1035.  * <1>  Focus to the property and value.
  1036.  * <2>  Read the total number of elements in the hashtable into numOfElemnts.
  1037.  * <3>  Loop to read linkid in each element of the hashtable.
  1038.  * <4>  Compare the linkid you read with the given linkid.
  1039.  * <5>  If the match - read in the corresponding link storage unit ref.
  1040.  * <6>  If they don't match - step to the next linkid entry.
  1041.  * <7>  Convert the storage unit ref you found to a storage unit id.
  1042.  * <8>  Return the storage unit id you found(or null if you did not find
  1043.  *      a matching LinkID).
  1044.  *=============================================================================
  1045. */
  1046.  
  1047. ODStorageUnitID FindLinkSrcSURefbyLinkID (Environment      *ev,
  1048.                                         ODStorageUnit    *su,
  1049.                                         ODLinkID         linkid)
  1050. {
  1051.     ODULong                i;
  1052.     ODLinkID               key;
  1053.     LinkSrcInfo*           linkSrcInfo;
  1054.     ODULong                numOfElmnts;
  1055.     ODID                   linkSUID;
  1056.     ODLinkID               tempLinkID;
  1057.     ODULong                offset;
  1058.     ODStorageUnitRef       linkSrcSURef;
  1059.     ODStorageUnitID        suID = kODNULL;
  1060.  
  1061.     //---<1>
  1062.     if (ODSUExistsThenFocus(ev, su, kODPropLinkSourceInfos, kODHashTable))
  1063.     {
  1064.       offset = su->GetOffset(ev);
  1065.       //---<2>
  1066.       StorageUnitGetValue(su, ev, kODULongLen, (ODValue)&numOfElmnts);
  1067.       offset += kODULongLen;
  1068.  
  1069.       //---<3>
  1070.       for (i = 0; i < numOfElmnts; i++)
  1071.       {
  1072.  
  1073.         StorageUnitGetValue(su,
  1074.                             ev,
  1075.                             kODLinkIDLen,
  1076.                             (ODValue)&tempLinkID);
  1077.  
  1078.        //---<4>
  1079.        if(tempLinkID == linkid)
  1080.        {
  1081.          //---<5>
  1082.          StorageUnitGetValue(su,
  1083.                              ev,
  1084.                              kODStorageUnitRefLen,
  1085.                              (ODValue)&linkSrcSURef);
  1086.          //---<3>
  1087.          if (su->IsValidStorageUnitRef(ev, linkSrcSURef))
  1088.          {
  1089.           suID = su->GetIDFromStorageUnitRef(ev, linkSrcSURef);
  1090.          }
  1091.          if (suID == (ODStorageUnitID)kODNULL)
  1092.          {
  1093.           ODSetSOMException(ev, kODErrInvalidLinkID);
  1094.          }
  1095.          break;
  1096.        }
  1097.        else
  1098.        {
  1099.          //---<6>
  1100.          offset += kODLinkIDLen;
  1101.          offset += kODStorageUnitRefLen;
  1102.          su->SetOffset(ev, offset);
  1103.        }
  1104.       } /* for loop over all elements */
  1105.     } /* if ODSUExistsThenFocus */
  1106.     //---<7>
  1107.     return (suID);
  1108. } /* end GetLinkSrcInfosProp */
  1109.  
  1110. /*
  1111. *=============================================================================
  1112. * DraftOpened
  1113. * Called by the Docshell after new writeable draft of
  1114. * a read-write document is opened (internalized)
  1115.   // Reads persistent information about an existing document
  1116.   // and calls "Open" on the AS; else calls "Register" on
  1117.   // the AS.
  1118.   // Initializes table of link sources for this draft
  1119.   // gets hold of the drafts _fDraftProperties storage unit
  1120.   // Internalizes the fLinkSrcInfos table from the draftproperties.
  1121.   // Internalizes the fLinkTrgtInfos table from the draftproperties.
  1122.   // (In this implementation, only one table per LinkService supported
  1123. * <0> Validate input variables.
  1124. * <1> Get the draft properties.
  1125. * <2> Initialize _fDraft and _fDocPathName instance variables
  1126. *     from input variable and set the _fExistsUnsavedLink to false.
  1127. * <3> Initialize empty LinkSrcInfos table.
  1128. * <4> Initialize empty LinkTrgtInfos table.
  1129. * <5> Remember whether document is new (or alternatively,
  1130. *     is old but has no ASName property, which could happen
  1131. *     if this is a saved template, in which case we treat it as new.)
  1132. *     This will be used later when
  1133. *     deferred opening or registration takes place.
  1134. *     If this is a new draft (or an existing draft with no suDraftProperties):
  1135. * <6> Get the Availability server name by query on environment variables
  1136. *     "HOSTNAME" and "SUFFIXNAME" and set the _fASName instance variable.
  1137. * <7> Leave _fAvlSvr null.  The acquisition of the availability server
  1138. *     will happen when later if a request to open or register a link is made
  1139. * <8>  This is not a new draft:
  1140. * <9>  Get the Availability Server name from the draft properties.
  1141. * <10> fAvlSvr remains null, as in <6> above.
  1142. * <11> Read the Document ID from draft properties.
  1143. * ** notice **: in the next version, we will compare new path name
  1144. *               to old path name and if they differ and if isnew is
  1145. *               false, then we know that if the old file is still there
  1146. *               we have detected a "copy" - otherwise, a "move"
  1147. * <12> Read the old Document pathname from draft properties.
  1148. * <14> Compare the old and new pathnames to detect a "move or "copy".
  1149. *      If they differ, bring up a dialogue to ask whether move or copy.
  1150. *      <14A.> If move, contact availability server to do DocMoved
  1151. *      <14B.> If copy, mark this as a new document but don't contact
  1152. *             the availability server.
  1153. * <16> If this is not a document copy - internalize the fLinkSrcInfos table
  1154. *      from the draftproperties.
  1155. * <17> If this is not a new document - internalize the fLinkTrgtInfos table
  1156. *      from the draftproperties.
  1157. * <18> An exception is caught - clean up and return.
  1158. *=============================================================================
  1159. */
  1160. SOM_Scope void
  1161. SOMLINK DraftOpened(IODLinkService *somSelf,
  1162.                     Environment *ev,
  1163.                     ODDraft* draft,
  1164.                     ODBoolean isNew,
  1165.                     IODFileName pathName)
  1166. {
  1167.  
  1168.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1169.   IODLinkServiceMethodDebug("IODLinkService","DraftOpened");
  1170.   ODMoveCopyResult      mcResult;
  1171.   mcResult.FileMoved  = kODFalse;
  1172.   mcResult.FileCopied = kODFalse;
  1173.   SOMDServer* server;
  1174.  
  1175.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1176.  
  1177.     // Sets up link service's data if the draft is
  1178.     // writeable only. 27463
  1179.  
  1180.     if (!(draft->GetPermissions(ev) > kODDPSharedWrite)) {
  1181.       return;
  1182.     }
  1183.  
  1184. SOM_TRY
  1185.   //---<0>
  1186.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1187.   ASSERT(pathName != (IODFileName)kODNULL, kODErrInvalidDocPathName);
  1188.   //---<1>
  1189.   ODStorageUnit* suDraftProperties = draft->AcquireDraftProperties(ev);
  1190.   ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1191.   //---<2>
  1192.  
  1193.  
  1194.   char pathbuffer[FILE_LENGTH];
  1195.   
  1196.   if (pathName)
  1197.   {
  1198.     APIRET rc = 
  1199.       DosQueryPathInfo(pathName, FIL_QUERYFULLNAME, pathbuffer, FILE_LENGTH);
  1200.  
  1201.     if (rc == NO_ERROR)
  1202.       pathName = pathbuffer; 
  1203.     else 
  1204.     LOG("Error %d converting %s to full pathname.\n", rc, pathName);
  1205.  
  1206.     pathName = strupr(pathName);
  1207.  
  1208.   }
  1209.  
  1210.         
  1211.   _fDraft = draft;
  1212.   _fDocPathName = ODISOStrFromCStr(pathName);
  1213.   _fExistsUnsavedLink = kODFalse;
  1214.   //---<3>
  1215.   _fLinkSrcInfos = new OpenHashTable;
  1216.   _fLinkSrcInfos->Initialize(kODInitialNumEntries,
  1217.                   sizeof(ODStorageUnitID),
  1218.                   sizeof(LinkSrcInfo*),
  1219.                   kODFalse);
  1220.   //---<4>
  1221.   _fLinkTrgtInfos = new OpenHashTable;
  1222.   _fLinkTrgtInfos->Initialize(kODInitialNumEntries,
  1223.                   sizeof(ODStorageUnitID),
  1224.                   sizeof(LinkTrgtInfo*),
  1225.                   kODFalse);
  1226.  
  1227.   //---<5> 
  1228.   // defect 27867 - defect 27438 was incomplete. rrk 20mar97 
  1229.   if (isNew || !suDraftProperties->Exists(ev, kODPropASName, kODLengthPrefixStr, 0))  
  1230.   {
  1231.     char            hostName[256];
  1232.     char            asName[256];
  1233.  
  1234.     _fIsNew = kODTrue;
  1235.  
  1236.     //---<6>
  1237.     strcpy(asName, getenv("HOSTNAME"));
  1238.     strcat(asName, "_");
  1239.     char *asSuffixName = getenv("AVLSVRNAME");
  1240.     if(asSuffixName != (char*)kODNULL)
  1241.     {
  1242.       strcat(asName, asSuffixName);
  1243.     }
  1244.     else
  1245.     {
  1246.       strcat(asName, "AS");
  1247.     }
  1248.     _fASName = ODISOStrFromCStr(asName);
  1249.     //XXXXX If the Availability Server is not started,
  1250.     //XXXXX   server->somdCreateObject(ev, "IODAvailServer", "")
  1251.     //XXXXX in ContactAvailabilityeServer always returns a NO_RESPONSE
  1252.     //XXXXX exception even though the Availability Server is fired up by that
  1253.     //XXXXX method call.
  1254.     //XXXXX This seems to be a DSOM bug!!!!!
  1255. //   SOMDServerMgr* servMgr;
  1256. //   servMgr = new SOMDServerMgr;
  1257. //   servMgr->somdStartServer(ev, _fASName);
  1258.  
  1259. }
  1260.   //---<7>
  1261.   else /* not a new draft */
  1262.   {
  1263.    _fIsNew = kODFalse;
  1264.  
  1265.     //---<8>
  1266.     GetISOStrProp(ev,
  1267.                   suDraftProperties,
  1268.                   kODPropASName,
  1269.                   &_fASName);
  1270.  
  1271.     //---<9>
  1272.     GetULongProp(ev,
  1273.                  suDraftProperties,
  1274.                  kODPropDocumentID,
  1275.                  _fDocumentID);
  1276.  
  1277.     //---<10>
  1278.     ODISOStr oldDocPathName;
  1279.     GetISOStrProp(ev,
  1280.                   suDraftProperties,
  1281.                   kODPropDocumentPathName,
  1282.                   &oldDocPathName);
  1283.  
  1284.     //---<11>
  1285.     if (!(ODISOStrEqual(oldDocPathName, _fDocPathName )))
  1286.     {
  1287.       char* pathName = GetPathName(oldDocPathName);
  1288.  
  1289.       // pathname is null: it is from a mounted dir which is no longer valid
  1290.       //                   so treat current file as a copy
  1291.       // pathname is a valid filename: treat current file as a copy
  1292.       if ((pathName == (char*)kODNULL) || (_access(pathName, 00) == 0))
  1293.       {
  1294.         SOMFree(pathName);
  1295.         _fIsNew = kODTrue;
  1296.       }
  1297.       else
  1298.       {
  1299.         // pathname does not exist: treat current file has been moved
  1300.         SOMFree(pathName);
  1301.         mcResult.FileMoved = kODTrue;
  1302.         mcResult.fNewDocPathName = _fDocPathName;
  1303.         mcResult.fOldDocPathName = oldDocPathName;
  1304.         ContactAvailabilityServer(ev, somSelf, somThis, &mcResult);
  1305.       }
  1306.     } /* end old pathname not equal new path name */
  1307.     SOMFree(oldDocPathName);
  1308.  
  1309.     //---<16>
  1310.     if (!_fIsNew)
  1311.     {
  1312.       GetLinkSrcInfosProp(ev,
  1313.                              suDraftProperties,
  1314.                              kODPropLinkSourceInfos,
  1315.                              kODHashTable,
  1316.                              *_fLinkSrcInfos);
  1317.     } /* if this is an original document, not a copy */
  1318.   } /* end if not a new draft */
  1319.   //---<17>
  1320.   if (!isNew)
  1321.   {
  1322.     GetLinkTrgtInfosProp(ev,
  1323.                            suDraftProperties,
  1324.                            kODPropLinkTargetInfos,
  1325.                            kODHashTable,
  1326.                            *_fLinkTrgtInfos);
  1327.   }
  1328.   _fDraftOpened = kODTrue;
  1329.  
  1330.  //---<18>
  1331. SOM_CATCH_ALL
  1332.    somSelf->CleanupLinkServiceProperties(ev);
  1333. SOM_ENDTRY
  1334. }/* end DraftOpened */
  1335.  
  1336. /*
  1337. *=============================================================================
  1338. * GetLSInDraft
  1339.       // Called by the AS Shell when a target requests a LinkSrc whose
  1340.       // draft is closed and its surrogate has not yet been constructed.
  1341.       // The AS Shell passes in a read-only draft and a linkid
  1342.       // and needs to get back the storage unit id for this linkid
  1343.       // in order to clone it.
  1344.       // The LinkService will focus the draft properties on the
  1345.       // LinkSrcInfos property, lookup the storage unit reference corresponding
  1346.       // to the linkid and map it to a storage unit id.
  1347.       // It will then clean up the temporary table and return a pointer
  1348.       // to the storage unit id.
  1349. * <0> Validate input variables.
  1350. * <1> Get the draft properties.
  1351. * <2> Browse the LinkSrcInfo hash table in the draft properties to get
  1352. *     the storage unit id corresponding to the given linkid.
  1353. * <3> Convert the storage unit ref to a storage unit id.
  1354. * <3> return the suID.
  1355. *=============================================================================
  1356. */
  1357. SOM_Scope ODStorageUnitID
  1358. SOMLINK GetLinkSrcInDraft(IODLinkService *somSelf,
  1359.                      Environment *ev,
  1360.                      ODDraft* draft,
  1361.                      ODLinkID linkid)
  1362. {
  1363.  
  1364.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1365.   IODLinkServiceMethodDebug("IODLinkService","GetLSInDraft");
  1366.  
  1367.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1368.  
  1369. SOM_TRY
  1370.   //---<0>
  1371.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1372.   ASSERT(linkid != (ODLinkID)kODNULL, kODErrInvalidLinkID);
  1373.   //---<1>
  1374.   ODStorageUnit* suDraftProperties = draft->AcquireDraftProperties(ev);
  1375.   ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1376.   //---<2>
  1377.   ODStorageUnitID suID =  FindLinkSrcSURefbyLinkID (ev,
  1378.                                                   suDraftProperties,
  1379.                                                   linkid);
  1380.  
  1381.   if (ODGetSOMException(ev) != kODNoError)
  1382.   {
  1383.     THROW(kODErrInvalidLinkID);
  1384.   }
  1385.   //---<3>
  1386.   return suID;
  1387. SOM_CATCH_ALL
  1388.   return 0;
  1389. SOM_ENDTRY
  1390. }/* end GetLinkSrcInDraft */
  1391.  
  1392. /*
  1393. *=============================================================================
  1394. * DraftMoved
  1395. * Called by the Docshell when a draft is moved.
  1396. *<0> Validate input variables.
  1397. *<1> Call the Availability Server's DocMoved, passing it both
  1398. *    the new and the old document pathnames.
  1399. *<2> Update instance variable to new pathname and save it to storage.
  1400. *=============================================================================
  1401. */
  1402. SOM_Scope void  SOMLINK DraftMoved(IODLinkService *somSelf, Environment *ev,
  1403.                 ODDraft* draft,
  1404.                 IODFileName oldPathName,
  1405.                 IODFileName newPathName)
  1406. {
  1407.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1408.   IODLinkServiceMethodDebug("IODLinkService","DraftMoved");
  1409.  
  1410.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1411.  
  1412. SOM_TRY
  1413.   //---<0>
  1414.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1415.   ASSERT(oldPathName != (IODFileName)kODNULL, kODErrInvalidDocPathName);
  1416.   ASSERT(newPathName != (IODFileName)kODNULL, kODErrInvalidDocPathName);
  1417.   //---<1>
  1418.   _fAvlSvr->DocMoved(ev,
  1419.                      _fDocumentID,
  1420.                      oldPathName,
  1421.                      newPathName);
  1422.   if (ODGetSOMException(ev) != kODNoError)
  1423.   {
  1424.     return;
  1425.   }
  1426.   //---<2>
  1427.   delete _fDocPathName;
  1428.   _fDocPathName = ODISOStrFromCStr(newPathName);
  1429.   ODStorageUnit* suDraftProperties = draft->AcquireDraftProperties(ev);
  1430.   ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1431.   SetISOStrProp(ev,
  1432.                 suDraftProperties,
  1433.                 kODPropDocumentPathName,
  1434.                 _fDocPathName);
  1435. SOM_CATCH_ALL
  1436.   return;
  1437. SOM_ENDTRY
  1438. } /* end DraftMoved */
  1439. /*
  1440. *=============================================================================
  1441. * DraftClosing
  1442. * Called by the Docshell when a draft opened with DraftOpened
  1443. * is closed.
  1444. * Notifies the AS that each LinkSource is closed.
  1445. * <0> Validate input variables.
  1446. * <1> For each LinkID entry in the LinkSrcInfos table:
  1447. * <2> If the link is unsaved call the AS to remove it.
  1448. * <3>   If the link is opened:
  1449. * <4>   Get its Auxilary State.
  1450. * <5>   Call the Availability Server: this link is closed
  1451. * <6>   Clean up the entry in the LinkSrcInfos table.
  1452. * <7> Delete and nullify the LinkSrcInfos which has been emptied out.
  1453. *     (This is done now to save iterating the hash table at cleanup )
  1454. * <7.1> If availability server contacted, ask AvailServer to close document.
  1455. * <8> Delete and nullify the LinkTrgtInfos which has been emptied out.
  1456. *     (This is done now to save iterating the hash table at cleanup )
  1457. * <9> Clean up the LinkService Properties
  1458. *     instance variables.
  1459. ****NOTICE**** find out what to do if LinkSrc is locked.
  1460. *=============================================================================
  1461. */
  1462. SOM_Scope void
  1463. SOMLINK DraftClosing(IODLinkService *somSelf,
  1464.                      Environment *ev,
  1465.                      ODDraft* draft)
  1466. {
  1467.     IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1468.     IODLinkServiceMethodDebug("IODLinkService","DraftClosing");
  1469.  
  1470.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1471.  
  1472. SOM_TRY
  1473.     //---<0>
  1474.     ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1475.  
  1476.     // Clean up link service's data if the draft is
  1477.     // writeable only. 27463
  1478.  
  1479.     if (!(draft->GetPermissions(ev) > kODDPSharedWrite)) {
  1480.       return;
  1481.     }
  1482.  
  1483.     // If a draft from the draft history is deleted, DraftClosing is
  1484.     // called. However, we should not do any cleanups as the
  1485.     // current active draft (_fDraft) is still valid. So the
  1486.     // check below will protect us from unnecessary cleanups.      
  1487.     // 27463 
  1488.  
  1489.     if (draft !=_fDraft) 
  1490.        return;
  1491.  
  1492.     if (!_fLinkSrcInfos) return;                      // 25006
  1493.     OpenHashTableIterator iter(_fLinkSrcInfos);
  1494.     ODLinkID linkID;
  1495.     LinkSrcInfo *linkSrcInfo = kODNULL;
  1496.     //---<1>
  1497.     for (iter.First(&linkID, &linkSrcInfo);
  1498.          iter.IsNotComplete();
  1499.          iter.Next(&linkID, &linkSrcInfo))
  1500.     {
  1501.       //---<2>
  1502.       // If there are links, then _fAvlSvr is non-null
  1503.       if (!linkSrcInfo->isSaved)
  1504.       {
  1505.       TRY
  1506.         _fAvlSvr-> RemoveLink(ev,
  1507.                               linkID);
  1508.       CATCH_ALL
  1509.       ENDTRY
  1510.       }
  1511.       //---<3>
  1512.       else if (linkSrcInfo->isOpened)
  1513.       {
  1514.         //---<4>
  1515.         IODAuxiliaryState *auxState = new IODAuxiliaryState;
  1516.         (linkSrcInfo->linkSrc)->GetAuxState(ev, &auxState);
  1517.  
  1518.         //---<5>
  1519.       TRY
  1520.         _fAvlSvr-> LinkClosed(ev,
  1521.                               linkID,
  1522.                               auxState);
  1523.       CATCH_ALL
  1524.       ENDTRY
  1525.         ODDisposePtr(auxState->remoteLinkInfos._buffer);
  1526.         delete auxState;
  1527.  
  1528.  
  1529.          //--<6>
  1530.          (linkSrcInfo->linkSrc)->Release(ev); /* once for linkservice */
  1531.          (linkSrcInfo->linkSrc)->Release(ev); /* once more for avs */
  1532.       }
  1533.     delete linkSrcInfo;
  1534.     }
  1535.     //---<7>
  1536.     delete _fLinkSrcInfos;
  1537.     _fLinkSrcInfos = (OpenHashTable*)kODNULL;
  1538.  
  1539.     //---<7.1>
  1540.     if (_fAvlSvr != kODNULL) {
  1541.       _fAvlSvr->DocClosed(ev, _fDocumentID);
  1542.      }
  1543.  
  1544.     //---<8>
  1545.     ODLinkConnectionID id;
  1546.     LinkTrgtInfo*   linkTrgtInfo;
  1547.     OpenHashTableIterator trgtIter(_fLinkTrgtInfos);
  1548.     for (trgtIter.First(&id, &linkTrgtInfo);
  1549.          trgtIter.IsNotComplete();
  1550.          trgtIter.Next(&id, &linkTrgtInfo))
  1551.     {
  1552.       delete linkTrgtInfo;
  1553.     }
  1554.     delete _fLinkTrgtInfos;
  1555.     _fLinkTrgtInfos = kODNULL;
  1556.  
  1557.     //---<9>
  1558.     somSelf->CleanupLinkServiceProperties(ev);
  1559. SOM_CATCH_ALL
  1560.   return;
  1561. SOM_ENDTRY
  1562. } /* end DraftClosing */
  1563.  
  1564.  
  1565. /*
  1566. *=============================================================================
  1567. * DraftSaving:
  1568.       // Called by the Docshell/Draft BEFORE a draft is saved.
  1569.       // The LinkService will externalize its properties as
  1570.       // well as the LinkSrcInfos hash table into the draft properties.
  1571.       // The LinkService will go over LinkSrcInfos hash table
  1572.       // and set the saved bit on each entry to true (in order
  1573.       // to keep track of which linksources have never been saved).
  1574. * <-1> Ignore if given draft is not opened.
  1575. * <0> Validate input variables.
  1576. * <1> Get hold of the draft properties storage unit to externalize the
  1577. *     Link Service properties.
  1578. * <3> Externalize the Document Path Name property.
  1579. * <4> If the AS was contacted, externalize the Availability Server Name property
  1580. *     and the DocumentID property, else set DocumentID to 0.
  1581. * <5> Externalize the Link Source Table.
  1582. * <6> Externalize the Link Target Table.
  1583. * <7> Iterate over the Link Source Table and set the isSaved field
  1584. *     in each entry to true.
  1585. *=============================================================================
  1586. */
  1587. SOM_Scope void
  1588. SOMLINK DraftSaving(IODLinkService *somSelf,
  1589.                    Environment *ev,
  1590.                    ODDraft* draft)
  1591. {
  1592.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1593.   IODLinkServiceMethodDebug("IODLinkService","DraftSaving");
  1594.  
  1595.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1596.  
  1597. SOM_TRY
  1598.   //---<-1>
  1599.   if (draft != _fDraft) return;
  1600.  
  1601.   //---<0>
  1602.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1603.   //---<1>
  1604.   ODStorageUnit* suDraftProperties = draft->AcquireDraftProperties(ev);
  1605.   ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1606.   //---<3>
  1607.   SetISOStrProp(ev,
  1608.                 suDraftProperties,
  1609.                 kODPropDocumentPathName,
  1610.                 _fDocPathName);
  1611.   //---<4>
  1612.   if (_fAvlSvr != kODNULL) {
  1613.     SetISOStrProp(ev,
  1614.                 suDraftProperties,
  1615.                 kODPropASName,
  1616.                 _fASName);
  1617.     SetULongProp(ev,
  1618.                  suDraftProperties,
  1619.                  kODPropDocumentID,
  1620.                  _fDocumentID);
  1621.     }
  1622.   else {
  1623.     ODULong Tmp = 0;
  1624.     SetULongProp(ev,
  1625.                  suDraftProperties,
  1626.                  kODPropDocumentID,
  1627.                  Tmp);
  1628.     }
  1629.  
  1630.  
  1631.   //---<5>
  1632.   SetLinkSrcInfosProp(ev,
  1633.                       suDraftProperties,
  1634.                       kODPropLinkSourceInfos,
  1635.                       kODHashTable,
  1636.                       *_fLinkSrcInfos);
  1637.   //---<6>
  1638.   SetLinkTrgtInfosProp(ev,
  1639.                       suDraftProperties,
  1640.                       kODPropLinkTargetInfos,
  1641.                       kODHashTable,
  1642.                       *_fLinkTrgtInfos);
  1643.   //---<7>
  1644.   OpenHashTableIterator iter(_fLinkSrcInfos);
  1645.   ODLinkID linkID;
  1646.   LinkSrcInfo *linkSrcInfo = kODNULL;
  1647.   for (iter.First(&linkID, &linkSrcInfo);
  1648.        iter.IsNotComplete();
  1649.        iter.Next(&linkID, &linkSrcInfo))
  1650.   {
  1651.     linkSrcInfo->isSaved = kODTrue;
  1652.   }
  1653. SOM_CATCH_ALL
  1654.   return;
  1655. SOM_ENDTRY
  1656. } /* end DraftSaving */
  1657.  
  1658. /*
  1659. *=============================================================================
  1660. * UnsavedExportedLinks:
  1661.       // Allows LinkSource to discover whether there are cross-document
  1662.       // links which would be lost if the user fails to save now.
  1663. * <0> Validate input variables.
  1664. * <1> If the _fExistsUnsavedLink instance data fields is set to true,
  1665. *     it means there is one or more unsaved links - return true.
  1666. * <2> If the _fExistsUnsavedLink instance data fields is set to false,
  1667. *     return false.
  1668. *=============================================================================
  1669. */
  1670. SOM_Scope ODBoolean
  1671. SOMLINK UnsavedExportedLinks(IODLinkService *somSelf,
  1672.                              Environment *ev,
  1673.                              ODDraft* draft)
  1674. {
  1675.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1676.   IODLinkServiceMethodDebug("IODLinkService","UnsavedExportedLinks");
  1677.  
  1678.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1679.  
  1680. SOM_TRY
  1681.   //---<0>
  1682.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1683.   //---<1>
  1684.   if (_fExistsUnsavedLink)
  1685.   {
  1686.     return kODTrue;
  1687.   }
  1688.   //---<2>
  1689.   else
  1690.   {
  1691.    return kODFalse;
  1692.   }
  1693. SOM_CATCH_ALL
  1694.   return kODFalse;
  1695. SOM_ENDTRY
  1696. }
  1697.  
  1698.  
  1699. /*
  1700. *=============================================================================
  1701. * RegisterLinkSource:
  1702.      // Called by draft when a new link source is being
  1703.      // created.  The draft must have previously issued DraftOpened.
  1704.      // The LinkService will remember the linkSource and
  1705.      // suid; it will register the linkSource with the AS.
  1706. * <0> Validate input variables.
  1707. * <1> Get hold of the Draft Properties storage unit.
  1708. * <2> Create a LinkSrcInfo entry, and set its linkSrc pointer field from input.
  1709. * <2bis> If availability server not contacted yet, contact it now.
  1710. * <3> Register the Link Source with the Availability Server and get back
  1711. *     a LinkID. Set the LinkID field of the LinkSrcInfo entry to this LinkID.
  1712. * <4> Set the isOpened field in the entry to true.
  1713. * <5> Set the ExistsUnsavedLink field property to true.
  1714. * <6> Get a Storage Unit Reference to the Link Source's suid which was passed
  1715. *     in as a parameter, and set the entry's suref field to it.
  1716. * <7> Get a Storage Unit Reference to the storage unit of the part which has
  1717. *     been passed in as a parameter, and set the entry's partSURef field to it.
  1718. * <8> Add the entry to the LinkSrcInfos HashTable.
  1719. * <8bis> Copy the ASName
  1720. * <9> If linkSrc registration failed<tested in 3> - null linkid was returned.
  1721. *     Release linkSrcInfo
  1722. *     Raise exception
  1723. *     Return 0 as linkID
  1724. *=============================================================================
  1725. */
  1726. SOM_Scope ODLinkID
  1727. SOMLINK RegisterLinkSource(IODLinkService *somSelf,
  1728.                            Environment *ev,
  1729.                            ODDraft* draft,
  1730.                            ODStorageUnitID suid,
  1731.                            ODLinkSource* linkSource,
  1732.                            ODPart* part,
  1733.                            ODISOStr* ASName)
  1734. {
  1735.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1736.   IODLinkServiceMethodDebug("IODLinkService","RegisterLinkSource");
  1737.  
  1738.   if (ev->_major) ODSetSOMException(ev, kODNoError);
  1739.   LinkSrcInfo* linkSrcInfo = kODNULL;
  1740.  
  1741. SOM_TRY
  1742.   //---<0>
  1743.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1744.   ASSERT(suid != (ODStorageUnitID)kODNULL, kODErrInvalidStorageUnit);
  1745.   ASSERT(linkSource != (ODLinkSource*)kODNULL, kODErrInvalidLinkSource);
  1746.   //---<1>
  1747.   ODStorageUnit* suDraftProperties = draft->AcquireDraftProperties(ev);
  1748.   ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1749.   //---<2>
  1750.   linkSrcInfo = new LinkSrcInfo;
  1751.   linkSrcInfo->linkSrc     = (IODLinkSource*)linkSource;
  1752.   linkSrcInfo->linkSrc->Acquire(ev);
  1753.   linkSrcInfo->linkID      = kODNULL;
  1754.  
  1755.   //--- <2bis>
  1756.   ContactAvailabilityServer(ev, somSelf, somThis, kODNULL);
  1757.  
  1758.     //---<3>
  1759.     linkSrcInfo->linkID      = _fAvlSvr->RegisterLink(ev,
  1760.                                                       _fDocumentID,
  1761.                                                       (IODLinkTargetToLinkSource*)linkSource);
  1762.  
  1763.     THROW_IF_NULL((void *)(linkSrcInfo->linkID));
  1764.     linkSource->Acquire(ev); /* record that avs retains a ptr to linkSource */
  1765.     //---<4>
  1766.     linkSrcInfo->isOpened    = kODTrue;
  1767.     //---<5>
  1768.     linkSrcInfo->isSaved  = kODFalse;
  1769.     _fExistsUnsavedLink = kODTrue;
  1770.     //---<6>
  1771.  
  1772.     ODSUForceFocus(ev, suDraftProperties,kODPropLinkSourceInfos, kODHashTable);
  1773.     suDraftProperties->GetWeakStorageUnitRef(ev,
  1774.                                              suid,
  1775.                                              linkSrcInfo->linkSrcSURef);
  1776.     //---<7>
  1777.     if (part != (ODPart*)kODNULL)
  1778.     {
  1779.      ODStorageUnit*  partSU   = part->GetStorageUnit(ev);
  1780.      ODStorageUnitID srcPartSUID = partSU->GetID(ev);
  1781.      ODSUForceFocus(ev, suDraftProperties,kODPropLinkSourceInfos, kODHashTable);
  1782.      suDraftProperties->GetWeakStorageUnitRef(ev,
  1783.                                              srcPartSUID,
  1784.                                              linkSrcInfo->srcPartSURef);
  1785.     }
  1786.     else
  1787.     {
  1788. //      linkSrcInfo->srcPartSURef = (ODStorageUnitRef)kODNULL;
  1789.     }
  1790.     //---<8>
  1791.     _fLinkSrcInfos->ReplaceEntry(&(linkSrcInfo->linkID), &linkSrcInfo);
  1792.  
  1793.     //---<8bis>
  1794.     *ASName = ODISOStrFromCStr(_fASName);
  1795.     return(linkSrcInfo->linkID);
  1796. SOM_CATCH_ALL
  1797.     //---<9>
  1798.     delete linkSrcInfo;
  1799.     return 0;
  1800. SOM_ENDTRY
  1801. }
  1802.  
  1803. /*
  1804. *=============================================================================
  1805. *  OpenLinkSource:
  1806.      // Called by the draft when an existing link source is being
  1807.      // internalized and the draft is read/write.  The draft must
  1808.      // have previously issued DraftOpened.
  1809.      // The LinkService will retrieve auxState and isLocked
  1810.      // by calling the Availability server's OpenLinkSource;
  1811.      //it will remember the location of the linkSource.
  1812.  * <0> Validate input variables.
  1813.  * <1bis> Contact the availability server if haven't yet done so.
  1814.  * <1> Get the LinkSrcInfos Table entry corresponding to the LinkID which
  1815.  *     is passed in as a parameter.If not found, or
  1816.  *     if the linkid corresponds to a different SU, then we
  1817.  *     assume the SU passed to OpenLinkSource is a copy, and do
  1818.  *     a register, returning the new linkid. Proceed if not a copy.
  1819.  * <1'> If the sourcepart SU ref is 0, then this is a "deleted"
  1820.  *     link source (i.e. it was externalized after the user did
  1821.  *     a SetSourcePart to null).  Raise an exception.
  1822.  * <2> Call the Availability Server's LinkOpened method passing in the
  1823.  *     LinkID and LinkSource pointer.
  1824.  *     We get back the auxiliary state and the isLocked info.
  1825.  * <3> If LinkOpened returned a LinkAlreadyOpen exception - return
  1826.  * <4> If LinkOpened returned any other exception - throw a LinkOpenedFailed
  1827.  *     exception.
  1828.  * <5> Set the entry's LinkSrc field to the linkSource passed in.
  1829.  * <6> Set the entry's isOpened field to true.
  1830.  * <7> Return a null ODLinkID, and the current ASName
  1831.  * <8> If a LinkOpened failure is caught<tested in 4> -
  1832.  *     Remove the linkSrcInfo entry
  1833.  *     Raise exception and return
  1834. *=============================================================================
  1835. */
  1836. SOM_Scope ODLinkID
  1837. SOMLINK OpenLinkSource(IODLinkService *somSelf,
  1838.                        Environment *ev,
  1839.                        ODDraft* draft,
  1840.                        ODStorageUnitID suid, /* for checking only */
  1841.                        ODLinkSource* linkSource,
  1842.                        ODLinkID linkid,
  1843.                        IODAuxiliaryState** auxState,
  1844.                        ODBoolean* isLocked,
  1845.                        ODISOStr* ASName)
  1846. {
  1847.  
  1848.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1849.   IODLinkServiceMethodDebug("IODLinkService","OpenLinkSource");
  1850.  
  1851.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1852.   LinkSrcInfo* linkSrcInfo;
  1853.  
  1854. SOM_TRY
  1855.   //---<0>
  1856.   ASSERT(draft != (ODDraft*)kODNULL, kODErrInvalidDraft);
  1857.   ASSERT(linkSource != (ODLinkSource*)kODNULL, kODErrInvalidLinkSource);
  1858.   ASSERT(linkid != (ODLinkID)kODNULL, kODErrInvalidLinkID);
  1859.  
  1860.   ODBoolean copy; /* true if this linksource is a copy */
  1861.  
  1862.   //---<1bis>
  1863.   ContactAvailabilityServer(ev, somSelf, somThis, kODNULL);
  1864.  
  1865.   //---<1>
  1866.   if (_fLinkSrcInfos->GetValue(&linkid, &linkSrcInfo) != kODTrue)
  1867.   {
  1868.      copy = kODTrue;
  1869.   } else {
  1870.     ODStorageUnit* suDraftProperties = _fDraft->AcquireDraftProperties(ev);
  1871.     ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1872.     ODSUForceFocus(ev, suDraftProperties, kODPropLinkSourceInfos, kODHashTable);
  1873.     if (suDraftProperties->IsValidStorageUnitRef(ev, linkSrcInfo->linkSrcSURef))
  1874.       {
  1875.         copy = (suid != suDraftProperties->GetIDFromStorageUnitRef(ev, linkSrcInfo->linkSrcSURef));
  1876.       } else {
  1877.         copy = kODTrue;
  1878.       };
  1879.   }
  1880.   if (copy) {
  1881.     *isLocked = kODFalse;
  1882.     *auxState = kODNULL;
  1883.     return somSelf->RegisterLinkSource(ev, draft, suid, linkSource,kODNULL, ASName);
  1884.     }
  1885. SOM_CATCH_ALL
  1886.   return 0;
  1887. SOM_ENDTRY
  1888.  
  1889.   //---<1'>
  1890.   if ((linkSrcInfo->srcPartSURef[0] == 0) &&
  1891.       (linkSrcInfo->srcPartSURef[1] == 0) &&
  1892.       (linkSrcInfo->srcPartSURef[2] == 0) &&
  1893.       (linkSrcInfo->srcPartSURef[3] == 0))
  1894.     {
  1895.       ODSetSOMException(ev,  kODErrInvalidStorageUnit);
  1896.       return 0;
  1897.     }
  1898.  
  1899.   //---<2>
  1900. SOM_TRY
  1901.   _fAvlSvr->LinkOpened(ev,
  1902.                        linkid,
  1903.                        (IODLinkTargetToLinkSource*)linkSource,
  1904.                        auxState,
  1905.                        isLocked);
  1906. SOM_CATCH_ALL
  1907.   if (ODGetSOMException(ev) == kODErrInvalidLinkID)
  1908.   {
  1909.     _fLinkSrcInfos->RemoveEntry(&linkid);
  1910.     return 0;
  1911.   }
  1912.   //---<4>
  1913.   ODSetSOMException(ev, kODErrLinkOpenedFailed);
  1914.   return 0;
  1915. SOM_ENDTRY
  1916.    //---<5>
  1917.   linkSrcInfo->linkSrc     = (IODLinkSource*)linkSource;
  1918.   linkSrcInfo->linkSrc->Acquire(ev); /* avs retains a ptr to ls */
  1919.   linkSrcInfo->linkSrc->Acquire(ev); /* linksrvc retains a ptr to ls */
  1920.   //---<6>
  1921.   linkSrcInfo->isOpened    = kODTrue;
  1922.   //---<7>
  1923.   *ASName = ODISOStrFromCStr(_fASName);
  1924.   return(0);
  1925. }
  1926.  
  1927. /*
  1928. *=============================================================================
  1929. * InternalizeLinkSource:
  1930.      // Called by the Availability Server to internalize a Link
  1931.      // Source frome storage.
  1932.      // If the LS is already opened - will return a pointer to it.
  1933.      // Otherwise, queries the LinkSrcInfos Hashtable for this
  1934.      // Link Source's storage unit reference using the LinkId as key,
  1935.      // Gets the storage unit ID from the storage unit reference,
  1936.      // Calls draft to get back a linksource pointer, updates the
  1937.      // table and returns the pointer to the Link Source.
  1938. * <0> Validate input variables.
  1939. * <1> Get the LinkSrcInfos Table entry corresponding to the LinkID which
  1940. *     is passed in as a parameter.
  1941. * <2> If the LinkSrc is already opened - return a pointer to it.
  1942. * <3> The LinkSrc is not yet opened:
  1943. * <4> Get the storage unit ID from the storage unit reference in the
  1944. *     LinkSrcInfo entry.
  1945. * <5> Call the draft to get the pointer to the LinkSource corresponding
  1946. *     to the storage unit id. Save it in the LinkSrcInfo entry.
  1947. * <6> Set the isOpened field in the LinkSrcInfo entry to true.
  1948. * <7> Increment refcount and Return a pointer to the LinkSrc.
  1949. *=============================================================================
  1950. */
  1951. SOM_Scope ODLinkSource*
  1952. SOMLINK InternalizeLinkSource(IODLinkService *somSelf,
  1953.                               Environment *ev,
  1954.                               ODLinkID linkid,
  1955.                               IODAuxiliaryState* auxState)
  1956. {
  1957.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  1958.   IODLinkServiceMethodDebug("IODLinkService","InternalizeLinkSource");
  1959.  
  1960.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  1961.  
  1962. SOM_TRY
  1963.   //---<0>
  1964.   ASSERT(linkid != (ODLinkID)kODNULL, kODErrInvalidLinkID);
  1965.   ASSERT(auxState != (IODAuxiliaryState*)kODNULL, kODErrInvalidAuxState);
  1966.   LinkSrcInfo *linkSrcInfo;
  1967.   //---<1>
  1968.   if (_fLinkSrcInfos->GetValue(&linkid, &linkSrcInfo) != kODTrue)
  1969.   {
  1970.    ODSetSOMException(ev, kODErrLinkIDNotInDoc);
  1971.    return (ODLinkSource*)kODNULL ;
  1972.   }
  1973.   //---<2>
  1974.   if (linkSrcInfo->isOpened)
  1975.   {
  1976.     return(linkSrcInfo->linkSrc);
  1977.   }
  1978.   //---<3>
  1979.   else /* LinkSrcInfo entry not in opened state */
  1980.   {
  1981.   SOM_TRY
  1982.     //---<4>
  1983.     ODStorageUnit* suDraftProperties = _fDraft->AcquireDraftProperties(ev);
  1984.     ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  1985.       ODStorageUnitID suID;
  1986.       if (suDraftProperties->IsValidStorageUnitRef(ev, linkSrcInfo->linkSrcSURef))
  1987.       {
  1988.        suID = suDraftProperties->GetIDFromStorageUnitRef(ev, linkSrcInfo->linkSrcSURef);
  1989.       }
  1990.       else
  1991.       {
  1992.         THROW(kODErrInvalidLinkSource);
  1993.       }
  1994.       //---<5>
  1995.       linkSrcInfo->linkSrc = (IODLinkSource*)
  1996.                              ((CMDraft*)_fDraft)->GetLinkSrcForAvlSvr(ev,
  1997.                                                            suID,
  1998.                                                            auxState);
  1999.       ASSERT(linkSrcInfo->linkSrc != (ODLinkSource*)kODNULL, kODErrInvalidLinkSource);
  2000.  
  2001.       linkSrcInfo->linkSrc->Acquire(ev);
  2002.  
  2003.  
  2004.       //---<6>
  2005.       linkSrcInfo->isOpened = kODTrue;
  2006.       //---<7>
  2007.       linkSrcInfo->linkSrc->Acquire(ev);
  2008.       return(linkSrcInfo->linkSrc);
  2009.  
  2010.   SOM_CATCH_ALL
  2011.       //---<7>
  2012.       _fLinkSrcInfos->RemoveEntry(&linkid);
  2013.       return kODNULL;
  2014.   SOM_ENDTRY
  2015.   } /* end if LinkSrcInfo entry not in opened state */
  2016. SOM_CATCH_ALL
  2017.   return kODNULL;
  2018. SOM_ENDTRY
  2019. } /* end InternalizeLinkSource */
  2020.  
  2021. /*
  2022. *=============================================================================
  2023.       // EstablishLinkFromTSpec:
  2024.       // Called in LinkSpec::EstablishLink to establish a new link
  2025.       // to the Part with sourcePartSUID.
  2026. * <0> Validate input variables.
  2027. * <1> Call the draft to get a pointer to the part from the part's suid.
  2028. * <2> Call CreateLink on the part. It will return a Link Source
  2029. * <3> Get the linkid and ASName of that link source
  2030. * <4> Add the established Link from the Link Spec to the LinkSource's table.
  2031. * <5> Set the LinkSrc pointer return value to the Link Target.
  2032. *=============================================================================
  2033. */
  2034. SOM_Scope void
  2035. SOMLINK EstablishLinkFromTSpec(IODLinkService *somSelf,
  2036.                                Environment *ev,
  2037.                                ODULong pid,
  2038.                                ODStorageUnitID srcPartSUID,
  2039.                                ODByteArray* data,
  2040.                                ODLinkConnectionData* trgtPartDesc,
  2041.                                IODLinkTarget* linkTrgt,
  2042.                                ODLinkID* linkid,
  2043.                                IODLinkTargetToLinkSource** linkSrc,
  2044.                                ODLinkConnectionID* trgtID,
  2045.                                ODBoolean* isLocal,
  2046.                                ODBoolean* trackTrgt,
  2047.                                ODISOStr*  ASName)
  2048. {
  2049.     IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2050.     IODLinkServiceMethodDebug("IODLinkService","EstablishLinkFromTSpec");
  2051.  
  2052.     ODStorageUnitID sourceSUID; /* not needed because linksrc is returned */
  2053.     if (ev->_major) ODSetSOMException(ev, kODNoError);
  2054.  
  2055. SOM_TRY
  2056.   //---<0>
  2057.     ASSERT(srcPartSUID != (ODStorageUnitID)kODNULL, kODErrInvalidStorageUnit);
  2058.     ASSERT(_fDraftOpened == kODTrue, kODErrDocNotOpened);
  2059.  
  2060.   //---<1>
  2061.     ODPart *part = _fDraft->AcquirePart(ev, srcPartSUID);
  2062.  
  2063.   //---<2>
  2064.     IODLinkSource *linkSource = (IODLinkSource*)part->CreateLink(ev, data);
  2065.  
  2066.   //---<3>
  2067.     ASSERT(linkSource != (ODLinkSource*)kODNULL, kODErrInvalidLinkSource);
  2068.  
  2069.     linkSource->GetPersistentLinkInfo(ev, linkid, ASName);
  2070.  
  2071.   //---<4>
  2072.     linkSource->AddLinkTarget(ev,
  2073.                               *linkid,
  2074.                               pid,
  2075.                               trgtPartDesc,
  2076.                               linkTrgt,
  2077.                               &sourceSUID,
  2078.                               trgtID,
  2079.                               isLocal,
  2080.                               trackTrgt);
  2081.  
  2082.   //---<5>
  2083.     if (*isLocal)
  2084.     {
  2085.       linkSource->Acquire(ev);
  2086.       *linkSrc = (IODLinkTargetToLinkSource*)linkSource;
  2087.     }
  2088.     else
  2089.     {
  2090.       *linkSrc = (IODLinkTargetToLinkSource*)_fAvlSvr;
  2091.     }
  2092. SOM_CATCH_ALL
  2093.   return;
  2094. SOM_ENDTRY
  2095. }
  2096.  
  2097. /*
  2098. *=============================================================================
  2099.       // RegisterLinkTarget:
  2100.       // Called in LinkSpec::EstablishLink to register a new target
  2101. * <1> create a linktrgtinfo entry for the established Link.
  2102. * <2> Add the linktrgtinfo to the LinkTarget's table.
  2103. *=============================================================================
  2104. */
  2105. SOM_Scope void  SOMLINK RegisterLinkTarget(IODLinkService *somSelf, Environment *ev,
  2106.                 ODStorageUnitID trgtPartSUID,
  2107.                 IODLinkTarget* linkTrgt)
  2108. {
  2109.     IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2110.     IODLinkServiceMethodDebug("IODLinkService","RegisterLinkTarget");
  2111.  
  2112. SOM_TRY
  2113.    //---<1>
  2114.    LinkTrgtInfo* linkTrgtInfo = new LinkTrgtInfo;
  2115.    THROW_IF_NULL((void *)linkTrgtInfo);
  2116.    linkTrgtInfo->trgtID         = ++_fTargetIDCounter;
  2117.    linkTrgtInfo->linkTrgt       = linkTrgt;
  2118.    ODStorageUnit* linkTrgtSU    = linkTrgt->GetStorageUnit(ev);
  2119.    ODStorageUnitID linkTrgtSUID = linkTrgtSU->GetID(ev);
  2120.    ODStorageUnit* suDraftProperties = _fDraft->AcquireDraftProperties(ev);
  2121.    ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  2122.    if (linkTrgtSUID != (ODStorageUnitID)kODNULL)
  2123.    {
  2124.      ODSUForceFocus(ev, suDraftProperties,kODPropLinkTargetInfos, kODHashTable);
  2125.      suDraftProperties->GetWeakStorageUnitRef(ev,
  2126.                                               linkTrgtSUID,
  2127.                                               linkTrgtInfo->linkTrgtSURef);
  2128.    }
  2129.    else
  2130.    {
  2131. //      linkTrgtInfo->linkTrgtSURef = (ODStorageUnitRef)kODNULL;
  2132.    }
  2133.    if (trgtPartSUID != (ODStorageUnitID)kODNULL)
  2134.    {
  2135.     ODSUForceFocus(ev, suDraftProperties,kODPropLinkTargetInfos, kODHashTable);
  2136.     suDraftProperties->GetWeakStorageUnitRef(ev,
  2137.                                              trgtPartSUID,
  2138.                                              linkTrgtInfo->trgtPartSURef);
  2139.    }
  2140.    else
  2141.    {
  2142. //      linkTrgtInfo->srcPartSURef = (ODStorageUnitRef)kODNULL;
  2143.    }
  2144.    //---<2>
  2145.    _fLinkTrgtInfos->ReplaceEntry(&(linkTrgtInfo->trgtID), &linkTrgtInfo);
  2146. SOM_CATCH_ALL
  2147.   return;
  2148. SOM_ENDTRY
  2149. }
  2150.  
  2151. /*
  2152.  *=============================================================================
  2153.  * Called by Draft to obtain the list of LinkSources belonging to a
  2154.  *   given part
  2155.  *
  2156.  * <1>  Get the Storage Unit Reference for the part.
  2157.  * <2>  Acquire fMutex before accessing fLinkInfos.
  2158.  * <3>  Retrieve all linkSource SUID's from fLinkInfos which have
  2159.  *      a part storage unit ref similar to given part,
  2160.  *      and add them to linkSourceIter.
  2161.  *      Release fMutex and return.
  2162.  * <4>  An exception is caught.
  2163.  *      Release fMutex.
  2164.  *      Cleanup linkSrcIter.
  2165.  *      Set SOM exception and return.
  2166.  *=============================================================================
  2167.  */
  2168. SOM_Scope void  SOMLINK GetLinkSourcesForPart(IODLinkService *somSelf, Environment *ev,
  2169.                 ODPart* part,
  2170.                 CMLinkSourceIterator* linkSourceIter)
  2171. {
  2172.     IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2173.     IODLinkServiceMethodDebug("IODLinkService","EstablishLinkFromTSpec");
  2174.  
  2175. SOM_TRY
  2176.     ODStorageUnit* suDraftProperties = _fDraft->AcquireDraftProperties(ev);
  2177.     ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  2178.  
  2179.     //---<1>
  2180.     ODStorageUnit*  partSU   = part->GetStorageUnit(ev);
  2181.     ODStorageUnitID partSUID = partSU->GetID(ev);
  2182.  
  2183.      //---<2>
  2184.     _fMutex->Acquire(ev);
  2185.  
  2186.       //---<3>
  2187.       ODLinkID linkID;
  2188.       ODStorageUnitID  linkSrcSUID;
  2189.       ODStorageUnitID  thisPartSUID;
  2190.       LinkSrcInfo *linkSrcInfo = kODNULL;
  2191.       ODSUForceFocus(ev, suDraftProperties,kODPropLinkSourceInfos, kODHashTable);
  2192.       if (_fLinkSrcInfos != (OpenHashTable*)kODNULL)
  2193.       {
  2194.        OpenHashTableIterator iter(_fLinkSrcInfos);
  2195.        for (iter.First(&linkID, &linkSrcInfo);
  2196.             iter.IsNotComplete();
  2197.             iter.Next(&linkID, &linkSrcInfo))
  2198.         {
  2199.          if (suDraftProperties->IsValidStorageUnitRef(ev, linkSrcInfo->srcPartSURef))
  2200.          {
  2201.           thisPartSUID = suDraftProperties->GetIDFromStorageUnitRef(ev, linkSrcInfo->srcPartSURef);
  2202.          }
  2203.          else
  2204.          {
  2205.            thisPartSUID = (ODStorageUnitID)kODNULL;
  2206.          }
  2207.          if (thisPartSUID == partSUID)
  2208.          {
  2209.            if (suDraftProperties->IsValidStorageUnitRef(ev, linkSrcInfo->linkSrcSURef))
  2210.            {
  2211.             linkSrcSUID = suDraftProperties->GetIDFromStorageUnitRef(ev, linkSrcInfo->linkSrcSURef);
  2212.            }
  2213.            else
  2214.            {
  2215.              THROW(kODErrInvalidLinkSource);
  2216.            }
  2217. // #ifdef OS2LinkChanges
  2218.           linkSourceIter->Add(ev, linkSrcSUID);
  2219. // #endif // OS2LinkChanges
  2220.          }
  2221.         }
  2222.       }
  2223.       _fMutex->Release(ev);
  2224.  
  2225. SOM_CATCH_ALL
  2226.  
  2227.       ODError exception = ODGetSOMException(ev);
  2228.  
  2229.       //---<4>
  2230.     TRY
  2231.       _fMutex->Release(ev);
  2232.     CATCH_ALL
  2233.     ENDTRY
  2234.  
  2235.  
  2236.       if (linkSourceIter != kODNULL)
  2237.       {
  2238.         delete linkSourceIter;
  2239.       }
  2240.  
  2241.       ODSetSOMException(ev, exception);
  2242. SOM_ENDTRY
  2243. }
  2244.  
  2245. /*
  2246.  *=============================================================================
  2247.  * Called by Draft to obtain the list of LinkTargets belonging to a
  2248.  *   given part
  2249.  *
  2250.  * <1>  Get the Storage Unit Reference for the part.
  2251.  * <2>  Acquire fMutex before accessing fLinkTargetInfos.
  2252.  * <3>  Retrieve all linkTarget SUID's from fLinkTargetInfos which have
  2253.  *      a part storage unit ref similar to given part,
  2254.  *      and add them to linkTargetIter.
  2255.  *      Release fMutex and return.
  2256.  * <4>  An exception is caught.
  2257.  *      Release fMutex.
  2258.  *      Cleanup linkTargetIter.
  2259.  *      Set SOM exception and return.
  2260.  *=============================================================================
  2261.  */
  2262. SOM_Scope void  SOMLINK GetLinkTargetsForPart(IODLinkService *somSelf, Environment *ev,
  2263.                 ODPart* part,
  2264.                 CMLinkIterator* linkTargetIter)
  2265. {
  2266.     IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2267.     IODLinkServiceMethodDebug("IODLinkService","GetLinkTargetsForPart");
  2268.  
  2269. SOM_TRY
  2270.     ODStorageUnit* suDraftProperties = _fDraft->AcquireDraftProperties(ev);
  2271.     ASSERT(suDraftProperties != (ODStorageUnit*)kODNULL, kODErrInvalidStorageUnit);
  2272.  
  2273.     //---<1>
  2274.     ODStorageUnit*  partSU   = part->GetStorageUnit(ev);
  2275.     ODStorageUnitID partSUID = partSU->GetID(ev);
  2276.  
  2277.      //---<2>
  2278.     _fMutex->Acquire(ev);
  2279.     if (ODGetSOMException(ev) != kODNoError)
  2280.     {
  2281.       return;
  2282.     }
  2283.  
  2284.       //---<3>
  2285.       ODID linkID;
  2286.       ODStorageUnitID  linkTrgtSUID;
  2287.       ODStorageUnitID  thisPartSUID;
  2288.       LinkTrgtInfo *linkTrgtInfo = kODNULL;
  2289.       ODSUForceFocus(ev, suDraftProperties,kODPropLinkTargetInfos, kODHashTable);
  2290.       if (_fLinkTrgtInfos != (OpenHashTable*)kODNULL)
  2291.       {
  2292.        OpenHashTableIterator iter(_fLinkTrgtInfos);
  2293.        for (iter.First(&linkID, &linkTrgtInfo);
  2294.             iter.IsNotComplete();
  2295.             iter.Next(&linkID, &linkTrgtInfo))
  2296.         {
  2297.          if (suDraftProperties->IsValidStorageUnitRef(ev, linkTrgtInfo->trgtPartSURef))
  2298.          {
  2299.           thisPartSUID = suDraftProperties->GetIDFromStorageUnitRef(ev, linkTrgtInfo->trgtPartSURef);
  2300.          }
  2301.          else
  2302.          {
  2303.            thisPartSUID = (ODStorageUnitID)kODNULL;
  2304.          }
  2305.          if (thisPartSUID == partSUID)
  2306.          {
  2307.            if (suDraftProperties->IsValidStorageUnitRef(ev, linkTrgtInfo->linkTrgtSURef))
  2308.            {
  2309.             linkTrgtSUID = suDraftProperties->GetIDFromStorageUnitRef(ev, linkTrgtInfo->linkTrgtSURef);
  2310.            }
  2311.            else
  2312.            {
  2313.              THROW(kODErrInvalidLink);
  2314.            }
  2315. // #ifdef OS2LinkChanges
  2316.           linkTargetIter->Add(ev, linkTrgtSUID);
  2317. // #endif // OS2LinkChanges
  2318.          }
  2319.         }
  2320.       }
  2321.       _fMutex->Release(ev);
  2322.  
  2323. SOM_CATCH_ALL
  2324.  
  2325.       ODError exception = ODGetSOMException(ev);
  2326.  
  2327.       //---<4>
  2328.     TRY
  2329.       _fMutex->Release(ev);
  2330.     CATCH_ALL
  2331.     ENDTRY
  2332.  
  2333.  
  2334.       if (linkTargetIter != kODNULL)
  2335.       {
  2336.         delete linkTargetIter;
  2337.       }
  2338.  
  2339.       ODSetSOMException(ev, exception);
  2340. SOM_ENDTRY
  2341. }
  2342.  
  2343. /*
  2344.  *=============================================================================
  2345.  * Called by Linkspec to obtain the Persistent Link Infos
  2346.  *
  2347.  * <1>  Use the draft to Acquire Part
  2348.  * <2>  Call CreateLink using the Data to get a pointer to the Linksrc
  2349.  * <3>  Call GetPersistentLinkInfo to get the LinkId and ASName
  2350.  * <4>  Release the Linksrc pointer
  2351.  *=============================================================================
  2352.  */
  2353. SOM_Scope void  SOMLINK GetPersistentLinkInfoFromTSpec(IODLinkService *somSelf, Environment *ev,
  2354.                 ODStorageUnitID   partSUID,
  2355.                 ODByteArray  *partData,
  2356.                 ODLinkID     *linkID,
  2357.                 ODISOStr     *ASName)
  2358. {
  2359.     IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2360.     IODLinkServiceMethodDebug("IODLinkService","GetPersistentLinkInfoFromTspec");
  2361.  
  2362. SOM_TRY
  2363.     // 1.
  2364.     ODPart* myPart = _fDraft->AcquirePart(ev, partSUID);
  2365.  
  2366.     // 2.
  2367.     IODLinkSource* myLinkSrc = (IODLinkSource*) myPart->CreateLink(ev,partData);
  2368.     ASSERT(myLinkSrc != (ODLinkSource*)kODNULL, kODErrInvalidLinkSource);
  2369.  
  2370.     // 3.
  2371.     myLinkSrc->GetPersistentLinkInfo(ev, linkID,  ASName);
  2372.  
  2373.     // 4.
  2374.     myLinkSrc->Release(ev);
  2375. SOM_CATCH_ALL
  2376.   return;
  2377. SOM_ENDTRY
  2378. }
  2379.  
  2380. /*
  2381. *=============================================================================
  2382.       //somInit
  2383. *=============================================================================
  2384. */
  2385. SOM_Scope void
  2386. SOMLINK somInit(IODLinkService *somSelf)
  2387. {
  2388.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2389.   IODLinkServiceMethodDebug("IODLinkService","InitLinkService");
  2390.   _fDraftOpened  = kODFalse; /* true if a docshell called DraftOpened*/
  2391.   _fDraft        = kODNULL;  /* initialized if DraftOpened   */
  2392.   _fDocumentID   = 0;        /* initialized if DraftOpened   */
  2393.   _fAvlSvr       = kODNULL;  /* initialized if DraftOpened   */
  2394.   _fLinkSrcInfos = kODNULL;  /* a table of LinkSrcInfos
  2395.                                            keyed by LinkId   */
  2396.   _fLinkTrgtInfos = kODNULL; /* a table of LinkTrgtInfos
  2397.                                            keyed by LinkId   */
  2398.   _fDocPathName  = kODNULL;  /* name from which doc was read */
  2399.   _fASName       = kODNULL;  /* name of availability server  */
  2400.   _fExistsUnsavedLink = kODFalse;  /* true if there is one or more */
  2401.   _fMutex = new IODMutex;
  2402.   THROW_IF_NULL((void*)_fMutex);
  2403. }
  2404.  
  2405. /*
  2406. *=============================================================================
  2407.       //somUnInit
  2408. *=============================================================================
  2409. */
  2410. SOM_Scope void
  2411. SOMLINK somUninit(IODLinkService *somSelf)
  2412. {
  2413.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2414.   IODLinkServiceMethodDebug("IODLinkService","UnInitLinkService");
  2415.   somSelf->CleanupLinkServiceProperties(somGetGlobalEnvironment());
  2416.   delete _fMutex;
  2417. }
  2418.  
  2419. SOM_Scope IODFileName
  2420. SOMLINK GetDocName(IODLinkService *somSelf,
  2421.                     Environment *ev)
  2422. {
  2423.   IODLinkServiceData *somThis = IODLinkServiceGetData(somSelf);
  2424.   IODLinkServiceMethodDebug("IODLinkService","GetDocName");
  2425.   return (IODFileName)_fDocPathName;
  2426. }
  2427. #endif
  2428.  
  2429.