project BLF > class BResource > method ApiLinkResource

Description

Method to link a resource.
It is best to give only 1 resource record.
Please provide all possible fields except the ID's.


Parameters


tInputResourceinputtemp-tableInput data for the creation, modification or deletion of Resources record(s).
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


BLF
method BSystem.ApiLoadDefaultSecurity
method BSystem.ApiSaveSODData


program code (program3/bresource.p)

vlDataLoadSkipCalculate = yes.

/* First check whether there is something to be processed.  If not, return a warning */
if not can-find(first tInputResource)
then do :
    <M-7 run SetMessage
       (input  #T-3'The input for creating, modifying or deleting of resources data is not available':100(8866)T-3# (icMessage), 
        input  '' (icArguments), 
        input  '' (icFieldName), 
        input  '' (icFieldValue), 
        input  'W':U (icType), 
        input  3 (iiSeverity), 
        input  '' (icRowid), 
        input  'BLF-162':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BResource>
    assign oiReturnStatus = 1.
    return.
end.

<M-5 run ClearData
   (output viFcReturnSuper (oiReturnStatus)) in BResource>
if viFcReturnSuper <> 0
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.

/* We first need to make sure the resources that need to be deleted are deleted,
   we only need to handle the resources linked to an MfgPro menu */
for each tInputResource where tInputResource.tcRequiredStatus = "D":U and
         tInputResource.tcResourceType = {&RESOURCE-TYPE-MENU} on error undo, throw:

    /* woa - changed 6 03 2008 form '= 1' to '<= 1' */
    /* 10249-0429 woa - changed it to '= 0 */
    if <M-9 NumberOfLinksBetweenResourceAndMndDet
          (input  tInputResource.tcResourceURI (icURI)) in BResource> = 0
    then do :
        <Q-11 run ResourcePrim (all) (Read) (NoCache)
           (input tInputResource.tcResourceURI, (ResourceURI)
            input ?, (ResourceId)
            output dataset tqResourcePrim) in BResource >
        find first tqResourcePrim no-error.
        if not available tqResourcePrim
        then do:
            <M-12 run SetMessage
               (input  #T-4'The resource that needs to be deleted does not exist. ($1)':255(8869)T-4# (icMessage), 
                input  tInputResource.tcResourceURI (icArguments), 
                input  '' (icFieldName), 
                input  '' (icFieldValue), 
                input  'E':U (icType), 
                input  2 (iiSeverity), 
                input  '' (icRowid), 
                input  'BLF-163':U (icFcMsgNumber), 
                input  '' (icFcExplanation), 
                input  '' (icFcIdentification), 
                input  '' (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BResource>
            assign oiReturnStatus = -1.
            return.
        end.

        <M-10 run DataLoad
           (input  '' (icRowids), 
            input  string(tqResourcePrim.tiResource_ID) (icPkeys), 
            input  '' (icObjectIds), 
            input  '' (icFreeform), 
            input  true (ilKeepPrevious), 
            output viFcReturnSuper (oiReturnStatus)) in BResource>
        if viFcReturnSuper <> 0
        then assign oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.

        find first tResources where tResources.Resource_ID = tqResourcePrim.tiResource_ID no-error.
        if available tResources
        then assign tResources.tc_Status = "D":U.
    end.
end.

/* The records for which the requiredStatus is marked "C" are the resources where the URI was not changed */
assign vcLoad = "".

for each tInputResource where
         tInputResource.tcRequiredStatus = "C":U on error undo, throw:

    <Q-68 run ResourceForChanges (all) (Read) (Cache)
       (input tInputResource.tcResourceURI, (ResourceURI)
        output dataset tqResourceForChanges) in BResource>

    find first tqResourceForChanges where tqResourceForChanges.tcResourceURI = tInputResource.tcResourceURI no-error.
    if not available tqResourceForChanges
    then do:
        assign vcMsg = trim(#T-33'The provided business activity resource URI does not exist ($1).':255(8867)T-33#)
               oiReturnStatus = -1.
        <M-20 run SetMessage
           (input  vcMsg (icMessage), 
            input  tInputResource.tcResourceURI (icArguments), 
            input  '' (icFieldName), 
            input  '' (icFieldValue), 
            input  'E':U (icType), 
            input  3 (iiSeverity), 
            input  '' (icRowid), 
            input  'BLF-872674':U (icFcMsgNumber), 
            input  '' (icFcExplanation), 
            input  '' (icFcIdentification), 
            input  '' (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BResource>
        assign oiReturnStatus = -1.
        return.
    end.

    if tInputResource.tcResourceCategory = tqResourceForChanges.tcSODCategoryCode
    and (tInputResource.tcResourceLabel = tqResourceForChanges.tcResourceLabel or
         tInputResource.tcResourceLabel = "" or
         tInputResource.tcResourceLabel = ?)
    then next.

    if vcLoad <> ""
    then assign vcLoad = vcLoad + chr(4).
    
    assign vcLoad = vcLoad + string(tqResourceForChanges.tiResource_ID).
    
    if length(vcLoad, "CHARACTER") > 31000
    then do:
        <M-29 run DataLoad
           (input  '' (icRowids), 
            input  vcLoad (icPkeys), 
            input  '' (icObjectIds), 
            input  '' (icFreeform), 
            input  true (ilKeepPrevious), 
            output viFcReturnSuper (oiReturnStatus)) in BResource>
            
        if viFcReturnSuper <> 0
        then assign oiReturnStatus = viFcReturnSuper.
        
        if viFcReturnSuper < 0
        then return.
        
        assign vcLoad = "".
    end.
end.

if vcLoad <> ""
then do:
    <M-15 run DataLoad
       (input  '' (icRowids), 
        input  vcLoad (icPkeys), 
        input  '' (icObjectIds), 
        input  '' (icFreeform), 
        input  true (ilKeepPrevious), 
        output viFcReturnSuper (oiReturnStatus)) in BResource>

    if viFcReturnSuper <> 0
    then assign oiReturnStatus = viFcReturnSuper.

    if viFcReturnSuper < 0
    then return.
end.

<M-97 run Calculate  (output viFcReturnSuper (oiReturnStatus)) in BResource>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.

for each tInputResource where
         tInputResource.tcRequiredStatus = "C":U on error undo, throw:
    find first tResources where
               tResources.ResourceURI = tInputResource.tcResourceURI
               no-error.

    if available tResources
    then do:
        if tInputResource.tcResourceLabel <> "" and
           tInputResource.tcResourceLabel <> ?  and
           tInputResource.tcResourceLabel <> tResources.ResourceLabel
        then assign tResources.ResourceLabel = tInputResource.tcResourceLabel
                    tResources.tc_Status     = "C".

        if tInputResource.tcResourceCategory <> tResources.tcSODCategoryCode
        then assign tResources.tcSODCategoryCode = if tInputResource.tcResourceCategory = ?
                                                   then ""
                                                   else tInputResource.tcResourceCategory
                    tResources.tc_Status         = "C".
    end.
end.

/* Treat the New ones */
for each tInputResource where 
         tInputResource.tcRequiredStatus = "N":U on error undo, throw:
    
    if tInputResource.tcResourceType = {&RESOURCE-TYPE-ACTIVITY}
    then do:

        <Q-1 run ResourcePrim (all) (Read) (NoCache)
           (input tInputResource.tcResourceURI, (ResourceURI)
            input ?, (ResourceId)
            output dataset tqResourcePrim) in BResource >
        if not can-find(first tqResourcePrim)
        then do:
            assign vcMsg = trim(#T-2'The provided business activity resource URI does not exist ($1).':255(8867)T-2#)
                   oiReturnStatus = -1.
            <M-3 run SetMessage
               (input  vcMsg (icMessage), 
                input  tInputResource.tcResourceURI (icArguments), 
                input  '' (icFieldName), 
                input  '' (icFieldValue), 
                input  'E':U (icType), 
                input  3 (iiSeverity), 
                input  '' (icRowid), 
                input  'BLF-161':U (icFcMsgNumber), 
                input  '' (icFcExplanation), 
                input  '' (icFcIdentification), 
                input  '' (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BResource>
            assign oiReturnStatus = -1.
            return.
        end.

        /* format is "urn:cbf:bc.ba" */
        if num-entries (tInputResource.tcResourceURI,':') <> 3 or
          (num-entries (tInputResource.tcResourceURI,':') = 3 and num-entries (entry (3,tInputResource.tcResourceURI,':'),".") <> 2)
        then do :                                                                                 
            assign vcMsg = trim (substitute (#T-24'The syntax of the URI (&1) is not respected.':255(8916)T-24#),'urn:cbf:<BusinessComponent>.<BusinessActivity>':U).
                   oiReturnStatus = -1.
            <M-26 run SetMessage
               (input  vcMsg (icMessage), 
                input  '' (icArguments), 
                input  'tInputResource.tcResourceURI' (icFieldName), 
                input  tInputResource.tcResourceURI (icFieldValue), 
                input  'E':U (icType), 
                input  3 (iiSeverity), 
                input  '' (icRowid), 
                input  'BLF-166':U (icFcMsgNumber), 
                input  '' (icFcExplanation), 
                input  '' (icFcIdentification), 
                input  '' (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in BResource>
            assign oiReturnStatus = -1.
            return.
        end.

        /* We need to test on sequence field of the activity. On longer term this should be part of Resources table */
        assign vcBusComponentCode = entry (1,entry (3,tInputResource.tcResourceURI,':'),".")
               vcBusActivityCode  = entry (2,entry (3,tInputResource.tcResourceURI,':'),".").

         <Q-27 run BusActivityByActCompDefault (all) (Read) (NoCache)
            (input vcBusActivityCode, (BusActitvityCode)
             input vcBusComponentCode, (BusComponentCode)
             input ?, (BusActiivtyIsDefault)
             input ?, (BusActivytIsActive)
             output dataset tqBusActivityByActCompDefault) in BBusinessComponent >

         find tqBusActivityByActCompDefault no-error.
         if not available tqBusActivityByActCompDefault
         then do :
                assign vcMsg = trim (substitute (#T-30'The activity '1' of component '&2' was not found.':255(8920)T-30#,vcBusActivityCode,vcBusComponentCode)).
                       oiReturnStatus = -1.
                <M-28 run SetMessage
                   (input  vcMsg (icMessage), 
                    input  '' (icArguments), 
                    input  'tInputResource.tcResourceURI' (icFieldName), 
                    input  tInputResource.tcResourceURI (icFieldValue), 
                    input  'E':U (icType), 
                    input  3 (iiSeverity), 
                    input  '' (icRowid), 
                    input  'BLF-167':U (icFcMsgNumber), 
                    input  '' (icFcExplanation), 
                    input  '' (icFcIdentification), 
                    input  '' (icFcContext), 
                    output viFcReturnSuper (oiReturnStatus)) in BResource>
                assign oiReturnStatus = -1.
                return.
         end.

         if  tqBusActivityByActCompDefault.tiBusActivitySequence = 0
         then do :
                assign vcMsg = trim (substitute (#T-32'The definition of the activity '&1' of component '&2' does not allow the activity to appear on the menu.':255(8922)T-32#,vcBusActivityCode,vcBusComponentCode)).
                       oiReturnStatus = -1.
                <M-31 run SetMessage
          (input  vcMsg (icMessage), 
           input  '' (icArguments), 
           input  'tInputResource.tcResourceURI' (icFieldName), 
           input  tInputResource.tcResourceURI (icFieldValue), 
           input  'E':U (icType), 
           input  3 (iiSeverity), 
           input  '' (icRowid), 
           input  'BLF-167':U (icFcMsgNumber), 
           input  '' (icFcExplanation), 
           input  '' (icFcIdentification), 
           input  '' (icFcContext), 
           output viFcReturnSuper (oiReturnStatus)) in BResource>
                assign oiReturnStatus = -1.
                return.
         end.
    end. /* {&RESOURCE-TYPE-ACTIVITY} */
    else if tInputResource.tcResourceType = {&RESOURCE-TYPE-MENU}
    then do:
        <Q-4 run ResourcePrim (all) (Read) (NoCache)
           (input tInputResource.tcResourceURI, (ResourceURI)
            input ?, (ResourceId)
            output dataset tqResourcePrim) in BResource >
        /* Only if we don't find the corresponding resources record, we need to create one */
        if not can-find(first tqResourcePrim)
        then do:
            /*create the resource*/
            <M-6 run AddDetailLine
               (input  'Resources':U (icTable), 
                input  '' (icParentRowid), 
                output viFcReturnSuper (oiReturnStatus)) in BResource>
            if viFcReturnSuper <> 0
            then assign oiReturnStatus = viFcReturnSuper.
            if viFcReturnSuper < 0
            then return.
            assign tResources.ResourceType      = {&RESOURCE-TYPE-MENU}
                   tResources.ResourceURI       = tInputResource.tcResourceURI
                   tResources.ResourceLabel     = tInputResource.tcResourceLabel
                   tResources.tcSODCategoryCode = tInputResource.tcResourceCategory.
        end.
    end.
end.

/* Validate, AdditionalUpdates and Save */    
<M-17 run ValidateBC
   (output viFcReturnSuper (oiReturnStatus)) in BResource>
if viFcReturnSuper <> 0 
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0 
then return.

<M-18 run AdditionalUpdates
   (output viFcReturnSuper (oiReturnStatus)) in BResource>
if viFcReturnSuper <> 0 
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0 
then return.

<M-19 run DataSave
   (output viFcReturnSuper (oiReturnStatus)) in BResource>
if viFcReturnSuper <> 0 
then assign oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0 
then return.

/** Return a warning if there are records passed with a blank required status **/
for each tInputResource where not can-do("N,D,C",tInputResource.tcRequiredStatus) on error undo, throw:
    <M-21 run SetMessage
       (input  #T-22'The input to ApiLinkResource should not contain records with an empty status indication. (URI=$1;Label=$2)':150(8879)T-22# (icMessage), 
        input  tInputResource.tcResourceURI + chr(2) + tinputResource.tcResourceLabel (icArguments), 
        input  'tcRequiredStatus' (icFieldName), 
        input  tInputResource.tcRequiredStatus (icFieldValue), 
        input  'W':U (icType), 
        input  3 (iiSeverity), 
        input  '' (icRowid), 
        input  'BLF-165':U (icFcMsgNumber), 
        input  '' (icFcExplanation), 
        input  '' (icFcIdentification), 
        input  '' (icFcContext), 
        output viFcReturnSuper (oiReturnStatus)) in BResource>
    assign oiReturnStatus = 1.
end.

finally:
    vlDataLoadSkipCalculate = no.
end finally.


Sample code: how to call this method through RPCRequestService (QXtend Inbound)

define temp-table ttContext no-undo
    field propertyQualifier as character
    field propertyName as character
    field propertyValue as character
    index entityContext is primary unique
        propertyQualifier
        propertyName
    index propertyQualifier
        propertyQualifier.

define dataset dsContext for ttContext.

define variable vhContextDS as handle no-undo.
define variable vhExceptionDS as handle no-undo.
define variable vhServer as handle no-undo.
define variable vhInputDS as handle no-undo.
define variable vhInputOutputDS as handle no-undo.
define variable vhOutputDS as handle no-undo.
define variable vhParameter as handle no-undo.

/* Create context */
create ttContext.
assign ttContext.propertyName = "programName"
       ttContext.propertyValue = "BResource".
create ttContext.
assign ttContext.propertyName = "methodName"
       ttContext.propertyValue = "ApiLinkResource".
create ttContext.
assign ttContext.propertyName = "applicationId"
       ttContext.propertyValue = "fin".
create ttContext.
assign ttContext.propertyName = "entity"
       ttContext.propertyValue = "1000".
create ttContext.
assign ttContext.propertyName = "userName"
       ttContext.propertyValue = "mfg".
create ttContext.
assign ttContext.propertyName = "password"
       ttContext.propertyValue = "".

/* Create input dataset */
create dataset vhInputDS.
vhInputDS:read-xmlschema("file", "xml/bresource.apilinkresource.i.xsd", ?).
vhParameter = vhInputDS:get-buffer-handle("tInputResource").
vhParameter:buffer-create().
assign vhParameter::<field-name-1> = <field-value-1>
       vhParameter::<field-name-2> = <field-value-2>
       ...

/* Connect the AppServer */
create server vhServer.
vhServer:connect("-URL <appserver-url>").

if not vhServer:connected()
then do:
    message "Could not connect AppServer" view-as alert-box error title "Error".
    return.
end.

/* Run */
assign vhContextDS = dataset dsContext:handle.

run program/rpcrequestservice.p on vhServer
    (input-output dataset-handle vhContextDS by-reference,
           output dataset-handle vhExceptionDS,
     input        dataset-handle vhInputDS by-reference,
     input-output dataset-handle vhInputOutputDS by-reference,
           output dataset-handle vhOutputDS).

/* Handle output however you want, in this example, we dump it to xml */
if valid-handle(vhExceptionDS)
then vhExceptionDS:write-xml("file", "Exceptions.xml", true).

if valid-handle(vhOutputDS)
then vhOutputDS:write-xml("file", "Output.xml", true).

/* Cleanup */
vhServer:disconnect().
assign vhServer = ?.

if valid-handle(vhInputDS)
then delete object vhInputDS.

if valid-handle(vhOutputDS)
then delete object vhOutputDS.

if valid-handle(vhExceptionDS)
then delete object vhExceptionDS.