rcap 1.3.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/README.md +78 -151
  3. data/Rakefile +1 -1
  4. data/lib/rcap/alert.rb +2 -2
  5. data/lib/rcap/base/alert.rb +446 -0
  6. data/lib/rcap/base/area.rb +228 -0
  7. data/lib/rcap/base/circle.rb +121 -0
  8. data/lib/rcap/base/event_code.rb +6 -0
  9. data/lib/rcap/base/geocode.rb +6 -0
  10. data/lib/rcap/base/info.rb +498 -0
  11. data/lib/rcap/base/parameter.rb +88 -0
  12. data/lib/rcap/base/point.rb +87 -0
  13. data/lib/rcap/base/polygon.rb +120 -0
  14. data/lib/rcap/base/resource.rb +168 -0
  15. data/lib/rcap/cap_1_0/alert.rb +59 -342
  16. data/lib/rcap/cap_1_0/area.rb +13 -188
  17. data/lib/rcap/cap_1_0/circle.rb +2 -100
  18. data/lib/rcap/cap_1_0/event_code.rb +8 -3
  19. data/lib/rcap/cap_1_0/geocode.rb +8 -3
  20. data/lib/rcap/cap_1_0/info.rb +16 -468
  21. data/lib/rcap/cap_1_0/parameter.rb +9 -67
  22. data/lib/rcap/cap_1_0/point.rb +2 -61
  23. data/lib/rcap/cap_1_0/polygon.rb +5 -95
  24. data/lib/rcap/cap_1_0/resource.rb +4 -144
  25. data/lib/rcap/cap_1_1/alert.rb +7 -412
  26. data/lib/rcap/cap_1_1/area.rb +13 -188
  27. data/lib/rcap/cap_1_1/circle.rb +2 -100
  28. data/lib/rcap/cap_1_1/event_code.rb +8 -3
  29. data/lib/rcap/cap_1_1/geocode.rb +7 -3
  30. data/lib/rcap/cap_1_1/info.rb +127 -386
  31. data/lib/rcap/cap_1_1/parameter.rb +4 -76
  32. data/lib/rcap/cap_1_1/point.rb +2 -61
  33. data/lib/rcap/cap_1_1/polygon.rb +5 -95
  34. data/lib/rcap/cap_1_1/resource.rb +37 -143
  35. data/lib/rcap/cap_1_2/alert.rb +8 -413
  36. data/lib/rcap/cap_1_2/area.rb +13 -188
  37. data/lib/rcap/cap_1_2/circle.rb +2 -100
  38. data/lib/rcap/cap_1_2/event_code.rb +8 -3
  39. data/lib/rcap/cap_1_2/geocode.rb +8 -3
  40. data/lib/rcap/cap_1_2/info.rb +132 -419
  41. data/lib/rcap/cap_1_2/parameter.rb +4 -76
  42. data/lib/rcap/cap_1_2/point.rb +2 -61
  43. data/lib/rcap/cap_1_2/polygon.rb +5 -92
  44. data/lib/rcap/cap_1_2/resource.rb +31 -134
  45. data/lib/rcap/config.rb +3 -0
  46. data/lib/{extensions → rcap/extensions}/array.rb +1 -1
  47. data/lib/rcap/extensions/date.rb +11 -0
  48. data/lib/{extensions → rcap/extensions}/date_time.rb +2 -5
  49. data/lib/{extensions → rcap/extensions}/string.rb +1 -1
  50. data/lib/{extensions → rcap/extensions}/time.rb +2 -4
  51. data/lib/rcap/utilities.rb +11 -11
  52. data/lib/rcap/validations.rb +7 -2
  53. data/lib/rcap/version.rb +1 -1
  54. data/lib/rcap.rb +21 -4
  55. data/spec/alert_spec.rb +69 -37
  56. data/spec/cap_1_0/alert_spec.rb +46 -61
  57. data/spec/cap_1_0/area_spec.rb +77 -37
  58. data/spec/cap_1_0/circle_spec.rb +26 -6
  59. data/spec/cap_1_0/event_code_spec.rb +10 -3
  60. data/spec/cap_1_0/geocode_spec.rb +11 -4
  61. data/spec/cap_1_0/info_spec.rb +74 -77
  62. data/spec/cap_1_0/parameter_spec.rb +18 -5
  63. data/spec/cap_1_0/point_spec.rb +9 -2
  64. data/spec/cap_1_0/polygon_spec.rb +52 -9
  65. data/spec/cap_1_0/resource_spec.rb +28 -21
  66. data/spec/cap_1_1/alert_spec.rb +47 -60
  67. data/spec/cap_1_1/area_spec.rb +66 -43
  68. data/spec/cap_1_1/circle_spec.rb +29 -6
  69. data/spec/cap_1_1/event_code_spec.rb +11 -3
  70. data/spec/cap_1_1/geocode_spec.rb +11 -3
  71. data/spec/cap_1_1/info_spec.rb +262 -118
  72. data/spec/cap_1_1/parameter_spec.rb +12 -3
  73. data/spec/cap_1_1/point_spec.rb +8 -2
  74. data/spec/cap_1_1/polygon_spec.rb +57 -18
  75. data/spec/cap_1_1/resource_spec.rb +70 -20
  76. data/spec/cap_1_2/alert_spec.rb +97 -110
  77. data/spec/cap_1_2/area_spec.rb +59 -41
  78. data/spec/cap_1_2/circle_spec.rb +15 -8
  79. data/spec/cap_1_2/event_code_spec.rb +11 -3
  80. data/spec/cap_1_2/geocode_spec.rb +11 -3
  81. data/spec/cap_1_2/info_spec.rb +266 -119
  82. data/spec/cap_1_2/parameter_spec.rb +11 -3
  83. data/spec/cap_1_2/point_spec.rb +10 -3
  84. data/spec/cap_1_2/polygon_spec.rb +25 -10
  85. data/spec/cap_1_2/resource_spec.rb +33 -28
  86. data/spec/{utilities_spec.rb → extensions_spec.rb} +0 -0
  87. data/spec/validations_spec.rb +18 -2
  88. metadata +20 -46
@@ -1,5 +1,6 @@
1
1
  module RCAP
2
2
  module CAP_1_2
3
+
3
4
  # In Info object is valid if
4
5
  # * it has an event
5
6
  # * it has an urgency with a valid value
@@ -8,263 +9,69 @@ module RCAP
8
9
  # * all categories are valid and categories has at minimum 1 entry
9
10
  # * all Resource objects in the resources collection are valid
10
11
  # * all Area objects in the areas collection are valid
11
- class Info
12
- include Validation
13
-
14
- CATEGORY_GEO = "Geo"
15
- CATEGORY_MET = "Met"
16
- CATEGORY_SAFETY = "Safety"
17
- CATEGORY_SECURITY = "Security"
18
- CATEGORY_RESCUE = "Rescue"
19
- CATEGORY_FIRE = "Fire"
20
- CATEGORY_HEALTH = "Health"
21
- CATEGORY_ENV = "Env"
22
- CATEGORY_TRANSPORT = "Transport"
23
- CATEGORY_INFRA = "Infra"
24
- CATEGORY_CBRNE = "CBRNE"
25
- CATEGORY_OTHER = "Other"
26
- # Valid values for categories
27
- VALID_CATEGORIES = [ CATEGORY_GEO, CATEGORY_MET, CATEGORY_SAFETY,
28
- CATEGORY_SECURITY, CATEGORY_RESCUE, CATEGORY_FIRE, CATEGORY_HEALTH,
29
- CATEGORY_ENV, CATEGORY_TRANSPORT, CATEGORY_INFRA, CATEGORY_CBRNE,
30
- CATEGORY_OTHER ]
31
-
32
- RESPONSE_TYPE_SHELTER = "Shelter"
33
- RESPONSE_TYPE_EVACUATE = "Evacuate"
34
- RESPONSE_TYPE_PREPARE = "Prepare"
35
- RESPONSE_TYPE_EXECUTE = "Execute"
36
- RESPONSE_TYPE_MONITOR = "Monitor"
37
- RESPONSE_TYPE_ASSESS = "Assess"
38
- RESPONSE_TYPE_ALL_CLEAR = "All Clear"
39
- RESPONSE_TYPE_AVOID = "Avoid"
40
- RESPONSE_TYPE_NONE = "None"
12
+ class Info < RCAP::Base::Info
13
+
14
+ RESPONSE_TYPE_SHELTER = "Shelter"
15
+ RESPONSE_TYPE_EVACUATE = "Evacuate"
16
+ RESPONSE_TYPE_PREPARE = "Prepare"
17
+ RESPONSE_TYPE_EXECUTE = "Execute"
18
+ RESPONSE_TYPE_MONITOR = "Monitor"
19
+ RESPONSE_TYPE_ASSESS = "Assess"
20
+ RESPONSE_TYPE_NONE = "None"
41
21
  # Valid values for response_type
42
- VALID_RESPONSE_TYPES = [ RESPONSE_TYPE_SHELTER, RESPONSE_TYPE_EVACUATE,
43
- RESPONSE_TYPE_PREPARE, RESPONSE_TYPE_EXECUTE, RESPONSE_TYPE_MONITOR,
44
- RESPONSE_TYPE_ASSESS, RESPONSE_TYPE_AVOID, RESPONSE_TYPE_ALL_CLEAR, RESPONSE_TYPE_NONE ]
22
+ VALID_RESPONSE_TYPES = [ RESPONSE_TYPE_SHELTER, RESPONSE_TYPE_EVACUATE, RESPONSE_TYPE_PREPARE, RESPONSE_TYPE_EXECUTE, RESPONSE_TYPE_MONITOR, RESPONSE_TYPE_ASSESS, RESPONSE_TYPE_NONE ]
45
23
 
46
- URGENCY_IMMEDIATE = "Immediate"
47
- URGENCY_EXPECTED = "Expected"
48
- URGENCY_FUTURE = "Future"
49
- URGENCY_PAST = "Past"
50
- URGENCY_UNKNOWN = "Unknown"
51
- # Valid values for urgency
52
- VALID_URGENCIES = [ URGENCY_IMMEDIATE, URGENCY_EXPECTED, URGENCY_FUTURE,
53
- URGENCY_PAST, URGENCY_UNKNOWN ]
54
24
 
55
- SEVERITY_EXTREME = "Extreme"
56
- SEVERITY_SEVERE = "Severe"
57
- SEVERITY_MODERATE = "Moderate"
58
- SEVERITY_MINOR = "Minor"
59
- SEVERITY_UNKNOWN = "Unknown"
60
- # Valid values for severity
61
- VALID_SEVERITIES = [ SEVERITY_EXTREME, SEVERITY_SEVERE, SEVERITY_MODERATE,
62
- SEVERITY_MINOR, SEVERITY_UNKNOWN ]
63
-
64
- CERTAINTY_OBSERVED = "Observed"
65
- CERTAINTY_LIKELY = "Likely"
66
- CERTAINTY_POSSIBLE = "Possible"
67
- CERTAINTY_UNLIKELY = "Unlikely"
68
- CERTAINTY_UNKNOWN = "Unknown"
25
+ CERTAINTY_OBSERVED = "Observed"
69
26
  # Valid valies for certainty
70
- VALID_CERTAINTIES = [ CERTAINTY_OBSERVED, CERTAINTY_LIKELY,
71
- CERTAINTY_POSSIBLE, CERTAINTY_UNLIKELY, CERTAINTY_UNKNOWN ]
72
-
73
- XML_ELEMENT_NAME = 'info'
74
- LANGUAGE_ELEMENT_NAME = 'language'
75
- CATEGORY_ELEMENT_NAME = 'category'
76
- EVENT_ELEMENT_NAME = 'event'
77
- RESPONSE_TYPE_ELEMENT_NAME = 'responseType'
78
- URGENCY_ELEMENT_NAME = 'urgency'
79
- SEVERITY_ELEMENT_NAME = 'severity'
80
- CERTAINTY_ELEMENT_NAME = 'certainty'
81
- AUDIENCE_ELEMENT_NAME = 'audience'
82
- EVENT_CODE_ELEMENT_NAME = 'eventCode'
83
- EFFECTIVE_ELEMENT_NAME = 'effective'
84
- ONSET_ELEMENT_NAME = 'onset'
85
- EXPIRES_ELEMENT_NAME = 'expires'
86
- SENDER_NAME_ELEMENT_NAME = 'senderName'
87
- HEADLINE_ELEMENT_NAME = 'headline'
88
- DESCRIPTION_ELEMENT_NAME = 'description'
89
- INSTRUCTION_ELEMENT_NAME = 'instruction'
90
- WEB_ELEMENT_NAME = 'web'
91
- CONTACT_ELEMENT_NAME = 'contact'
27
+ VALID_CERTAINTIES = [ CERTAINTY_OBSERVED, CERTAINTY_LIKELY, CERTAINTY_POSSIBLE, CERTAINTY_UNLIKELY, CERTAINTY_UNKNOWN ]
92
28
 
93
- XPATH = "cap:#{ XML_ELEMENT_NAME }"
94
- LANGUAGE_XPATH = "cap:#{ LANGUAGE_ELEMENT_NAME }"
95
- EVENT_XPATH = "cap:#{ EVENT_ELEMENT_NAME }"
96
- URGENCY_XPATH = "cap:#{ URGENCY_ELEMENT_NAME }"
97
- RESPONSE_TYPE_XPATH = "cap:#{ RESPONSE_TYPE_ELEMENT_NAME }"
98
- CATEGORY_XPATH = "cap:#{ CATEGORY_ELEMENT_NAME }"
99
- SEVERITY_XPATH = "cap:#{ SEVERITY_ELEMENT_NAME }"
100
- CERTAINTY_XPATH = "cap:#{ CERTAINTY_ELEMENT_NAME }"
101
- AUDIENCE_XPATH = "cap:#{ AUDIENCE_ELEMENT_NAME }"
102
- EVENT_CODE_XPATH = "cap:#{ EVENT_CODE_ELEMENT_NAME }"
103
- EFFECTIVE_XPATH = "cap:#{ EFFECTIVE_ELEMENT_NAME }"
104
- ONSET_XPATH = "cap:#{ ONSET_ELEMENT_NAME }"
105
- EXPIRES_XPATH = "cap:#{ EXPIRES_ELEMENT_NAME }"
106
- SENDER_NAME_XPATH = "cap:#{ SENDER_NAME_ELEMENT_NAME }"
107
- HEADLINE_XPATH = "cap:#{ HEADLINE_ELEMENT_NAME }"
108
- DESCRIPTION_XPATH = "cap:#{ DESCRIPTION_ELEMENT_NAME }"
109
- INSTRUCTION_XPATH = "cap:#{ INSTRUCTION_ELEMENT_NAME }"
110
- WEB_XPATH = "cap:#{ WEB_ELEMENT_NAME }"
111
- CONTACT_XPATH = "cap:#{ CONTACT_ELEMENT_NAME }"
29
+ RESPONSE_TYPE_ELEMENT_NAME = 'responseType'
30
+ RESPONSE_TYPE_XPATH = "cap:#{ RESPONSE_TYPE_ELEMENT_NAME }"
112
31
 
113
- DEFAULT_LANGUAGE = 'en-US'
114
-
115
- validates_presence_of( :event, :urgency, :severity, :certainty )
116
32
  validates_length_of( :categories, :minimum => 1 )
117
- validates_inclusion_of( :certainty, :allow_nil => true, :in => VALID_CERTAINTIES, :message => "can only be assigned the following values: #{ VALID_CERTAINTIES.join(', ') }")
118
- validates_inclusion_of( :severity, :allow_nil => true, :in => VALID_SEVERITIES, :message => "can only be assigned the following values: #{ VALID_SEVERITIES.join(', ') }" )
119
- validates_inclusion_of( :urgency, :allow_nil => true, :in => VALID_URGENCIES, :message => "can only be assigned the following values: #{ VALID_URGENCIES.join(', ') }" )
120
33
  validates_inclusion_of_members_of( :response_types, :in => VALID_RESPONSE_TYPES, :allow_blank => true )
121
- validates_inclusion_of_members_of( :categories, :in => VALID_CATEGORIES, :allow_blank => true )
122
- validates_collection_of( :resources, :areas, :event_codes, :parameters )
123
-
124
- # @return [String]
125
- attr_accessor( :event )
126
- # @return [String] Value can only be one of {VALID_URGENCIES}
127
- attr_accessor( :urgency )
128
- # @return [String] Value can only be one of {VALID_SEVERITIES}
129
- attr_accessor( :severity )
130
- # @return [String] Value can only be one of {VALID_CERTAINTIES}
131
- attr_accessor( :certainty )
132
- # @return [String]
133
- attr_accessor( :language )
134
- # @return [String]
135
- attr_accessor( :audience )
136
- # @return [DateTime] Effective start time of information
137
- attr_accessor( :effective )
138
- # @return [DateTime] Expected start of event
139
- attr_accessor( :onset )
140
- # @return [DateTime] Effective expiry time of information
141
- attr_accessor( :expires )
142
- # @return [String]
143
- attr_accessor( :sender_name )
144
- # @return [String]
145
- attr_accessor( :headline )
146
- # @return [String]
147
- attr_accessor( :description )
148
- # @return [String]
149
- attr_accessor( :instruction )
150
- # @return [String]
151
- attr_accessor( :web )
152
- # @return [String]
153
- attr_accessor( :contact )
34
+ validates_inclusion_of( :certainty, :allow_nil => true, :in => VALID_CERTAINTIES, :message => "can only be assigned the following values: #{ VALID_CERTAINTIES.join(', ') }")
154
35
 
155
- # @return [Array<String>] Collection of textual categories; elements can be one of {VALID_CATEGORIES}
156
- attr_reader( :categories )
157
- # @return [Array<String>] Collection of textual response types; elements must be from {VALID_RESPONSE_TYPES}
36
+ # @return [Array<String>] Collection of textual response types; elements must be from {VALID_RESPONSE_TYPES}
158
37
  attr_reader( :response_types )
159
- # @return [Array<EventCode>] Collection of {EventCode} objects
160
- attr_reader( :event_codes )
161
- # @return [Array<Parameter>] Collection of {Parameter} objects
162
- attr_reader( :parameters )
163
- # @return [Array<Resource> Collection of {Resource} objects
164
- attr_reader( :resources )
165
- # @return [Array<Area>] Collection of {Area} objects
166
- attr_reader( :areas )
167
38
 
168
- # @param [Hash] attributes
169
- # @option attributes [String] :language Defaults to {DEFAULT_LANGUAGE}
170
- # @option attributes [Array<String>] :categories Collection of categories in {VALID_CATEGORIES}
171
- # @option attributes [String] :audience
172
- # @option attributes [String] :event
173
- # @option attributes [Array<String>] :response_types Collection of textual response types from {VALID_RESPONSE_TYPES}
174
- # @option attributes [String] :urgency A member of {VALID_URGENCIES}
175
- # @option attributes [String] :severity A member of {VALID_SEVERITIES}
176
- # @option attributes [String] :certainty A member of {VALID_CERTAINTIES}
177
- # @option attributes [DateTime] :effective
178
- # @option attributes [DateTime] :onset
179
- # @option attributes [DateTime] :expires
180
- # @option attributes [Array<EventCode>] :event_codes Collection of {EventCode} objects
181
- # @option attributes [String] :sender_name
182
- # @option attributes [String] :headline
183
- # @option attributes [String] :description
184
- # @option attributes [String] :instruction
185
- # @option attributes [String] :web URL
186
- # @option attributes [String] :contact
187
- # @option attributes [Array<Parameter>] :parameters Collection of {Parameter} objects
188
- # @option attributes [Array<Resource>] :resources Collection of {Resource} objects
189
- # @option attributes [Array<Area>] :areas Collection of {Area} objects
190
- def initialize( attributes = {} )
191
- @language = attributes[ :language ] || DEFAULT_LANGUAGE
192
- @categories = Array( attributes[ :categories ])
193
- @audience = attributes [ :audience ]
194
- @event = attributes [ :event ]
195
- @response_types = Array( attributes[ :response_types ])
196
- @urgency = attributes[ :urgency ]
197
- @severity = attributes[ :severity ]
198
- @certainty = attributes[ :certainty ]
199
- @effective = attributes[ :effective ]
200
- @onset = attributes[ :onset ]
201
- @expires = attributes[ :expires ]
202
- @event_codes = Array( attributes[ :event_codes ])
203
- @sender_name = attributes[ :sender_name ]
204
- @headline = attributes[ :headline ]
205
- @description = attributes[ :description ]
206
- @instruction = attributes[ :instruction ]
207
- @web = attributes[ :web ]
208
- @contact = attributes[ :contact ]
209
- @parameters = Array( attributes[ :parameters ])
210
- @resources = Array( attributes[ :resources ])
211
- @areas = Array( attributes[ :areas ])
39
+ # Initialises a new Info object which will be yielded to an attached block if given
40
+ #
41
+ # @yieldparam info [Info] An instance of an Info object
42
+ # @return [Info]
43
+ def initialize
44
+ @response_types = []
45
+ super
212
46
  end
213
47
 
214
- # Creates a new EventCode object and adds it to the event_codes array. The
215
- # event_code_attributes are passed as a parameter to EventCode.new.
216
- #
217
- # @see EventCode#initialize
218
- #
219
- # @param [Hash] event_code_attributes (see EventCode#initialize)
220
- # @return [EventCode]
221
- def add_event_code( event_code_attributes = {})
222
- event_code = EventCode.new( event_code_attributes )
223
- @event_codes << event_code
224
- event_code
48
+ # @return [Class]
49
+ def event_code_class
50
+ EventCode
225
51
  end
226
52
 
227
- # Creates a new Parameter object and adds it to the parameters array. The
228
- # parameter_attributes are passed as a parameter to Parameter.new.
229
- #
230
- # @see Parameter#initialize
231
- #
232
- # @param [Hash] parameter_attributes (see Parameter#initialize)
233
- # @return [Parameter]
234
- def add_parameter( parameter_attributes = {})
235
- parameter = Parameter.new( parameter_attributes )
236
- @parameters << parameter
237
- parameter
53
+ # @return [Class]
54
+ def parameter_class
55
+ Parameter
238
56
  end
239
57
 
240
- # Creates a new Resource object and adds it to the resources array. The
241
- # resource_attributes are passed as a parameter to Resource.new.
242
- #
243
- # @see Resource#initialize
244
- #
245
- # @param [Hash] resource_attributes (See Resource#initialize)
246
- # @return [Resource]
247
- def add_resource( resource_attributes = {})
248
- resource = Resource.new( resource_attributes )
249
- @resources << resource
250
- resource
58
+ # @return [Class]
59
+ def area_class
60
+ Area
251
61
  end
252
62
 
253
- # Creates a new Area object and adds it to the areas array. The
254
- # area_attributes are passed as a parameter to Area.new.
255
- #
256
- # @see Area#initialize
257
- #
258
- # @param [Hash] area_attributes (see Area#initialize)
259
- # @return [Area]
260
- def add_area( area_attributes = {})
261
- area = Area.new( area_attributes )
262
- @areas << area
263
- area
63
+ # @return [Class]
64
+ def resource_class
65
+ Resource
66
+ end
67
+
68
+ # @return [String]
69
+ def xmlns
70
+ Alert::XMLNS
264
71
  end
265
72
 
266
73
  # @return [REXML::Element]
267
- def to_xml_element
74
+ def to_xml_element
268
75
  xml_element = REXML::Element.new( XML_ELEMENT_NAME )
269
76
  xml_element.add_element( LANGUAGE_ELEMENT_NAME ).add_text( @language ) if @language
270
77
  @categories.each do |category|
@@ -303,37 +110,37 @@ module RCAP
303
110
  end
304
111
 
305
112
  # @return [String]
306
- def to_xml
113
+ def to_xml
307
114
  self.to_xml_element.to_s
308
115
  end
309
116
 
310
117
  # @return [String]
311
- def inspect
118
+ def inspect
312
119
  info_inspect = "Language: #{ @language }\n"+
313
- "Categories: #{ @categories.to_s_for_cap }\n"+
314
- "Event: #{ @event }\n"+
315
- "Response Types: #{ @response_types.to_s_for_cap }\n"+
316
- "Urgency: #{ @urgency }\n"+
317
- "Severity: #{ @severity }\n"+
318
- "Certainty: #{ @certainty }\n"+
319
- "Audience: #{ @audience }\n"+
320
- "Event Codes: #{ @event_codes.inspect }\n"+
321
- "Effective: #{ @effective }\n"+
322
- "Onset: #{ @onset }\n"+
323
- "Expires: #{ @expires }\n"+
324
- "Sender Name: #{ @sender_name }\n"+
325
- "Headline: #{ @headline }\n"+
326
- "Description:\n"+
327
- @description.to_s.lines.map{ |line| " " + line }.join( "\n")+"\n"+
328
- "Instruction: #{ @instruction }\n"+
329
- "Web: #{ @web }\n"+
330
- "Contact: #{ @contact }\n"+
331
- "Parameters:\n"+
332
- @parameters.map{ |parameter| parameter.inspect }.join( "\n" )+"\n"+
333
- "Resources:\n"+
334
- @resources.map{ |resource| " " + resource.inspect }.join( "\n" )+"\n"+
335
- "Area:\n"+
336
- @areas.map{ |area| " #{ area }" }.join( "\n" )+"\n"
120
+ "Categories: #{ @categories.to_s_for_cap }\n"+
121
+ "Event: #{ @event }\n"+
122
+ "Response Types: #{ @response_types.to_s_for_cap }\n"+
123
+ "Urgency: #{ @urgency }\n"+
124
+ "Severity: #{ @severity }\n"+
125
+ "Certainty: #{ @certainty }\n"+
126
+ "Audience: #{ @audience }\n"+
127
+ "Event Codes: #{ @event_codes.inspect }\n"+
128
+ "Effective: #{ @effective }\n"+
129
+ "Onset: #{ @onset }\n"+
130
+ "Expires: #{ @expires }\n"+
131
+ "Sender Name: #{ @sender_name }\n"+
132
+ "Headline: #{ @headline }\n"+
133
+ "Description:\n"+
134
+ @description.to_s.lines.map{ |line| " " + line }.join( "\n")+"\n"+
135
+ "Instruction: #{ @instruction }\n"+
136
+ "Web: #{ @web }\n"+
137
+ "Contact: #{ @contact }\n"+
138
+ "Parameters:\n"+
139
+ @parameters.map{ |parameter| " " + parameter.inspect }.join( "\n" )+"\n"+
140
+ "Resources:\n"+
141
+ @resources.map{ |resource| " " + resource.inspect }.join( "\n" )+"\n"+
142
+ "Area:\n"+
143
+ @areas.map{ |area| " #{ area }" }.join( "\n" )+"\n"
337
144
  RCAP.format_lines_for_inspect( 'INFO', info_inspect )
338
145
  end
339
146
 
@@ -347,182 +154,88 @@ module RCAP
347
154
 
348
155
  # @param [REXML::Element] info_xml_element
349
156
  # @return [Info]
350
- def self.from_xml_element( info_xml_element )
351
- self.new(
352
- :language => RCAP.xpath_text( info_xml_element, LANGUAGE_XPATH, Alert::XMLNS ) || DEFAULT_LANGUAGE,
353
- :categories => RCAP.xpath_match( info_xml_element, CATEGORY_XPATH, Alert::XMLNS ).map{ |element| element.text },
354
- :event => RCAP.xpath_text( info_xml_element, EVENT_XPATH, Alert::XMLNS ),
355
- :response_types => RCAP.xpath_match( info_xml_element, RESPONSE_TYPE_XPATH, Alert::XMLNS ).map{ |element| element.text },
356
- :urgency => RCAP.xpath_text( info_xml_element, URGENCY_XPATH, Alert::XMLNS ),
357
- :severity => RCAP.xpath_text( info_xml_element, SEVERITY_XPATH, Alert::XMLNS ),
358
- :certainty => RCAP.xpath_text( info_xml_element, CERTAINTY_XPATH, Alert::XMLNS ),
359
- :audience => RCAP.xpath_text( info_xml_element, AUDIENCE_XPATH, Alert::XMLNS ),
360
- :effective => (( effective = RCAP.xpath_first( info_xml_element, EFFECTIVE_XPATH, Alert::XMLNS )) ? DateTime.parse( effective.text ) : nil ),
361
- :onset => (( onset = RCAP.xpath_first( info_xml_element, ONSET_XPATH, Alert::XMLNS )) ? DateTime.parse( onset.text ) : nil ),
362
- :expires => (( expires = RCAP.xpath_first( info_xml_element, EXPIRES_XPATH, Alert::XMLNS )) ? DateTime.parse( expires.text ) : nil ),
363
- :sender_name => RCAP.xpath_text( info_xml_element, SENDER_NAME_XPATH, Alert::XMLNS ),
364
- :headline => RCAP.xpath_text( info_xml_element, HEADLINE_XPATH, Alert::XMLNS ),
365
- :description => RCAP.xpath_text( info_xml_element, DESCRIPTION_XPATH, Alert::XMLNS ),
366
- :instruction => RCAP.xpath_text( info_xml_element, INSTRUCTION_XPATH, Alert::XMLNS ),
367
- :web => RCAP.xpath_text( info_xml_element, WEB_XPATH, Alert::XMLNS ),
368
- :contact => RCAP.xpath_text( info_xml_element, CONTACT_XPATH, Alert::XMLNS ),
369
- :event_codes => RCAP.xpath_match( info_xml_element, EventCode::XPATH, Alert::XMLNS ).map{ |element| EventCode.from_xml_element( element )},
370
- :parameters => RCAP.xpath_match( info_xml_element, Parameter::XPATH, Alert::XMLNS ).map{ |element| Parameter.from_xml_element( element )},
371
- :resources => RCAP.xpath_match( info_xml_element, Resource::XPATH, Alert::XMLNS ).map{ |element| Resource.from_xml_element( element )},
372
- :areas => RCAP.xpath_match( info_xml_element, Area::XPATH, Alert::XMLNS ).map{ |element| Area.from_xml_element( element )}
373
- )
157
+ def self.from_xml_element( info_xml_element )
158
+ super.tap do |info|
159
+ RCAP.xpath_match( info_xml_element, RESPONSE_TYPE_XPATH, Alert::XMLNS ).each do |element|
160
+ info.response_types << element.text
161
+ end
162
+ end
374
163
  end
375
164
 
376
- LANGUAGE_YAML = 'Language'
377
- CATEGORIES_YAML = 'Categories'
378
- EVENT_YAML = 'Event'
379
- RESPONSE_TYPES_YAML = 'Response Types'
380
- URGENCY_YAML = 'Urgency'
381
- SEVERITY_YAML = 'Severity'
382
- CERTAINTY_YAML = 'Certainty'
383
- AUDIENCE_YAML = 'Audience'
384
- EFFECTIVE_YAML = 'Effective'
385
- ONSET_YAML = 'Onset'
386
- EXPIRES_YAML = 'Expires'
387
- SENDER_NAME_YAML = 'Sender Name'
388
- HEADLINE_YAML = 'Headline'
389
- DESCRIPTION_YAML = 'Description'
390
- INSTRUCTION_YAML = 'Instruction'
391
- WEB_YAML = 'Web'
392
- CONTACT_YAML = 'Contact'
393
- EVENT_CODES_YAML = 'Event Codes'
394
- PARAMETERS_YAML = 'Parameters'
395
- RESOURCES_YAML = 'Resources'
396
- AREAS_YAML = 'Areas'
165
+ RESPONSE_TYPES_YAML = 'Response Types'
397
166
 
398
167
  # @return [String]
399
- def to_yaml( options = {} )
168
+ def to_yaml( options = {} )
400
169
  parameter_to_hash = lambda{ |hash, parameter| hash.merge( parameter.name => parameter.value )}
401
170
 
402
- RCAP.attribute_values_to_hash(
403
- [ LANGUAGE_YAML, @language ],
404
- [ CATEGORIES_YAML, @categories ],
405
- [ EVENT_YAML, @event ],
406
- [ RESPONSE_TYPES_YAML, @response_types ],
407
- [ URGENCY_YAML, @urgency ],
408
- [ SEVERITY_YAML, @severity ],
409
- [ CERTAINTY_YAML, @certainty ],
410
- [ AUDIENCE_YAML, @audience ],
411
- [ EFFECTIVE_YAML, @effective ],
412
- [ ONSET_YAML, @onset ],
413
- [ EXPIRES_YAML, @expires ],
414
- [ SENDER_NAME_YAML, @sender_name ],
415
- [ HEADLINE_YAML, @headline ],
416
- [ DESCRIPTION_YAML, @description ],
417
- [ INSTRUCTION_YAML, @instruction ],
418
- [ WEB_YAML, @web ],
419
- [ CONTACT_YAML, @contact ],
420
- [ EVENT_CODES_YAML, @event_codes.inject({}, &parameter_to_hash )],
421
- [ PARAMETERS_YAML, @parameters.inject({}, &parameter_to_hash )],
422
- [ RESOURCES_YAML, @resources ],
423
- [ AREAS_YAML, @areas ]).to_yaml( options )
171
+ RCAP.attribute_values_to_hash( [ LANGUAGE_YAML, @language ],
172
+ [ CATEGORIES_YAML, @categories ],
173
+ [ EVENT_YAML, @event ],
174
+ [ RESPONSE_TYPES_YAML, @response_types ],
175
+ [ URGENCY_YAML, @urgency ],
176
+ [ SEVERITY_YAML, @severity ],
177
+ [ CERTAINTY_YAML, @certainty ],
178
+ [ AUDIENCE_YAML, @audience ],
179
+ [ EFFECTIVE_YAML, RCAP.to_s_for_cap( @effective )],
180
+ [ ONSET_YAML, RCAP.to_s_for_cap( @onset )],
181
+ [ EXPIRES_YAML, RCAP.to_s_for_cap( @expires )],
182
+ [ SENDER_NAME_YAML, @sender_name ],
183
+ [ HEADLINE_YAML, @headline ],
184
+ [ DESCRIPTION_YAML, @description ],
185
+ [ INSTRUCTION_YAML, @instruction ],
186
+ [ WEB_YAML, @web ],
187
+ [ CONTACT_YAML, @contact ],
188
+ [ EVENT_CODES_YAML, @event_codes.inject({}, &parameter_to_hash )],
189
+ [ PARAMETERS_YAML, @parameters.inject({}, &parameter_to_hash )],
190
+ [ RESOURCES_YAML, @resources ],
191
+ [ AREAS_YAML, @areas ]).to_yaml( options )
424
192
  end
425
193
 
426
194
  # @param [Hash] info_yaml_data
427
195
  # @return [Info]
428
- def self.from_yaml_data( info_yaml_data )
429
- self.new(
430
- :language => info_yaml_data [ LANGUAGE_YAML ],
431
- :categories => info_yaml_data [ CATEGORIES_YAML ],
432
- :event => info_yaml_data [ EVENT_YAML ],
433
- :response_types => info_yaml_data [ RESPONSE_TYPES_YAML ],
434
- :urgency => info_yaml_data [ URGENCY_YAML ],
435
- :severity => info_yaml_data [ SEVERITY_YAML ],
436
- :certainty => info_yaml_data [ CERTAINTY_YAML ],
437
- :audience => info_yaml_data [ AUDIENCE_YAML ],
438
- :effective => ( effective = info_yaml_data[ EFFECTIVE_YAML ]).blank? ? nil : DateTime.parse( effective.to_s ),
439
- :onset => ( onset = info_yaml_data[ ONSET_YAML ]).blank? ? nil : DateTime.parse( onset.to_s ),
440
- :expires => ( expires = info_yaml_data[ EXPIRES_YAML ]).blank? ? nil : DateTime.parse( expires.to_s ),
441
- :sender_name => info_yaml_data [ SENDER_NAME_YAML ],
442
- :headline => info_yaml_data [ HEADLINE_YAML ],
443
- :description => info_yaml_data [ DESCRIPTION_YAML ],
444
- :instruction => info_yaml_data [ INSTRUCTION_YAML ],
445
- :web => info_yaml_data [ WEB_YAML ],
446
- :contact => info_yaml_data [ CONTACT_YAML ],
447
- :event_codes => Array( info_yaml_data [ EVENT_CODES_YAML ]).map{ |name,value| EventCode.new( :name => name, :value => value )},
448
- :parameters => Array( info_yaml_data [ PARAMETERS_YAML ]).map{ |parameter_yaml_data| Parameter.new( :name => name, :value => value )},
449
- :resources => Array( info_yaml_data [ RESOURCES_YAML ]).map{ |resource_yaml_data| Resource.from_yaml_data( resource_yaml_data )},
450
- :areas => Array( info_yaml_data [ AREAS_YAML ]).map{ |area_yaml_data| Area.from_yaml_data( area_yaml_data )}
451
- )
196
+ def self.from_yaml_data( info_yaml_data )
197
+ super.tap do |info|
198
+ Array( info_yaml_data [ RESPONSE_TYPES_YAML ]).each do |response_type|
199
+ info.response_types << response_type
200
+ end
201
+ end
452
202
  end
453
203
 
454
- LANGUAGE_KEY = 'language'
455
- CATEGORIES_KEY = 'categories'
456
- EVENT_KEY = 'event'
457
- RESPONSE_TYPES_KEY = 'response_types'
458
- URGENCY_KEY = 'urgency'
459
- SEVERITY_KEY = 'severity'
460
- CERTAINTY_KEY = 'certainty'
461
- AUDIENCE_KEY = 'audience'
462
- EFFECTIVE_KEY = 'effective'
463
- ONSET_KEY = 'onset'
464
- EXPIRES_KEY = 'expires'
465
- SENDER_NAME_KEY = 'sender_name'
466
- HEADLINE_KEY = 'headline'
467
- DESCRIPTION_KEY = 'description'
468
- INSTRUCTION_KEY = 'instruction'
469
- WEB_KEY = 'web'
470
- CONTACT_KEY = 'contact'
471
- RESOURCES_KEY = 'resources'
472
- EVENT_CODES_KEY = 'event_codes'
473
- PARAMETERS_KEY = 'parameters'
474
- AREAS_KEY = 'areas'
204
+ RESPONSE_TYPES_KEY = 'response_types'
475
205
 
476
206
  # @return [Hash]
477
- def to_h
478
- RCAP.attribute_values_to_hash(
479
- [ LANGUAGE_KEY, @language ],
480
- [ CATEGORIES_KEY, @categories ],
481
- [ EVENT_KEY, @event ],
482
- [ RESPONSE_TYPES_KEY, @response_types ],
483
- [ URGENCY_KEY, @urgency ],
484
- [ SEVERITY_KEY, @severity ],
485
- [ CERTAINTY_KEY, @certainty ],
486
- [ AUDIENCE_KEY, @audience ],
487
- [ EFFECTIVE_KEY, RCAP.to_s_for_cap( @effective )],
488
- [ ONSET_KEY, RCAP.to_s_for_cap( @onset )],
489
- [ EXPIRES_KEY, RCAP.to_s_for_cap( @expires )],
490
- [ SENDER_NAME_KEY, @sender_name ],
491
- [ HEADLINE_KEY, @headline ],
492
- [ DESCRIPTION_KEY, @description ],
493
- [ INSTRUCTION_KEY, @instruction ],
494
- [ WEB_KEY, @web ],
495
- [ CONTACT_KEY, @contact ],
496
- [ RESOURCES_KEY, @resources.map{ |resource| resource.to_h } ],
497
- [ EVENT_CODES_KEY, @event_codes.map{ |event_code| event_code.to_h } ],
498
- [ PARAMETERS_KEY, @parameters.map{ |parameter| parameter.to_h } ],
499
- [ AREAS_KEY, @areas.map{ |area| area.to_h }])
207
+ def to_h
208
+ RCAP.attribute_values_to_hash( [ LANGUAGE_KEY, @language ],
209
+ [ CATEGORIES_KEY, @categories ],
210
+ [ EVENT_KEY, @event ],
211
+ [ RESPONSE_TYPES_KEY, @response_types ],
212
+ [ URGENCY_KEY, @urgency ],
213
+ [ SEVERITY_KEY, @severity ],
214
+ [ CERTAINTY_KEY, @certainty ],
215
+ [ AUDIENCE_KEY, @audience ],
216
+ [ EFFECTIVE_KEY, RCAP.to_s_for_cap( @effective )],
217
+ [ ONSET_KEY, RCAP.to_s_for_cap( @onset )],
218
+ [ EXPIRES_KEY, RCAP.to_s_for_cap( @expires )],
219
+ [ SENDER_NAME_KEY, @sender_name ],
220
+ [ HEADLINE_KEY, @headline ],
221
+ [ DESCRIPTION_KEY, @description ],
222
+ [ INSTRUCTION_KEY, @instruction ],
223
+ [ WEB_KEY, @web ],
224
+ [ CONTACT_KEY, @contact ],
225
+ [ RESOURCES_KEY, @resources.map{ |resource| resource.to_h } ],
226
+ [ EVENT_CODES_KEY, @event_codes.map{ |event_code| event_code.to_h } ],
227
+ [ PARAMETERS_KEY, @parameters.map{ |parameter| parameter.to_h } ],
228
+ [ AREAS_KEY, @areas.map{ |area| area.to_h }])
500
229
  end
501
230
 
502
231
  # @param [Hash] info_hash
503
232
  # @return [Info]
504
- def self.from_h( info_hash )
505
- self.new( :language => info_hash[ LANGUAGE_KEY ],
506
- :categories => info_hash[ CATEGORIES_KEY ],
507
- :event => info_hash[ EVENT_KEY ],
508
- :response_types => info_hash[ RESPONSE_TYPES_KEY ],
509
- :urgency => info_hash[ URGENCY_KEY ],
510
- :severity => info_hash[ SEVERITY_KEY ],
511
- :certainty => info_hash[ CERTAINTY_KEY ],
512
- :audience => info_hash[ AUDIENCE_KEY ],
513
- :effective => RCAP.parse_datetime( info_hash[ EFFECTIVE_KEY ]),
514
- :onset => RCAP.parse_datetime( info_hash[ ONSET_KEY ]),
515
- :expires => RCAP.parse_datetime( info_hash[ EXPIRES_KEY ]),
516
- :sender_name => info_hash[ SENDER_NAME_KEY ],
517
- :headline => info_hash[ HEADLINE_KEY ],
518
- :description => info_hash[ DESCRIPTION_KEY ],
519
- :instruction => info_hash[ INSTRUCTION_KEY ],
520
- :web => info_hash[ WEB_KEY ],
521
- :contact => info_hash[ CONTACT_KEY ],
522
- :resources => Array( info_hash[ RESOURCES_KEY ]).map{ |resource_hash| Resource.from_h( resource_hash ) },
523
- :event_codes => Array( info_hash[ EVENT_CODES_KEY ]).map{ |event_code_hash| EventCode.from_h( event_code_hash )},
524
- :parameters => Array( info_hash[ PARAMETERS_KEY ]).map{ |parameter_hash| Parameter.from_h( parameter_hash )},
525
- :areas => Array( info_hash[ AREAS_KEY ]).map{ |area_hash| Area.from_h( area_hash )})
233
+ def self.from_h( info_hash )
234
+ super.tap do |info|
235
+ Array( info_hash[ RESPONSE_TYPES_KEY ]).each do |response_type|
236
+ info.response_types << response_type
237
+ end
238
+ end
526
239
  end
527
240
  end
528
241
  end