roadforest 0.5 → 0.7
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.
- checksums.yaml +4 -4
- data/examples/file-management.rb +70 -58
- data/lib/roadforest/application.rb +9 -17
- data/lib/roadforest/application/dispatcher.rb +76 -9
- data/lib/roadforest/application/parameters.rb +9 -1
- data/lib/roadforest/application/path-provider.rb +30 -3
- data/lib/roadforest/application/route-adapter.rb +96 -14
- data/lib/roadforest/application/services-host.rb +21 -3
- data/lib/roadforest/augment/affordance.rb +82 -11
- data/lib/roadforest/augment/augmentation.rb +24 -6
- data/lib/roadforest/augment/augmenter.rb +12 -3
- data/lib/roadforest/authorization.rb +7 -229
- data/lib/roadforest/authorization/auth-entity.rb +26 -0
- data/lib/roadforest/authorization/authentication-chain.rb +79 -0
- data/lib/roadforest/authorization/default-authentication-store.rb +33 -0
- data/lib/roadforest/authorization/grant-builder.rb +23 -0
- data/lib/roadforest/authorization/grants-holder.rb +58 -0
- data/lib/roadforest/authorization/manager.rb +85 -0
- data/lib/roadforest/authorization/policy.rb +19 -0
- data/lib/roadforest/graph/access-manager.rb +25 -2
- data/lib/roadforest/graph/focus-list.rb +4 -0
- data/lib/roadforest/graph/graph-focus.rb +30 -13
- data/lib/roadforest/graph/nav-affordance-builder.rb +62 -0
- data/lib/roadforest/graph/normalization.rb +3 -3
- data/lib/roadforest/graph/path-vocabulary.rb +64 -0
- data/lib/roadforest/graph/post-focus.rb +5 -0
- data/lib/roadforest/graph/vocabulary.rb +4 -1
- data/lib/roadforest/http/adapters/excon.rb +4 -0
- data/lib/roadforest/http/graph-transfer.rb +17 -1
- data/lib/roadforest/http/keychain.rb +121 -33
- data/lib/roadforest/http/user-agent.rb +5 -3
- data/lib/roadforest/interface/application.rb +25 -8
- data/lib/roadforest/interface/rdf.rb +114 -15
- data/lib/roadforest/interface/utility.rb +3 -0
- data/lib/roadforest/interface/utility/backfill.rb +63 -0
- data/lib/roadforest/interface/utility/grant-list.rb +45 -0
- data/lib/roadforest/interface/utility/grant.rb +22 -0
- data/lib/roadforest/interfaces.rb +1 -0
- data/lib/roadforest/path-matcher.rb +471 -0
- data/lib/roadforest/remote-host.rb +159 -35
- data/lib/roadforest/resource/read-only.rb +23 -4
- data/lib/roadforest/server.rb +32 -3
- data/lib/roadforest/source-rigor/graph-store.rb +0 -2
- data/lib/roadforest/source-rigor/rigorous-access.rb +138 -21
- data/lib/roadforest/templates/affordance-property-values.haml +3 -0
- data/lib/roadforest/templates/rdfpost-curie.haml +1 -1
- data/lib/roadforest/test-support/matchers.rb +41 -12
- data/lib/roadforest/test-support/remote-host.rb +3 -3
- data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +1 -1
- data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +40 -27
- data/lib/roadforest/type-handlers/rdfa.rb +10 -3
- data/lib/roadforest/utility/class-registry.rb +44 -4
- data/spec/affordance-augmenter.rb +46 -19
- data/spec/affordances-flow.rb +46 -30
- data/spec/authorization.rb +16 -4
- data/spec/client.rb +22 -4
- data/spec/focus-list.rb +24 -0
- data/spec/full-integration.rb +8 -3
- data/spec/graph-store.rb +8 -0
- data/spec/keychain.rb +18 -14
- data/spec/rdf-normalization.rb +32 -6
- data/spec/update-focus.rb +36 -39
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6db5d72add13365fd11e006d8942448265f13f61
|
4
|
+
data.tar.gz: 85a7105fe1995e4a340c6540e4f02d4f84c5d900
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eaa87181e7ee19771dd8e3e561afac00885dee1b9f49b27978423e1d6850ca3bd9768bd21861f528b0327fb8732b5d109bdb03a852812ce3d97cd8a8ef2648b
|
7
|
+
data.tar.gz: 441c94a9a790b7e6e94978a8c4ca5407a343562ad106c2a45d86ae6f7b09d6e90afb888501e1b401c03c7517de3000f5aa437802bd70e5cd6b0399cff6490b05
|
data/examples/file-management.rb
CHANGED
@@ -3,7 +3,9 @@ require 'rdf/vocab/skos'
|
|
3
3
|
|
4
4
|
module FileManagementExample
|
5
5
|
module Vocabulary
|
6
|
-
class LC < ::RDF::Vocabulary("http://lrdesign.com/vocabularies/logical-construct#")
|
6
|
+
class LC < ::RDF::Vocabulary("http://lrdesign.com/vocabularies/logical-construct#")
|
7
|
+
property :name
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
11
|
class ServicesHost < ::RoadForest::Application::ServicesHost
|
@@ -11,13 +13,7 @@ module FileManagementExample
|
|
11
13
|
|
12
14
|
def initialize
|
13
15
|
@file_records = []
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
FileRecord = Struct.new(:name, :resolved)
|
18
16
|
|
19
|
-
class Application < RoadForest::Application
|
20
|
-
def setup
|
21
17
|
router.add :root, [], :read_only, Interfaces::Navigation
|
22
18
|
router.add :unresolved_needs, ["unresolved_needs"], :parent, Interfaces::UnresolvedNeedsList
|
23
19
|
router.add_traced :need, ["needs",'*'], :leaf, Interfaces::Need
|
@@ -25,77 +21,93 @@ module FileManagementExample
|
|
25
21
|
route.content_engine = RoadForest::ContentHandling.plaintext_engine
|
26
22
|
end
|
27
23
|
end
|
24
|
+
end
|
28
25
|
|
29
|
-
|
30
|
-
class Navigation < RoadForest::Interface::RDF
|
31
|
-
def exists?
|
32
|
-
true
|
33
|
-
end
|
26
|
+
FileRecord = Struct.new(:name, :resolved)
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
module Interfaces
|
29
|
+
class Navigation < RoadForest::Interface::RDF
|
30
|
+
def exists?
|
31
|
+
true
|
32
|
+
end
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
entry[:skos, :prefLabel] = name
|
43
|
-
entry[:foaf, "page"] = path
|
44
|
-
end
|
45
|
-
end
|
34
|
+
def update(graph)
|
35
|
+
return false
|
36
|
+
end
|
46
37
|
|
47
|
-
|
48
|
-
|
49
|
-
|
38
|
+
def nav_entry(graph, name, path)
|
39
|
+
graph.add_node([:skos, :hasTopConcept], "#" + name) do |entry|
|
40
|
+
entry[:rdf, :type] = [:skos, "Concept"]
|
41
|
+
entry[:skos, :prefLabel] = name
|
42
|
+
entry[:foaf, "page"] = path
|
50
43
|
end
|
51
44
|
end
|
52
45
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
46
|
+
def fill_graph(graph)
|
47
|
+
graph[:rdf, "type"] = [:skos, "ConceptScheme"]
|
48
|
+
nav_entry(graph, "Unresolved", url_for(:unresolved_needs))
|
49
|
+
end
|
50
|
+
end
|
57
51
|
|
58
|
-
|
59
|
-
|
52
|
+
class UnresolvedNeedsList < RoadForest::Interface::RDF
|
53
|
+
def exists?
|
54
|
+
true
|
55
|
+
end
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
new_file = FileRecord.new(graph.first(:lc, "name"), false)
|
64
|
-
services.file_records << new_file
|
65
|
-
end
|
57
|
+
def update(graph)
|
58
|
+
end
|
66
59
|
|
67
|
-
|
60
|
+
def add_child(graph)
|
61
|
+
services.logger.debug(graph.access_manager.source_graph.dump(:nquads))
|
62
|
+
new_file = FileRecord.new(graph.first(:lc, "name"), false)
|
63
|
+
services.file_records << new_file
|
64
|
+
end
|
65
|
+
|
66
|
+
def fill_graph(graph)
|
67
|
+
unresolved = services.file_records.select do |record|
|
68
|
+
!record.resolved
|
69
|
+
end
|
70
|
+
if unresolved.empty?
|
71
|
+
graph.add_list(:lc, "needs")
|
72
|
+
else
|
68
73
|
graph.add_list(:lc, "needs") do |list|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
list.append(need.subject)
|
76
|
-
end
|
74
|
+
unresolved.each do |record|
|
75
|
+
need = copy_interface(graph, :need, '*' => [record.name])
|
76
|
+
need[:lc, :name]
|
77
|
+
need[:lc, :digest]
|
78
|
+
|
79
|
+
list.append(need.subject)
|
77
80
|
end
|
78
81
|
end
|
79
82
|
end
|
80
83
|
end
|
84
|
+
end
|
81
85
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
86
|
+
class Need < RoadForest::Interface::RDF
|
87
|
+
def data
|
88
|
+
@data ||= services.file_records.find do |record|
|
89
|
+
record.name == params.remainder
|
87
90
|
end
|
91
|
+
end
|
88
92
|
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
def update_payload
|
94
|
+
payload_focus do |payload|
|
95
|
+
payload.add_node([:path, "forward"]) do |resolved|
|
96
|
+
resolved[[:path, "predicate"]] = [:lc, "resolved"]
|
97
|
+
resolved[[:path, "type"]] = [:xsd, "boolean"]
|
98
|
+
end
|
92
99
|
end
|
100
|
+
end
|
93
101
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
102
|
+
def graph_update(graph)
|
103
|
+
data.resolved = graph[:lc, "resolved"]
|
104
|
+
new_graph
|
105
|
+
end
|
106
|
+
|
107
|
+
def fill_graph(graph)
|
108
|
+
graph[[:lc, "resolved"]] = data.resolved
|
109
|
+
graph[[:lc, "name"]] = data.name
|
110
|
+
graph[[:lc, "contents"]] = url_for(:file_content)
|
99
111
|
end
|
100
112
|
end
|
101
113
|
end
|
@@ -13,33 +13,25 @@ require 'roadforest/authorization'
|
|
13
13
|
|
14
14
|
module RoadForest
|
15
15
|
class Application
|
16
|
-
|
17
|
-
|
18
|
-
def initialize(canonical_host, services = nil, configuration = nil, dispatcher = nil)
|
19
|
-
@canonical_host = normalize_resource(canonical_host)
|
16
|
+
def initialize(services, configuration = nil)
|
17
|
+
@services = services
|
20
18
|
configuration ||= Webmachine::Configuration.default
|
21
|
-
dispatcher ||= Dispatcher.new(self)
|
22
19
|
super(configuration, dispatcher)
|
23
|
-
self.services = services unless services.nil?
|
24
|
-
|
25
|
-
setup
|
26
20
|
end
|
27
21
|
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
attr_accessor :services, :canonical_host, :default_content_engine
|
22
|
+
attr_reader :services
|
32
23
|
|
24
|
+
def dispatcher
|
25
|
+
services.dispatcher
|
26
|
+
end
|
33
27
|
alias router dispatcher
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
@services = service_host
|
38
|
-
service_host.application = self
|
29
|
+
def canonical_host
|
30
|
+
services.canonical_host
|
39
31
|
end
|
40
32
|
|
41
33
|
def default_content_engine
|
42
|
-
|
34
|
+
services.default_content_engine
|
43
35
|
end
|
44
36
|
end
|
45
37
|
end
|
@@ -1,31 +1,57 @@
|
|
1
1
|
require 'webmachine'
|
2
2
|
require 'roadforest/application/route-adapter'
|
3
|
+
require 'roadforest/application/path-provider'
|
3
4
|
require 'roadforest/resource'
|
4
5
|
|
5
6
|
module RoadForest
|
6
7
|
class Dispatcher < Webmachine::Dispatcher
|
7
|
-
def initialize(
|
8
|
+
def initialize(services)
|
8
9
|
super(method(:create_resource))
|
9
|
-
@
|
10
|
+
@services = services
|
10
11
|
@route_names = {}
|
12
|
+
@route_mappings = []
|
11
13
|
@trace_by_default = false
|
12
14
|
end
|
13
|
-
attr_accessor :
|
15
|
+
attr_accessor :services, :trace_by_default
|
14
16
|
|
15
17
|
def route_for_name(name)
|
16
18
|
@route_names.fetch(name)
|
17
19
|
end
|
18
20
|
|
19
|
-
def
|
20
|
-
@
|
21
|
+
def mapped_route_for_name(from, name, params)
|
22
|
+
mapping = @route_mappings.find do |mapping|
|
23
|
+
mapping.matches?(from, name, params)
|
24
|
+
end
|
25
|
+
|
26
|
+
unless mapping.nil?
|
27
|
+
name = mapping.to_name
|
28
|
+
end
|
29
|
+
|
30
|
+
return route_for_name(name)
|
21
31
|
end
|
22
32
|
|
23
|
-
def
|
24
|
-
|
33
|
+
def find_route(*args)
|
34
|
+
if block_given?
|
35
|
+
@routes.find{|route| yield(route)}
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def each_route(&block)
|
42
|
+
@routes.each(&block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def each_name_and_route(&block)
|
46
|
+
@route_names.each_pair(&block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_content_engine
|
50
|
+
@services.default_content_engine
|
25
51
|
end
|
26
52
|
|
27
|
-
def
|
28
|
-
|
53
|
+
def path_provider(route_name)
|
54
|
+
PathProvider.new(route_name, self)
|
29
55
|
end
|
30
56
|
|
31
57
|
# Add a named route to the dispatcher - the 90% case is handled by passing
|
@@ -68,5 +94,46 @@ module RoadForest
|
|
68
94
|
end
|
69
95
|
end
|
70
96
|
alias add_traced add_traced_route
|
97
|
+
|
98
|
+
def add_route_map(route_map)
|
99
|
+
@route_mappings << route_map
|
100
|
+
end
|
101
|
+
|
102
|
+
class RouteMap
|
103
|
+
class Configurator
|
104
|
+
def initialize(name, router)
|
105
|
+
@router = router
|
106
|
+
@map = RouteMap.new
|
107
|
+
@map.in_name = name
|
108
|
+
end
|
109
|
+
|
110
|
+
def from(name, params=nil)
|
111
|
+
@map.from_name = name
|
112
|
+
@map.from_params = [*params]
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
def to(name)
|
117
|
+
@map.to_name = name
|
118
|
+
@router.add_route_map(@map)
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def initialize
|
124
|
+
end
|
125
|
+
attr_accessor :in_name, :from_name, :from_params, :to_name
|
126
|
+
|
127
|
+
def matches?(in_name, name, params)
|
128
|
+
return false unless in_name == @in_name
|
129
|
+
return false unless name == @from_name
|
130
|
+
return false unless @from_params.all?{|name| params.has_key?(name)}
|
131
|
+
return true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def map_in(route_name)
|
136
|
+
RouteMap::Configurator.new(route_name, self)
|
137
|
+
end
|
71
138
|
end
|
72
139
|
end
|
@@ -19,7 +19,15 @@ module RoadForest
|
|
19
19
|
|
20
20
|
def fetch(field_name)
|
21
21
|
return path_tokens if field_name == '*'
|
22
|
-
@path_info.fetch(field_name)
|
22
|
+
@path_info.fetch(field_name) do
|
23
|
+
if @query_params.respond_to?(:fetch)
|
24
|
+
@query_params.fetch(field_name) do
|
25
|
+
@query_params.fetch(field_name.to_s)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise KeyError, "No parameter: #{field_name}"
|
29
|
+
end
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
25
33
|
def slice(*fields)
|
@@ -1,9 +1,18 @@
|
|
1
1
|
module RoadForest
|
2
2
|
class PathProvider
|
3
|
-
def initialize(dispatcher)
|
3
|
+
def initialize(route_name, dispatcher)
|
4
|
+
@route_name = route_name
|
4
5
|
@dispatcher = dispatcher
|
5
6
|
end
|
6
7
|
|
8
|
+
def services
|
9
|
+
@dispatcher.services
|
10
|
+
end
|
11
|
+
|
12
|
+
def route_for_name(name, params=nil)
|
13
|
+
@dispatcher.mapped_route_for_name(@route_name, name, params)
|
14
|
+
end
|
15
|
+
|
7
16
|
# Get the URL to the given resource, with optional variables to be used
|
8
17
|
# for bindings in the path spec.
|
9
18
|
# @param [Webmachine::Resource] resource the resource to link to
|
@@ -12,10 +21,28 @@ module RoadForest
|
|
12
21
|
# @return [String] the URL
|
13
22
|
def path_for(name, vars = nil)
|
14
23
|
vars ||= {}
|
15
|
-
route =
|
24
|
+
route = route_for_name(name)
|
16
25
|
::RDF::URI.parse(route.build_path(vars))
|
17
26
|
end
|
18
27
|
|
28
|
+
def pattern_for(name, vals = nil, extra = nil)
|
29
|
+
vars ||= {}
|
30
|
+
route = route_for_name(name)
|
31
|
+
Addressable::URI.parse(services.canonical_host.to_s).join(route.build_pattern(vals, extra))
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_route(&block)
|
35
|
+
@dispatcher.find_route(&block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def each_name_and_route(&block)
|
39
|
+
@dispatcher.each_name_and_route(&block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def url_for(route_name, params = nil)
|
43
|
+
::RDF::URI.new(Addressable::URI.parse(services.canonical_host.to_s).join(path_for(route_name, params)))
|
44
|
+
end
|
45
|
+
|
19
46
|
def request_for(name, vars = nil)
|
20
47
|
url = path_for(name, vars) #full url?
|
21
48
|
|
@@ -23,7 +50,7 @@ module RoadForest
|
|
23
50
|
end
|
24
51
|
|
25
52
|
def interface_for(name, vars = nil)
|
26
|
-
route =
|
53
|
+
route = route_for_name(name)
|
27
54
|
params = route.build_params(vars)
|
28
55
|
route.resource.build_interface(params)
|
29
56
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RoadForest
|
2
|
-
class Application
|
2
|
+
class Application #XXX Lotta classes in this one file
|
3
3
|
#Embedded in WebMachine's Routes to compose the object structure at need
|
4
4
|
class ResourceAdapter
|
5
5
|
attr_accessor :resource_builder, :interface_builder, :route_name, :router, :services, :content_engine, :trace, :router
|
@@ -21,7 +21,15 @@ module RoadForest
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def build_interface(params)
|
24
|
-
interface_builder.call(route_name, params, router, router.services)
|
24
|
+
interface_builder.call(route_name, params, router.path_provider(route_name), router.services)
|
25
|
+
end
|
26
|
+
|
27
|
+
def interface_class
|
28
|
+
if interface_builder.respond_to? :interface_class
|
29
|
+
interface_builder.interface_class
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
35
|
def trace?
|
@@ -36,20 +44,82 @@ module RoadForest
|
|
36
44
|
#Extension of Webmachine's Routes that allows for rendering url paths and
|
37
45
|
#parameter lists.
|
38
46
|
class Route < Webmachine::Dispatcher::Route
|
47
|
+
attr_accessor :name
|
39
48
|
# Create a complete URL for this route, doing any necessary variable
|
40
49
|
# substitution.
|
41
50
|
# @param [Hash] vars values for the path variables
|
42
51
|
# @return [String] the valid URL for the route
|
43
52
|
def build_path(vars = nil)
|
44
53
|
vars ||= {}
|
45
|
-
|
54
|
+
vars = vars.to_hash
|
55
|
+
vars = vars.dup
|
56
|
+
path_spec = resolve_path_spec(vars)
|
57
|
+
if path_spec.any?{|segment| segment.is_a?(Symbol) or segment == "*"}
|
58
|
+
raise "Cannot build path - missing vars: #{path_spec.inspect}"
|
59
|
+
end
|
60
|
+
path = "/" + path_spec.join("/")
|
61
|
+
vars.delete('*')
|
62
|
+
unless vars.empty?
|
63
|
+
path += "?" + vars.map do |key,value|
|
64
|
+
[key,value].join("=")
|
65
|
+
end.join("&")
|
66
|
+
end
|
67
|
+
return path
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_pattern(vals = nil, extra_vars = nil)
|
71
|
+
vals ||= {}
|
72
|
+
extra_vars ||= []
|
73
|
+
vals = vals.to_hash
|
74
|
+
vals = vals.dup
|
75
|
+
extra_vars -= path_spec.find_all{|segment| segment.is_a? Symbol}
|
76
|
+
|
77
|
+
pattern_spec = resolve_path_spec(vals)
|
78
|
+
|
79
|
+
pattern = pattern_spec.map do |segment|
|
80
|
+
case segment
|
81
|
+
when '*'
|
82
|
+
"{/rest*}"
|
83
|
+
when Symbol
|
84
|
+
"{/#{segment}}"
|
85
|
+
else
|
86
|
+
"/" + segment
|
87
|
+
end
|
88
|
+
end.join("")
|
89
|
+
|
90
|
+
vals.delete('*')
|
91
|
+
unless vals.empty?
|
92
|
+
pattern += "?" + vals.map do |key,value|
|
93
|
+
[key,value].join("=")
|
94
|
+
end.join("&")
|
95
|
+
end
|
96
|
+
unless extra_vars.empty?
|
97
|
+
pattern += "{?#{extra_vars.join(",")}}"
|
98
|
+
end
|
99
|
+
return pattern
|
100
|
+
end
|
101
|
+
|
102
|
+
def resolve_path_spec(vars)
|
103
|
+
path_spec.map do |segment|
|
46
104
|
case segment
|
47
105
|
when '*',Symbol
|
48
|
-
vars.
|
106
|
+
if (string = vars.delete(segment)).nil?
|
107
|
+
segment
|
108
|
+
else
|
109
|
+
string
|
110
|
+
end
|
49
111
|
when String
|
50
112
|
segment
|
51
113
|
end
|
52
|
-
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def interface_class
|
118
|
+
if resource.respond_to? :interface_class
|
119
|
+
resource.interface_class
|
120
|
+
else
|
121
|
+
nil
|
122
|
+
end
|
53
123
|
end
|
54
124
|
|
55
125
|
def build_params(vars = nil)
|
@@ -69,13 +139,24 @@ module RoadForest
|
|
69
139
|
end
|
70
140
|
end
|
71
141
|
|
142
|
+
class InterfaceBuilder
|
143
|
+
attr_reader :interface_class
|
144
|
+
def initialize(interface_class)
|
145
|
+
@interface_class = interface_class
|
146
|
+
end
|
147
|
+
|
148
|
+
def call(name, params, router, services)
|
149
|
+
interface_class.new(name, params, router, services)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
72
153
|
class RouteBinding
|
73
154
|
def initialize(router)
|
74
155
|
@router = router
|
75
156
|
end
|
76
157
|
|
77
158
|
attr_accessor :route_name, :path_spec, :bindings, :guard
|
78
|
-
attr_accessor :resource_type, :interface_class, :services, :trace, :content_engine
|
159
|
+
attr_accessor :resource_type, :interface_builder, :interface_class, :services, :trace, :content_engine
|
79
160
|
|
80
161
|
def resource_builder
|
81
162
|
@resource_builder ||= proc do |request, response|
|
@@ -88,9 +169,7 @@ module RoadForest
|
|
88
169
|
end
|
89
170
|
|
90
171
|
def interface_builder
|
91
|
-
@interface_builder ||=
|
92
|
-
interface_class.new(name, params, router.path_provider, services)
|
93
|
-
end
|
172
|
+
@interface_builder ||= InterfaceBuilder.new(interface_class)
|
94
173
|
end
|
95
174
|
|
96
175
|
def build_interface(&block)
|
@@ -100,11 +179,14 @@ module RoadForest
|
|
100
179
|
def route
|
101
180
|
@route ||=
|
102
181
|
begin
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
182
|
+
route =
|
183
|
+
if guard.nil?
|
184
|
+
Route.new(path_spec, resource_adapter, bindings || {})
|
185
|
+
else
|
186
|
+
Route.new(path_spec, resource_adapter, bindings || {}, &guard)
|
187
|
+
end
|
188
|
+
route.name = route_name
|
189
|
+
route
|
108
190
|
end
|
109
191
|
end
|
110
192
|
|