rcap 1.3.0 → 1.3.1

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 (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