rgeoserver 0.5.9 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +1 -1
  2. data/Gemfile +1 -7
  3. data/Gemfile.lock +147 -0
  4. data/README.rdoc +69 -78
  5. data/Rakefile +2 -1
  6. data/VERSION +1 -1
  7. data/bin/batch_load.rb +138 -0
  8. data/config/defaults.yml +17 -0
  9. data/examples/batch_demo.rb +170 -0
  10. data/examples/catalog_migration.rb +2 -2
  11. data/examples/cluster_demo.rb +1 -1
  12. data/examples/coverage_stores.rb +42 -0
  13. data/examples/demo_druid_workspace.rb +6 -0
  14. data/examples/deploy_dor_layer.rb +19 -0
  15. data/examples/sql_layer_demo.rb +1 -1
  16. data/lib/rgeoserver/catalog.rb +83 -86
  17. data/lib/rgeoserver/config.rb +11 -1
  18. data/lib/rgeoserver/coverage.rb +43 -15
  19. data/lib/rgeoserver/coveragestore.rb +46 -11
  20. data/lib/rgeoserver/datastore.rb +73 -62
  21. data/lib/rgeoserver/featuretype.rb +134 -71
  22. data/lib/rgeoserver/geoserver_url_helpers.rb +140 -10
  23. data/lib/rgeoserver/layer.rb +52 -16
  24. data/lib/rgeoserver/layergroup.rb +1 -2
  25. data/lib/rgeoserver/namespace.rb +1 -2
  26. data/lib/rgeoserver/resource.rb +37 -34
  27. data/lib/rgeoserver/rest_api_client.rb +33 -14
  28. data/lib/rgeoserver/style.rb +1 -2
  29. data/lib/rgeoserver/utils/boundingbox.rb +59 -16
  30. data/lib/rgeoserver/utils/metadata.rb +21 -0
  31. data/lib/rgeoserver/version.rb +1 -1
  32. data/lib/rgeoserver/wmsstore.rb +1 -6
  33. data/lib/rgeoserver/workspace.rb +23 -8
  34. data/lib/rgeoserver.rb +31 -38
  35. data/rgeoserver.gemspec +28 -20
  36. data/spec/fixtures/load_ex1.yml +45 -0
  37. data/spec/fixtures/load_ex2.yml +14 -0
  38. data/spec/functional/catalog_spec.rb +71 -0
  39. data/spec/functional/rest_api_client_spec.rb +215 -0
  40. data/spec/integration/geoserver_spec.rb +2 -2
  41. metadata +120 -66
  42. data/config/config_defaults.yml +0 -10
  43. data/examples/batch_example.rb +0 -105
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding : utf-8 -*-
3
+ #
4
+ # RGeoServer Batch load layers (batch_demo.rb)
5
+ # Usage: #{File.basename(__FILE__)} [input.yml]
6
+
7
+ require 'rubygems'
8
+ require 'yaml'
9
+ require 'rgeoserver'
10
+ require 'awesome_print'
11
+ require 'optparse'
12
+
13
+ #= Input data. *See DATA section at end of file*
14
+ # The input file is in YAML syntax with each record is a Hash with keys:
15
+ # - layername
16
+ # - filename
17
+ # - format
18
+ # - title
19
+ # and optionally
20
+ # - description
21
+ # - keywords
22
+ # - metadata_links
23
+
24
+ #= Configuration constants
25
+ WORKSPACE_NAME = 'rgeoserver'
26
+ NAMESPACE = 'urn:rgeoserver'
27
+
28
+ # GeoWebCache configuration
29
+ SEED = true
30
+ SEED_OPTIONS = {
31
+ :srs => {
32
+ :number => 4326
33
+ },
34
+ :zoomStart => 1,
35
+ :zoomStop => 8,
36
+ :format => 'image/png',
37
+ :threadCount => 1
38
+ }
39
+
40
+ def main layers, flags = {}
41
+ return unless layers
42
+ datadir = flags[:datadir]
43
+ # Connect to the GeoServer catalog
44
+ cat = RGeoServer::Catalog.new
45
+
46
+ # Obtain a handle to the workspace and clean it up.
47
+ ws = RGeoServer::Workspace.new cat, :name => WORKSPACE_NAME
48
+ ws.delete :recurse => true if flags[:delete] and not ws.new?
49
+ ws.save if ws.new?
50
+
51
+ # Iterate over all records in YAML file and create stores in the catalog
52
+ layers.each do |k, v|
53
+ ['layername', 'format', 'filename', 'title'].each do |id|
54
+ raise ArgumentError, "Layer is missing #{id}" unless v.include?(id)
55
+ end
56
+ ap v
57
+
58
+ layername = v['layername'].strip
59
+ format = v['format'].strip
60
+
61
+ ap "Layer: #{layername} #{format}"
62
+ if format == 'GeoTIFF'
63
+ # Create of a coverage store
64
+ cs = RGeoServer::CoverageStore.new cat, :workspace => ws, :name => layername
65
+ cs.url = File.join(datadir, v['filename'])
66
+ cs.description = v['description']
67
+ cs.enabled = 'true'
68
+ cs.data_type = format
69
+ cs.save
70
+
71
+ # Now create the actual coverage
72
+ cv = RGeoServer::Coverage.new cat, :workspace => ws, :coverage_store => cs, :name => layername
73
+ cv.title = v['title']
74
+ cv.keywords = v['keywords']
75
+ cv.metadata_links = v['metadata_links']
76
+ cv.save
77
+
78
+ elsif format == 'Shapefile'
79
+ # Create data stores for shapefiles
80
+ ds = RGeoServer::DataStore.new cat, :workspace => ws, :name => layername
81
+ ds.description = v['description']
82
+ ds.connection_parameters = {
83
+ "url" => File.join(datadir, v['filename']),
84
+ "namespace" => NAMESPACE
85
+ }
86
+ ds.enabled = 'true'
87
+ ds.save
88
+
89
+ ft = RGeoServer::FeatureType.new cat, :workspace => ws, :data_store => ds, :name => layername
90
+ ft.title = v['title']
91
+ ft.abstract = v['description']
92
+ ft.keywords = v['keywords']
93
+ ft.metadata_links = v['metadata_links']
94
+ ft.save
95
+ end
96
+
97
+ # Check if a layer has been created, extract some metadata
98
+ lyr = RGeoServer::Layer.new cat, :name => layername
99
+ if not lyr.new? and SEED
100
+ lyr.seed :issue, SEED_OPTIONS
101
+ else
102
+ raise NotImplementedError, "Unsupported format #{format}"
103
+ end
104
+ end
105
+ end
106
+
107
+ begin
108
+ flags = {
109
+ :delete => true,
110
+ :verbose => false,
111
+ :datadir => 'file:///data'
112
+ }
113
+
114
+ OptionParser.new do |opts|
115
+ opts.banner = "Usage: #{File.basename(__FILE__)} [-v] [--delete] [input.yml ...]"
116
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
117
+ flags[:verbose] = v
118
+ end
119
+ opts.on(nil, "--[no-]delete", "Delete workspaces recursively") do |v|
120
+ flags[:delete] = v
121
+ end
122
+ opts.on("-d DIR", "--datadir DIR", "Data directory on GeoServer (default: file:///data)") do |v|
123
+ flags[:datadir] = v
124
+ end
125
+ end.parse!
126
+ ap flags
127
+
128
+ if ARGV.size > 0
129
+ ARGV.each do |fn|
130
+ main(YAML::load_file(fn), flags)
131
+ end
132
+ else
133
+ main(YAML::load(DATA), flags)
134
+ end
135
+ rescue SystemCallError => e
136
+ $stderr.puts "ERROR: #{e.message}"
137
+ exit(-1)
138
+ end
139
+
140
+ __END__
141
+ ---
142
+ example_vector:
143
+ layername: "Precincts_Jan262012_5"
144
+ filename: "branner/Precincts_Jan262012_5/Precincts_Jan262012_5.shp"
145
+ format: "Shapefile"
146
+ title: "US Precincts, 2008"
147
+ description: "This is a dataset developed by Prof. Jonathan Rodden at Stanford University showing precinct polygon data for the United States for the year 2008."
148
+ keywords: ["vector", "precinct", "political", "US", "voting", "2008", "elections", {
149
+ keyword: "California", language: "en", vocabulary: "ISOTC211/19115:place"}]
150
+ metadata_links: [{
151
+ metadataType: TC211,
152
+ content: "http://purl.stanford.edu/catalog/aa111aa1111/iso19139.xml"}]
153
+ metadata:
154
+ druid: aa111aa1111
155
+ publisher: "Jonathan Rodden, Stanford University"
156
+
157
+ example_raster:
158
+ layername: antietam_1867
159
+ filename: rumsey/g3881015alpha.tif
160
+ format: GeoTIFF
161
+ title: "U.S. Civil War battle of Antietam, 1867"
162
+ description: "Map shows the U.S. Civil War battle of Antietam. It indicates fortifications, roads, railroads, houses, names of residents, fences, drainage, vegetation, and relief by hachures."
163
+ keywords: ["civil war", "battles", {
164
+ keyword: "Sharpsburg, MD", language: "en", vocabulary: "urn:geonames.org?GeoNameId=4369352"}]
165
+ metadata_links: [{
166
+ metadataType: TC211,
167
+ content: "http://purl.stanford.edu/catalog/bb222bb2222/iso19139.xml"}]
168
+ metadata:
169
+ druid: bb222bb2222
170
+ publisher: Unknown
@@ -6,10 +6,10 @@
6
6
  require 'rgeoserver'
7
7
 
8
8
  # The source catalog is a GeoServer instance version 2.1.0
9
- $source_gs = RGeoServer::Catalog.new :url=> 'https://oldgeodata.example.com/geoserver/rest', :user=>'admin', :password=>'changeme'
9
+ $source_gs = RGeoServer::Catalog.new
10
10
 
11
11
  # The target catalog is a GeoServer instance version 2.1.3
12
- $target_gs = RGeoServer::Catalog.new :url=> 'http://newgeodata.example.com/geoserver/rest', :user=> 'admin', :password => 'geoserver'
12
+ $target_gs = RGeoServer::Catalog.new
13
13
 
14
14
  # We don't migrate all workspaces except the following:
15
15
  $workspaces_to_migrate = [
@@ -17,7 +17,7 @@ layers = {
17
17
  }
18
18
 
19
19
  (1..7).each do |cat_id|
20
- cat = RGeoServer::Catalog.new :user=>'admin', :url => "http://geoserver-app#{cat_id}/rest", :password => "osgeo!"
20
+ cat = RGeoServer::Catalog.new
21
21
  ws = cat.get_workspace('cite')
22
22
  RGeoServer::ResourceInfo.list(RGeoServer::CoverageStore, cat, layers.keys, :workspace => ws) do |cs|
23
23
  cs.description = layers[cs.name]['description']
@@ -0,0 +1,42 @@
1
+
2
+ require 'rgeoserver'
3
+
4
+ layers = {
5
+ 'south_america_1787' => {
6
+ 'url' => 'file:///geo_data/rumsey/g0411047.tif',
7
+ 'description' => "Map of South America by D'Anville",
8
+ 'type' => 'GeoTIFF'
9
+ },
10
+ 'city_of_san_francisco_1859' => {
11
+ 'url' => 'file:///geo_data/rumsey/g1030000alpha.tif',
12
+ 'description' => 'Map of San Francisco by the U.S. Coast Survey, with detail of the unsettled lands',
13
+ 'type' => 'GeoTIFF'
14
+ }
15
+ }
16
+
17
+ (1..7).each do |cat_id|
18
+ cat = RGeoServer::Catalog.new
19
+ ws = cat.get_default_workspace
20
+ cat.list(RGeoServer::CoverageStore, layers.keys, :workspace => ws) do |cs|
21
+ cs.url = layers[cs.name]['url']
22
+ cs.data_type = layers[cs.name]['type']
23
+ cs.enabled = 'true'
24
+ cs.save
25
+ # Create the corresponding layer
26
+ c = RGeoServer::Coverage.new cat, :workspace => ws, :coverage_store => cs, :name => cs.name
27
+ c.title = cs_name.gsub('_',' ').titleize
28
+ c.abstract = layers[cs.name]['description']
29
+ c.save
30
+ # Seed the tile cache
31
+ l = RGeoServer::Layer.new cat, :name => cs.name
32
+ l.seed :issue, {
33
+ :srs => {
34
+ :number => 4326
35
+ },
36
+ :zoomStart => 1,
37
+ :zoomStop => 10,
38
+ :format => 'image/png',
39
+ :threadCount => 1
40
+ }
41
+ end
42
+ end
@@ -0,0 +1,6 @@
1
+ require 'rgeoserver'
2
+
3
+ c = RGeoServer::Catalog.new
4
+ w = c.get_default_workspace
5
+ ds = w.data_stores
6
+ ds.first.profile
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rgeoserver'
4
+ require 'awesome_print'
5
+
6
+ RestClient.log = '/tmp/restclient.log'
7
+ @config = RGeoServer::Config
8
+ ap @config
9
+ @c = RGeoServer.Catalog.new
10
+ ap @c
11
+ @w = @c.get_workspace 'druid'
12
+ ap @w
13
+
14
+ @w.data_stores do |ds|
15
+ ds.featuretypes do |ft|
16
+ ap [ft, ft.name, ft.message]
17
+ end
18
+ ap [ds, ds.name]
19
+ end
@@ -5,7 +5,7 @@
5
5
 
6
6
  require 'rgeoserver'
7
7
 
8
- $catalog = RGeoServer::Catalog.new :url => 'http://localhost:8080/geoserver/rest', :user => 'admin', :password => 'geoserver'
8
+ $catalog = RGeoServer::Catalog.new
9
9
 
10
10
  # 1. Register a POSTGIS database as data store in GeoServer
11
11
  connection_parameters = {
@@ -1,29 +1,35 @@
1
1
  module RGeoServer
2
- # This class represents the main class of the data model.
2
+ # This class represents the main class of the data model, and provides all REST APIs to GeoServer.
3
3
  # Refer to
4
4
  # - http://geoserver.org/display/GEOS/Catalog+Design
5
- # - http://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html#workspaces
5
+ # - http://docs.geoserver.org/stable/en/user/rest/api/
6
6
 
7
7
  class Catalog
8
8
  include RGeoServer::RestApiClient
9
9
 
10
10
  attr_reader :config
11
11
 
12
- # @param [OrderedHash] options
13
- # @option options [String] :url
14
- # @option options [String] :user
15
- # @option options [String] :password
16
- def initialize options = {}
17
- @config = options
12
+ # @param [OrderedHash] options, if nil, uses RGeoServer::Config[:geoserver] loaded from $RGEOSERVER_CONFIG or config/defaults.yml
13
+ # @param [String] options :url
14
+ # @param [String] options :user
15
+ # @param [String] options :password
16
+ def initialize options = nil
17
+ @config = options || RGeoServer::Config[:geoserver]
18
+ unless config.include?(:url)
19
+ raise ArgumentError.new("Catalog: Requires :url option: #{config}")
20
+ end
21
+ RestClient.log = config[:logfile] || nil
18
22
  end
19
23
 
20
24
  def to_s
21
- "Catalog: #{@config[:url]}"
25
+ "Catalog: #{config[:url]}"
22
26
  end
23
27
 
24
- def headers format
25
- sym = :xml || format.to_sym
26
- {:accept => sym, :content_type=> sym}
28
+ def headers format = :xml
29
+ {
30
+ :accept => format.to_sym,
31
+ :content_type => format.to_sym
32
+ }
27
33
  end
28
34
 
29
35
  #== Resources
@@ -35,7 +41,10 @@ module RGeoServer
35
41
  # @param [Hash] options
36
42
  # @param [bool] check_remote if already exists in catalog and cache it
37
43
  # @yield [RGeoServer::ResourceInfo]
38
- def list klass, names, options, check_remote = false, &block
44
+ def list klass, names, options = {}, check_remote = false, &block
45
+ unless names.is_a? Array and not names.empty?
46
+ raise ArgumentError, "Missing names #{names}"
47
+ end
39
48
  ResourceInfo.list klass, self, names, options, check_remote, &block
40
49
  end
41
50
 
@@ -43,28 +52,23 @@ module RGeoServer
43
52
 
44
53
  # List of available workspaces
45
54
  # @return [Array<RGeoServer::Workspace>]
46
- def get_workspaces &block
47
- response = self.search :workspaces => nil
48
- doc = Nokogiri::XML(response)
49
- workspaces = doc.xpath(Workspace.root_xpath).collect{|w| w.text.to_s }
50
- list Workspace, workspaces, {}, &block
55
+ def get_workspaces
56
+ doc = Nokogiri::XML(search :workspaces => nil)
57
+ workspaces = doc.xpath("#{Workspace.root_xpath}/name/text()").collect {|w| w.to_s }
58
+ list Workspace.class, workspaces
51
59
  end
52
60
 
53
- # @param [String] workspace name
61
+ # @param ws [String] workspace name
54
62
  # @return [RGeoServer::Workspace]
55
- def get_workspace workspace
56
- response = self.search :workspaces => workspace
57
- doc = Nokogiri::XML(response)
58
- name = doc.at_xpath(Workspace.member_xpath)
59
- return Workspace.new self, :name => name.text if name
63
+ def get_workspace ws
64
+ doc = Nokogiri::XML(search :workspaces => ws)
65
+ Workspace.new self, :name => parse_name(doc, Workspace)
60
66
  end
67
+
61
68
 
62
- # @return [RGeoServer::Workspace]
69
+ # @return [RGeoServer::Workspace] get_workspace('default')
63
70
  def get_default_workspace
64
- response = self.search :workspaces => 'default'
65
- doc = Nokogiri::XML(response)
66
- name = doc.at_xpath("#{Workspace.member_xpath}/name/text()").to_s
67
- return Workspace.new self, :name => name
71
+ get_workspace 'default'
68
72
  end
69
73
 
70
74
  # Assign default workspace
@@ -77,6 +81,7 @@ module RGeoServer
77
81
  dws
78
82
  end
79
83
 
84
+ # @deprecated see RGeoServer::Workspace
80
85
  # @param [String] store
81
86
  # @param [String] workspace
82
87
  def reassign_workspace store, workspace
@@ -87,30 +92,29 @@ module RGeoServer
87
92
 
88
93
  # List of available layers
89
94
  # @return [Array<RGeoServer::Layer>]
90
- def get_layers options = {}, &block
91
- response = self.search :layers => nil
92
- doc = Nokogiri::XML(response)
93
- workspace_name = Workspace === options[:workspace] ? options[:workspace].name : options[:workspace]
94
- layer_nodes = doc.xpath(Layer.root_xpath).collect{|l| l.text.to_s }
95
- layers = list(Layer, layer_nodes, {}, &block)
96
- layers = layers.find_all { |layer| layer.workspace.name == workspace_name } if options[:workspace]
97
- layers
95
+ def each_layer options = {}
96
+ doc = Nokogiri::XML(self.search :layers => nil)
97
+ ap({:each_layer_doc => doc, :xpath => Layer.root_xpath}) if $DEBUG
98
+ doc.xpath(Layer.root_xpath + '/name/text()').each { |l|
99
+ ap({:layer => l.to_s.strip}) if $DEBUG
100
+ yield get_layer l.to_s.strip unless l.nil?
101
+ }
98
102
  end
99
103
 
100
- # @param [String] layer name
104
+ # @param [String] layername
101
105
  # @return [RGeoServer::Layer]
102
- def get_layer layer
103
- response = self.search :layers => layer
104
- doc = Nokogiri::XML(response)
105
- name = doc.at_xpath("#{Layer.member_xpath}/name/text()").to_s
106
- return Layer.new self, :name => name
106
+ def get_layer layername
107
+ raise ArgumentError, "#get_layer requires String #{layername}" unless layername.is_a? String
108
+ ap({:layers => layername}) if $DEBUG
109
+ doc = Nokogiri::XML(search :layers => layername)
110
+ Layer.new self, :name => layername
107
111
  end
108
112
 
109
113
  #= LayerGroups
110
114
 
111
115
  # List of available layer groups
112
116
  # @return [Array<RGeoServer::LayerGroup>]
113
- def get_layergroups options = {}, &block
117
+ def get_layergroups options = {}
114
118
  response = unless options[:workspace]
115
119
  self.search :layergroups => nil
116
120
  else
@@ -118,36 +122,31 @@ module RGeoServer
118
122
  end
119
123
  doc = Nokogiri::XML(response)
120
124
  layer_groups = doc.xpath(LayerGroup.root_xpath).collect{|l| l.text.to_s }.map(&:strip)
121
- list LayerGroup, layer_groups, {workspace: options[:workspace]}, &block
125
+ list LayerGroup, layer_groups, :workspace => options[:workspace]
122
126
  end
123
127
 
124
128
  # @param [String] layer group name
125
129
  # @return [RGeoServer::LayerGroup]
126
130
  def get_layergroup layergroup
127
- response = self.search :layergroups => layergroup
128
- doc = Nokogiri::XML(response)
129
- name = doc.at_xpath("#{LayerGroup.member_xpath}/name/text()").to_s
130
- return LayerGroup.new self, :name => name
131
+ doc = Nokogiri::XML(search :layergroups => layergroup)
132
+ LayerGroup.new self, :name => parse_name(doc, LayerGroup)
131
133
  end
132
134
 
133
135
  #= Styles (SLD Style Layer Descriptor)
134
136
 
135
137
  # List of available styles
136
138
  # @return [Array<RGeoServer::Style>]
137
- def get_styles &block
138
- response = self.search :styles => nil
139
- doc = Nokogiri::XML(response)
140
- styles = doc.xpath(Style.root_xpath).collect{|l| l.text.to_s }
141
- list Style, styles, {}, &block
139
+ def get_styles
140
+ doc = Nokogiri::XML(search :styles => nil)
141
+ styles = doc.xpath("#{Style.root_xpath}/name/text()").collect {|s| s.to_s }
142
+ list Style, styles
142
143
  end
143
144
 
144
145
  # @param [String] style name
145
146
  # @return [RGeoServer::Style]
146
147
  def get_style style
147
- response = self.search :styles => style
148
- doc = Nokogiri::XML(response)
149
- name = doc.at_xpath("#{Style.member_xpath}/name/text()").to_s
150
- return Style.new self, :name => name
148
+ doc = Nokogiri::XML(search :styles => style)
149
+ Style.new self, :name => parse_name(doc, Style)
151
150
  end
152
151
 
153
152
 
@@ -161,11 +160,9 @@ module RGeoServer
161
160
 
162
161
  # @return [RGeoServer::Namespace]
163
162
  def get_default_namespace
164
- response = self.search :namespaces => 'default'
165
- doc = Nokogiri::XML(response)
166
- name = doc.at_xpath("#{Namespace.member_xpath}/prefix/text()").to_s
167
- uri = doc.at_xpath("#{Namespace.member_xpath}/uri/text()").to_s
168
- return Namespace.new self, :name => name, :uri => uri
163
+ doc = Nokogiri::XML(search :namespaces => 'default')
164
+ Namespace.new self, :name => parse_name(doc, Namespace, 'prefix'),
165
+ :uri => parse_name(doc, Namespace, 'uri')
169
166
  end
170
167
 
171
168
  def set_default_namespace id, prefix, uri
@@ -178,27 +175,24 @@ module RGeoServer
178
175
  # @param [String] workspace
179
176
  # @return [Array<RGeoServer::DataStore>]
180
177
  def get_data_stores workspace = nil
181
- ws = workspace.nil?? get_workspaces : [get_workspace(workspace)]
182
- ds = []
183
- ws.each{ |w| ds += w.data_stores if w.data_stores }
184
- ds
178
+ ws = workspace.nil?? get_workspaces : [get_workspace(workspace)]
179
+ ws.map { |w| w.data_stores }.flatten
185
180
  end
186
181
 
187
182
  # @param [String] workspace
188
183
  # @param [String] datastore
189
184
  # @return [RGeoServer::DataStore]
190
185
  def get_data_store workspace, datastore
191
- response = self.search({:workspaces => workspace, :name => datastore})
192
- doc = Nokogiri::XML(response)
193
- name = doc.at_xpath(DataStore.member_xpath)
194
- return DataStore.new self, workspace, name.text if name
186
+ doc = Nokogiri::XML(search :workspaces => workspace, :datastores => datastore)
187
+ DataStore.new self, :workspace => workspace,
188
+ :name => parse_name(doc, DataStore)
195
189
  end
196
190
 
197
191
  # List of feature types
198
192
  # @param [String] workspace
199
193
  # @param [String] datastore
200
194
  # @return [Array<RGeoServer::FeatureType>]
201
- def get_feature_types workspace, datastore
195
+ def get_feature_types workspace, datastore, &block
202
196
  raise NotImplementedError
203
197
  end
204
198
 
@@ -210,17 +204,14 @@ module RGeoServer
210
204
  raise NotImplementedError
211
205
  end
212
206
 
213
-
214
207
  #= Coverages (Raster datasets)
215
208
 
216
209
  # List of coverage stores
217
210
  # @param [String] workspace
218
211
  # @return [Array<RGeoServer::CoverageStore>]
219
212
  def get_coverage_stores workspace = nil
220
- ws = workspace.nil?? get_workspaces : [get_workspace(workspace)]
221
- cs = []
222
- ws.each{ |w| cs += w.coverage_stores if w.coverage_stores }
223
- cs
213
+ ws = workspace.nil?? get_workspaces : [get_workspace(workspace)]
214
+ ws.map { |w| w.coverage_stores }.flatten
224
215
  end
225
216
 
226
217
  # @param [String] workspace
@@ -232,7 +223,10 @@ module RGeoServer
232
223
  end
233
224
 
234
225
  def get_coverage workspace, coverage_store, coverage
235
- c = Coverage.new self, :workspace => workspace, :coverage_store => coverage_store, :name => coverage
226
+ c = Coverage.new self,
227
+ :workspace => workspace,
228
+ :coverage_store => coverage_store,
229
+ :name => coverage
236
230
  return c.new?? nil : c
237
231
  end
238
232
 
@@ -242,20 +236,16 @@ module RGeoServer
242
236
  # @param [String] workspace
243
237
  # @return [Array<RGeoServer::WmsStore>]
244
238
  def get_wms_stores workspace = nil
245
- ws = workspace.nil?? get_workspaces : [get_workspace(workspace)]
246
- cs = []
247
- ws.each{ |w| cs += w.wms_stores if w.wms_stores }
248
- cs
239
+ ws = workspace.nil?? get_workspaces : [get_workspace(workspace)]
240
+ ws.map { |w| w.wms_stores }.flatten
249
241
  end
250
242
 
251
243
  # @param [String] workspace
252
244
  # @param [String] wmsstore
253
245
  # @return [RGeoServer::WmsStore]
254
246
  def get_wms_store workspace, wmsstore
255
- response = self.search({:workspaces => workspace, :name => wmsstore})
256
- doc = Nokogiri::XML(response)
257
- name = doc.at_xpath(WmsStore.member_xpath)
258
- return WmsStore.new self, workspace, name.text if name
247
+ doc = Nokogiri::XML(search :workspaces => workspace, :name => wmsstore)
248
+ WmsStore.new self, workspace, parse_name(doc, WmsStore)
259
249
  end
260
250
 
261
251
  #= Configuration reloading
@@ -270,6 +260,13 @@ module RGeoServer
270
260
  do_url 'reset', :put
271
261
  end
272
262
 
263
+ private
264
+ def parse_name doc, klass, k = 'name'
265
+ name = doc.at_xpath("#{klass.member_xpath}/#{k}/text()")
266
+ name = name.to_s unless name.nil?
267
+ name
268
+ end
269
+
273
270
  end
274
271
 
275
272
  end
@@ -1,7 +1,17 @@
1
1
  require 'confstruct/configuration'
2
2
 
3
+ # Uses config/defaults.yml or $RGEOSERVER_CONFIG from environment
4
+ # See https://rubygems.org/gems/confstruct for details on file format
3
5
  module RGeoServer
4
- Config = Confstruct::Configuration.new(YAML.load(File.read(File.expand_path('../../../config/config_defaults.yml', __FILE__))))
6
+ Config = Confstruct::Configuration.new(
7
+ YAML.load(
8
+ File.read(
9
+ ENV['RGEOSERVER_CONFIG'] ||
10
+ File.join(File.dirname(__FILE__), '..', '..', 'config', 'defaults.yml')
11
+ )
12
+ )
13
+ )
14
+
5
15
  end
6
16
 
7
17