rcap 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +6 -0
- data/README.rdoc +44 -10
- data/lib/rcap.rb +3 -1
- data/lib/rcap/alert.rb +165 -103
- data/lib/rcap/area.rb +28 -2
- data/lib/rcap/circle.rb +27 -19
- data/lib/rcap/info.rb +73 -3
- data/lib/rcap/parameter.rb +10 -0
- data/lib/rcap/point.rb +13 -0
- data/lib/rcap/polygon.rb +10 -0
- data/lib/rcap/resource.rb +31 -4
- data/lib/rcap/utilities.rb +46 -26
- data/lib/rcap/validations.rb +17 -17
- data/spec/alert_spec.rb +52 -13
- data/spec/area_spec.rb +79 -20
- data/spec/circle_spec.rb +39 -10
- data/spec/geocode_spec.rb +18 -6
- data/spec/info_spec.rb +172 -21
- data/spec/point_spec.rb +13 -1
- data/spec/polygon_spec.rb +24 -1
- data/spec/resource_spec.rb +88 -6
- data/spec/spec_helper.rb +2 -1
- data/spec/utilities_spec.rb +1 -1
- data/spec/validations_spec.rb +1 -1
- metadata +36 -12
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -8,7 +8,7 @@ RCAP currently supports only CAP Version 1.1.
|
|
8
8
|
|
9
9
|
== Version
|
10
10
|
|
11
|
-
0.
|
11
|
+
0.4
|
12
12
|
|
13
13
|
== Dependencies
|
14
14
|
|
@@ -16,13 +16,14 @@ RCAP depends on the following gems
|
|
16
16
|
|
17
17
|
* {Assistance}[http://assistance.rubyforge.org]
|
18
18
|
* {UUIDTools}[http://uuidtools.rubyforge.org]
|
19
|
+
* {JSON}[http://json.rubyforge.org]
|
19
20
|
|
20
21
|
RCAP uses the REXML API, included in Ruby, to parse and generate XML.
|
21
22
|
|
22
23
|
== Installation
|
23
24
|
|
24
25
|
RCAP is distributed as a Ruby gem and is available from {Gemcutter}[http://gemcutter.org]. If you have Gemcutter set as a source of your gems then RCAP can be installed from the command line
|
25
|
-
|
26
|
+
|
26
27
|
gem install rcap
|
27
28
|
|
28
29
|
The gem is also available for download and manual installtion at http://www.aimred.com/gems .
|
@@ -31,8 +32,8 @@ The gem is also available for download and manual installtion at http://www.aimr
|
|
31
32
|
|
32
33
|
* The RCAP project page can be found at http://www.aimred.com/projects/rcap
|
33
34
|
* The RCAP API docs can be fount at http://www.aimred.com/projects/rcap/api
|
34
|
-
* A public git repository can be found at
|
35
|
-
|
35
|
+
* A public git repository can be found at git://github.com/farrel/RCAP.git
|
36
|
+
|
36
37
|
== Usage
|
37
38
|
|
38
39
|
To include RCAP into your application add the following require
|
@@ -136,6 +137,32 @@ will produce the following YAML document
|
|
136
137
|
|
137
138
|
Note: If you use Ruby 1.8 the order of the attributes is jumbled due to hashes being unorderd (Ruby 1.9 implements ordered hashes). This does not affect the ability to parse documents generated from RCAP::Alert#to_yaml, it just makes things the output slightly messy.
|
138
139
|
|
140
|
+
=== To JSON
|
141
|
+
|
142
|
+
JSON(JavaScript Object Notation) is a text serialization format that can be easily loaded in a JavaScript environment.
|
143
|
+
|
144
|
+
alert.to_json
|
145
|
+
|
146
|
+
will produce the following JSON string
|
147
|
+
|
148
|
+
{"identifier":"0eb97e40-195b-437b-9a01-55fe89691def",
|
149
|
+
"sender":"cape_town_disaster_relief@capetown.municipal.za",
|
150
|
+
"sent":"2011-03-04T15:58:01+02:00",
|
151
|
+
"status":"Actual",
|
152
|
+
"msg_type":"Alert",
|
153
|
+
"scope":"Public",
|
154
|
+
"infos":[
|
155
|
+
{"language":"en-ZA",
|
156
|
+
"categories":["Transport","Fire"],
|
157
|
+
"event":"Liquid Petroleoum Tanker Fire",
|
158
|
+
"urgency":"Immediate",
|
159
|
+
"severity":"Severe",
|
160
|
+
"certainty":"Observed",
|
161
|
+
"headline":"LIQUID PETROLEOUM TANKER FIRE ON N2 INCOMING FREEWAY",
|
162
|
+
"description":"A liquid petroleoum tanker has caught fire on the N2 incoming freeway 1km
|
163
|
+
after the R300 interchange. Municipal fire fighting crews have been dispatched.
|
164
|
+
Traffic control officers are on the scene and have diverted traffic onto \nalternate routes."}]}
|
165
|
+
|
139
166
|
=== Parsing an Alert From An External Source
|
140
167
|
|
141
168
|
==== From XML
|
@@ -152,6 +179,12 @@ Alert messgaes can be read in from text files containing data formatted in YAML
|
|
152
179
|
|
153
180
|
alert = RCAP::Alert.from_yaml( yaml_string )
|
154
181
|
|
182
|
+
==== From JSON
|
183
|
+
|
184
|
+
An Alert can also be initialised from a JSON string produced by Alert#to_json
|
185
|
+
|
186
|
+
alert = RCAP::Alert.from_json( json_string )
|
187
|
+
|
155
188
|
=== Validating an alert
|
156
189
|
|
157
190
|
The RCAP API aims to codify as many of the rules of the CAP XML format into validation rules that can be checked using the Assistance API. The following Info object has two attributes ('severity' and 'certainty') set to incorrect values.
|
@@ -162,18 +195,19 @@ The RCAP API aims to codify as many of the rules of the CAP XML format into vali
|
|
162
195
|
:urgency => Info::URGENCY_IMMEDIATE,
|
163
196
|
:severity => nil, # Severity is not assigned
|
164
197
|
:certainty => 'Unknown Certainty' ) # Certainty is assigned in incorrect value
|
165
|
-
|
166
|
-
puts info.
|
198
|
+
|
199
|
+
puts "Is info valid: #{ info.valid? }"
|
200
|
+
info.errors.full_messages.each{ |message| puts "Error: #{ message }" }
|
167
201
|
|
168
202
|
Will produce the folling output:
|
169
203
|
|
170
|
-
false
|
171
|
-
severity is not present
|
172
|
-
certainty can only be assigned the following values: Observed, Likely, Possible, Unlikely, Unknown
|
204
|
+
Is info valid: false
|
205
|
+
Error: severity is not present
|
206
|
+
Error: certainty can only be assigned the following values: Observed, Likely, Possible, Unlikely, Unknown
|
173
207
|
|
174
208
|
All RCAP classes include the Validation module.
|
175
209
|
|
176
|
-
A full spec suite using {RSpec}[http://www.rspec.info] was used to test the validations and currently numbers over
|
210
|
+
A full spec suite using {RSpec}[http://www.rspec.info] was used to test the validations and currently numbers over 250 tests.
|
177
211
|
|
178
212
|
=== DateTime and Time
|
179
213
|
|
data/lib/rcap.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'assistance'
|
3
3
|
require 'uuidtools'
|
4
|
+
require 'yaml'
|
5
|
+
require 'json'
|
4
6
|
require 'rexml/document'
|
5
7
|
require 'rcap/utilities'
|
6
8
|
require 'rcap/validations'
|
@@ -17,5 +19,5 @@ require 'rcap/area'
|
|
17
19
|
|
18
20
|
module RCAP
|
19
21
|
XMLNS = "urn:oasis:names:tc:emergency:cap:1.1"
|
20
|
-
VERSION = "0.
|
22
|
+
VERSION = "0.4"
|
21
23
|
end
|
data/lib/rcap/alert.rb
CHANGED
@@ -7,30 +7,30 @@ module RCAP
|
|
7
7
|
# * it has a valid messge type value
|
8
8
|
# * it has a valid scope value
|
9
9
|
# * all Info objects contained in infos are valid
|
10
|
-
|
11
|
-
|
10
|
+
class Alert
|
11
|
+
include Validation
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
STATUS_ACTUAL = "Actual"
|
14
|
+
STATUS_EXERCISE = "Exercise"
|
15
|
+
STATUS_SYSTEM = "System"
|
16
|
+
STATUS_TEST = "Test"
|
17
|
+
STATUS_DRAFT = "Draft"
|
18
18
|
# Valid values for status
|
19
|
-
|
19
|
+
VALID_STATUSES = [ STATUS_ACTUAL, STATUS_EXERCISE, STATUS_SYSTEM, STATUS_TEST, STATUS_DRAFT ]
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
MSG_TYPE_ALERT = "Alert"
|
22
|
+
MSG_TYPE_UPDATE = "Update"
|
23
|
+
MSG_TYPE_CANCEL = "Cancel"
|
24
|
+
MSG_TYPE_ACK = "Ack"
|
25
|
+
MSG_TYPE_ERROR = "Error"
|
26
26
|
# Valid values for msg_type
|
27
|
-
|
27
|
+
VALID_MSG_TYPES = [ MSG_TYPE_ALERT, MSG_TYPE_UPDATE, MSG_TYPE_CANCEL, MSG_TYPE_ACK, MSG_TYPE_ERROR ]
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
SCOPE_PUBLIC = "Public"
|
30
|
+
SCOPE_RESTRICTED = "Restricted"
|
31
|
+
SCOPE_PRIVATE = "Private"
|
32
32
|
# Valid values for scope
|
33
|
-
|
33
|
+
VALID_SCOPES = [ SCOPE_PUBLIC, SCOPE_PRIVATE, SCOPE_RESTRICTED ]
|
34
34
|
|
35
35
|
XML_ELEMENT_NAME = 'alert' # :nodoc:
|
36
36
|
IDENTIFIER_ELEMENT_NAME = 'identifier' # :nodoc:
|
@@ -63,7 +63,7 @@ module RCAP
|
|
63
63
|
INCIDENTS_XPATH = "cap:#{ INCIDENTS_ELEMENT_NAME }" # :nodoc:
|
64
64
|
|
65
65
|
# If not set a UUID will be set by default
|
66
|
-
|
66
|
+
attr_accessor( :identifier)
|
67
67
|
attr_accessor( :sender )
|
68
68
|
# Sent Time - If not set will value will be time of creation.
|
69
69
|
attr_accessor( :sent )
|
@@ -80,7 +80,7 @@ module RCAP
|
|
80
80
|
attr_accessor( :note )
|
81
81
|
|
82
82
|
# Collection of address strings. Depends on scope being SCOPE_PRIVATE.
|
83
|
-
|
83
|
+
attr_reader( :addresses )
|
84
84
|
# Collection of reference strings - see Alert#to_reference
|
85
85
|
attr_reader( :references)
|
86
86
|
# Collection of incident strings
|
@@ -88,7 +88,7 @@ module RCAP
|
|
88
88
|
# Collection of Info objects
|
89
89
|
attr_reader( :infos )
|
90
90
|
|
91
|
-
|
91
|
+
validates_presence_of( :identifier, :sender, :sent, :status, :msg_type, :scope )
|
92
92
|
|
93
93
|
validates_inclusion_of( :status, :in => VALID_STATUSES )
|
94
94
|
validates_inclusion_of( :msg_type, :in => VALID_MSG_TYPES )
|
@@ -102,20 +102,20 @@ module RCAP
|
|
102
102
|
|
103
103
|
validates_collection_of( :infos )
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
105
|
+
def initialize( attributes = {})
|
106
|
+
@identifier = attributes[ :identifier ] || UUIDTools::UUID.random_create.to_s
|
107
|
+
@sender = attributes[ :sender ]
|
108
|
+
@sent = attributes[ :sent ] || DateTime.now
|
109
|
+
@status = attributes[ :status ]
|
110
|
+
@msg_type = attributes[ :msg_type ]
|
111
|
+
@scope = attributes[ :scope ]
|
112
|
+
@source = attributes[ :source ]
|
113
|
+
@restriction = attributes[ :restriction ]
|
114
|
+
@addresses = Array( attributes[ :addresses ])
|
115
|
+
@references = Array( attributes[ :references ])
|
116
|
+
@incidents = Array( attributes[ :incidents ])
|
117
|
+
@infos = Array( attributes[ :infos ])
|
118
|
+
end
|
119
119
|
|
120
120
|
def to_xml_element #:nodoc:
|
121
121
|
xml_element = REXML::Element.new( XML_ELEMENT_NAME )
|
@@ -181,7 +181,7 @@ Incidents: #{ self.incidents.join( ' ')}
|
|
181
181
|
Information:
|
182
182
|
#{ self.infos.map{ |info| " " + info.to_s }.join( "\n" )}
|
183
183
|
EOF
|
184
|
-
|
184
|
+
RCAP.format_lines_for_inspect( 'ALERT', alert_inspect )
|
185
185
|
end
|
186
186
|
|
187
187
|
# Returns a string representation of the alert of the form
|
@@ -192,20 +192,20 @@ EOF
|
|
192
192
|
end
|
193
193
|
|
194
194
|
def self.from_xml_element( alert_xml_element ) # :nodoc:
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
195
|
+
self.new( :identifier => RCAP.xpath_text( alert_xml_element, RCAP::Alert::IDENTIFIER_XPATH ),
|
196
|
+
:sender => RCAP.xpath_text( alert_xml_element, SENDER_XPATH ),
|
197
|
+
:sent => (( sent = RCAP.xpath_first( alert_xml_element, SENT_XPATH )) ? DateTime.parse( sent.text ) : nil ),
|
198
|
+
:status => RCAP.xpath_text( alert_xml_element, STATUS_XPATH ),
|
199
|
+
:msg_type => RCAP.xpath_text( alert_xml_element, MSG_TYPE_XPATH ),
|
200
|
+
:source => RCAP.xpath_text( alert_xml_element, SOURCE_XPATH ),
|
201
|
+
:scope => RCAP.xpath_text( alert_xml_element, SCOPE_XPATH ),
|
202
|
+
:restriction => RCAP.xpath_text( alert_xml_element, RESTRICTION_XPATH ),
|
203
|
+
:addresses => (( address = RCAP.xpath_text( alert_xml_element, ADDRESSES_XPATH )) ? address.unpack_cap_list : nil ),
|
204
|
+
:code => RCAP.xpath_text( alert_xml_element, CODE_XPATH ),
|
205
|
+
:note => RCAP.xpath_text( alert_xml_element, NOTE_XPATH ),
|
206
|
+
:references => (( references = RCAP.xpath_text( alert_xml_element, REFERENCES_XPATH )) ? references.split( ' ' ) : nil ),
|
207
|
+
:incidents => (( incidents = RCAP.xpath_text( alert_xml_element, INCIDENTS_XPATH )) ? incidents.split( ' ' ) : nil ),
|
208
|
+
:infos => RCAP.xpath_match( alert_xml_element, RCAP::Info::XPATH ).map{ |element| RCAP::Info.from_xml_element( element )})
|
209
209
|
end
|
210
210
|
|
211
211
|
def self.from_xml_document( xml_document ) # :nodoc:
|
@@ -217,63 +217,125 @@ EOF
|
|
217
217
|
self.from_xml_document( REXML::Document.new( xml ))
|
218
218
|
end
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
220
|
+
IDENTIFIER_YAML = "Identifier" # :nodoc:
|
221
|
+
SENDER_YAML = "Sender" # :nodoc:
|
222
|
+
SENT_YAML = "Sent" # :nodoc:
|
223
|
+
STATUS_YAML = "Status" # :nodoc:
|
224
|
+
MSG_TYPE_YAML = "Message Type" # :nodoc:
|
225
|
+
SOURCE_YAML = "Source" # :nodoc:
|
226
|
+
SCOPE_YAML = "Scope" # :nodoc:
|
227
|
+
RESTRICTION_YAML = "Restriction" # :nodoc:
|
228
|
+
ADDRESSES_YAML = "Addresses" # :nodoc:
|
229
|
+
CODE_YAML = "Code" # :nodoc:
|
230
|
+
NOTE_YAML = "Note" # :nodoc:
|
231
|
+
REFERENCES_YAML = "References" # :nodoc:
|
232
|
+
INCIDENTS_YAML = "Incidents" # :nodoc:
|
233
|
+
INFOS_YAML = "Information" # :nodoc:
|
234
234
|
|
235
235
|
# Returns a string containing the YAML representation of the alert.
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
236
|
+
def to_yaml( options = {} )
|
237
|
+
RCAP.attribute_values_to_hash(
|
238
|
+
[ IDENTIFIER_YAML, self.identifier ],
|
239
|
+
[ SENDER_YAML, self.sender ],
|
240
|
+
[ SENT_YAML, self.sent ],
|
241
|
+
[ STATUS_YAML, self.status ],
|
242
|
+
[ MSG_TYPE_YAML, self.msg_type ],
|
243
|
+
[ SOURCE_YAML, self.source ],
|
244
|
+
[ SCOPE_YAML, self.scope ],
|
245
|
+
[ RESTRICTION_YAML, self.restriction ],
|
246
|
+
[ ADDRESSES_YAML, self.addresses ],
|
247
|
+
[ CODE_YAML, self.code ],
|
248
|
+
[ NOTE_YAML, self.note ],
|
249
|
+
[ REFERENCES_YAML, self.references ],
|
250
|
+
[ INCIDENTS_YAML, self.incidents ],
|
251
|
+
[ INFOS_YAML, self.infos ]
|
252
|
+
).to_yaml( options )
|
253
|
+
end
|
254
254
|
|
255
255
|
# Initialise an Alert object from a YAML string. Any object that is a subclass of IO (e.g. File) can be passed in.
|
256
|
-
|
257
|
-
|
258
|
-
|
256
|
+
def self.from_yaml( yaml )
|
257
|
+
self.from_yaml_data( YAML.load( yaml ))
|
258
|
+
end
|
259
259
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
260
|
+
def self.from_yaml_data( alert_yaml_data ) # :nodoc:
|
261
|
+
Alert.new(
|
262
|
+
:identifier => alert_yaml_data[ IDENTIFIER_YAML ],
|
263
|
+
:sender => alert_yaml_data[ SENDER_YAML ],
|
264
|
+
:sent => ( sent = alert_yaml_data[ SENT_YAML ]).blank? ? nil : DateTime.parse( sent.to_s ),
|
265
|
+
:status => alert_yaml_data[ STATUS_YAML ],
|
266
|
+
:msg_type => alert_yaml_data[ MSG_TYPE_YAML ],
|
267
|
+
:source => alert_yaml_data[ SOURCE_YAML ],
|
268
|
+
:scope => alert_yaml_data[ SCOPE_YAML ],
|
269
|
+
:restriction => alert_yaml_data[ RESTRICTION_YAML ],
|
270
|
+
:addresses => alert_yaml_data[ ADDRESSES_YAML ],
|
271
|
+
:code => alert_yaml_data[ CODE_YAML ],
|
272
|
+
:note => alert_yaml_data[ NOTE_YAML ],
|
273
|
+
:references => alert_yaml_data[ REFERENCES_YAML ],
|
274
|
+
:incidents => alert_yaml_data[ INCIDENTS_YAML ],
|
275
|
+
:infos => Array( alert_yaml_data[ INFOS_YAML ]).map{ |info_yaml_data| RCAP::Info.from_yaml_data( info_yaml_data )}
|
276
|
+
)
|
277
|
+
end
|
278
|
+
|
279
|
+
IDENTIFIER_KEY = 'identifier' # :nodoc:
|
280
|
+
SENDER_KEY = 'sender' # :nodoc:
|
281
|
+
SENT_KEY = 'sent' # :nodoc:
|
282
|
+
STATUS_KEY = 'status' # :nodoc:
|
283
|
+
MSG_TYPE_KEY = 'msg_type' # :nodoc:
|
284
|
+
SOURCE_KEY = 'source' # :nodoc:
|
285
|
+
SCOPE_KEY = 'scope' # :nodoc:
|
286
|
+
RESTRICTION_KEY = 'restriction' # :nodoc:
|
287
|
+
ADDRESSES_KEY = 'addresses' # :nodoc:
|
288
|
+
CODE_KEY = 'code' # :nodoc:
|
289
|
+
NOTE_KEY = 'note' # :nodoc:
|
290
|
+
REFERENCES_KEY = 'references' # :nodoc:
|
291
|
+
INCIDENTS_KEY = 'incidents' # :nodoc:
|
292
|
+
INFOS_KEY = 'infos' # :nodoc:
|
293
|
+
|
294
|
+
# Returns a Hash representation of an Alert object
|
295
|
+
def to_h
|
296
|
+
RCAP.attribute_values_to_hash([ IDENTIFIER_KEY, self.identifier ],
|
297
|
+
[ SENDER_KEY, self.sender ],
|
298
|
+
[ SENT_KEY, RCAP.to_s_for_cap( self.sent )],
|
299
|
+
[ STATUS_KEY, self.status ],
|
300
|
+
[ MSG_TYPE_KEY, self.msg_type ],
|
301
|
+
[ SOURCE_KEY, self.source ],
|
302
|
+
[ SCOPE_KEY, self.scope ],
|
303
|
+
[ RESTRICTION_KEY, self.restriction ],
|
304
|
+
[ ADDRESSES_KEY, self.addresses ],
|
305
|
+
[ CODE_KEY, self.code ],
|
306
|
+
[ NOTE_KEY, self.note ],
|
307
|
+
[ REFERENCES_KEY, self.references ],
|
308
|
+
[ INCIDENTS_KEY, self.incidents ],
|
309
|
+
[ INFOS_KEY, self.infos.map{ |info| info.to_h }])
|
310
|
+
end
|
311
|
+
|
312
|
+
# Initialises an Alert object from a Hash produced by Alert#to_h
|
313
|
+
def self.from_h( alert_hash )
|
314
|
+
self.new(
|
315
|
+
:identifier => alert_hash[ IDENTIFIER_KEY ],
|
316
|
+
:sender => alert_hash[ SENDER_KEY ],
|
317
|
+
:sent => RCAP.parse_datetime( alert_hash[ SENT_KEY ]),
|
318
|
+
:status => alert_hash[ STATUS_KEY ],
|
319
|
+
:msg_type => alert_hash[ MSG_TYPE_KEY ],
|
320
|
+
:source => alert_hash[ SOURCE_KEY ],
|
321
|
+
:scope => alert_hash[ SCOPE_KEY ],
|
322
|
+
:restriction => alert_hash[ RESTRICTION_KEY ],
|
323
|
+
:addresses => alert_hash[ ADDRESSES_KEY ],
|
324
|
+
:code => alert_hash[ CODE_KEY ],
|
325
|
+
:note => alert_hash[ NOTE_KEY ],
|
326
|
+
:references => alert_hash[ REFERENCES_KEY ],
|
327
|
+
:incidents => alert_hash[ INCIDENTS_KEY ],
|
328
|
+
:infos => Array( alert_hash[ INFOS_KEY ]).map{ |info_hash| RCAP::Info.from_h( info_hash )})
|
329
|
+
end
|
330
|
+
|
331
|
+
# Returns a JSON string representation of an Alert object
|
332
|
+
def to_json
|
333
|
+
self.to_h.to_json
|
334
|
+
end
|
335
|
+
|
336
|
+
# Initiialises an Alert object from a JSON string produced by Alert#to_json
|
337
|
+
def self.from_json( json_string )
|
338
|
+
self.from_h( JSON.parse( json_string ))
|
339
|
+
end
|
278
340
|
end
|
279
341
|
end
|