rcap 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/{CHANGELOG.rdoc → CHANGELOG.md} +26 -20
  2. data/README.md +259 -0
  3. data/Rakefile +8 -7
  4. data/lib/extensions/array.rb +7 -1
  5. data/lib/extensions/date_time.rb +5 -1
  6. data/lib/extensions/string.rb +14 -1
  7. data/lib/extensions/time.rb +5 -1
  8. data/lib/rcap.rb +1 -1
  9. data/lib/rcap/alert.rb +24 -10
  10. data/lib/rcap/cap_1_0/alert.rb +232 -166
  11. data/lib/rcap/cap_1_0/area.rb +100 -67
  12. data/lib/rcap/cap_1_0/circle.rb +47 -22
  13. data/lib/rcap/cap_1_0/event_code.rb +3 -2
  14. data/lib/rcap/cap_1_0/geocode.rb +3 -2
  15. data/lib/rcap/cap_1_0/info.rb +265 -202
  16. data/lib/rcap/cap_1_0/parameter.rb +43 -20
  17. data/lib/rcap/cap_1_0/point.rb +23 -9
  18. data/lib/rcap/cap_1_0/polygon.rb +37 -19
  19. data/lib/rcap/cap_1_0/resource.rb +77 -55
  20. data/lib/rcap/cap_1_1/alert.rb +222 -156
  21. data/lib/rcap/cap_1_1/area.rb +100 -67
  22. data/lib/rcap/cap_1_1/circle.rb +49 -22
  23. data/lib/rcap/cap_1_1/event_code.rb +3 -2
  24. data/lib/rcap/cap_1_1/geocode.rb +3 -2
  25. data/lib/rcap/cap_1_1/info.rb +281 -217
  26. data/lib/rcap/cap_1_1/parameter.rb +35 -16
  27. data/lib/rcap/cap_1_1/point.rb +23 -9
  28. data/lib/rcap/cap_1_1/polygon.rb +38 -20
  29. data/lib/rcap/cap_1_1/resource.rb +106 -65
  30. data/lib/rcap/cap_1_2/alert.rb +224 -158
  31. data/lib/rcap/cap_1_2/area.rb +100 -67
  32. data/lib/rcap/cap_1_2/circle.rb +49 -24
  33. data/lib/rcap/cap_1_2/event_code.rb +3 -2
  34. data/lib/rcap/cap_1_2/geocode.rb +3 -2
  35. data/lib/rcap/cap_1_2/info.rb +285 -219
  36. data/lib/rcap/cap_1_2/parameter.rb +39 -19
  37. data/lib/rcap/cap_1_2/point.rb +23 -9
  38. data/lib/rcap/cap_1_2/polygon.rb +37 -20
  39. data/lib/rcap/cap_1_2/resource.rb +107 -67
  40. data/lib/rcap/config.rb +4 -0
  41. data/lib/rcap/utilities.rb +55 -2
  42. data/lib/rcap/validations.rb +2 -2
  43. data/lib/rcap/version.rb +1 -1
  44. data/rcap.gemspec +2 -2
  45. data/spec/cap_1_0/parameter_spec.rb +5 -1
  46. data/spec/cap_1_1/resource_spec.rb +6 -0
  47. data/spec/cap_1_2/alert_spec.rb +8 -0
  48. data/spec/cap_1_2/resource_spec.rb +8 -2
  49. metadata +11 -10
  50. data/README.rdoc +0 -247
  51. data/lib/config.rb +0 -2
data/lib/rcap.rb CHANGED
@@ -50,4 +50,4 @@ require 'rcap/cap_1_2/geocode'
50
50
  require 'rcap/cap_1_2/area'
51
51
  require 'rcap/alert'
52
52
  # Configuration
53
- require 'config'
53
+ require 'rcap/config'
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. The namespace of the
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
- # The namespace key ('cap' if the CAP document is stored under 'xmlns:cap')
15
- # can be specified explicitly by passing it in as a second parameter.
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
- # CAP_1_0::Alert, CAP_1_1::Alert or CAP_1_2::Alert is instantiated.
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
- # CAP_1_0::Alert, CAP_1_1::Alert or CAP_1_2::Alert is instantiated.
50
- def self.from_json( json_string )
51
- json_hash = JSON.parse( json_string )
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
- def self.from_h( hash ) # :nodoc:
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 )
@@ -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" # :nodoc:
18
- STATUS_EXERCISE = "Exercise" # :nodoc:
19
- STATUS_SYSTEM = "System" # :nodoc:
20
- STATUS_TEST = "Test" # :nodoc:
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" # :nodoc:
25
- MSG_TYPE_UPDATE = "Update" # :nodoc:
26
- MSG_TYPE_CANCEL = "Cancel" # :nodoc:
27
- MSG_TYPE_ACK = "Ack" # :nodoc:
28
- MSG_TYPE_ERROR = "Error" # :nodoc:
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" # :nodoc:
33
- SCOPE_RESTRICTED = "Restricted" # :nodoc:
34
- SCOPE_PRIVATE = "Private" # :nodoc:
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
- XML_ELEMENT_NAME = 'alert' # :nodoc:
39
- IDENTIFIER_ELEMENT_NAME = 'identifier' # :nodoc:
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
- # Sent Time - If not set will value will be time of creation.
43
+ # @return [DateTime] If not set will value will be time of creation.
74
44
  attr_accessor( :sent )
75
- # Value can only be one of VALID_STATUSES
45
+ # @return [String] Can only be one of {VALID_STATUSES}
76
46
  attr_accessor( :status )
77
- # Value can only be one of VALID_MSG_TYPES
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
- # Value can only be one of VALID_SCOPES
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
- # Collection of reference strings - see Alert#to_reference
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
- # Collection of Info objects
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. The
129
- # info_attributes are passed as a parameter to Info.new.
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
- self.infos << info
131
+ @infos << info
133
132
  info
134
133
  end
135
134
 
136
- def to_xml_element #:nodoc:
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( self.identifier ) if self.identifier
140
- xml_element.add_element( SENDER_ELEMENT_NAME ).add_text( self.sender ) if self.sender
141
- xml_element.add_element( SENT_ELEMENT_NAME ).add_text( self.sent.to_s_for_cap ) if self.sent
142
- xml_element.add_element( STATUS_ELEMENT_NAME ).add_text( self.status ) if self.status
143
- xml_element.add_element( MSG_TYPE_ELEMENT_NAME ).add_text( self.msg_type ) if self.msg_type
144
- xml_element.add_element( PASSWORD_ELEMENT_NAME ).add_text( self.password ) if self.password
145
- xml_element.add_element( SOURCE_ELEMENT_NAME ).add_text( self.source ) if self.source
146
- xml_element.add_element( SCOPE_ELEMENT_NAME ).add_text( self.scope ) if self.scope
147
- xml_element.add_element( RESTRICTION_ELEMENT_NAME ).add_text( self.restriction ) if self.restriction
148
- unless self.addresses.empty?
149
- xml_element.add_element( ADDRESSES_ELEMENT_NAME ).add_text( self.addresses.to_s_for_cap )
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
- self.codes.each do |code|
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( self.note ) if self.note
155
- unless self.references.empty?
156
- xml_element.add_element( REFERENCES_ELEMENT_NAME ).add_text( self.references.join( ' ' ))
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
- unless self.incidents.empty?
159
- xml_element.add_element( INCIDENTS_ELEMENT_NAME ).add_text( self.incidents.join( ' ' ))
174
+ if @incidents.any?
175
+ xml_element.add_element( INCIDENTS_ELEMENT_NAME ).add_text( @incidents.join( ' ' ))
160
176
  end
161
- self.infos.each do |info|
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
- def to_xml_document #:nodoc:
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( self.to_xml_element )
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( self.to_xml_document, xml_document )
198
+ RCAP::XML_PRETTY_PRINTER.write( to_xml_document, xml_document )
179
199
  xml_document
180
200
  else
181
- self.to_xml_document.to_s
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
- "#{ self.sender },#{ self.identifier },#{ self.sent }"
210
+ "#{ @sender },#{ @identifier },#{ @sent }"
189
211
  end
190
212
 
191
- def inspect # :nodoc:
213
+ # @return [String]
214
+ def inspect
192
215
  alert_inspect = [ "CAP Version: #{ CAP_VERSION }",
193
- "Identifier: #{ self.identifier }",
194
- "Sender: #{ self.sender }",
195
- "Sent: #{ self.sent }",
196
- "Status: #{ self.status }",
197
- "Message Type: #{ self.msg_type }",
198
- "Password: #{ self.password }",
199
- "Source: #{ self.source }",
200
- "Scope: #{ self.scope }",
201
- "Restriction: #{ self.restriction }",
202
- "Addresses: #{ self.addresses.to_s_for_cap }",
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
- self.codes.map{ |code| " " + code }.join("\n")+"",
205
- "Note: #{ self.note }",
206
- "References: #{ self.references.join( ' ' )}",
207
- "Incidents: #{ self.incidents.join( ' ')}",
227
+ @codes.map{ |code| " " + code }.join("\n")+"",
228
+ "Note: #{ @note }",
229
+ "References: #{ @references.join( ' ' )}",
230
+ "Incidents: #{ @incidents.join( ' ')}",
208
231
  "Information:",
209
- self.infos.map{ |info| " " + info.to_s }.join( "\n" )].join("\n")
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 Alert#to_reference for another string representation suitable as a CAP reference.
238
+ # See {#to_reference} for another string representation suitable as a CAP reference.
239
+ #
240
+ # @return [String]
216
241
  def to_s
217
- "#{ self.sender }/#{ self.identifier }/#{ self.sent }"
242
+ "#{ @sender }/#{ @identifier }/#{ @sent }"
218
243
  end
219
244
 
220
- def self.from_xml_element( alert_xml_element ) # :nodoc:
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
- def self.from_xml_document( xml_document ) # :nodoc:
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" # :nodoc:
248
- IDENTIFIER_YAML = "Identifier" # :nodoc:
249
- SENDER_YAML = "Sender" # :nodoc:
250
- SENT_YAML = "Sent" # :nodoc:
251
- STATUS_YAML = "Status" # :nodoc:
252
- MSG_TYPE_YAML = "Message Type" # :nodoc:
253
- PASSWORD_YAML = "Password" # :nodoc:
254
- SOURCE_YAML = "Source" # :nodoc:
255
- SCOPE_YAML = "Scope" # :nodoc:
256
- RESTRICTION_YAML = "Restriction" # :nodoc:
257
- ADDRESSES_YAML = "Addresses" # :nodoc:
258
- CODES_YAML = "Codes" # :nodoc:
259
- NOTE_YAML = "Note" # :nodoc:
260
- REFERENCES_YAML = "References" # :nodoc:
261
- INCIDENTS_YAML = "Incidents" # :nodoc:
262
- INFOS_YAML = "Information" # :nodoc:
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, CAP_VERSION ],
268
- [ IDENTIFIER_YAML, self.identifier ],
269
- [ SENDER_YAML, self.sender ],
270
- [ SENT_YAML, self.sent ],
271
- [ STATUS_YAML, self.status ],
272
- [ MSG_TYPE_YAML, self.msg_type ],
273
- [ PASSWORD_YAML, self.password ],
274
- [ SOURCE_YAML, self.source ],
275
- [ SCOPE_YAML, self.scope ],
276
- [ RESTRICTION_YAML, self.restriction ],
277
- [ ADDRESSES_YAML, self.addresses ],
278
- [ CODES_YAML, self.codes ],
279
- [ NOTE_YAML, self.note ],
280
- [ REFERENCES_YAML, self.references ],
281
- [ INCIDENTS_YAML, self.incidents ],
282
- [ INFOS_YAML, self.infos ]
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
- def self.from_yaml_data( alert_yaml_data ) # :nodoc:
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' # :nodoc:
312
- IDENTIFIER_KEY = 'identifier' # :nodoc:
313
- SENDER_KEY = 'sender' # :nodoc:
314
- SENT_KEY = 'sent' # :nodoc:
315
- STATUS_KEY = 'status' # :nodoc:
316
- MSG_TYPE_KEY = 'msg_type' # :nodoc:
317
- PASSWORD_KEY = 'password' # :nodoc:
318
- SOURCE_KEY = 'source' # :nodoc:
319
- SCOPE_KEY = 'scope' # :nodoc:
320
- RESTRICTION_KEY = 'restriction' # :nodoc:
321
- ADDRESSES_KEY = 'addresses' # :nodoc:
322
- CODES_KEY = 'codes' # :nodoc:
323
- NOTE_KEY = 'note' # :nodoc:
324
- REFERENCES_KEY = 'references' # :nodoc:
325
- INCIDENTS_KEY = 'incidents' # :nodoc:
326
- INFOS_KEY = 'infos' # :nodoc:
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, self.identifier ],
332
- [ SENDER_KEY, self.sender ],
333
- [ SENT_KEY, RCAP.to_s_for_cap( self.sent )],
334
- [ STATUS_KEY, self.status ],
335
- [ MSG_TYPE_KEY, self.msg_type ],
336
- [ PASSWORD_KEY, self.password ],
337
- [ SOURCE_KEY, self.source ],
338
- [ SCOPE_KEY, self.scope ],
339
- [ RESTRICTION_KEY, self.restriction ],
340
- [ ADDRESSES_KEY, self.addresses ],
341
- [ CODES_KEY, self.codes ],
342
- [ NOTE_KEY, self.note ],
343
- [ REFERENCES_KEY, self.references ],
344
- [ INCIDENTS_KEY, self.incidents ],
345
- [ INFOS_KEY, self.infos.map{ |info| info.to_h }])
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
- # Initiialises an Alert object from a JSON string produced by Alert#to_json
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