adiwg-mdtranslator 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/adiwg-mdtranslator.gemspec +1 -0
  4. data/lib/adiwg/mdtranslator/internal/module_coordinates.rb +13 -0
  5. data/lib/adiwg/mdtranslator/readers/fgdc/fgdc_reader.rb +49 -0
  6. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_citation.rb +144 -0
  7. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_date.rb +57 -0
  8. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_dateTime.rb +108 -0
  9. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_distribution.rb +28 -0
  10. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_entityAttribute.rb +28 -0
  11. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_fgdc.rb +193 -0
  12. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_identification.rb +136 -0
  13. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_metadataInfo.rb +28 -0
  14. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_onlineResource.rb +35 -0
  15. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_publication.rb +63 -0
  16. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_quality.rb +28 -0
  17. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_responsibility.rb +46 -0
  18. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_series.rb +44 -0
  19. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialDomain.rb +184 -0
  20. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialOrganization.rb +28 -0
  21. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialReference.rb +28 -0
  22. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_timeInstant.rb +40 -0
  23. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_timePeriod.rb +88 -0
  24. data/lib/adiwg/mdtranslator/readers/fgdc/readme.md +18 -0
  25. data/lib/adiwg/mdtranslator/readers/{fgcd → fgdc}/version.rb +0 -0
  26. data/lib/adiwg/mdtranslator/readers/mdJson/readme.md +1 -1
  27. data/lib/adiwg/mdtranslator/readers/mdJson/version.rb +2 -1
  28. data/lib/adiwg/mdtranslator/readers/sbJson/modules/module_browseCategory.rb +5 -5
  29. data/lib/adiwg/mdtranslator/readers/sbJson/modules/module_relatedItem.rb +4 -10
  30. data/lib/adiwg/mdtranslator/readers/sbJson/modules/module_sbJson.rb +1 -1
  31. data/lib/adiwg/mdtranslator/readers/sbJson/readme.md +1 -1
  32. data/lib/adiwg/mdtranslator/readers/sbJson/sbJson_reader.rb +2 -2
  33. data/lib/adiwg/mdtranslator/readers/sbJson/version.rb +1 -1
  34. data/lib/adiwg/mdtranslator/version.rb +1 -1
  35. data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_resourceType.rb +1 -0
  36. metadata +37 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 424da312bdcfc7617f563857a6e8767ebb3b3c4c
4
- data.tar.gz: f35fdf24c6a34dd418bab443b39d4050a748cdbc
3
+ metadata.gz: d2be0aaa21383741efd06ac414b0ba47453777e6
4
+ data.tar.gz: 5eb25c34b45babdff52a7fadaa0e32668d2b0c9a
5
5
  SHA512:
6
- metadata.gz: 4fb9075e39f5f0406ca5196353a7dd75a19735b0a72870f0d7a7814a3361a0390feec8080a6fa6fbf458fb7d46dd382f816e42db3fe955d1462e2248b0d51b38
7
- data.tar.gz: 8db4fd7f94bac35cf98473c353dde6513e9dfc56347ca71218bf719d5919e28c533a47e532620d19ae52305c71c424a18e6d9055f1b8eb520cad16e016c24aad
6
+ metadata.gz: b085419641422ad940aec5f9bbc2b014585f76a1063750012bb2274711f934cc126e32a62d1e2783855d0f4ee6f321ab21632ca07f65d7e3d69f896b54bd1ff5
7
+ data.tar.gz: 7e5912f670bacbdca633ec763742be8f703a95c0b5fd107407eaf3f7a875cb6e23995001557b37844b74db21c07f3db106f4e77212ae8b5a0b32870e8e1c16a7
data/Rakefile CHANGED
@@ -6,6 +6,7 @@ Rake::TestTask.new do |t|
6
6
  t.test_files = FileList[
7
7
  'test/readers/mdJson/tc*.rb',
8
8
  'test/readers/sbJson/tc*.rb',
9
+ 'test/readers/fgdc/tc*.rb',
9
10
  'test/writers/iso19115-2/tc*.rb',
10
11
  'test/writers/iso19110/tc*.rb',
11
12
  'test/writers/mdJson/tc*.rb',
@@ -38,5 +38,6 @@ Gem::Specification.new do |spec|
38
38
  spec.add_runtime_dependency "jbuilder", "~> 2.5"
39
39
  spec.add_runtime_dependency "kramdown", "~> 1.13"
40
40
  spec.add_runtime_dependency "coderay", "~> 1.1"
41
+ spec.add_runtime_dependency "nokogiri", "~> 1.7"
41
42
 
42
43
  end
@@ -1,6 +1,7 @@
1
1
  # repack coordinates
2
2
 
3
3
  # History:
4
+ # Stan Smith 2017-08-23 added is_polygon_clockwise method
4
5
  # Stan Smith 2017-05-24 added checkGeometry method to move objects to real world
5
6
  # Stan Smith 2016-11-10 added computedBbox computation
6
7
  # Stan Smith 2015-07-16 moved module_coordinates from mdJson reader to internal
@@ -219,4 +220,16 @@ module AdiwgCoordinates
219
220
  aNorthings << aPoint[1]
220
221
  end
221
222
 
223
+ def self.is_polygon_clockwise(aCoords)
224
+ area = 0.0
225
+ i = 0
226
+ n = aCoords.length - 1
227
+ until i == n
228
+ area += (aCoords[i][0] * aCoords[i+1][1]) - (aCoords[i][1] * aCoords[i+1][0])
229
+ i += 1
230
+ end
231
+ area += (aCoords[n][0] * aCoords[0][1]) - (aCoords[n][1] * aCoords[0][0])
232
+ return area >= 0 ? false : true
233
+ end
234
+
222
235
  end
@@ -0,0 +1,49 @@
1
+ # fgdc reader
2
+
3
+ # History:
4
+ # Stan Smith 2017-08-10 original script
5
+
6
+ require 'nokogiri'
7
+ require_relative 'modules/module_fgdc'
8
+
9
+ module ADIWG
10
+ module Mdtranslator
11
+ module Readers
12
+ module Fgdc
13
+
14
+ def self.readFile(file, hResponseObj)
15
+
16
+ # receive XML file
17
+ if file.nil? || file == ''
18
+ hResponseObj[:readerStructureMessages] << 'XML file is missing'
19
+ hResponseObj[:readerStructurePass] = false
20
+ return {}
21
+ end
22
+
23
+ # file must be well formed XML
24
+ begin
25
+ xDoc = Nokogiri::XML(file) { |form| form.strict }
26
+ rescue Nokogiri::XML::SyntaxError => err
27
+ hResponseObj[:readerStructureMessages] << 'XML file is not well formed'
28
+ hResponseObj[:readerStructureMessages] << err
29
+ hResponseObj[:readerStructurePass] = false
30
+ return {}
31
+ end
32
+
33
+ # file must contain an fgdc <metadata> tag
34
+ xMetadata = xDoc.xpath('/metadata')
35
+ if xMetadata.empty?
36
+ hResponseObj[:readerValidationMessages] << 'FGDC file did not contain a <metadata> tag'
37
+ hResponseObj[:readerValidationPass] = false
38
+ return {}
39
+ end
40
+
41
+ # load fgdc file into internal object
42
+ return Fgdc.unpack(xDoc, hResponseObj)
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,144 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc citation
3
+
4
+ # History:
5
+ # Stan Smith 2017-08-15 original script
6
+
7
+ require 'nokogiri'
8
+ require 'uuidtools'
9
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
10
+ require_relative 'module_fgdc'
11
+ require_relative 'module_date'
12
+ require_relative 'module_series'
13
+ require_relative 'module_publication'
14
+ require_relative 'module_onlineResource'
15
+ require_relative 'module_citation'
16
+ require_relative 'module_responsibility'
17
+
18
+ module ADIWG
19
+ module Mdtranslator
20
+ module Readers
21
+ module Fgdc
22
+
23
+ module Citation
24
+
25
+ def self.unpack(xCitation, hResponseObj)
26
+
27
+ xCiteInfo = xCitation.xpath('./citeinfo')
28
+
29
+ # instance classes needed in script
30
+ intMetadataClass = InternalMetadata.new
31
+ hCitation = intMetadataClass.newCitation
32
+
33
+ # citation 8.1 (origin) - originator [] (required)
34
+ aContacts = []
35
+ axOrigins = xCiteInfo.xpath('./origin')
36
+ axOrigins.each do |xOrigin|
37
+ name = xOrigin.text
38
+ unless name.empty?
39
+ contactId = Fgdc.find_contact_by_name(name)
40
+ if contactId.nil?
41
+ # add a new contact for this originator
42
+ contactId = Fgdc.add_contact(name, false)
43
+ aContacts << contactId
44
+ else
45
+ aContacts << contactId
46
+ end
47
+ end
48
+ end
49
+ unless aContacts.empty?
50
+ hResponsibility = Responsibility.unpack(aContacts, 'originator', hResponseObj)
51
+ unless hResponsibility.nil?
52
+ hCitation[:responsibleParties] << hResponsibility
53
+ end
54
+ end
55
+
56
+ # citation 8.2/8.3 (pubdate/pubtime) - publication date/time {date} (required) {time} (optional)
57
+ pubDate = xCiteInfo.xpath('./pubdate').text
58
+ pubTime = xCiteInfo.xpath('./pubtime').text
59
+ unless pubDate.empty?
60
+ hDate = Date.unpack(pubDate, pubTime, 'publication', hResponseObj)
61
+ unless hDate.nil?
62
+ hCitation[:dates] << hDate
63
+ end
64
+ end
65
+
66
+ # citation 8.4 (title) - citation title (required)
67
+ title = xCiteInfo.xpath('./title').text
68
+ unless title.empty?
69
+ hCitation[:title] = title
70
+ end
71
+
72
+ # citation 8.5 (edition) - edition
73
+ edition = xCiteInfo.xpath('./edition').text
74
+ unless edition.empty?
75
+ hCitation[:edition] = edition
76
+ end
77
+
78
+ # citation 8.6 (geoform) - edition
79
+ presentationForm = xCiteInfo.xpath('./geoform').text
80
+ unless presentationForm.empty?
81
+ hCitation[:presentationForms] << presentationForm
82
+ end
83
+
84
+ # citation 8.7 (serinfo) - series information
85
+ xSeries = xCiteInfo.xpath('./serinfo')
86
+ unless xSeries.empty?
87
+ hSeries = Series.unpack(xSeries, hResponseObj)
88
+ unless hSeries.nil?
89
+ hCitation[:series] = hSeries
90
+ end
91
+ end
92
+
93
+ # citation 8.8 (pubinfo) - publication information
94
+ xPublication = xCiteInfo.xpath('./pubinfo')
95
+ unless xPublication.empty?
96
+ hResponsibility = Publication.unpack(xPublication, hResponseObj)
97
+ unless hResponsibility.nil?
98
+ hCitation[:responsibleParties] << hResponsibility
99
+ end
100
+ end
101
+
102
+ # citation 8.9 (othercit) - other citation details
103
+ other = xCiteInfo.xpath('./othercit').text
104
+ unless other.empty?
105
+ hCitation[:otherDetails] << other
106
+ end
107
+
108
+ # citation 8.10 (onlink) - online linkage []
109
+ axOnLink = xCiteInfo.xpath('./onlink')
110
+ unless axOnLink.empty?
111
+ description = 'Link to the resource described in this citation'
112
+ axOnLink.each do |xLink|
113
+ onLink = xLink.text
114
+ unless onLink.empty?
115
+ hURI = OnlineResource.unpack(onLink, description, hResponseObj)
116
+ unless hURI.nil?
117
+ hCitation[:onlineResources] << hURI
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ # citation 8.11 (lworkcit) - larger work citation
124
+ xLWCitation = xCiteInfo.xpath('./lworkcit')
125
+ unless xLWCitation.empty?
126
+ hLWCitation = Citation.unpack(xLWCitation, hResponseObj)
127
+ unless hLWCitation.nil?
128
+ hAssResource = intMetadataClass.newAssociatedResource
129
+ hAssResource[:associationType] = 'largerWorkCitation'
130
+ hAssResource[:resourceCitation] = hLWCitation
131
+ Fgdc.add_associated_resource(hAssResource)
132
+ end
133
+ end
134
+
135
+ return hCitation
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,57 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc metadata date
3
+
4
+ # History:
5
+ # Stan Smith 2017-08-15 original script
6
+
7
+ require 'date'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+ require 'adiwg/mdtranslator/internal/module_dateTimeFun'
10
+ require_relative 'module_fgdc'
11
+ require_relative 'module_dateTime'
12
+
13
+ module ADIWG
14
+ module Mdtranslator
15
+ module Readers
16
+ module Fgdc
17
+
18
+ module Date
19
+
20
+ def self.unpack(date, time, type, hResponseObj)
21
+
22
+ # instance classes needed in script
23
+ intMetadataClass = InternalMetadata.new
24
+ hDate = intMetadataClass.newDate
25
+
26
+ if date.nil? || date == ''
27
+ hResponseObj[:readerExecutionMessages] << 'date string is missing from date conversion'
28
+ hResponseObj[:readerExecutionPass] = false
29
+ return nil
30
+ end
31
+
32
+ if type.nil? || type == ''
33
+ hResponseObj[:readerExecutionMessages] << 'date type is missing from date conversion'
34
+ hResponseObj[:readerExecutionPass] = false
35
+ return nil
36
+ end
37
+
38
+ hDateTime = DateTime.unpack(date, time, hResponseObj)
39
+
40
+ # build internal date object
41
+ unless hDateTime.nil?
42
+ hDate[:date] = hDateTime[:dateTime]
43
+ hDate[:dateResolution] = hDateTime[:dateResolution]
44
+ hDate[:dateType] = type
45
+ return hDate
46
+ end
47
+
48
+ return nil
49
+
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,108 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc metadata date
3
+
4
+ # History:
5
+ # Stan Smith 2017-08-15 original script
6
+
7
+ require 'date'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+ require 'adiwg/mdtranslator/internal/module_dateTimeFun'
10
+ require_relative 'module_fgdc'
11
+
12
+ module ADIWG
13
+ module Mdtranslator
14
+ module Readers
15
+ module Fgdc
16
+
17
+ module DateTime
18
+
19
+ def self.unpack(date, time, hResponseObj)
20
+
21
+ # instance classes needed in script
22
+ intMetadataClass = InternalMetadata.new
23
+ hDateTime = intMetadataClass.newDateTime
24
+
25
+ if date.nil? || date == ''
26
+ hResponseObj[:readerExecutionMessages] << 'date string is missing from dateTime conversion'
27
+ hResponseObj[:readerExecutionPass] = false
28
+ return nil
29
+ end
30
+
31
+ # convert date from fgdc to iso format
32
+ year = date.byteslice(0,4)
33
+ month = date.byteslice(4,2)
34
+ day = date.byteslice(6,2)
35
+ month = '01' if month.nil? || month == ''
36
+ day = '01' if day.nil? || day == ''
37
+ dtIn = year + '-' + month + '-' + day
38
+
39
+ # add time element to date string
40
+ if time.empty?
41
+ dtIn = dtIn + 'T' + '00:00:00'
42
+ else
43
+ aScan = time.scan(/:/)
44
+ if aScan.empty?
45
+ hour = time.byteslice(0,2)
46
+ minute = time.byteslice(2,2)
47
+ second = time.byteslice(4,2)
48
+ else
49
+ aTime = time.split(':')
50
+ hour = aTime[0]
51
+ minute = aTime[1]
52
+ second = aTime[2]
53
+ end
54
+ minute = '00' if minute.nil? || minute == ''
55
+ second = '00' if second.nil? || second == ''
56
+ dtIn = dtIn + 'T' + hour + ':' + minute + ':' + second
57
+ end
58
+
59
+ # determine if date/time is 'universal time' or other
60
+ timeFlag = Fgdc.get_metadata_time_convention
61
+ timeFlag = 'local time' if timeFlag.nil? || timeFlag == ''
62
+
63
+ # add offset to date/time string
64
+ if timeFlag == 'universal time'
65
+ dtIn = dtIn + '+00:00'
66
+ else
67
+ timeOffset = Time.now.gmt_offset
68
+ aOffset = timeOffset.divmod(3600)
69
+ hOffset = aOffset[0]
70
+ mOffset = aOffset[1] * 60
71
+ if hOffset >= 0
72
+ zone = '+' + '%02d' % hOffset + ':' + '%02d' % mOffset
73
+ else
74
+ zone = '%03d' % hOffset + ':' + '%02d' % mOffset
75
+ end
76
+ dtIn = dtIn + zone
77
+ end
78
+
79
+ # if dateTimeFromString fails, [0] = nil; [1] = 'ERROR'
80
+ aDateTimeReturn = AdiwgDateTimeFun.dateTimeFromString(dtIn)
81
+ if aDateTimeReturn[1] == 'ERROR'
82
+ hResponseObj[:readerExecutionMessages] << 'Date string is invalid'
83
+ hResponseObj[:readerExecutionPass] = false
84
+ return nil
85
+ end
86
+
87
+ # if not 'universal time' change the offset to utc
88
+ dateTimeReturn = aDateTimeReturn[0]
89
+ if timeFlag == 'universal time'
90
+ utc = dateTimeReturn
91
+ else
92
+ utc = dateTimeReturn.new_offset(Rational(0,24))
93
+ end
94
+
95
+ # build internal dateTime object
96
+ hDateTime[:dateTime] = utc
97
+ hDateTime[:dateResolution] = aDateTimeReturn[1]
98
+
99
+ return hDateTime
100
+
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,28 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc distribution
3
+
4
+ # History:
5
+ # Stan Smith 2017-08-15 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+
10
+ module ADIWG
11
+ module Mdtranslator
12
+ module Readers
13
+ module Fgdc
14
+
15
+ module Distribution
16
+
17
+ def self.unpack(xDistribution, hResponseObj)
18
+
19
+
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc entity and attribute
3
+
4
+ # History:
5
+ # Stan Smith 2017-08-15 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+
10
+ module ADIWG
11
+ module Mdtranslator
12
+ module Readers
13
+ module Fgdc
14
+
15
+ module EntityAttribute
16
+
17
+ def self.unpack(xEntity, hResponseObj)
18
+
19
+
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,193 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc metadata
3
+
4
+ # History:
5
+ # Stan Smith 2017-08-10 original script
6
+
7
+ require 'nokogiri'
8
+ require 'uuidtools'
9
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
10
+ require_relative 'module_identification'
11
+ require_relative 'module_quality'
12
+ require_relative 'module_spatialOrganization'
13
+ require_relative 'module_spatialReference'
14
+ require_relative 'module_entityAttribute'
15
+ require_relative 'module_distribution'
16
+ require_relative 'module_metadataInfo'
17
+
18
+ module ADIWG
19
+ module Mdtranslator
20
+ module Readers
21
+ module Fgdc
22
+
23
+ module Fgdc
24
+
25
+ def self.unpack(xDoc, hResponseObj)
26
+
27
+ # instance classes needed in script
28
+ intMetadataClass = InternalMetadata.new
29
+
30
+ intObj = intMetadataClass.newBase
31
+ @intObj = intObj
32
+ @contacts = intObj[:contacts]
33
+ @xDoc = xDoc
34
+
35
+ # build basic mdTranslator internal object
36
+ hMetadata = intMetadataClass.newMetadata
37
+ hMetadataInfo = intMetadataClass.newMetadataInfo
38
+ hResourceInfo = intMetadataClass.newResourceInfo
39
+ hMetadata[:metadataInfo] = hMetadataInfo
40
+ hMetadata[:resourceInfo] = hResourceInfo
41
+ intObj[:metadata] = hMetadata
42
+
43
+ xMetadata = xDoc.xpath('./metadata')
44
+
45
+ # metadata (idinfo 1) - identification information (required)
46
+ xIdInfo = xMetadata.xpath('./idinfo')
47
+ unless xIdInfo.empty?
48
+ Identification.unpack(xIdInfo, intObj, hResponseObj)
49
+ end
50
+ if xIdInfo.empty?
51
+ hResponseObj[:readerExecutionMessages] << 'FGDC is missing identification information section (idinfo)'
52
+ end
53
+
54
+ # metadata (dataqual 2) - data quality
55
+ xDataQual = xMetadata.xpath('./dataqual')
56
+ unless xDataQual.empty?
57
+ Quality.unpack(xDataQual, hResponseObj)
58
+ end
59
+
60
+ # metadata (spdoinfo 3) - spatial data organization
61
+ xSpatialOrg = xMetadata.xpath('./spdoinfo')
62
+ unless xSpatialOrg.empty?
63
+ SpatialOrganization.unpack(xSpatialOrg, hResponseObj)
64
+ end
65
+
66
+ # metadata (spref 4) - spatial reference
67
+ xSpatialRef = xMetadata.xpath('./spref')
68
+ unless xSpatialRef.empty?
69
+ SpatialReference.unpack(xSpatialRef, hResponseObj)
70
+ end
71
+
72
+ # metadata (eainfo 5) - entity and attribute
73
+ xEntity = xMetadata.xpath('./eainfo')
74
+ unless xEntity.empty?
75
+ EntityAttribute.unpack(xEntity, hResponseObj)
76
+ end
77
+
78
+ # metadata (distinfo 6) - distribution information
79
+ xDistribution = xMetadata.xpath('./distinfo')
80
+ unless xDistribution.empty?
81
+ Distribution.unpack(xDistribution, hResponseObj)
82
+ end
83
+
84
+ # metadata (metainfo 7) - metadata reference (required)
85
+ xMetaInfo = xMetadata.xpath('./metainfo')
86
+ unless xMetaInfo.empty?
87
+ MetadataInformation.unpack(xMetaInfo, hResponseObj)
88
+ end
89
+ if xMetaInfo.empty?
90
+ hResponseObj[:readerExecutionMessages] << 'FGDC is missing metadata information section (metainfo)'
91
+ end
92
+
93
+ return intObj
94
+
95
+ end
96
+
97
+ # find the array pointer and type for a contact
98
+ def self.find_contact_by_id(contactId)
99
+ contactIndex = nil
100
+ contactType = nil
101
+ unless @contacts.empty?
102
+ @contacts.each_with_index do |contact, i|
103
+ if contact[:contactId] == contactId
104
+ if contact[:isOrganization]
105
+ contactType = 'organization'
106
+ else
107
+ contactType = 'individual'
108
+ end
109
+ contactIndex = i
110
+ end
111
+ end
112
+ end
113
+ return contactIndex, contactType
114
+ end
115
+
116
+ # find contact id for a name
117
+ def self.find_contact_by_name(contactName)
118
+ @contacts.each do |contact|
119
+ if contact[:name] == contactName
120
+ return contact[:contactId]
121
+ end
122
+ end
123
+ return nil
124
+ end
125
+
126
+ # add new contact to contacts array
127
+ def self.add_contact(name, isOrg)
128
+ contactId = find_contact_by_name(name)
129
+ if contactId.nil?
130
+ intMetadataClass = InternalMetadata.new
131
+ hContact = intMetadataClass.newContact
132
+ contactId = UUIDTools::UUID.random_create.to_s
133
+ hContact[:contactId] = contactId
134
+ hContact[:name] = name
135
+ hContact[:isOrganization] = isOrg
136
+ @contacts << hContact
137
+ end
138
+ return contactId
139
+ end
140
+
141
+ # return contact by id
142
+ def self.get_contact_by_id(contactId)
143
+ index = find_contact_by_id(contactId)[0]
144
+ unless index.nil?
145
+ return @contacts[index]
146
+ end
147
+ return nil
148
+ end
149
+
150
+ # add or replace the contact
151
+ def self.set_contact(hContact)
152
+ index = find_contact_by_id(hContact[:contactId])[0]
153
+ if index.nil?
154
+ @contacts << hContact
155
+ index = @contacts.length - 1
156
+ else
157
+ @contacts[index] = hContact
158
+ end
159
+ return index
160
+ end
161
+
162
+ # set an internal object for tests
163
+ def self.set_intObj(intObj)
164
+ @intObj = intObj
165
+ @contacts = @intObj[:contacts]
166
+ end
167
+
168
+ # get internal object for test modules
169
+ def self.get_intObj
170
+ return @intObj
171
+ end
172
+
173
+ # get metadata time convention
174
+ def self.get_metadata_time_convention
175
+ return @xDoc.xpath('./metadata/metainfo/mettc').text
176
+ end
177
+
178
+ # set @xDoc for minitests
179
+ def self.set_xDoc(xDoc)
180
+ @xDoc = xDoc
181
+ end
182
+
183
+ # add new associated resource
184
+ def self.add_associated_resource(hResource)
185
+ @intObj[:metadata][:associatedResources] << hResource
186
+ end
187
+
188
+ end
189
+
190
+ end
191
+ end
192
+ end
193
+ end