rcap 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. data/CHANGELOG.rdoc +4 -0
  2. data/lib/rcap.rb +10 -0
  3. data/lib/rcap/alert.rb +7 -1
  4. data/lib/rcap/cap_1_0/alert.rb +383 -0
  5. data/lib/rcap/cap_1_0/area.rb +178 -0
  6. data/lib/rcap/cap_1_0/circle.rb +81 -0
  7. data/lib/rcap/cap_1_0/event_code.rb +8 -0
  8. data/lib/rcap/cap_1_0/geocode.rb +8 -0
  9. data/lib/rcap/cap_1_0/info.rb +435 -0
  10. data/lib/rcap/cap_1_0/parameter.rb +71 -0
  11. data/lib/rcap/cap_1_0/point.rb +55 -0
  12. data/lib/rcap/cap_1_0/polygon.rb +89 -0
  13. data/lib/rcap/cap_1_0/resource.rb +132 -0
  14. data/lib/rcap/cap_1_1/event_code.rb +0 -14
  15. data/lib/rcap/cap_1_1/geocode.rb +0 -14
  16. data/lib/rcap/cap_1_1/parameter.rb +5 -5
  17. data/lib/rcap/cap_1_1/resource.rb +5 -5
  18. data/lib/rcap/cap_1_2/event_code.rb +0 -14
  19. data/lib/rcap/cap_1_2/geocode.rb +0 -14
  20. data/lib/rcap/cap_1_2/parameter.rb +2 -3
  21. data/lib/rcap/cap_1_2/resource.rb +5 -5
  22. data/lib/rcap/version.rb +1 -1
  23. data/rcap.gemspec +0 -1
  24. data/spec/alert_spec.rb +64 -0
  25. data/spec/cap_1_0/alert_spec.rb +222 -0
  26. data/spec/cap_1_0/area_spec.rb +247 -0
  27. data/spec/cap_1_0/circle_spec.rb +88 -0
  28. data/spec/cap_1_0/event_code_spec.rb +37 -0
  29. data/spec/cap_1_0/geocode_spec.rb +38 -0
  30. data/spec/cap_1_0/info_spec.rb +324 -0
  31. data/spec/cap_1_0/parameter_spec.rb +65 -0
  32. data/spec/cap_1_0/point_spec.rb +46 -0
  33. data/spec/cap_1_0/polygon_spec.rb +97 -0
  34. data/spec/cap_1_0/resource_spec.rb +140 -0
  35. data/spec/cap_1_1/event_code_spec.rb +38 -0
  36. data/spec/cap_1_1/parameter_spec.rb +37 -0
  37. data/spec/cap_1_2/event_code_spec.rb +38 -0
  38. data/spec/cap_1_2/parameter_spec.rb +37 -0
  39. metadata +49 -34
@@ -0,0 +1,71 @@
1
+ module RCAP
2
+ module CAP_1_0
3
+ # A Parameter object is valid if
4
+ # * it has a name
5
+ # * it has a value
6
+ class Parameter
7
+ include Validation
8
+
9
+ validates_presence_of( :name, :value )
10
+
11
+ attr_accessor( :name, :value )
12
+
13
+ XML_ELEMENT_NAME = "parameter" # :nodoc:
14
+ NAME_ELEMENT_NAME = "valueName" # :nodoc:
15
+ VALUE_ELEMENT_NAME = "value" # :nodoc:
16
+
17
+ XPATH = "cap:#{ XML_ELEMENT_NAME }" # :nodoc:
18
+ NAME_XPATH = "cap:#{ NAME_ELEMENT_NAME }" # :nodoc:
19
+ VALUE_XPATH = "cap:#{ VALUE_ELEMENT_NAME }" # :nodoc:
20
+
21
+ def initialize( attributes = {} )
22
+ @name = attributes[ :name ]
23
+ @value = attributes[ :value ]
24
+ end
25
+
26
+ def to_xml_element # :nodoc:
27
+ xml_element = REXML::Element.new( self.class::XML_ELEMENT_NAME )
28
+ xml_element.add_text( "#{ self.name }=#{ self.value }")
29
+ xml_element
30
+ end
31
+
32
+ def to_xml # :nodoc:
33
+ self.to_xml_element.to_s
34
+ end
35
+
36
+ def inspect # :nodoc:
37
+ "#{ self.name }: #{ self.value }"
38
+ end
39
+
40
+ # Returns a string representation of the parameter of the form
41
+ # name: value
42
+ def to_s
43
+ self.inspect
44
+ end
45
+
46
+ def self.from_xml_element( parameter_xml_element ) # :nodoc:
47
+ self.new( self.parse_parameter( parameter_xml_element.text ))
48
+ end
49
+
50
+ # Two parameters are equivalent if they have the same name and value.
51
+ def ==( other )
52
+ [ self.name, self.value ] == [ other.name, other.value ]
53
+ end
54
+
55
+ def to_h # :nodoc:
56
+ RCAP.attribute_values_to_hash( [ self.name, self.value ])
57
+ end
58
+
59
+ def self.from_h( hash ) # :nodoc:
60
+ key = hash.keys.first
61
+ self.new( :name => key, :value => hash[ key ])
62
+ end
63
+
64
+ def self.parse_parameter( parameter_string ) # :nodoc:
65
+ name, value = parameter_string.split("=")
66
+ { :name => name,
67
+ :value => value }
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,55 @@
1
+ module RCAP
2
+ module CAP_1_0
3
+ # A Point object is valid if
4
+ # * it has a lattitude within the minimum and maximum lattitude values
5
+ # * it has a longitude within the minimum and maximum longitude values
6
+ class Point
7
+ include Validation
8
+
9
+ MAX_LONGITUDE = 180
10
+ MIN_LONGITUDE = -180
11
+ MAX_LATTITUDE = 90
12
+ MIN_LATTITUDE= -90
13
+
14
+ attr_accessor( :lattitude )
15
+ attr_accessor( :longitude )
16
+
17
+ validates_numericality_of( :lattitude, :longitude )
18
+ validates_inclusion_of( :lattitude, :in => MIN_LATTITUDE..MAX_LATTITUDE )
19
+ validates_inclusion_of( :longitude, :in => MIN_LONGITUDE..MAX_LONGITUDE)
20
+
21
+ def initialize( attributes = {} )
22
+ @lattitude = attributes[ :lattitude ]
23
+ @longitude = attributes[ :longitude ]
24
+ end
25
+
26
+ # Returns a string representation of the point of the form
27
+ # lattitude,longitude
28
+ def to_s
29
+ "#{ self.lattitude },#{ self.longitude }"
30
+ end
31
+
32
+ def inspect # :nodoc:
33
+ '('+self.to_s+')'
34
+ end
35
+
36
+ # Two points are equivalent if they have the same lattitude and longitude
37
+ def ==( other )
38
+ [ self.lattitude, self.longitude ] == [ other.lattitude, other.longitude ]
39
+ end
40
+
41
+ LATTITUDE_KEY = 'lattitude' # :nodoc:
42
+ LONGITUDE_KEY = 'longitude' # :nodoc:
43
+
44
+ def to_h # :nodoc:
45
+ RCAP.attribute_values_to_hash(
46
+ [ LATTITUDE_KEY, self.lattitude ],
47
+ [ LONGITUDE_KEY, self.longitude ])
48
+ end
49
+
50
+ def self.from_h( point_hash ) # :nodoc:
51
+ self.new( :lattitude => point_hash[ LATTITUDE_KEY ], :longitude => point_hash[ LONGITUDE_KEY ])
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,89 @@
1
+ module RCAP
2
+ module CAP_1_0
3
+ # A Polygon object is valid if
4
+ # * it has a minimum of three points
5
+ # * each Point object in the points collection is valid
6
+ class Polygon
7
+ include Validation
8
+
9
+ # Collection of Point objects.
10
+ attr_reader( :points )
11
+
12
+ validates_length_of( :points, :minimum => 3 )
13
+ validates_collection_of( :points )
14
+
15
+ XML_ELEMENT_NAME = 'polygon' # :nodoc:
16
+ XPATH = "cap:#{ XML_ELEMENT_NAME }" # :nodoc:
17
+
18
+ def initialize( attributes = {})
19
+ @points = Array( attributes[ :points ])
20
+ end
21
+
22
+ # Creates a new Point object and adds it to the points array. The
23
+ # poitn_attributes are passed as a parameter to Point.new.
24
+ def add_point( point_attributes = {})
25
+ point = Point.new( point_attributes )
26
+ self.points << point
27
+ point
28
+ end
29
+
30
+ # Returns a string representation of the polygon of the form
31
+ # points[0] points[1] points[2] ... points[n-1] points[0]
32
+ # where each point is formatted with Point#to_s
33
+ def to_s
34
+ (@points + [ @points.first ]).join( ' ' )
35
+ end
36
+
37
+ def inspect # :nodoc:
38
+ "(#{ @points.map{|point| point.inspect}.join(', ')})"
39
+ end
40
+
41
+ def to_xml_element # :nodoc:
42
+ xml_element = REXML::Element.new( XML_ELEMENT_NAME )
43
+ xml_element.add_text( self.to_s )
44
+ xml_element
45
+ end
46
+
47
+ # Two polygons are equivalent if their collection of points is equivalent.
48
+ def ==( other )
49
+ self.points == other.points
50
+ end
51
+
52
+ def self.parse_polygon_string( polygon_string ) # :nodoc:
53
+ polygon_string.split( ' ' ).map{ |coordinate_string| coordinate_string.split( ',' ).map{|coordinate| coordinate.to_f }}
54
+ end
55
+
56
+ def self.from_xml_element( polygon_xml_element ) # :nodoc:
57
+ if !polygon_xml_element.text.nil? && !polygon_xml_element.text.empty?
58
+ coordinates = self.parse_polygon_string( polygon_xml_element.text )
59
+ points = coordinates.map{ |lattitude, longitude| Point.new( :lattitude => lattitude, :longitude => longitude )}[0..-2]
60
+ polygon = self.new( :points => points )
61
+ else
62
+ self.new
63
+ end
64
+ end
65
+
66
+
67
+ def to_yaml( options = {} ) # :nodoc:
68
+ yaml_points = self.points.map{ |point| [ point.lattitude, point.longitude ]}
69
+ def yaml_points.to_yaml_style; :inline; end
70
+
71
+ yaml_points.to_yaml( options )
72
+ end
73
+
74
+ def self.from_yaml_data( polygon_yaml_data ) # :nodoc:
75
+ self.new( :points => Array( polygon_yaml_data ).map{ |lattitude, longitude| Point.new( :lattitude => lattitude, :longitude => longitude )})
76
+ end
77
+
78
+ POINTS_KEY = 'points' # :nodoc:
79
+
80
+ def to_h # :nodoc:
81
+ { POINTS_KEY => self.points.map{ |point| point.to_h }}
82
+ end
83
+
84
+ def self.from_h( polygon_hash ) # :nodoc:
85
+ self.new( :points => polygon_hash[ POINTS_KEY ].map{ |point_hash| Point.from_h( point_hash )})
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,132 @@
1
+ module RCAP
2
+ module CAP_1_0
3
+ # A Resourse object is valid if
4
+ # * it has a resource description
5
+ class Resource
6
+ include Validation
7
+
8
+ # Resource Description
9
+ attr_accessor( :resource_desc )
10
+ attr_accessor( :mime_type )
11
+ # Expressed in bytes
12
+ attr_accessor( :size )
13
+ # Resource location
14
+ attr_accessor( :uri )
15
+ # SHA-1 hash of contents of resource
16
+ attr_accessor( :digest )
17
+
18
+ validates_presence_of( :resource_desc )
19
+
20
+ XML_ELEMENT_NAME = 'resource' # :nodoc:
21
+ MIME_TYPE_ELEMENT_NAME = 'mimeType' # :nodoc:
22
+ SIZE_ELEMENT_NAME = 'size' # :nodoc:
23
+ URI_ELEMENT_NAME = 'uri' # :nodoc:
24
+ DIGEST_ELEMENT_NAME = 'digest' # :nodoc:
25
+ RESOURCE_DESC_ELEMENT_NAME = 'resourceDesc' # :nodoc:
26
+
27
+ XPATH = "cap:#{ XML_ELEMENT_NAME }" # :nodoc:
28
+ MIME_TYPE_XPATH = "cap:#{ MIME_TYPE_ELEMENT_NAME }" # :nodoc:
29
+ SIZE_XPATH = "cap:#{ SIZE_ELEMENT_NAME }" # :nodoc:
30
+ URI_XPATH = "cap:#{ URI_ELEMENT_NAME }" # :nodoc:
31
+ DIGEST_XPATH = "cap:#{ DIGEST_ELEMENT_NAME }" # :nodoc:
32
+ RESOURCE_DESC_XPATH = "cap:#{ RESOURCE_DESC_ELEMENT_NAME }" # :nodoc:
33
+
34
+ def initialize( attributes = {} )
35
+ @mime_type = attributes[ :mime_type ]
36
+ @size = attributes[ :size ]
37
+ @uri = attributes[ :uri ]
38
+ @digest = attributes[ :digest ]
39
+ @resource_desc = attributes[ :resource_desc ]
40
+ end
41
+
42
+ def to_xml_element # :nodoc:
43
+ xml_element = REXML::Element.new( XML_ELEMENT_NAME )
44
+ xml_element.add_element( RESOURCE_DESC_ELEMENT_NAME ).add_text( self.resource_desc )
45
+ xml_element.add_element( MIME_TYPE_ELEMENT_NAME ).add_text( self.mime_type ) if self.mime_type
46
+ xml_element.add_element( SIZE_ELEMENT_NAME ).add_text( self.size ) if self.size
47
+ xml_element.add_element( URI_ELEMENT_NAME ).add_text( self.uri ) if self.uri
48
+ xml_element.add_element( DIGEST_ELEMENT_NAME ).add_text( self.digest ) if self.digest
49
+ xml_element
50
+ end
51
+
52
+ # If size is defined returns the size in kilobytes
53
+ def size_in_kb
54
+ if self.size
55
+ self.size.to_f/1024
56
+ end
57
+ end
58
+
59
+ def to_xml # :nodoc:
60
+ self.to_xml_element.to_s
61
+ end
62
+
63
+ def inspect # :nodoc:
64
+ [ self.resource_desc, self.uri, self.mime_type, self.size ? format( "%.1fKB", self.size_in_kb ) : nil ].compact.join(' - ')
65
+ end
66
+
67
+ # Returns a string representation of the resource of the form
68
+ # resource_desc
69
+ def to_s
70
+ self.resource_desc
71
+ end
72
+
73
+ def self.from_xml_element( resource_xml_element ) # :nodoc:
74
+ resource = self.new( :resource_desc => RCAP.xpath_text( resource_xml_element, RESOURCE_DESC_XPATH, Alert::XMLNS ),
75
+ :uri => RCAP.xpath_text( resource_xml_element, URI_XPATH, Alert::XMLNS ),
76
+ :mime_type => RCAP.xpath_text( resource_xml_element, MIME_TYPE_XPATH, Alert::XMLNS ),
77
+ :size => RCAP.xpath_text( resource_xml_element, SIZE_XPATH, Alert::XMLNS ),
78
+ :digest => RCAP.xpath_text( resource_xml_element, DIGEST_XPATH, Alert::XMLNS ))
79
+ end
80
+
81
+ RESOURCE_DESC_YAML = "Resource Description" # :nodoc:
82
+ URI_YAML = "URI" # :nodoc:
83
+ MIME_TYPE_YAML = "Mime Type" # :nodoc:
84
+ SIZE_YAML = "Size" # :nodoc:
85
+ DIGEST_YAML = "Digest" # :nodoc:
86
+
87
+ def to_yaml( options ) # :nodoc:
88
+ RCAP.attribute_values_to_hash(
89
+ [ RESOURCE_DESC_YAML, self.resource_desc ],
90
+ [ URI_YAML, self.uri ],
91
+ [ MIME_TYPE_YAML, self.mime_type ],
92
+ [ SIZE_YAML, self.size ],
93
+ [ DIGEST_YAML, self.digest ]
94
+ ).to_yaml( options )
95
+ end
96
+
97
+ def self.from_yaml_data( resource_yaml_data ) # :nodoc:
98
+ self.new(
99
+ :resource_desc => reource_yaml_data[ RESOURCE_DESC_YAML ],
100
+ :uri => reource_yaml_data[ URI_YAML ],
101
+ :mime_type => reource_yaml_data[ MIME_TYPE_YAML ],
102
+ :size => reource_yaml_data[ SIZE_YAML ],
103
+ :digest => reource_yaml_data[ DIGEST_YAML ]
104
+ )
105
+ end
106
+
107
+ RESOURCE_DESC_KEY = 'resource_desc' # :nodoc:
108
+ URI_KEY = 'uri' # :nodoc:
109
+ MIME_TYPE_KEY = 'mime_type' # :nodoc:
110
+ SIZE_KEY = 'size' # :nodoc:
111
+ DIGEST_KEY = 'digest' # :nodoc:
112
+
113
+ def to_h # :nodoc:
114
+ RCAP.attribute_values_to_hash(
115
+ [ RESOURCE_DESC_KEY, self.resource_desc ],
116
+ [ URI_KEY, self.uri],
117
+ [ MIME_TYPE_KEY, self.mime_type],
118
+ [ SIZE_KEY, self.size ],
119
+ [ DIGEST_KEY, self.digest ])
120
+ end
121
+
122
+ def self.from_h( resource_hash ) # :nodoc:
123
+ self.new(
124
+ :resource_desc => resource_hash[ RESOURCE_DESC_KEY ],
125
+ :uri => resource_hash[ URI_KEY ],
126
+ :mime_type => resource_hash[ MIME_TYPE_KEY ],
127
+ :size => resource_hash[ SIZE_KEY ],
128
+ :digest => resource_hash[ DIGEST_KEY ])
129
+ end
130
+ end
131
+ end
132
+ end
@@ -1,22 +1,8 @@
1
1
  module RCAP
2
2
  module CAP_1_1
3
3
  class EventCode < Parameter
4
-
5
4
  XML_ELEMENT_NAME = 'eventCode' # :nodoc:
6
-
7
5
  XPATH = "cap:#{ XML_ELEMENT_NAME }" # :nodoc:
8
-
9
- def to_xml_element # :nodoc:
10
- xml_element = REXML::Element.new( XML_ELEMENT_NAME )
11
- xml_element.add_element( NAME_ELEMENT_NAME ).add_text( self.name )
12
- xml_element.add_element( VALUE_ELEMENT_NAME ).add_text( self.value )
13
- xml_element
14
- end
15
-
16
- def self.from_xml_element( event_code_xml_element ) # :nodoc:
17
- EventCode.new( :name => RCAP.xpath_text( event_code_xml_element, NAME_XPATH, Alert::XMLNS ),
18
- :value => RCAP.xpath_text( event_code_xml_element, VALUE_XPATH, Alert::XMLNS ))
19
- end
20
6
  end
21
7
  end
22
8
  end
@@ -1,22 +1,8 @@
1
1
  module RCAP
2
2
  module CAP_1_1
3
3
  class Geocode < Parameter
4
-
5
4
  XML_ELEMENT_NAME = 'geocode' # :nodoc:
6
-
7
5
  XPATH = "cap:#{ XML_ELEMENT_NAME }" # :nodoc:
8
-
9
- def to_xml_element # :nodoc:
10
- xml_element = REXML::Element.new( XML_ELEMENT_NAME )
11
- xml_element.add_element( NAME_ELEMENT_NAME ).add_text( @name )
12
- xml_element.add_element( VALUE_ELEMENT_NAME ).add_text( @value )
13
- xml_element
14
- end
15
-
16
- def self.from_xml_element( geocode_xml_element ) # :nodoc:
17
- self.new( :name => RCAP.xpath_text( geocode_xml_element, NAME_XPATH, Alert::XMLNS ),
18
- :value => RCAP.xpath_text( geocode_xml_element, VALUE_XPATH, Alert::XMLNS ))
19
- end
20
6
  end
21
7
  end
22
8
  end
@@ -24,9 +24,9 @@ module RCAP
24
24
  end
25
25
 
26
26
  def to_xml_element # :nodoc:
27
- xml_element = REXML::Element.new( XML_ELEMENT_NAME )
28
- xml_element.add_element( NAME_ELEMENT_NAME ).add_text( self.name )
29
- xml_element.add_element( VALUE_ELEMENT_NAME ).add_text( self.value )
27
+ xml_element = REXML::Element.new( self.class::XML_ELEMENT_NAME )
28
+ xml_element.add_element( self.class::NAME_ELEMENT_NAME ).add_text( self.name )
29
+ xml_element.add_element( self.class::VALUE_ELEMENT_NAME ).add_text( self.value )
30
30
  xml_element
31
31
  end
32
32
 
@@ -45,8 +45,8 @@ module RCAP
45
45
  end
46
46
 
47
47
  def self.from_xml_element( parameter_xml_element ) # :nodoc:
48
- Parameter.new( :name => RCAP.xpath_text( parameter_xml_element, NAME_XPATH, Alert::XMLNS ),
49
- :value => RCAP.xpath_text( parameter_xml_element, VALUE_XPATH, Alert::XMLNS ))
48
+ Parameter.new( :name => RCAP.xpath_text( parameter_xml_element, self::NAME_XPATH, Alert::XMLNS ),
49
+ :value => RCAP.xpath_text( parameter_xml_element, self::VALUE_XPATH, Alert::XMLNS ))
50
50
  end
51
51
 
52
52
  # Two parameters are equivalent if they have the same name and value.
@@ -134,11 +134,11 @@ module RCAP
134
134
  def self.from_h( resource_hash ) # :nodoc:
135
135
  self.new(
136
136
  :resource_desc => resource_hash[ RESOURCE_DESC_KEY ],
137
- :uri => resource_hash[ URI_KEY ],
138
- :mime_type => resource_hash[ MIME_TYPE_KEY ],
139
- :deref_uri => resource_hash[ DEREF_URI_KEY ],
140
- :size => resource_hash[ SIZE_KEY ],
141
- :digest => resource_hash[ DIGEST_KEY ])
137
+ :uri => resource_hash[ URI_KEY ],
138
+ :mime_type => resource_hash[ MIME_TYPE_KEY ],
139
+ :deref_uri => resource_hash[ DEREF_URI_KEY ],
140
+ :size => resource_hash[ SIZE_KEY ],
141
+ :digest => resource_hash[ DIGEST_KEY ])
142
142
  end
143
143
  end
144
144
  end
@@ -1,22 +1,8 @@
1
1
  module RCAP
2
2
  module CAP_1_2
3
3
  class EventCode < Parameter
4
-
5
4
  XML_ELEMENT_NAME = 'eventCode' # :nodoc:
6
-
7
5
  XPATH = "cap:#{ XML_ELEMENT_NAME }" # :nodoc:
8
-
9
- def to_xml_element # :nodoc:
10
- xml_element = REXML::Element.new( XML_ELEMENT_NAME )
11
- xml_element.add_element( NAME_ELEMENT_NAME ).add_text( self.name )
12
- xml_element.add_element( VALUE_ELEMENT_NAME ).add_text( self.value )
13
- xml_element
14
- end
15
-
16
- def self.from_xml_element( event_code_xml_element ) # :nodoc:
17
- EventCode.new( :name => RCAP.xpath_text( event_code_xml_element, NAME_XPATH, Alert::XMLNS ),
18
- :value => RCAP.xpath_text( event_code_xml_element, VALUE_XPATH, Alert::XMLNS ))
19
- end
20
6
  end
21
7
  end
22
8
  end