module ADIWG::Mdtranslator::Readers::SbJson::RelatedItem

Public Class Methods

unpack(hSbJson, hMetadata, hResponseObj) click to toggle source
# File lib/adiwg/mdtranslator/readers/sbJson/modules/module_relatedItem.rb, line 22
def self.unpack(hSbJson, hMetadata, hResponseObj)

   # instance classes needed in script
   intMetadataClass = InternalMetadata.new

   # relationship direction of related items depends on the main record id
   sbId = nil
   if hSbJson.has_key?('id')
      sbId = hSbJson['id']
   end
   if sbId.nil? || sbId == ''
      hResponseObj[:readerExecutionMessages] << 'ScienceBase id missing'
      return hMetadata
   end

   # get the link to the related items array
   hRelatedItems = hSbJson['relatedItems']
   itemsLink = nil
   if hRelatedItems.has_key?('link')
      hLink = hRelatedItems['link']
      unless hLink.empty?
         itemsLink = hLink['url']
      end
   end
   return hMetadata if itemsLink.nil?

   # fetch the related items array in json format
   itemsLink = itemsLink + '&format=json'
   begin
      web_contents = open(itemsLink, :read_timeout => 30) { |f| f.read }
   rescue => readErr
      hResponseObj[:readerExecutionMessages] << "Failed reading ScienceBase relatedItems #{itemsLink} - see following message(s):\n"
      hResponseObj[:readerExecutionMessages] << readErr.to_s.slice(0, 300)
      return hMetadata
   else
      # parse related items array
      aItems = []
      begin
         aItems = JSON.parse(web_contents)
      rescue JSON::JSONError => parseErr
         hResponseObj[:readerExecutionMessages] << 'Parsing related links failed - see following message(s):\n'
         hResponseObj[:readerExecutionMessages] << parseErr.to_s.slice(0, 300)
         return hMetadata
      end

      # process each returned related item as a separate associated resource
      aItems.each do |hItem|
         unless hItem.empty?

            # determine relationship direction
            # forward: how the associated resource relates to the main resource
            # ... in other words - the relationship is defined in terms of the associated resource
            # ... example: the associated resource is a 'subProject' of the main resource
            # reverse: how the main resource relates to the associated resource
            # ... in other words - the relationship is defined in terms of the main resource
            # ... example: the main resource is the 'parentProject' of the associated resource
            # all mdJson/mdTranslator relationships must be expressed as forward
            forward = nil
            if hItem.has_key?('itemId')
               forward = false if sbId == hItem['itemId']
            end
            if hItem.has_key?('relatedItemId')
               forward = true if sbId == hItem['relatedItemId']
            end
            if forward.nil?
               hResponseObj[:readerExecutionMessages] << 'Main ScienceBase id was not referenced in related item'
               return hMetadata
            end

            # fetch resourceTypes from related item's record
            if forward
               resourceId = hItem['itemId']
            else
               resourceId = hItem['relatedItemId']
            end
            resourceLink = "https://www.sciencebase.gov/catalog/item/#{resourceId}?format=json"
            begin
               web_contents = open(resourceLink, :read_timeout => 30) { |f| f.read }
            rescue => readErr
               hResponseObj[:readerExecutionMessages] << "Failed reading ScienceBase relatedItem #{resourceId} - see following message(s)"
               hResponseObj[:readerExecutionMessages] << readErr.to_s.slice(0, 300)
               hResponseObj[:readerExecutionMessages] << 'Either the item does not exist or the item is secured and requires authentication to access.'
               break
            else

               # parse related item
               begin
                  hRelatedItem = JSON.parse(web_contents)
               rescue JSON::JSONError => parseErr
                  hResponseObj[:readerExecutionMessages] << 'Parsing related item failed - see following message(s):\n'
                  hResponseObj[:readerExecutionMessages] << parseErr.to_s.slice(0, 300)
                  break
               end

               # create mew associated resource
               hResource = intMetadataClass.newAssociatedResource

               # add resource types
               BrowseCategory.unpack(hRelatedItem, hResource[:resourceTypes], hResponseObj)

               # add association type
               if hItem.has_key?('type')
                  sbAssocType = hItem['type']
                  unless sbAssocType.nil? || sbAssocType == ''
                     assocType = nil
                     if forward
                        assocType = Codelists.codelist_sb2adiwg('association_sb2adiwg_assoc2main', sbAssocType)
                     else
                        assocType = Codelists.codelist_sb2adiwg('association_sb2adiwg_main2assoc', sbAssocType)
                     end
                     if assocType.nil?
                        hResource[:associationType] = sbAssocType
                     else
                        hResource[:associationType] = assocType
                     end
                  end
               end
               if hResource[:associationType].nil?
                  hResource[:associationType] = 'missing'
               end

               # fill in associated resource citation
               hCitation = intMetadataClass.newCitation
               citationTitle = 'associated resource title'
               if forward
                  if hItem.has_key?('title')
                     citationTitle = hItem['title']
                  end
               else
                  if hItem.has_key?('relatedItemTitle')
                     citationTitle = hItem['relatedItemTitle']
                  end
               end
               hCitation[:title] = citationTitle

               # create an identifier for the related item
               # use resourceId computed above
               hIdentifier = intMetadataClass.newIdentifier
               hIdentifier[:identifier] = resourceId
               hIdentifier[:namespace] = 'gov.sciencebase.catalog'
               hIdentifier[:description] = 'relatedItemId'
               hCitation[:identifiers] << hIdentifier

               hResource[:resourceCitation] = hCitation
               hMetadata[:associatedResources] << hResource

            end

         end
      end

      return hMetadata
   end

end