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_0
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,486 +9,33 @@ 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
- URGENCY_IMMEDIATE = "Immediate"
33
- URGENCY_EXPECTED = "Expected"
34
- URGENCY_FUTURE = "Future"
35
- URGENCY_PAST = "Past"
36
- URGENCY_UNKNOWN = "Unknown"
37
- # Valid values for urgency
38
- VALID_URGENCIES = [ URGENCY_IMMEDIATE, URGENCY_EXPECTED, URGENCY_FUTURE,
39
- URGENCY_PAST, URGENCY_UNKNOWN ]
40
-
41
- SEVERITY_EXTREME = "Extreme"
42
- SEVERITY_SEVERE = "Severe"
43
- SEVERITY_MODERATE = "Moderate"
44
- SEVERITY_MINOR = "Minor"
45
- SEVERITY_UNKNOWN = "Unknown"
46
- # Valid values for severity
47
- VALID_SEVERITIES = [ SEVERITY_EXTREME, SEVERITY_SEVERE, SEVERITY_MODERATE,
48
- SEVERITY_MINOR, SEVERITY_UNKNOWN ]
49
-
50
- CERTAINTY_VERY_LIKELY = "Very Likely"
51
- CERTAINTY_LIKELY = "Likely"
52
- CERTAINTY_POSSIBLE = "Possible"
53
- CERTAINTY_UNLIKELY = "Unlikely"
54
- CERTAINTY_UNKNOWN = "Unknown"
55
- # Valid valies for certainty
56
- VALID_CERTAINTIES = [ CERTAINTY_VERY_LIKELY, CERTAINTY_LIKELY,
57
- CERTAINTY_POSSIBLE, CERTAINTY_UNLIKELY, CERTAINTY_UNKNOWN ]
58
-
59
- XML_ELEMENT_NAME = 'info'
60
- LANGUAGE_ELEMENT_NAME = 'language'
61
- CATEGORY_ELEMENT_NAME = 'category'
62
- EVENT_ELEMENT_NAME = 'event'
63
- URGENCY_ELEMENT_NAME = 'urgency'
64
- SEVERITY_ELEMENT_NAME = 'severity'
65
- CERTAINTY_ELEMENT_NAME = 'certainty'
66
- AUDIENCE_ELEMENT_NAME = 'audience'
67
- EVENT_CODE_ELEMENT_NAME = 'eventCode'
68
- EFFECTIVE_ELEMENT_NAME = 'effective'
69
- ONSET_ELEMENT_NAME = 'onset'
70
- EXPIRES_ELEMENT_NAME = 'expires'
71
- SENDER_NAME_ELEMENT_NAME = 'senderName'
72
- HEADLINE_ELEMENT_NAME = 'headline'
73
- DESCRIPTION_ELEMENT_NAME = 'description'
74
- INSTRUCTION_ELEMENT_NAME = 'instruction'
75
- WEB_ELEMENT_NAME = 'web'
76
- CONTACT_ELEMENT_NAME = 'contact'
12
+ class Info < RCAP::Base::Info
77
13
 
78
- XPATH = "cap:#{ XML_ELEMENT_NAME }"
79
- LANGUAGE_XPATH = "cap:#{ LANGUAGE_ELEMENT_NAME }"
80
- EVENT_XPATH = "cap:#{ EVENT_ELEMENT_NAME }"
81
- URGENCY_XPATH = "cap:#{ URGENCY_ELEMENT_NAME }"
82
- CATEGORY_XPATH = "cap:#{ CATEGORY_ELEMENT_NAME }"
83
- SEVERITY_XPATH = "cap:#{ SEVERITY_ELEMENT_NAME }"
84
- CERTAINTY_XPATH = "cap:#{ CERTAINTY_ELEMENT_NAME }"
85
- AUDIENCE_XPATH = "cap:#{ AUDIENCE_ELEMENT_NAME }"
86
- EVENT_CODE_XPATH = "cap:#{ EVENT_CODE_ELEMENT_NAME }"
87
- EFFECTIVE_XPATH = "cap:#{ EFFECTIVE_ELEMENT_NAME }"
88
- ONSET_XPATH = "cap:#{ ONSET_ELEMENT_NAME }"
89
- EXPIRES_XPATH = "cap:#{ EXPIRES_ELEMENT_NAME }"
90
- SENDER_NAME_XPATH = "cap:#{ SENDER_NAME_ELEMENT_NAME }"
91
- HEADLINE_XPATH = "cap:#{ HEADLINE_ELEMENT_NAME }"
92
- DESCRIPTION_XPATH = "cap:#{ DESCRIPTION_ELEMENT_NAME }"
93
- INSTRUCTION_XPATH = "cap:#{ INSTRUCTION_ELEMENT_NAME }"
94
- WEB_XPATH = "cap:#{ WEB_ELEMENT_NAME }"
95
- CONTACT_XPATH = "cap:#{ CONTACT_ELEMENT_NAME }"
96
-
97
- DEFAULT_LANGUAGE = 'en-US'
98
-
99
- validates_presence_of( :event, :urgency, :severity, :certainty )
100
14
  validates_inclusion_of( :certainty, :allow_nil => true, :in => VALID_CERTAINTIES, :message => "can only be assigned the following values: #{ VALID_CERTAINTIES.join(', ') }")
101
- validates_inclusion_of( :severity, :allow_nil => true, :in => VALID_SEVERITIES, :message => "can only be assigned the following values: #{ VALID_SEVERITIES.join(', ') }" )
102
- validates_inclusion_of( :urgency, :allow_nil => true, :in => VALID_URGENCIES, :message => "can only be assigned the following values: #{ VALID_URGENCIES.join(', ') }" )
103
- validates_inclusion_of_members_of( :categories, :in => VALID_CATEGORIES, :allow_blank => true )
104
- validates_collection_of( :resources, :areas, :event_codes, :parameters )
105
15
 
106
16
  # @return [String]
107
- attr_accessor( :event )
108
- # @return [String] Value can only be one of {VALID_URGENCIES}
109
- attr_accessor( :urgency )
110
- # @return [String] Value can only be one of {VALID_SEVERITIES}
111
- attr_accessor( :severity )
112
- # @return [String] Value can only be one of {VALID_CERTAINTIES}
113
- attr_accessor( :certainty )
114
- # @return [String]
115
- attr_accessor( :language )
116
- # @return [String]
117
- attr_accessor( :audience )
118
- # @return [DateTime] Effective start time of information
119
- attr_accessor( :effective )
120
- # @return [DateTime] Expected start of event
121
- attr_accessor( :onset )
122
- # @return [DateTime] Effective expiry time of information
123
- attr_accessor( :expires )
124
- # @return [String]
125
- attr_accessor( :sender_name )
126
- # @return [String]
127
- attr_accessor( :headline )
128
- # @return [String]
129
- attr_accessor( :description )
130
- # @return [String]
131
- attr_accessor( :instruction )
132
- # @return [String]
133
- attr_accessor( :web )
134
- # @return [String]
135
- attr_accessor( :contact )
136
-
137
- # @return [Array<String>] Collection of textual categories; elements can be one of {VALID_CATEGORIES}
138
- attr_reader( :categories )
139
- # @return [Array<EventCode>] Collection of {EventCode} objects
140
- attr_reader( :event_codes )
141
- # @return [Array<Parameter>] Collection of {Parameter} objects
142
- attr_reader( :parameters )
143
- # @return [Array<Resource> Collection of {Resource} objects
144
- attr_reader( :resources )
145
- # @return [Array<Area>] Collection of {Area} objects
146
- attr_reader( :areas )
147
-
148
- # @param [Hash] attributes
149
- # @option attributes [String] :language Defaults to {DEFAULT_LANGUAGE}
150
- # @option attributes [Array<String>] :categories Collection of categories in {VALID_CATEGORIES}
151
- # @option attributes [String] :audience
152
- # @option attributes [String] :event
153
- # @option attributes [String] :urgency A member of {VALID_URGENCIES}
154
- # @option attributes [String] :severity A member of {VALID_SEVERITIES}
155
- # @option attributes [String] :certainty A member of {VALID_CERTAINTIES}
156
- # @option attributes [DateTime] :effective
157
- # @option attributes [DateTime] :onset
158
- # @option attributes [DateTime] :expires
159
- # @option attributes [Array<EventCode>] :event_codes Collection of {EventCode} objects
160
- # @option attributes [String] :sender_name
161
- # @option attributes [String] :headline
162
- # @option attributes [String] :description
163
- # @option attributes [String] :instruction
164
- # @option attributes [String] :web URL
165
- # @option attributes [String] :contact
166
- # @option attributes [Array<Parameter>] :parameters Collection of {Parameter} objects
167
- # @option attributes [Array<Resource>] :resources Collection of {Resource} objects
168
- # @option attributes [Array<Area>] :areas Collection of {Area} objects
169
- def initialize( attributes = {} )
170
- @language = attributes[ :language ] || DEFAULT_LANGUAGE
171
- @categories = Array( attributes[ :categories ])
172
- @audience = attributes [ :audience ]
173
- @event = attributes [ :event ]
174
- @urgency = attributes[ :urgency ]
175
- @severity = attributes[ :severity ]
176
- @certainty = attributes[ :certainty ]
177
- @effective = attributes[ :effective ]
178
- @onset = attributes[ :onset ]
179
- @expires = attributes[ :expires ]
180
- @event_codes = Array( attributes[ :event_codes ])
181
- @sender_name = attributes[ :sender_name ]
182
- @headline = attributes[ :headline ]
183
- @description = attributes[ :description ]
184
- @instruction = attributes[ :instruction ]
185
- @web = attributes[ :web ]
186
- @contact = attributes[ :contact ]
187
- @parameters = Array( attributes[ :parameters ])
188
- @resources = Array( attributes[ :resources ])
189
- @areas = Array( attributes[ :areas ])
190
- end
191
-
192
- # Creates a new EventCode object and adds it to the event_codes array. The
193
- # event_code_attributes are passed as a parameter to EventCode.new.
194
- #
195
- # @see EventCode#initialize
196
- #
197
- # @param [Hash] event_code_attributes (see EventCode#initialize)
198
- # @return [EventCode]
199
- def add_event_code( event_code_attributes = {})
200
- event_code = EventCode.new( event_code_attributes )
201
- @event_codes << event_code
202
- event_code
203
- end
204
-
205
- # Creates a new Parameter object and adds it to the parameters array. The
206
- # parameter_attributes are passed as a parameter to Parameter.new.
207
- #
208
- # @see Parameter#initialize
209
- #
210
- # @param [Hash] parameter_attributes (see Parameter#initialize)
211
- # @return [Parameter]
212
- def add_parameter( parameter_attributes = {})
213
- parameter = Parameter.new( parameter_attributes )
214
- @parameters << parameter
215
- parameter
17
+ def xmlns
18
+ Alert::XMLNS
216
19
  end
217
20
 
218
- # Creates a new Resource object and adds it to the resources array. The
219
- # resource_attributes are passed as a parameter to Resource.new.
220
- #
221
- # @see Resource#initialize
222
- #
223
- # @param [Hash] resource_attributes (See Resource#initialize)
224
- # @return [Resource]
225
- def add_resource( resource_attributes = {})
226
- resource = Resource.new( resource_attributes )
227
- @resources << resource
228
- resource
21
+ # @return [Class]
22
+ def event_code_class
23
+ EventCode
229
24
  end
230
25
 
231
- # Creates a new Area object and adds it to the areas array. The
232
- # area_attributes are passed as a parameter to Area.new.
233
- #
234
- # @see Area#initialize
235
- #
236
- # @param [Hash] area_attributes (see Area#initialize)
237
- # @return [Area]
238
- def add_area( area_attributes = {})
239
- area = Area.new( area_attributes )
240
- @areas << area
241
- area
26
+ # @return [Class]
27
+ def parameter_class
28
+ Parameter
242
29
  end
243
30
 
244
- # @return [REXML::Element]
245
- def to_xml_element
246
- xml_element = REXML::Element.new( XML_ELEMENT_NAME )
247
- xml_element.add_element( LANGUAGE_ELEMENT_NAME ).add_text( @language ) if @language
248
- @categories.each do |category|
249
- xml_element.add_element( CATEGORY_ELEMENT_NAME ).add_text( category )
250
- end
251
- xml_element.add_element( EVENT_ELEMENT_NAME ).add_text( @event )
252
- xml_element.add_element( URGENCY_ELEMENT_NAME ).add_text( @urgency )
253
- xml_element.add_element( SEVERITY_ELEMENT_NAME ).add_text( @severity )
254
- xml_element.add_element( CERTAINTY_ELEMENT_NAME ).add_text( @certainty )
255
- xml_element.add_element( AUDIENCE_ELEMENT_NAME ).add_text( @audience ) if @audience
256
- @event_codes.each do |event_code|
257
- xml_element.add_element( event_code.to_xml_element )
258
- end
259
- xml_element.add_element( EFFECTIVE_ELEMENT_NAME ).add_text( @effective.to_s_for_cap ) if @effective
260
- xml_element.add_element( ONSET_ELEMENT_NAME ).add_text( @onset.to_s_for_cap ) if @onset
261
- xml_element.add_element( EXPIRES_ELEMENT_NAME ).add_text( @expires.to_s_for_cap ) if @expires
262
- xml_element.add_element( SENDER_NAME_ELEMENT_NAME ).add_text( @sender_name ) if @sender_name
263
- xml_element.add_element( HEADLINE_ELEMENT_NAME ).add_text( @headline ) if @headline
264
- xml_element.add_element( DESCRIPTION_ELEMENT_NAME ).add_text( @description ) if @description
265
- xml_element.add_element( INSTRUCTION_ELEMENT_NAME ).add_text( @instruction ) if @instruction
266
- xml_element.add_element( WEB_ELEMENT_NAME ).add_text( @web ) if @web
267
- xml_element.add_element( CONTACT_ELEMENT_NAME ).add_text( @contact ) if @contact
268
- @parameters.each do |parameter|
269
- xml_element.add_element( parameter.to_xml_element )
270
- end
271
- @resources.each do |resource|
272
- xml_element.add_element( resource.to_xml_element )
273
- end
274
- @areas.each do |area|
275
- xml_element.add_element( area.to_xml_element )
276
- end
277
- xml_element
278
- end
279
-
280
- # @return [String]
281
- def to_xml
282
- self.to_xml_element.to_s
283
- end
284
-
285
- # @return [String]
286
- def inspect
287
- info_inspect = "Language: #{ @language }\n"+
288
- "Categories: #{ @categories.to_s_for_cap }\n"+
289
- "Event: #{ @event }\n"+
290
- "Urgency: #{ @urgency }\n"+
291
- "Severity: #{ @severity }\n"+
292
- "Certainty: #{ @certainty }\n"+
293
- "Audience: #{ @audience }\n"+
294
- "Event Codes: #{ @event_codes.inspect }\n"+
295
- "Effective: #{ @effective }\n"+
296
- "Onset: #{ @onset }\n"+
297
- "Expires: #{ @expires }\n"+
298
- "Sender Name: #{ @sender_name }\n"+
299
- "Headline: #{ @headline }\n"+
300
- "Description:\n"+
301
- @description.to_s.lines.map{ |line| " " + line }.join( "\n")+"\n"+
302
- "Instruction: #{ @instruction }\n"+
303
- "Web: #{ @web }\n"+
304
- "Contact: #{ @contact }\n"+
305
- "Parameters:\n"+
306
- @parameters.map{ |parameter| parameter.inspect }.join( "\n" )+"\n"+
307
- "Resources:\n"+
308
- @resources.map{ |resource| " " + resource.inspect }.join( "\n" )+"\n"+
309
- "Area:\n"+
310
- @areas.map{ |area| " #{ area }" }.join( "\n" )+"\n"
311
- RCAP.format_lines_for_inspect( 'INFO', info_inspect )
312
- end
313
-
314
- # Returns a string representation of the event of the form
315
- # event(urgency/severity/certainty)
316
- #
317
- # @return [String]
318
- def to_s
319
- "#{ @event }(#{ @urgency }/#{ @severity }/#{ @certainty })"
320
- end
321
-
322
- # @param [REXML::Element] info_xml_element
323
- # @return [Info]
324
- def self.from_xml_element( info_xml_element )
325
- self.new(
326
- :language => RCAP.xpath_text( info_xml_element, LANGUAGE_XPATH, Alert::XMLNS ) || DEFAULT_LANGUAGE,
327
- :categories => RCAP.xpath_match( info_xml_element, CATEGORY_XPATH, Alert::XMLNS ).map{ |element| element.text },
328
- :event => RCAP.xpath_text( info_xml_element, EVENT_XPATH, Alert::XMLNS ),
329
- :urgency => RCAP.xpath_text( info_xml_element, URGENCY_XPATH, Alert::XMLNS ),
330
- :severity => RCAP.xpath_text( info_xml_element, SEVERITY_XPATH, Alert::XMLNS ),
331
- :certainty => RCAP.xpath_text( info_xml_element, CERTAINTY_XPATH, Alert::XMLNS ),
332
- :audience => RCAP.xpath_text( info_xml_element, AUDIENCE_XPATH, Alert::XMLNS ),
333
- :effective => (( effective = RCAP.xpath_first( info_xml_element, EFFECTIVE_XPATH, Alert::XMLNS )) ? DateTime.parse( effective.text ) : nil ),
334
- :onset => (( onset = RCAP.xpath_first( info_xml_element, ONSET_XPATH, Alert::XMLNS )) ? DateTime.parse( onset.text ) : nil ),
335
- :expires => (( expires = RCAP.xpath_first( info_xml_element, EXPIRES_XPATH, Alert::XMLNS )) ? DateTime.parse( expires.text ) : nil ),
336
- :sender_name => RCAP.xpath_text( info_xml_element, SENDER_NAME_XPATH, Alert::XMLNS ),
337
- :headline => RCAP.xpath_text( info_xml_element, HEADLINE_XPATH, Alert::XMLNS ),
338
- :description => RCAP.xpath_text( info_xml_element, DESCRIPTION_XPATH, Alert::XMLNS ),
339
- :instruction => RCAP.xpath_text( info_xml_element, INSTRUCTION_XPATH, Alert::XMLNS ),
340
- :web => RCAP.xpath_text( info_xml_element, WEB_XPATH, Alert::XMLNS ),
341
- :contact => RCAP.xpath_text( info_xml_element, CONTACT_XPATH, Alert::XMLNS ),
342
- :event_codes => RCAP.xpath_match( info_xml_element, EventCode::XPATH, Alert::XMLNS ).map{ |element| EventCode.from_xml_element( element )},
343
- :parameters => RCAP.xpath_match( info_xml_element, Parameter::XPATH, Alert::XMLNS ).map{ |element| Parameter.from_xml_element( element )},
344
- :resources => RCAP.xpath_match( info_xml_element, Resource::XPATH, Alert::XMLNS ).map{ |element| Resource.from_xml_element( element )},
345
- :areas => RCAP.xpath_match( info_xml_element, Area::XPATH, Alert::XMLNS ).map{ |element| Area.from_xml_element( element )}
346
- )
347
- end
348
-
349
- LANGUAGE_YAML = 'Language'
350
- CATEGORIES_YAML = 'Categories'
351
- EVENT_YAML = 'Event'
352
- URGENCY_YAML = 'Urgency'
353
- SEVERITY_YAML = 'Severity'
354
- CERTAINTY_YAML = 'Certainty'
355
- AUDIENCE_YAML = 'Audience'
356
- EFFECTIVE_YAML = 'Effective'
357
- ONSET_YAML = 'Onset'
358
- EXPIRES_YAML = 'Expires'
359
- SENDER_NAME_YAML = 'Sender Name'
360
- HEADLINE_YAML = 'Headline'
361
- DESCRIPTION_YAML = 'Description'
362
- INSTRUCTION_YAML = 'Instruction'
363
- WEB_YAML = 'Web'
364
- CONTACT_YAML = 'Contact'
365
- EVENT_CODES_YAML = 'Event Codes'
366
- PARAMETERS_YAML = 'Parameters'
367
- RESOURCES_YAML = 'Resources'
368
- AREAS_YAML = 'Areas'
369
-
370
- # @return [String]
371
- def to_yaml( options = {} )
372
- parameter_to_hash = lambda{ |hash, parameter| hash.merge( parameter.name => parameter.value )}
373
-
374
- RCAP.attribute_values_to_hash( [ LANGUAGE_YAML, @language ],
375
- [ CATEGORIES_YAML, @categories ],
376
- [ EVENT_YAML, @event ],
377
- [ URGENCY_YAML, @urgency ],
378
- [ SEVERITY_YAML, @severity ],
379
- [ CERTAINTY_YAML, @certainty ],
380
- [ AUDIENCE_YAML, @audience ],
381
- [ EFFECTIVE_YAML, @effective ],
382
- [ ONSET_YAML, @onset ],
383
- [ EXPIRES_YAML, @expires ],
384
- [ SENDER_NAME_YAML, @sender_name ],
385
- [ HEADLINE_YAML, @headline ],
386
- [ DESCRIPTION_YAML, @description ],
387
- [ INSTRUCTION_YAML, @instruction ],
388
- [ WEB_YAML, @web ],
389
- [ CONTACT_YAML, @contact ],
390
- [ EVENT_CODES_YAML, @event_codes.inject({}, &parameter_to_hash )],
391
- [ PARAMETERS_YAML, @parameters.inject({}, &parameter_to_hash )],
392
- [ RESOURCES_YAML, @resources ],
393
- [ AREAS_YAML, @areas ]).to_yaml( options )
394
- end
395
-
396
- # @param [Hash] info_yaml_data
397
- # @return [Info]
398
- def self.from_yaml_data( info_yaml_data )
399
- self.new(
400
- :language => info_yaml_data [ LANGUAGE_YAML ],
401
- :categories => info_yaml_data [ CATEGORIES_YAML ],
402
- :event => info_yaml_data [ EVENT_YAML ],
403
- :urgency => info_yaml_data [ URGENCY_YAML ],
404
- :severity => info_yaml_data [ SEVERITY_YAML ],
405
- :certainty => info_yaml_data [ CERTAINTY_YAML ],
406
- :audience => info_yaml_data [ AUDIENCE_YAML ],
407
- :effective => ( effective = info_yaml_data[ EFFECTIVE_YAML ]).blank? ? nil : DateTime.parse( effective.to_s ),
408
- :onset => ( onset = info_yaml_data[ ONSET_YAML ]).blank? ? nil : DateTime.parse( onset.to_s ),
409
- :expires => ( expires = info_yaml_data[ EXPIRES_YAML ]).blank? ? nil : DateTime.parse( expires.to_s ),
410
- :sender_name => info_yaml_data [ SENDER_NAME_YAML ],
411
- :headline => info_yaml_data [ HEADLINE_YAML ],
412
- :description => info_yaml_data [ DESCRIPTION_YAML ],
413
- :instruction => info_yaml_data [ INSTRUCTION_YAML ],
414
- :web => info_yaml_data [ WEB_YAML ],
415
- :contact => info_yaml_data [ CONTACT_YAML ],
416
- :event_codes => Array( info_yaml_data [ EVENT_CODES_YAML ]).map{ |name,value| EventCode.new( :name => name, :value => value )},
417
- :parameters => Array( info_yaml_data [ PARAMETERS_YAML ]).map{ |parameter_yaml_data| Parameter.new( :name => name, :value => value )},
418
- :resources => Array( info_yaml_data [ RESOURCES_YAML ]).map{ |resource_yaml_data| Resource.from_yaml_data( resource_yaml_data )},
419
- :areas => Array( info_yaml_data [ AREAS_YAML ]).map{ |area_yaml_data| Area.from_yaml_data( area_yaml_data )}
420
- )
421
- end
422
-
423
- LANGUAGE_KEY = 'language'
424
- CATEGORIES_KEY = 'categories'
425
- EVENT_KEY = 'event'
426
- URGENCY_KEY = 'urgency'
427
- SEVERITY_KEY = 'severity'
428
- CERTAINTY_KEY = 'certainty'
429
- AUDIENCE_KEY = 'audience'
430
- EFFECTIVE_KEY = 'effective'
431
- ONSET_KEY = 'onset'
432
- EXPIRES_KEY = 'expires'
433
- SENDER_NAME_KEY = 'sender_name'
434
- HEADLINE_KEY = 'headline'
435
- DESCRIPTION_KEY = 'description'
436
- INSTRUCTION_KEY = 'instruction'
437
- WEB_KEY = 'web'
438
- CONTACT_KEY = 'contact'
439
- RESOURCES_KEY = 'resources'
440
- EVENT_CODES_KEY = 'event_codes'
441
- PARAMETERS_KEY = 'parameters'
442
- AREAS_KEY = 'areas'
443
-
444
- # @return [Hash]
445
- def to_h
446
- RCAP.attribute_values_to_hash( [ LANGUAGE_KEY, @language ],
447
- [ CATEGORIES_KEY, @categories ],
448
- [ EVENT_KEY, @event ],
449
- [ URGENCY_KEY, @urgency ],
450
- [ SEVERITY_KEY, @severity ],
451
- [ CERTAINTY_KEY, @certainty ],
452
- [ AUDIENCE_KEY, @audience ],
453
- [ EFFECTIVE_KEY, RCAP.to_s_for_cap( @effective )],
454
- [ ONSET_KEY, RCAP.to_s_for_cap( @onset )],
455
- [ EXPIRES_KEY, RCAP.to_s_for_cap( @expires )],
456
- [ SENDER_NAME_KEY, @sender_name ],
457
- [ HEADLINE_KEY, @headline ],
458
- [ DESCRIPTION_KEY, @description ],
459
- [ INSTRUCTION_KEY, @instruction ],
460
- [ WEB_KEY, @web ],
461
- [ CONTACT_KEY, @contact ],
462
- [ RESOURCES_KEY, @resources.map{ |resource| resource.to_h } ],
463
- [ EVENT_CODES_KEY, @event_codes.map{ |event_code| event_code.to_h } ],
464
- [ PARAMETERS_KEY, @parameters.map{ |parameter| parameter.to_h } ],
465
- [ AREAS_KEY, @areas.map{ |area| area.to_h }])
31
+ # @return [Class]
32
+ def resource_class
33
+ Resource
466
34
  end
467
35
 
468
- # @param [Hash] info_hash
469
- # @return [Info]
470
- def self.from_h( info_hash )
471
- self.new( :language => info_hash[ LANGUAGE_KEY ],
472
- :categories => info_hash[ CATEGORIES_KEY ],
473
- :event => info_hash[ EVENT_KEY ],
474
- :urgency => info_hash[ URGENCY_KEY ],
475
- :severity => info_hash[ SEVERITY_KEY ],
476
- :certainty => info_hash[ CERTAINTY_KEY ],
477
- :audience => info_hash[ AUDIENCE_KEY ],
478
- :effective => RCAP.parse_datetime( info_hash[ EFFECTIVE_KEY ]),
479
- :onset => RCAP.parse_datetime( info_hash[ ONSET_KEY ]),
480
- :expires => RCAP.parse_datetime( info_hash[ EXPIRES_KEY ]),
481
- :sender_name => info_hash[ SENDER_NAME_KEY ],
482
- :headline => info_hash[ HEADLINE_KEY ],
483
- :description => info_hash[ DESCRIPTION_KEY ],
484
- :instruction => info_hash[ INSTRUCTION_KEY ],
485
- :web => info_hash[ WEB_KEY ],
486
- :contact => info_hash[ CONTACT_KEY ],
487
- :resources => Array( info_hash[ RESOURCES_KEY ]).map{ |resource_hash| Resource.from_h( resource_hash ) },
488
- :event_codes => Array( info_hash[ EVENT_CODES_KEY ]).map{ |event_code_hash| EventCode.from_h( event_code_hash )},
489
- :parameters => Array( info_hash[ PARAMETERS_KEY ]).map{ |parameter_hash| Parameter.from_h( parameter_hash )},
490
- :areas => Array( info_hash[ AREAS_KEY ]).map{ |area_hash| Area.from_h( area_hash )})
36
+ # @return [Class]
37
+ def area_class
38
+ Area
491
39
  end
492
40
  end
493
41
  end
@@ -3,86 +3,28 @@ module RCAP
3
3
  # A Parameter object is valid if
4
4
  # * it has a name
5
5
  # * it has a value
6
- class Parameter
7
- include Validation
8
-
9
- validates_presence_of( :name, :value )
10
-
11
- # @return [String]
12
- attr_accessor( :name )
13
- # @return [String]
14
- attr_accessor( :value )
15
-
16
- XML_ELEMENT_NAME = "parameter"
17
- NAME_ELEMENT_NAME = "valueName"
18
- VALUE_ELEMENT_NAME = "value"
19
-
20
- XPATH = "cap:#{ XML_ELEMENT_NAME }"
21
- NAME_XPATH = "cap:#{ NAME_ELEMENT_NAME }"
22
- VALUE_XPATH = "cap:#{ VALUE_ELEMENT_NAME }"
23
-
24
- # @param [Hash] attributes
25
- # @option attributes [Symbol] :name Parameter name
26
- # @option attributes [Symbol] :value Parameter value
27
- def initialize( attributes = {} )
28
- @name = attributes[ :name ]
29
- @value = attributes[ :value ]
30
- end
6
+ class Parameter < RCAP::Base::Parameter
31
7
 
32
8
  # @return [REXML::Element]
33
- def to_xml_element
9
+ def to_xml_element
34
10
  xml_element = REXML::Element.new( self.class::XML_ELEMENT_NAME )
35
11
  xml_element.add_text( "#{ @name }=#{ @value }")
36
12
  xml_element
37
13
  end
38
14
 
39
- # @return [String]
40
- def to_xml
41
- self.to_xml_element.to_s
42
- end
43
-
44
- # @return [String]
45
- def inspect
46
- "#{ @name }: #{ @value }"
47
- end
48
-
49
- # Returns a string representation of the parameter of the form
50
- # name: value
51
- #
52
- # @return [String]
53
- def to_s
54
- self.inspect
55
- end
56
-
57
15
  # @param [REXML::Element] parameter_xml_element
58
- # @return [Parameter]
59
- def self.from_xml_element( parameter_xml_element )
60
- self.new( self.parse_parameter( parameter_xml_element.text ))
61
- end
62
-
63
- # Two parameters are equivalent if they have the same name and value.
64
- #
65
- # @param [Parameter] other
66
- # @return [true, false]
67
- def ==( other )
68
- [ @name, @value ] == [ other.name, other.value ]
69
- end
70
-
71
- # @return [Hash]
72
- def to_h
73
- RCAP.attribute_values_to_hash( [ @name, @value ])
74
- end
75
-
76
- # @param [Hash] hash
77
16
  # @return [Parameter]
78
- def self.from_h( hash )
79
- key = hash.keys.first
80
- self.new( :name => key, :value => hash[ key ])
17
+ def self.from_xml_element( parameter_xml_element )
18
+ parameter_hash = self.parse_parameter( parameter_xml_element.text )
19
+ self.new do |parameter|
20
+ parameter.name = parameter_hash[ :name ]
21
+ parameter.value = parameter_hash[ :value ]
22
+ end
81
23
  end
82
24
 
83
25
  # @param [String] parameter_string
84
26
  # @return [Hash]
85
- def self.parse_parameter( parameter_string )
27
+ def self.parse_parameter( parameter_string )
86
28
  name, value = parameter_string.split("=")
87
29
  if name && value
88
30
  { :name => name,
@@ -1,69 +1,10 @@
1
1
  module RCAP
2
2
  module CAP_1_0
3
+
3
4
  # A Point object is valid if
4
5
  # * it has a lattitude within the minimum and maximum lattitude values
5
6
  # * it has a longitude within the minimum and maximum longitude values
6
- class Point
7
- include Validation
8
-
9
- MAX_LONGITUDE = 180
10
- MIN_LONGITUDE = -180
11
- MAX_LATTITUDE = 90
12
- MIN_LATTITUDE = -90
13
-
14
- # @return [Numeric]
15
- attr_accessor( :lattitude )
16
- # @return [Numeric]
17
- attr_accessor( :longitude )
18
-
19
- validates_numericality_of( :lattitude, :longitude )
20
- validates_inclusion_of( :lattitude, :in => MIN_LATTITUDE..MAX_LATTITUDE )
21
- validates_inclusion_of( :longitude, :in => MIN_LONGITUDE..MAX_LONGITUDE)
22
-
23
- # @param [Hash] attributes
24
- # @option attributes [Numeric] :lattitude
25
- # @option attributes [Numeric] :longitude
26
- def initialize( attributes = {} )
27
- @lattitude = attributes[ :lattitude ]
28
- @longitude = attributes[ :longitude ]
29
- end
30
-
31
- # Returns a string representation of the point of the form
32
- # lattitude,longitude
33
- #
34
- # @return [String]
35
- def to_s
36
- "#{ @lattitude },#{ @longitude }"
37
- end
38
-
39
- # @return [String]
40
- def inspect
41
- '('+self.to_s+')'
42
- end
43
-
44
- # Two points are equivalent if they have the same lattitude and longitude
45
- #
46
- # @param [Point] other
47
- # @return [true, false]
48
- def ==( other )
49
- [ @lattitude, @longitude ] == [ other.lattitude, other.longitude ]
50
- end
51
-
52
- LATTITUDE_KEY = 'lattitude'
53
- LONGITUDE_KEY = 'longitude'
54
-
55
- # @return [Hash]
56
- def to_h
57
- RCAP.attribute_values_to_hash(
58
- [ LATTITUDE_KEY, @lattitude ],
59
- [ LONGITUDE_KEY, @longitude ])
60
- end
61
-
62
- # @param [Hash] point_hash
63
- # @return [Point]
64
- def self.from_h( point_hash )
65
- self.new( :lattitude => point_hash[ LATTITUDE_KEY ], :longitude => point_hash[ LONGITUDE_KEY ])
66
- end
7
+ class Point < RCAP::Base::Point
67
8
  end
68
9
  end
69
10
  end