<commit_before>(ns cmr.umm.iso-smap.granule
  "Contains functions for parsing and generating the SMAP ISO dialect."
  (:require [clojure.data.xml :as x]
            [clojure.java.io :as io]
            [cmr.common.xml :as cx]
            [clj-time.format :as f]
            [cmr.umm.granule :as g]
            [cmr.umm.iso-smap.collection :as c]
            [cmr.umm.iso-smap.granule.spatial :as s]
            [cmr.umm.iso-smap.granule.temporal :as gt]
            [cmr.umm.iso-smap.granule.related-url :as ru]
            [cmr.common.xml :as v]
            [cmr.umm.echo10.core]
            [cmr.umm.iso-smap.helper :as h])
  (:import cmr.umm.granule.UmmGranule))

(defn- xml-elem->CollectionRef
  "Returns a UMM ref element from a parsed Granule XML structure"
  [id-elems]
  (let [dataset-id-elem (h/xml-elem-with-title-tag id-elems "DataSetId")
        entry-title (cx/string-at-path
                      dataset-id-elem
                      [:aggregationInfo :MD_AggregateInformation :aggregateDataSetIdentifier
                       :MD_Identifier :code :CharacterString])
        coll-elems (mapcat
                     #(cx/elements-at-path % [:citation :CI_Citation :identifier :MD_Identifier])
                     id-elems)
        parse-fn (fn [tag]
                   (let [elem (h/xml-elem-with-path-value
                                coll-elems
                                [:description :CharacterString] tag)]
                     (cx/string-at-path elem [:code :CharacterString])))
        short-name (parse-fn "The ECS Short Name")
        version-id (parse-fn "The ECS Version ID")]
    (g/collection-ref entry-title short-name version-id)))

(defn- xml-elem->granule-ur
  "Returns a UMM granule ur from a parsed Granule XML structure"
  [id-elems]
  (let [granule-ur-elem (h/xml-elem-with-path-value
                          id-elems [:purpose :CharacterString] "GranuleUR")]
    (cx/string-at-path
      granule-ur-elem
      [:citation :CI_Citation :title :CharacterString])))

(defn- xml-elem->DataGranule
  "Returns a UMM data-granule element from a parsed Granule XML structure"
  [xml-struct]
  (let [producer-gran-id (cx/string-at-path
                           xml-struct
                           [:composedOf :DS_DataSet :has :MI_Metadata :identificationInfo
                            :MD_DataIdentification :citation :CI_Citation :title :FileName])
        production-date-time (cx/datetime-at-path
                               xml-struct
                               [:composedOf :DS_DataSet :has :MI_Metadata :dataQualityInfo
                                :DQ_DataQuality :lineage :LI_Lineage :processStep :LE_ProcessStep
                                :dateTime :DateTime])]
    (when (or producer-gran-id production-date-time)
      (g/map->DataGranule {:producer-gran-id producer-gran-id
                           :production-date-time production-date-time}))))

(defn- xml-elem->access-value
  "Returns a UMM access value from a parsed Granule XML structure"
  [id-elems]
  (let [restriction-flag-elem (h/xml-elem-with-title-tag id-elems "RestrictionFlag")]
    (cx/double-at-path
      restriction-flag-elem
      [:resourceConstraints :MD_LegalConstraints :otherConstraints :CharacterString])))

(defn- xml-elem->Granule
  "Returns a UMM Product from a parsed Granule XML structure"
  [xml-struct]
  (let [id-elems (cx/elements-at-path
                   xml-struct
                   [:composedOf :DS_DataSet :has :MI_Metadata
                    :identificationInfo :MD_DataIdentification])]
    (g/map->UmmGranule
      {:granule-ur (xml-elem->granule-ur id-elems)
       :data-provider-timestamps (c/xml-elem->DataProviderTimestamps id-elems)
       :collection-ref (xml-elem->CollectionRef id-elems)
       :data-granule (xml-elem->DataGranule xml-struct)
       :access-value (xml-elem->access-value id-elems)
       :temporal (gt/xml-elem->Temporal xml-struct)
       :spatial-coverage (s/xml-elem->SpatialCoverage xml-struct)
       :related-urls (ru/xml-elem->related-urls xml-struct)})))

(defn parse-granule
  "Parses ECHO10 XML into a UMM Granule record."
  [xml]
  (xml-elem->Granule (x/parse-str xml)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Generators
<commit_msg>Added function to retrieve access-value for SMAP ISO granules.<commit_after>(ns cmr.umm.iso-smap.granule
  "Contains functions for parsing and generating the SMAP ISO dialect."
  (:require [clojure.data.xml :as x]
            [clojure.java.io :as io]
            [cmr.common.xml :as cx]
            [clj-time.format :as f]
            [cmr.umm.granule :as g]
            [cmr.umm.iso-smap.collection :as c]
            [cmr.umm.iso-smap.granule.spatial :as s]
            [cmr.umm.iso-smap.granule.temporal :as gt]
            [cmr.umm.iso-smap.granule.related-url :as ru]
            [cmr.common.xml :as v]
            [cmr.umm.echo10.core]
            [cmr.umm.iso-smap.helper :as h])
  (:import cmr.umm.granule.UmmGranule))

(defn- xml-elem->CollectionRef
  "Returns a UMM ref element from a parsed Granule XML structure"
  [id-elems]
  (let [dataset-id-elem (h/xml-elem-with-title-tag id-elems "DataSetId")
        entry-title (cx/string-at-path
                      dataset-id-elem
                      [:aggregationInfo :MD_AggregateInformation :aggregateDataSetIdentifier
                       :MD_Identifier :code :CharacterString])
        coll-elems (mapcat
                     #(cx/elements-at-path % [:citation :CI_Citation :identifier :MD_Identifier])
                     id-elems)
        parse-fn (fn [tag]
                   (let [elem (h/xml-elem-with-path-value
                                coll-elems
                                [:description :CharacterString] tag)]
                     (cx/string-at-path elem [:code :CharacterString])))
        short-name (parse-fn "The ECS Short Name")
        version-id (parse-fn "The ECS Version ID")]
    (g/collection-ref entry-title short-name version-id)))

(defn- xml-elem->granule-ur
  "Returns a UMM granule ur from a parsed Granule XML structure"
  [id-elems]
  (let [granule-ur-elem (h/xml-elem-with-path-value
                          id-elems [:purpose :CharacterString] "GranuleUR")]
    (cx/string-at-path
      granule-ur-elem
      [:citation :CI_Citation :title :CharacterString])))

(defn- xml-elem->DataGranule
  "Returns a UMM data-granule element from a parsed Granule XML structure"
  [xml-struct]
  (let [producer-gran-id (cx/string-at-path
                           xml-struct
                           [:composedOf :DS_DataSet :has :MI_Metadata :identificationInfo
                            :MD_DataIdentification :citation :CI_Citation :title :FileName])
        production-date-time (cx/datetime-at-path
                               xml-struct
                               [:composedOf :DS_DataSet :has :MI_Metadata :dataQualityInfo
                                :DQ_DataQuality :lineage :LI_Lineage :processStep :LE_ProcessStep
                                :dateTime :DateTime])]
    (when (or producer-gran-id production-date-time)
      (g/map->DataGranule {:producer-gran-id producer-gran-id
                           :production-date-time production-date-time}))))

(defn- xml-elem->access-value
  "Returns a UMM access value from a parsed Granule XML structure"
  [id-elems]
  (let [restriction-flag-elem (h/xml-elem-with-title-tag id-elems "RestrictionFlag")]
    (cx/double-at-path
      restriction-flag-elem
      [:resourceConstraints :MD_LegalConstraints :otherConstraints :CharacterString])))

(defn- xml-elem->Granule
  "Returns a UMM Product from a parsed Granule XML structure"
  [xml-struct]
  (let [id-elems (cx/elements-at-path
                   xml-struct
                   [:composedOf :DS_DataSet :has :MI_Metadata
                    :identificationInfo :MD_DataIdentification])]
    (g/map->UmmGranule
      {:granule-ur (xml-elem->granule-ur id-elems)
       :data-provider-timestamps (c/xml-elem->DataProviderTimestamps id-elems)
       :collection-ref (xml-elem->CollectionRef id-elems)
       :data-granule (xml-elem->DataGranule xml-struct)
       :access-value (xml-elem->access-value id-elems)
       :temporal (gt/xml-elem->Temporal xml-struct)
       :spatial-coverage (s/xml-elem->SpatialCoverage xml-struct)
       :related-urls (ru/xml-elem->related-urls xml-struct)})))

(defn parse-granule
  "Parses ECHO10 XML into a UMM Granule record."
  [xml]
  (xml-elem->Granule (x/parse-str xml)))

(defn xml->access-value
  "Parse and return the access-value for the given SMAP ISO granule xml.
  This function is used by cmr-search-app to retrieve the access-value from xml directly"
  [xml]
  (let [xml-struct (x/parse-str xml)
        id-elems (cx/elements-at-path
                   xml-struct
                   [:composedOf :DS_DataSet :has :MI_Metadata
                    :identificationInfo :MD_DataIdentification])]
    (xml-elem->access-value id-elems)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Generators

{'fraction_non_alphanumeric': 0.12985436893203883, 'fraction_numerical': 0.00088261253309797, 'mean_word_length': 2.1497567755385685, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 72}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6938227', 'n_tokens_mistral': 2975, 'n_tokens_neox': 2822, 'n_words': 615}