rcap 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/{CHANGELOG.rdoc → CHANGELOG.md} +26 -20
- data/README.md +259 -0
- data/Rakefile +8 -7
- data/lib/extensions/array.rb +7 -1
- data/lib/extensions/date_time.rb +5 -1
- data/lib/extensions/string.rb +14 -1
- data/lib/extensions/time.rb +5 -1
- data/lib/rcap.rb +1 -1
- data/lib/rcap/alert.rb +24 -10
- data/lib/rcap/cap_1_0/alert.rb +232 -166
- data/lib/rcap/cap_1_0/area.rb +100 -67
- data/lib/rcap/cap_1_0/circle.rb +47 -22
- data/lib/rcap/cap_1_0/event_code.rb +3 -2
- data/lib/rcap/cap_1_0/geocode.rb +3 -2
- data/lib/rcap/cap_1_0/info.rb +265 -202
- data/lib/rcap/cap_1_0/parameter.rb +43 -20
- data/lib/rcap/cap_1_0/point.rb +23 -9
- data/lib/rcap/cap_1_0/polygon.rb +37 -19
- data/lib/rcap/cap_1_0/resource.rb +77 -55
- data/lib/rcap/cap_1_1/alert.rb +222 -156
- data/lib/rcap/cap_1_1/area.rb +100 -67
- data/lib/rcap/cap_1_1/circle.rb +49 -22
- data/lib/rcap/cap_1_1/event_code.rb +3 -2
- data/lib/rcap/cap_1_1/geocode.rb +3 -2
- data/lib/rcap/cap_1_1/info.rb +281 -217
- data/lib/rcap/cap_1_1/parameter.rb +35 -16
- data/lib/rcap/cap_1_1/point.rb +23 -9
- data/lib/rcap/cap_1_1/polygon.rb +38 -20
- data/lib/rcap/cap_1_1/resource.rb +106 -65
- data/lib/rcap/cap_1_2/alert.rb +224 -158
- data/lib/rcap/cap_1_2/area.rb +100 -67
- data/lib/rcap/cap_1_2/circle.rb +49 -24
- data/lib/rcap/cap_1_2/event_code.rb +3 -2
- data/lib/rcap/cap_1_2/geocode.rb +3 -2
- data/lib/rcap/cap_1_2/info.rb +285 -219
- data/lib/rcap/cap_1_2/parameter.rb +39 -19
- data/lib/rcap/cap_1_2/point.rb +23 -9
- data/lib/rcap/cap_1_2/polygon.rb +37 -20
- data/lib/rcap/cap_1_2/resource.rb +107 -67
- data/lib/rcap/config.rb +4 -0
- data/lib/rcap/utilities.rb +55 -2
- data/lib/rcap/validations.rb +2 -2
- data/lib/rcap/version.rb +1 -1
- data/rcap.gemspec +2 -2
- data/spec/cap_1_0/parameter_spec.rb +5 -1
- data/spec/cap_1_1/resource_spec.rb +6 -0
- data/spec/cap_1_2/alert_spec.rb +8 -0
- data/spec/cap_1_2/resource_spec.rb +8 -2
- metadata +11 -10
- data/README.rdoc +0 -247
- data/lib/config.rb +0 -2
data/lib/rcap.rb
CHANGED
data/lib/rcap/alert.rb
CHANGED
@@ -7,12 +7,14 @@ module RCAP
|
|
7
7
|
|
8
8
|
CAP_NAMESPACES = [ RCAP::CAP_1_0::Alert::XMLNS, RCAP::CAP_1_1::Alert::XMLNS, RCAP::CAP_1_2::Alert::XMLNS ]
|
9
9
|
|
10
|
-
# Initialise a RCAP Alert from a XML document.
|
11
|
-
# document is inspected and a CAP_1_0::Alert, CAP_1_1::Alert
|
12
|
-
# or CAP_1_2::Alert is instantiated.
|
10
|
+
# Initialise a RCAP Alert from a XML document.
|
13
11
|
#
|
14
|
-
#
|
15
|
-
#
|
12
|
+
# @param [IO,String] xml CAP alert in XML format. Can be a String or any IO object.
|
13
|
+
# @param [String] namespace_key The XML namespace that the CAP alert is in. If omitted
|
14
|
+
# the namespace of the document is inspected and a CAP_1_0::Alert, CAP_1_1::Alert
|
15
|
+
# or CAP_1_2::Alert is instantiated accordingly. If no namespace can be detected
|
16
|
+
# a CAP 1.2 message will be assumed.
|
17
|
+
# @return [ RCAP::CAP_1_0::Alert, RCAP::CAP_1_1::Alert, RCAP::CAP_1_2::Alert ]
|
16
18
|
def self.from_xml( xml, namespace_key = nil )
|
17
19
|
xml_document = REXML::Document.new( xml )
|
18
20
|
document_namespaces = xml_document.root.namespaces.invert
|
@@ -30,7 +32,10 @@ module RCAP
|
|
30
32
|
|
31
33
|
# Initialise a RCAP Alert from a YAML document produced by
|
32
34
|
# CAP_1_2::Alert#to_yaml. The version of the document is inspected and a
|
33
|
-
#
|
35
|
+
# CAP 1.0, 1.1 or 1.2 Alert is instantiated accordingly.
|
36
|
+
#
|
37
|
+
# @param [IO, String] yaml CAP Alert in YAML format. Can be a String or any IO object.
|
38
|
+
# @return [ RCAP::CAP_1_0::Alert, RCAP::CAP_1_1::Alert, RCAP::CAP_1_2::Alert ]
|
34
39
|
def self.from_yaml( yaml )
|
35
40
|
yaml_data = YAML.load( yaml )
|
36
41
|
|
@@ -46,13 +51,22 @@ module RCAP
|
|
46
51
|
|
47
52
|
# Initialise a RCAP Alert from a JSON document produced by
|
48
53
|
# CAP_1_2::Alert#to_json. The version of the document is inspected and a
|
49
|
-
#
|
50
|
-
|
51
|
-
|
54
|
+
# CAP 1.0, 1.1 or 1.2 Alert is instantiated accordingly.
|
55
|
+
#
|
56
|
+
# @param [#to_s] json Alert in JSON format
|
57
|
+
# @return [ RCAP::CAP_1_0::Alert, RCAP::CAP_1_1::Alert, RCAP::CAP_1_2::Alert ]
|
58
|
+
def self.from_json( json )
|
59
|
+
json_hash = JSON.parse( json.to_s )
|
52
60
|
self.from_h( json_hash )
|
53
61
|
end
|
54
62
|
|
55
|
-
|
63
|
+
# Initialise a RCAP Alert from a Ruby hash produced by
|
64
|
+
# CAP_1_2::Alert#to_h. The cap_version key is inspected and a
|
65
|
+
# CAP 1.0, 1.1 or 1.2 Alert is instantiated accordingly.
|
66
|
+
#
|
67
|
+
# @param [Hash] hash Alert as a Ruby hash.
|
68
|
+
# @return [ RCAP::CAP_1_0::Alert, RCAP::CAP_1_1::Alert, RCAP::CAP_1_2::Alert ]
|
69
|
+
def self.from_h( hash )
|
56
70
|
case hash[ JSON_CAP_VERSION_KEY ]
|
57
71
|
when CAP_1_0::Alert::CAP_VERSION
|
58
72
|
CAP_1_0::Alert.from_h( hash )
|
data/lib/rcap/cap_1_0/alert.rb
CHANGED
@@ -14,84 +14,58 @@ module RCAP
|
|
14
14
|
XMLNS = "http://www.incident.com/cap/1.0"
|
15
15
|
CAP_VERSION = "1.0"
|
16
16
|
|
17
|
-
STATUS_ACTUAL = "Actual"
|
18
|
-
STATUS_EXERCISE = "Exercise"
|
19
|
-
STATUS_SYSTEM = "System"
|
20
|
-
STATUS_TEST = "Test"
|
17
|
+
STATUS_ACTUAL = "Actual"
|
18
|
+
STATUS_EXERCISE = "Exercise"
|
19
|
+
STATUS_SYSTEM = "System"
|
20
|
+
STATUS_TEST = "Test"
|
21
21
|
# Valid values for status
|
22
22
|
VALID_STATUSES = [ STATUS_ACTUAL, STATUS_EXERCISE, STATUS_SYSTEM, STATUS_TEST ]
|
23
23
|
|
24
|
-
MSG_TYPE_ALERT = "Alert"
|
25
|
-
MSG_TYPE_UPDATE = "Update"
|
26
|
-
MSG_TYPE_CANCEL = "Cancel"
|
27
|
-
MSG_TYPE_ACK = "Ack"
|
28
|
-
MSG_TYPE_ERROR = "Error"
|
24
|
+
MSG_TYPE_ALERT = "Alert"
|
25
|
+
MSG_TYPE_UPDATE = "Update"
|
26
|
+
MSG_TYPE_CANCEL = "Cancel"
|
27
|
+
MSG_TYPE_ACK = "Ack"
|
28
|
+
MSG_TYPE_ERROR = "Error"
|
29
29
|
# Valid values for msg_type
|
30
30
|
VALID_MSG_TYPES = [ MSG_TYPE_ALERT, MSG_TYPE_UPDATE, MSG_TYPE_CANCEL, MSG_TYPE_ACK, MSG_TYPE_ERROR ]
|
31
31
|
|
32
|
-
SCOPE_PUBLIC = "Public"
|
33
|
-
SCOPE_RESTRICTED = "Restricted"
|
34
|
-
SCOPE_PRIVATE = "Private"
|
32
|
+
SCOPE_PUBLIC = "Public"
|
33
|
+
SCOPE_RESTRICTED = "Restricted"
|
34
|
+
SCOPE_PRIVATE = "Private"
|
35
35
|
# Valid values for scope
|
36
36
|
VALID_SCOPES = [ SCOPE_PUBLIC, SCOPE_PRIVATE, SCOPE_RESTRICTED ]
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
SENDER_ELEMENT_NAME = 'sender' # :nodoc:
|
41
|
-
SENT_ELEMENT_NAME = 'sent' # :nodoc:
|
42
|
-
STATUS_ELEMENT_NAME = 'status' # :nodoc:
|
43
|
-
MSG_TYPE_ELEMENT_NAME = 'msgType' # :nodoc:
|
44
|
-
PASSWORD_ELEMENT_NAME = 'password' # :nodoc:
|
45
|
-
SOURCE_ELEMENT_NAME = 'source' # :nodoc:
|
46
|
-
SCOPE_ELEMENT_NAME = 'scope' # :nodoc:
|
47
|
-
RESTRICTION_ELEMENT_NAME = 'restriction' # :nodoc:
|
48
|
-
ADDRESSES_ELEMENT_NAME = 'addresses' # :nodoc:
|
49
|
-
CODE_ELEMENT_NAME = 'code' # :nodoc:
|
50
|
-
NOTE_ELEMENT_NAME = 'note' # :nodoc:
|
51
|
-
REFERENCES_ELEMENT_NAME = 'references' # :nodoc:
|
52
|
-
INCIDENTS_ELEMENT_NAME = 'incidents' # :nodoc:
|
53
|
-
|
54
|
-
XPATH = 'cap:alert' # :nodoc:
|
55
|
-
IDENTIFIER_XPATH = "cap:#{ IDENTIFIER_ELEMENT_NAME }" # :nodoc:
|
56
|
-
SENDER_XPATH = "cap:#{ SENDER_ELEMENT_NAME }" # :nodoc:
|
57
|
-
SENT_XPATH = "cap:#{ SENT_ELEMENT_NAME }" # :nodoc:
|
58
|
-
STATUS_XPATH = "cap:#{ STATUS_ELEMENT_NAME }" # :nodoc:
|
59
|
-
MSG_TYPE_XPATH = "cap:#{ MSG_TYPE_ELEMENT_NAME }" # :nodoc:
|
60
|
-
PASSWORD_XPATH = "cap:#{ PASSWORD_ELEMENT_NAME }" # :nodoc:
|
61
|
-
SOURCE_XPATH = "cap:#{ SOURCE_ELEMENT_NAME }" # :nodoc:
|
62
|
-
SCOPE_XPATH = "cap:#{ SCOPE_ELEMENT_NAME }" # :nodoc:
|
63
|
-
RESTRICTION_XPATH = "cap:#{ RESTRICTION_ELEMENT_NAME }" # :nodoc:
|
64
|
-
ADDRESSES_XPATH = "cap:#{ ADDRESSES_ELEMENT_NAME }" # :nodoc:
|
65
|
-
CODE_XPATH = "cap:#{ CODE_ELEMENT_NAME }" # :nodoc:
|
66
|
-
NOTE_XPATH = "cap:#{ NOTE_ELEMENT_NAME }" # :nodoc:
|
67
|
-
REFERENCES_XPATH = "cap:#{ REFERENCES_ELEMENT_NAME }" # :nodoc:
|
68
|
-
INCIDENTS_XPATH = "cap:#{ INCIDENTS_ELEMENT_NAME }" # :nodoc:
|
69
|
-
|
70
|
-
# If not set a UUID will be set by default
|
38
|
+
|
39
|
+
# @return [String] If not set a UUID will be set by default
|
71
40
|
attr_accessor( :identifier)
|
41
|
+
# @return [String]
|
72
42
|
attr_accessor( :sender )
|
73
|
-
#
|
43
|
+
# @return [DateTime] If not set will value will be time of creation.
|
74
44
|
attr_accessor( :sent )
|
75
|
-
#
|
45
|
+
# @return [String] Can only be one of {VALID_STATUSES}
|
76
46
|
attr_accessor( :status )
|
77
|
-
#
|
47
|
+
# @return [String] Can only be one of {VALID_MSG_TYPES}
|
78
48
|
attr_accessor( :msg_type )
|
49
|
+
# @return [String]
|
79
50
|
attr_accessor( :password )
|
80
|
-
#
|
51
|
+
# @return [String] Can only be one of {VALID_SCOPES}
|
81
52
|
attr_accessor( :scope )
|
53
|
+
# @return [String]
|
82
54
|
attr_accessor( :source )
|
83
|
-
# Depends on scope being SCOPE_RESTRICTED
|
55
|
+
# @return [String ] Depends on scope being {SCOPE_RESTRICTED}
|
84
56
|
attr_accessor( :restriction )
|
57
|
+
# @return [String]
|
85
58
|
attr_accessor( :note )
|
86
59
|
|
87
|
-
# Collection of address strings. Depends on scope being SCOPE_PRIVATE
|
60
|
+
# @return [Array<String>] Collection of address strings. Depends on scope being {SCOPE_PRIVATE}
|
88
61
|
attr_reader( :addresses )
|
62
|
+
# @return [Array<String>]
|
89
63
|
attr_reader( :codes )
|
90
|
-
#
|
64
|
+
# @return [Array<String>] See {#to_reference}
|
91
65
|
attr_reader( :references)
|
92
|
-
# Collection of incident strings
|
66
|
+
# @return [Array<String>] Collection of incident strings
|
93
67
|
attr_reader( :incidents )
|
94
|
-
#
|
68
|
+
# @return [Array<Info>]
|
95
69
|
attr_reader( :infos )
|
96
70
|
|
97
71
|
validates_presence_of( :identifier, :sender, :sent, :status, :msg_type, :scope )
|
@@ -108,6 +82,28 @@ module RCAP
|
|
108
82
|
|
109
83
|
validates_collection_of( :infos )
|
110
84
|
|
85
|
+
# @example
|
86
|
+
# Alert.new( sender: 'disaster_management@cape_town.municipal.za',
|
87
|
+
# sent: Date.today,
|
88
|
+
# status: Alert::STATUS_ACTUAL,
|
89
|
+
# msg_type: Alert::MSG_TYPE_ALERT,
|
90
|
+
# scope: Alert::SCOPE_PUBLIC )
|
91
|
+
#
|
92
|
+
# @param [Hash] attributes
|
93
|
+
# @option attributes [String] :identifier Unique identifier - autogenerated if not given
|
94
|
+
# @option attributes [String] :sender
|
95
|
+
# @option attributes [DateTime] :sent
|
96
|
+
# @option attributes [String] :status A member of {VALID_STATUSES}
|
97
|
+
# @option attributes [String] :msg_type A member of {VALID_MSG_TYPES}
|
98
|
+
# @option attributes [String] :password
|
99
|
+
# @option attributes [String] :scope A member of {VALID_SCOPES}
|
100
|
+
# @option attributes [String] :source
|
101
|
+
# @option attributes [String] :restriction
|
102
|
+
# @option attributes [Array<String>] :addresses
|
103
|
+
# @option attributes [Array<String>] :codes
|
104
|
+
# @option attributes [Array<String>] :references see {#to_reference}
|
105
|
+
# @option attributes [Array<String>] :incidents
|
106
|
+
# @option attributes [Array<Info>] :infos
|
111
107
|
def initialize( attributes = {})
|
112
108
|
@identifier = attributes[ :identifier ] || RCAP.generate_identifier
|
113
109
|
@sender = attributes[ :sender ]
|
@@ -125,99 +121,146 @@ module RCAP
|
|
125
121
|
@infos = Array( attributes[ :infos ])
|
126
122
|
end
|
127
123
|
|
128
|
-
# Creates a new Info object and adds it to the infos array.
|
129
|
-
#
|
124
|
+
# Creates a new {Info} object and adds it to the {#infos array}.
|
125
|
+
#
|
126
|
+
# @see Info#initialize
|
127
|
+
# @param [Hash] info_attributes Info attributes - see {Info#initialize}
|
128
|
+
# @return [Info]
|
130
129
|
def add_info( info_attributes = {})
|
131
130
|
info = Info.new( info_attributes )
|
132
|
-
|
131
|
+
@infos << info
|
133
132
|
info
|
134
133
|
end
|
135
134
|
|
136
|
-
|
135
|
+
XML_ELEMENT_NAME = 'alert'
|
136
|
+
IDENTIFIER_ELEMENT_NAME = 'identifier'
|
137
|
+
SENDER_ELEMENT_NAME = 'sender'
|
138
|
+
SENT_ELEMENT_NAME = 'sent'
|
139
|
+
STATUS_ELEMENT_NAME = 'status'
|
140
|
+
MSG_TYPE_ELEMENT_NAME = 'msgType'
|
141
|
+
PASSWORD_ELEMENT_NAME = 'password'
|
142
|
+
SOURCE_ELEMENT_NAME = 'source'
|
143
|
+
SCOPE_ELEMENT_NAME = 'scope'
|
144
|
+
RESTRICTION_ELEMENT_NAME = 'restriction'
|
145
|
+
ADDRESSES_ELEMENT_NAME = 'addresses'
|
146
|
+
CODE_ELEMENT_NAME = 'code'
|
147
|
+
NOTE_ELEMENT_NAME = 'note'
|
148
|
+
REFERENCES_ELEMENT_NAME = 'references'
|
149
|
+
INCIDENTS_ELEMENT_NAME = 'incidents'
|
150
|
+
|
151
|
+
# @return [REXML::Element]
|
152
|
+
def to_xml_element
|
137
153
|
xml_element = REXML::Element.new( XML_ELEMENT_NAME )
|
138
154
|
xml_element.add_namespace( XMLNS )
|
139
|
-
xml_element.add_element( IDENTIFIER_ELEMENT_NAME ).add_text(
|
140
|
-
xml_element.add_element( SENDER_ELEMENT_NAME ).add_text(
|
141
|
-
xml_element.add_element( SENT_ELEMENT_NAME ).add_text(
|
142
|
-
xml_element.add_element( STATUS_ELEMENT_NAME ).add_text(
|
143
|
-
xml_element.add_element( MSG_TYPE_ELEMENT_NAME ).add_text(
|
144
|
-
xml_element.add_element( PASSWORD_ELEMENT_NAME ).add_text(
|
145
|
-
xml_element.add_element( SOURCE_ELEMENT_NAME ).add_text(
|
146
|
-
xml_element.add_element( SCOPE_ELEMENT_NAME ).add_text(
|
147
|
-
xml_element.add_element( RESTRICTION_ELEMENT_NAME ).add_text(
|
148
|
-
|
149
|
-
xml_element.add_element( ADDRESSES_ELEMENT_NAME ).add_text(
|
155
|
+
xml_element.add_element( IDENTIFIER_ELEMENT_NAME ).add_text( @identifier ) if @identifier
|
156
|
+
xml_element.add_element( SENDER_ELEMENT_NAME ).add_text( @sender ) if @sender
|
157
|
+
xml_element.add_element( SENT_ELEMENT_NAME ).add_text( @sent.to_s_for_cap ) if @sent
|
158
|
+
xml_element.add_element( STATUS_ELEMENT_NAME ).add_text( @status ) if @status
|
159
|
+
xml_element.add_element( MSG_TYPE_ELEMENT_NAME ).add_text( @msg_type ) if @msg_type
|
160
|
+
xml_element.add_element( PASSWORD_ELEMENT_NAME ).add_text( @password ) if @password
|
161
|
+
xml_element.add_element( SOURCE_ELEMENT_NAME ).add_text( @source ) if @source
|
162
|
+
xml_element.add_element( SCOPE_ELEMENT_NAME ).add_text( @scope ) if @scope
|
163
|
+
xml_element.add_element( RESTRICTION_ELEMENT_NAME ).add_text( @restriction ) if @restriction
|
164
|
+
if @addresses.any?
|
165
|
+
xml_element.add_element( ADDRESSES_ELEMENT_NAME ).add_text( @addresses.to_s_for_cap )
|
150
166
|
end
|
151
|
-
|
167
|
+
@codes.each do |code|
|
152
168
|
xml_element.add_element( CODE_ELEMENT_NAME ).add_text( code )
|
153
169
|
end
|
154
|
-
xml_element.add_element( NOTE_ELEMENT_NAME ).add_text(
|
155
|
-
|
156
|
-
xml_element.add_element( REFERENCES_ELEMENT_NAME ).add_text(
|
170
|
+
xml_element.add_element( NOTE_ELEMENT_NAME ).add_text( @note ) if @note
|
171
|
+
if @references.any?
|
172
|
+
xml_element.add_element( REFERENCES_ELEMENT_NAME ).add_text( @references.join( ' ' ))
|
157
173
|
end
|
158
|
-
|
159
|
-
xml_element.add_element( INCIDENTS_ELEMENT_NAME ).add_text(
|
174
|
+
if @incidents.any?
|
175
|
+
xml_element.add_element( INCIDENTS_ELEMENT_NAME ).add_text( @incidents.join( ' ' ))
|
160
176
|
end
|
161
|
-
|
177
|
+
@infos.each do |info|
|
162
178
|
xml_element.add_element( info.to_xml_element )
|
163
179
|
end
|
164
180
|
xml_element
|
165
181
|
end
|
166
182
|
|
167
|
-
|
183
|
+
# @return [REXML::Document]
|
184
|
+
def to_xml_document
|
168
185
|
xml_document = REXML::Document.new
|
169
186
|
xml_document.add( REXML::XMLDecl.new )
|
170
|
-
xml_document.add(
|
187
|
+
xml_document.add( to_xml_element )
|
171
188
|
xml_document
|
172
189
|
end
|
173
190
|
|
174
191
|
# Returns a string containing the XML representation of the alert.
|
192
|
+
#
|
193
|
+
# @param [true,false] pretty_print Pretty print output
|
194
|
+
# @return [String]
|
175
195
|
def to_xml( pretty_print = false )
|
176
196
|
if pretty_print
|
177
197
|
xml_document = ""
|
178
|
-
XML_PRETTY_PRINTER.write(
|
198
|
+
RCAP::XML_PRETTY_PRINTER.write( to_xml_document, xml_document )
|
179
199
|
xml_document
|
180
200
|
else
|
181
|
-
|
201
|
+
to_xml_document.to_s
|
182
202
|
end
|
183
203
|
end
|
184
204
|
|
185
205
|
# Returns a string representation of the alert suitable for usage as a reference in a CAP message of the form
|
186
206
|
# sender,identifier,sent
|
207
|
+
#
|
208
|
+
# @return [String]
|
187
209
|
def to_reference
|
188
|
-
"#{
|
210
|
+
"#{ @sender },#{ @identifier },#{ @sent }"
|
189
211
|
end
|
190
212
|
|
191
|
-
|
213
|
+
# @return [String]
|
214
|
+
def inspect
|
192
215
|
alert_inspect = [ "CAP Version: #{ CAP_VERSION }",
|
193
|
-
"Identifier: #{
|
194
|
-
"Sender: #{
|
195
|
-
"Sent: #{
|
196
|
-
"Status: #{
|
197
|
-
"Message Type: #{
|
198
|
-
"Password: #{
|
199
|
-
"Source: #{
|
200
|
-
"Scope: #{
|
201
|
-
"Restriction: #{
|
202
|
-
"Addresses: #{
|
216
|
+
"Identifier: #{ @identifier }",
|
217
|
+
"Sender: #{ @sender }",
|
218
|
+
"Sent: #{ @sent }",
|
219
|
+
"Status: #{ @status }",
|
220
|
+
"Message Type: #{ @msg_type }",
|
221
|
+
"Password: #{ @password }",
|
222
|
+
"Source: #{ @source }",
|
223
|
+
"Scope: #{ @scope }",
|
224
|
+
"Restriction: #{ @restriction }",
|
225
|
+
"Addresses: #{ @addresses.to_s_for_cap }",
|
203
226
|
"Codes:",
|
204
|
-
|
205
|
-
"Note: #{
|
206
|
-
"References: #{
|
207
|
-
"Incidents: #{
|
227
|
+
@codes.map{ |code| " " + code }.join("\n")+"",
|
228
|
+
"Note: #{ @note }",
|
229
|
+
"References: #{ @references.join( ' ' )}",
|
230
|
+
"Incidents: #{ @incidents.join( ' ')}",
|
208
231
|
"Information:",
|
209
|
-
|
232
|
+
@infos.map{ |info| " " + info.to_s }.join( "\n" )].join("\n")
|
210
233
|
RCAP.format_lines_for_inspect( 'ALERT', alert_inspect )
|
211
234
|
end
|
212
235
|
|
213
236
|
# Returns a string representation of the alert of the form
|
214
237
|
# sender/identifier/sent
|
215
|
-
# See
|
238
|
+
# See {#to_reference} for another string representation suitable as a CAP reference.
|
239
|
+
#
|
240
|
+
# @return [String]
|
216
241
|
def to_s
|
217
|
-
"#{
|
242
|
+
"#{ @sender }/#{ @identifier }/#{ @sent }"
|
218
243
|
end
|
219
244
|
|
220
|
-
|
245
|
+
XPATH = 'cap:alert'
|
246
|
+
IDENTIFIER_XPATH = "cap:#{ IDENTIFIER_ELEMENT_NAME }"
|
247
|
+
SENDER_XPATH = "cap:#{ SENDER_ELEMENT_NAME }"
|
248
|
+
SENT_XPATH = "cap:#{ SENT_ELEMENT_NAME }"
|
249
|
+
STATUS_XPATH = "cap:#{ STATUS_ELEMENT_NAME }"
|
250
|
+
MSG_TYPE_XPATH = "cap:#{ MSG_TYPE_ELEMENT_NAME }"
|
251
|
+
PASSWORD_XPATH = "cap:#{ PASSWORD_ELEMENT_NAME }"
|
252
|
+
SOURCE_XPATH = "cap:#{ SOURCE_ELEMENT_NAME }"
|
253
|
+
SCOPE_XPATH = "cap:#{ SCOPE_ELEMENT_NAME }"
|
254
|
+
RESTRICTION_XPATH = "cap:#{ RESTRICTION_ELEMENT_NAME }"
|
255
|
+
ADDRESSES_XPATH = "cap:#{ ADDRESSES_ELEMENT_NAME }"
|
256
|
+
CODE_XPATH = "cap:#{ CODE_ELEMENT_NAME }"
|
257
|
+
NOTE_XPATH = "cap:#{ NOTE_ELEMENT_NAME }"
|
258
|
+
REFERENCES_XPATH = "cap:#{ REFERENCES_ELEMENT_NAME }"
|
259
|
+
INCIDENTS_XPATH = "cap:#{ INCIDENTS_ELEMENT_NAME }"
|
260
|
+
|
261
|
+
# @param [REXML::Element] alert_xml_element
|
262
|
+
# @return [RCAP::CAP_1_0::Alert]
|
263
|
+
def self.from_xml_element( alert_xml_element )
|
221
264
|
self.new( :identifier => RCAP.xpath_text( alert_xml_element, IDENTIFIER_XPATH, Alert::XMLNS ),
|
222
265
|
:sender => RCAP.xpath_text( alert_xml_element, SENDER_XPATH, Alert::XMLNS ),
|
223
266
|
:sent => (( sent = RCAP.xpath_first( alert_xml_element, SENT_XPATH, Alert::XMLNS )) ? DateTime.parse( sent.text ) : nil ),
|
@@ -235,60 +278,72 @@ module RCAP
|
|
235
278
|
:infos => RCAP.xpath_match( alert_xml_element, Info::XPATH, Alert::XMLNS ).map{ |element| Info.from_xml_element( element )})
|
236
279
|
end
|
237
280
|
|
238
|
-
|
281
|
+
# @param [REXML::Document] xml_document
|
282
|
+
# @return [RCAP::CAP_1_0::Alert]
|
283
|
+
def self.from_xml_document( xml_document )
|
239
284
|
self.from_xml_element( xml_document.root )
|
240
285
|
end
|
241
286
|
|
242
287
|
# Initialise an Alert object from an XML string. Any object that is a subclass of IO (e.g. File) can be passed in.
|
288
|
+
#
|
289
|
+
# @param [String] xml
|
290
|
+
# @return [RCAP::CAP_1_0::Alert]
|
243
291
|
def self.from_xml( xml )
|
244
292
|
self.from_xml_document( REXML::Document.new( xml ))
|
245
293
|
end
|
246
294
|
|
247
|
-
CAP_VERSION_YAML = "CAP Version"
|
248
|
-
IDENTIFIER_YAML = "Identifier"
|
249
|
-
SENDER_YAML = "Sender"
|
250
|
-
SENT_YAML = "Sent"
|
251
|
-
STATUS_YAML = "Status"
|
252
|
-
MSG_TYPE_YAML = "Message Type"
|
253
|
-
PASSWORD_YAML = "Password"
|
254
|
-
SOURCE_YAML = "Source"
|
255
|
-
SCOPE_YAML = "Scope"
|
256
|
-
RESTRICTION_YAML = "Restriction"
|
257
|
-
ADDRESSES_YAML = "Addresses"
|
258
|
-
CODES_YAML = "Codes"
|
259
|
-
NOTE_YAML = "Note"
|
260
|
-
REFERENCES_YAML = "References"
|
261
|
-
INCIDENTS_YAML = "Incidents"
|
262
|
-
INFOS_YAML = "Information"
|
295
|
+
CAP_VERSION_YAML = "CAP Version"
|
296
|
+
IDENTIFIER_YAML = "Identifier"
|
297
|
+
SENDER_YAML = "Sender"
|
298
|
+
SENT_YAML = "Sent"
|
299
|
+
STATUS_YAML = "Status"
|
300
|
+
MSG_TYPE_YAML = "Message Type"
|
301
|
+
PASSWORD_YAML = "Password"
|
302
|
+
SOURCE_YAML = "Source"
|
303
|
+
SCOPE_YAML = "Scope"
|
304
|
+
RESTRICTION_YAML = "Restriction"
|
305
|
+
ADDRESSES_YAML = "Addresses"
|
306
|
+
CODES_YAML = "Codes"
|
307
|
+
NOTE_YAML = "Note"
|
308
|
+
REFERENCES_YAML = "References"
|
309
|
+
INCIDENTS_YAML = "Incidents"
|
310
|
+
INFOS_YAML = "Information"
|
263
311
|
|
264
312
|
# Returns a string containing the YAML representation of the alert.
|
313
|
+
#
|
314
|
+
# @return [String]
|
265
315
|
def to_yaml( options = {} )
|
266
316
|
RCAP.attribute_values_to_hash(
|
267
|
-
[ CAP_VERSION_YAML,
|
268
|
-
[ IDENTIFIER_YAML,
|
269
|
-
[ SENDER_YAML,
|
270
|
-
[ SENT_YAML,
|
271
|
-
[ STATUS_YAML,
|
272
|
-
[ MSG_TYPE_YAML,
|
273
|
-
[ PASSWORD_YAML,
|
274
|
-
[ SOURCE_YAML,
|
275
|
-
[ SCOPE_YAML,
|
276
|
-
[ RESTRICTION_YAML,
|
277
|
-
[ ADDRESSES_YAML,
|
278
|
-
[ CODES_YAML,
|
279
|
-
[ NOTE_YAML,
|
280
|
-
[ REFERENCES_YAML,
|
281
|
-
[ INCIDENTS_YAML,
|
282
|
-
[ INFOS_YAML,
|
317
|
+
[ CAP_VERSION_YAML, CAP_VERSION ],
|
318
|
+
[ IDENTIFIER_YAML, @identifier ],
|
319
|
+
[ SENDER_YAML, @sender ],
|
320
|
+
[ SENT_YAML, @sent ],
|
321
|
+
[ STATUS_YAML, @status ],
|
322
|
+
[ MSG_TYPE_YAML, @msg_type ],
|
323
|
+
[ PASSWORD_YAML, @password ],
|
324
|
+
[ SOURCE_YAML, @source ],
|
325
|
+
[ SCOPE_YAML, @scope ],
|
326
|
+
[ RESTRICTION_YAML, @restriction ],
|
327
|
+
[ ADDRESSES_YAML, @addresses ],
|
328
|
+
[ CODES_YAML, @codes ],
|
329
|
+
[ NOTE_YAML, @note ],
|
330
|
+
[ REFERENCES_YAML, @references ],
|
331
|
+
[ INCIDENTS_YAML, @incidents ],
|
332
|
+
[ INFOS_YAML, @infos ]
|
283
333
|
).to_yaml( options )
|
284
334
|
end
|
285
335
|
|
286
336
|
# Initialise an Alert object from a YAML string. Any object that is a subclass of IO (e.g. File) can be passed in.
|
337
|
+
#
|
338
|
+
# @param [String] yaml
|
339
|
+
# @return [RCAP::CAP_1_0::Alert]
|
287
340
|
def self.from_yaml( yaml )
|
288
341
|
self.from_yaml_data( YAML.load( yaml ))
|
289
342
|
end
|
290
343
|
|
291
|
-
|
344
|
+
# @param [Hash] yaml_data
|
345
|
+
# @return [RCAP::CAP_1_0::Alert]
|
346
|
+
def self.from_yaml_data( alert_yaml_data )
|
292
347
|
Alert.new(
|
293
348
|
:identifier => alert_yaml_data[ IDENTIFIER_YAML ],
|
294
349
|
:sender => alert_yaml_data[ SENDER_YAML ],
|
@@ -308,44 +363,49 @@ module RCAP
|
|
308
363
|
)
|
309
364
|
end
|
310
365
|
|
311
|
-
CAP_VERSION_KEY = 'cap_version'
|
312
|
-
IDENTIFIER_KEY = 'identifier'
|
313
|
-
SENDER_KEY = 'sender'
|
314
|
-
SENT_KEY = 'sent'
|
315
|
-
STATUS_KEY = 'status'
|
316
|
-
MSG_TYPE_KEY = 'msg_type'
|
317
|
-
PASSWORD_KEY = 'password'
|
318
|
-
SOURCE_KEY = 'source'
|
319
|
-
SCOPE_KEY = 'scope'
|
320
|
-
RESTRICTION_KEY = 'restriction'
|
321
|
-
ADDRESSES_KEY = 'addresses'
|
322
|
-
CODES_KEY = 'codes'
|
323
|
-
NOTE_KEY = 'note'
|
324
|
-
REFERENCES_KEY = 'references'
|
325
|
-
INCIDENTS_KEY = 'incidents'
|
326
|
-
INFOS_KEY = 'infos'
|
366
|
+
CAP_VERSION_KEY = 'cap_version'
|
367
|
+
IDENTIFIER_KEY = 'identifier'
|
368
|
+
SENDER_KEY = 'sender'
|
369
|
+
SENT_KEY = 'sent'
|
370
|
+
STATUS_KEY = 'status'
|
371
|
+
MSG_TYPE_KEY = 'msg_type'
|
372
|
+
PASSWORD_KEY = 'password'
|
373
|
+
SOURCE_KEY = 'source'
|
374
|
+
SCOPE_KEY = 'scope'
|
375
|
+
RESTRICTION_KEY = 'restriction'
|
376
|
+
ADDRESSES_KEY = 'addresses'
|
377
|
+
CODES_KEY = 'codes'
|
378
|
+
NOTE_KEY = 'note'
|
379
|
+
REFERENCES_KEY = 'references'
|
380
|
+
INCIDENTS_KEY = 'incidents'
|
381
|
+
INFOS_KEY = 'infos'
|
327
382
|
|
328
383
|
# Returns a Hash representation of an Alert object
|
384
|
+
#
|
385
|
+
# @return [Hash]
|
329
386
|
def to_h
|
330
387
|
RCAP.attribute_values_to_hash( [ CAP_VERSION_KEY, CAP_VERSION ],
|
331
|
-
[ IDENTIFIER_KEY,
|
332
|
-
[ SENDER_KEY,
|
333
|
-
[ SENT_KEY, RCAP.to_s_for_cap(
|
334
|
-
[ STATUS_KEY,
|
335
|
-
[ MSG_TYPE_KEY,
|
336
|
-
[ PASSWORD_KEY,
|
337
|
-
[ SOURCE_KEY,
|
338
|
-
[ SCOPE_KEY,
|
339
|
-
[ RESTRICTION_KEY,
|
340
|
-
[ ADDRESSES_KEY,
|
341
|
-
[ CODES_KEY,
|
342
|
-
[ NOTE_KEY,
|
343
|
-
[ REFERENCES_KEY,
|
344
|
-
[ INCIDENTS_KEY,
|
345
|
-
[ INFOS_KEY,
|
388
|
+
[ IDENTIFIER_KEY, @identifier ],
|
389
|
+
[ SENDER_KEY, @sender ],
|
390
|
+
[ SENT_KEY, RCAP.to_s_for_cap( @sent )],
|
391
|
+
[ STATUS_KEY, @status ],
|
392
|
+
[ MSG_TYPE_KEY, @msg_type ],
|
393
|
+
[ PASSWORD_KEY, @password ],
|
394
|
+
[ SOURCE_KEY, @source ],
|
395
|
+
[ SCOPE_KEY, @scope ],
|
396
|
+
[ RESTRICTION_KEY, @restriction ],
|
397
|
+
[ ADDRESSES_KEY, @addresses ],
|
398
|
+
[ CODES_KEY, @codes ],
|
399
|
+
[ NOTE_KEY, @note ],
|
400
|
+
[ REFERENCES_KEY, @references ],
|
401
|
+
[ INCIDENTS_KEY, @incidents ],
|
402
|
+
[ INFOS_KEY, @infos.map{ |info| info.to_h }])
|
346
403
|
end
|
347
404
|
|
348
405
|
# Initialises an Alert object from a Hash produced by Alert#to_h
|
406
|
+
#
|
407
|
+
# @param [Hash] alert_hash
|
408
|
+
# @return [RCAP::CAP_1_0::Alert]
|
349
409
|
def self.from_h( alert_hash )
|
350
410
|
self.new(
|
351
411
|
:identifier => alert_hash[ IDENTIFIER_KEY ],
|
@@ -366,6 +426,9 @@ module RCAP
|
|
366
426
|
end
|
367
427
|
|
368
428
|
# Returns a JSON string representation of an Alert object
|
429
|
+
#
|
430
|
+
# @param [true,false] pretty_print
|
431
|
+
# @return [String]
|
369
432
|
def to_json( pretty_print = false )
|
370
433
|
if pretty_print
|
371
434
|
JSON.pretty_generate( self.to_h )
|
@@ -374,7 +437,10 @@ module RCAP
|
|
374
437
|
end
|
375
438
|
end
|
376
439
|
|
377
|
-
#
|
440
|
+
# Initialises an Alert object from a JSON string produced by Alert#to_json
|
441
|
+
#
|
442
|
+
# @param [String] json_string
|
443
|
+
# @return [RCAP::CAP_1_0::Alert]
|
378
444
|
def self.from_json( json_string )
|
379
445
|
self.from_h( JSON.parse( json_string ))
|
380
446
|
end
|