roadforest 0.1 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/examples/file-management.rb +12 -13
  3. data/lib/roadforest-client.rb +3 -0
  4. data/lib/roadforest-common.rb +2 -0
  5. data/lib/roadforest-server.rb +7 -0
  6. data/lib/roadforest-testing.rb +1 -0
  7. data/lib/roadforest/application.rb +9 -7
  8. data/lib/roadforest/application/dispatcher.rb +39 -63
  9. data/lib/roadforest/application/parameters.rb +1 -1
  10. data/lib/roadforest/application/path-provider.rb +2 -2
  11. data/lib/roadforest/application/route-adapter.rb +130 -18
  12. data/lib/roadforest/application/services-host.rb +0 -4
  13. data/lib/roadforest/augment/affordance.rb +78 -0
  14. data/lib/roadforest/augment/augmentation.rb +97 -0
  15. data/lib/roadforest/augment/augmenter.rb +54 -0
  16. data/lib/roadforest/augmentations.rb +1 -0
  17. data/lib/roadforest/content-handling.rb +1 -0
  18. data/lib/roadforest/content-handling/common-engines.rb +67 -0
  19. data/lib/roadforest/content-handling/engine.rb +2 -14
  20. data/lib/roadforest/content-handling/handler-wrap.rb +29 -31
  21. data/lib/roadforest/content-handling/media-type.rb +6 -0
  22. data/lib/roadforest/{rdf.rb → graph.rb} +1 -1
  23. data/lib/roadforest/{rdf → graph}/access-manager.rb +12 -74
  24. data/lib/roadforest/{rdf → graph}/document.rb +1 -1
  25. data/lib/roadforest/{rdf → graph}/etagging.rb +2 -2
  26. data/lib/roadforest/{rdf → graph}/focus-list.rb +1 -9
  27. data/lib/roadforest/{rdf → graph}/graph-copier.rb +2 -2
  28. data/lib/roadforest/{rdf → graph}/graph-focus.rb +5 -7
  29. data/lib/roadforest/{rdf → graph}/normalization.rb +1 -1
  30. data/lib/roadforest/{rdf → graph}/post-focus.rb +2 -3
  31. data/lib/roadforest/graph/vocabulary.rb +96 -0
  32. data/lib/roadforest/http/graph-transfer.rb +2 -2
  33. data/lib/roadforest/interface/application.rb +145 -0
  34. data/lib/roadforest/interface/blob.rb +38 -0
  35. data/lib/roadforest/interface/rdf.rb +77 -0
  36. data/lib/roadforest/interfaces.rb +2 -0
  37. data/lib/roadforest/remote-host.rb +17 -17
  38. data/lib/roadforest/resource.rb +4 -0
  39. data/lib/roadforest/resource/{rdf/leaf-item.rb → leaf-item.rb} +1 -1
  40. data/lib/roadforest/resource/{rdf/list.rb → list.rb} +1 -1
  41. data/lib/roadforest/resource/{rdf/parent-item.rb → parent-item.rb} +1 -1
  42. data/lib/roadforest/resource/{rdf/read-only.rb → read-only.rb} +18 -18
  43. data/lib/roadforest/resource/role/has-children.rb +1 -1
  44. data/lib/roadforest/resource/role/writable.rb +2 -2
  45. data/lib/roadforest/server.rb +1 -1
  46. data/lib/roadforest/source-rigor.rb +9 -0
  47. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence-annealer.rb +2 -2
  48. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence.rb +5 -5
  49. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/any.rb +1 -1
  50. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/none-if-role-absent.rb +1 -1
  51. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/role-if-available.rb +1 -1
  52. data/lib/roadforest/source-rigor/engine.rb +45 -0
  53. data/lib/roadforest/{rdf → source-rigor}/graph-store.rb +9 -9
  54. data/lib/roadforest/{rdf/source-rigor → source-rigor}/http-investigator.rb +2 -2
  55. data/lib/roadforest/{rdf → source-rigor}/investigation.rb +2 -2
  56. data/lib/roadforest/{rdf/source-rigor → source-rigor}/investigator.rb +3 -3
  57. data/lib/roadforest/{rdf/source-rigor → source-rigor}/null-investigator.rb +3 -2
  58. data/lib/roadforest/{rdf → source-rigor}/parcel.rb +5 -5
  59. data/lib/roadforest/{rdf → source-rigor}/resource-pattern.rb +6 -6
  60. data/lib/roadforest/{rdf → source-rigor}/resource-query.rb +2 -2
  61. data/lib/roadforest/source-rigor/rigorous-access.rb +101 -0
  62. data/lib/roadforest/templates/affordance-doc.haml +23 -0
  63. data/lib/roadforest/templates/affordance-property-values.haml +13 -0
  64. data/lib/roadforest/templates/affordance-subject.haml +9 -0
  65. data/lib/roadforest/templates/affordance-uri-object.haml +2 -0
  66. data/lib/roadforest/templates/base/{property_value.haml → property-value.haml} +0 -0
  67. data/lib/roadforest/templates/base/{property_values.haml → property-values.haml} +0 -0
  68. data/lib/roadforest/templates/distiller/{property_value.haml → property-value.haml} +0 -0
  69. data/lib/roadforest/templates/distiller/{property_values.haml → property-values.haml} +0 -0
  70. data/lib/roadforest/templates/min/{property_values.haml → property-values.haml} +0 -0
  71. data/lib/roadforest/templates/rdfpost-curie.haml +6 -0
  72. data/lib/roadforest/test-support/dispatcher-facade.rb +2 -0
  73. data/lib/roadforest/test-support/matchers.rb +169 -5
  74. data/lib/roadforest/test-support/remote-host.rb +2 -2
  75. data/lib/roadforest/type-handlers/handler.rb +74 -0
  76. data/lib/roadforest/type-handlers/jsonld.rb +34 -0
  77. data/lib/roadforest/type-handlers/rdf-handler.rb +36 -0
  78. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer.rb +2 -2
  79. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/document-environment.rb +9 -8
  80. data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +312 -0
  81. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/object-environment.rb +3 -3
  82. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/property-environment.rb +5 -11
  83. data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +427 -0
  84. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/render-environment.rb +33 -26
  85. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/subject-environment.rb +7 -23
  86. data/lib/roadforest/type-handlers/rdfa.rb +73 -0
  87. data/lib/roadforest/type-handlers/rdfpost.rb +301 -0
  88. data/lib/roadforest/utility/class-registry.rb +23 -5
  89. data/spec/.ctrlp-root +0 -0
  90. data/spec/affordance-augmenter.rb +75 -0
  91. data/spec/affordances-flow.rb +438 -0
  92. data/spec/authorization.rb +34 -0
  93. data/spec/client.rb +13 -12
  94. data/spec/credence-annealer.rb +5 -5
  95. data/spec/focus-list.rb +8 -8
  96. data/spec/full-integration.rb +3 -3
  97. data/spec/graph-copier.rb +4 -4
  98. data/spec/graph-store.rb +19 -31
  99. data/spec/keychain.rb +82 -0
  100. data/spec/rdf-normalization.rb +2 -2
  101. data/spec/rdf-parcel.rb +3 -3
  102. data/spec/rdfa-handler.rb +514 -0
  103. data/spec/rdfpost.rb +96 -0
  104. data/spec/source-rigor.rb +57 -0
  105. data/spec/update-focus.rb +11 -10
  106. metadata +91 -66
  107. data/lib/roadforest/blob-model.rb +0 -53
  108. data/lib/roadforest/content-handling/type-handler.rb +0 -76
  109. data/lib/roadforest/content-handling/type-handlers/jsonld.rb +0 -36
  110. data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +0 -38
  111. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +0 -574
  112. data/lib/roadforest/content-handling/type-handlers/rdfa.rb +0 -175
  113. data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +0 -297
  114. data/lib/roadforest/model.rb +0 -209
  115. data/lib/roadforest/models.rb +0 -2
  116. data/lib/roadforest/rdf/source-rigor.rb +0 -44
  117. data/lib/roadforest/rdf/vocabulary.rb +0 -11
  118. data/lib/roadforest/resource/http/form-parsing.rb +0 -81
  119. data/lib/roadforest/resource/rdf.rb +0 -4
  120. data/spec/form-parsing.rb +0 -1
@@ -0,0 +1,38 @@
1
+ require 'roadforest/interface/application'
2
+
3
+ module RoadForest
4
+ module Interface
5
+ class Blob < Application
6
+ def destination_dir
7
+ Pathname.new(services.destination_dir)
8
+ end
9
+
10
+ def sub_path
11
+ params.remainder
12
+ end
13
+
14
+ def path
15
+ destination_dir.join(sub_path)
16
+ end
17
+
18
+ def retrieve
19
+ File::open(path)
20
+ end
21
+
22
+ def incomplete_path
23
+ [path,"incomplete"].join(".")
24
+ end
25
+
26
+ def update(incoming)
27
+ File::open(incomplete_path, "w") do |file|
28
+ incoming.each do |chunk|
29
+ file.write(chunk)
30
+ end
31
+ end
32
+ Pathname.new(incomplete_path).rename(path)
33
+
34
+ return nil
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,77 @@
1
+ require 'roadforest/interface/application'
2
+
3
+ module RoadForest
4
+ module Interface
5
+ class RDF < Application
6
+ include RoadForest::Graph::Etagging
7
+
8
+ def update(graph)
9
+ graph_update(start_focus(graph))
10
+ end
11
+
12
+ def graph_update(focus)
13
+ fill_graph(focus)
14
+ end
15
+
16
+ def add_graph_child(graph)
17
+ add_child(start_focus(graph))
18
+ new_graph
19
+ end
20
+
21
+ def add_child(focus)
22
+ new_graph
23
+ end
24
+
25
+ def retrieve
26
+ new_graph
27
+ end
28
+
29
+ def fill_graph(graph)
30
+ end
31
+
32
+ def start_focus(graph, resource_url=nil)
33
+ access = RoadForest::Graph::WriteManager.new
34
+ access.source_graph = graph
35
+ focus = RoadForest::Graph::GraphFocus.new(access, resource_url || my_url)
36
+
37
+ yield focus if block_given?
38
+ return focus
39
+ end
40
+
41
+ def copy_interface(node, route_name, params=nil)
42
+ params ||= {}
43
+
44
+ url = url_for(route_name, params)
45
+ source_interface = interface_for(route_name, params)
46
+
47
+ access = RoadForest::Graph::CopyManager.new
48
+ access.source_graph = source_interface.current_graph
49
+ access.target_graph = node.access_manager.destination_graph
50
+ copier = RoadForest::Graph::GraphFocus.new(access, url)
51
+
52
+ yield copier if block_given?
53
+ copier
54
+ end
55
+
56
+ def etag
57
+ @etag ||= etag_from(etag_graph)
58
+ end
59
+
60
+ def etag_graph
61
+ current_graph
62
+ end
63
+
64
+ def current_graph
65
+ return response_data if response_values.has_key?(:data)
66
+ new_graph
67
+ end
68
+
69
+ def new_graph
70
+ graph = ::RDF::Graph.new
71
+ focus = start_focus(graph, my_url)
72
+ fill_graph(focus)
73
+ self.response_data = graph
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,2 @@
1
+ require 'roadforest/interface/rdf'
2
+ require 'roadforest/interface/blob'
@@ -1,15 +1,15 @@
1
- require 'roadforest/rdf/source-rigor'
2
- require 'roadforest/rdf/source-rigor/credence-annealer'
3
- require 'roadforest/rdf/graph-store'
1
+ require 'roadforest/source-rigor'
2
+ require 'roadforest/source-rigor/credence-annealer'
3
+ require 'roadforest/source-rigor/rigorous-access'
4
+ require 'roadforest/source-rigor/graph-store' #XXX
5
+ require 'roadforest/graph/graph-focus'
4
6
  require 'roadforest/http/user-agent'
5
7
  require 'roadforest/http/graph-transfer'
6
8
  require 'roadforest/http/adapters/excon'
7
- require 'roadforest/rdf/access-manager'
8
- require 'roadforest/rdf/graph-focus'
9
9
 
10
10
  module RoadForest
11
11
  class RemoteHost
12
- include RDF::Normalization
12
+ include Graph::Normalization
13
13
 
14
14
  def initialize(well_known_url)
15
15
  self.url = well_known_url
@@ -21,7 +21,7 @@ module RoadForest
21
21
  end
22
22
 
23
23
  def build_graph_store
24
- RDF::GraphStore.new
24
+ SourceRigor::GraphStore.new
25
25
  end
26
26
 
27
27
  attr_writer :http_client
@@ -48,7 +48,7 @@ module RoadForest
48
48
  def source_rigor
49
49
  @source_rigor ||=
50
50
  begin
51
- rigor = RDF::SourceRigor.http
51
+ rigor = SourceRigor.http
52
52
  rigor.graph_transfer = graph_transfer
53
53
  rigor
54
54
  end
@@ -60,7 +60,7 @@ module RoadForest
60
60
 
61
61
  def anneal(focus)
62
62
  graph = build_graph_store
63
- annealer = RDF::SourceRigor::CredenceAnnealer.new(graph)
63
+ annealer = SourceRigor::CredenceAnnealer.new(graph)
64
64
  annealer.resolve do
65
65
  yield focus
66
66
  end
@@ -69,12 +69,12 @@ module RoadForest
69
69
  def putting(&block)
70
70
 
71
71
  graph = build_graph_store
72
- access = RDF::UpdateManager.new
72
+ access = SourceRigor::UpdateManager.new
73
73
  access.rigor = source_rigor
74
74
  access.source_graph = graph
75
- updater = RDF::GraphFocus.new(access, url)
75
+ updater = Graph::GraphFocus.new(access, url)
76
76
 
77
- annealer = RDF::SourceRigor::CredenceAnnealer.new(graph)
77
+ annealer = SourceRigor::CredenceAnnealer.new(graph)
78
78
 
79
79
  annealer.resolve do
80
80
  access.target_graph = ::RDF::Repository.new
@@ -89,13 +89,13 @@ module RoadForest
89
89
  end
90
90
 
91
91
  def posting(&block)
92
- require 'roadforest/rdf/post-focus'
92
+ require 'roadforest/graph/post-focus'
93
93
 
94
94
  graph = build_graph_store
95
- access = RDF::PostManager.new
95
+ access = SourceRigor::PostManager.new
96
96
  access.rigor = source_rigor
97
97
  access.source_graph = graph
98
- poster = RDF::PostFocus.new(access, url)
98
+ poster = Graph::PostFocus.new(access, url)
99
99
 
100
100
  graphs = {}
101
101
  poster.graphs = graphs
@@ -110,10 +110,10 @@ module RoadForest
110
110
  def getting(&block)
111
111
 
112
112
  graph = build_graph_store
113
- access = RDF::ReadOnlyManager.new
113
+ access = SourceRigor::RetrieveManager.new
114
114
  access.rigor = source_rigor
115
115
  access.source_graph = graph
116
- reader = RDF::GraphFocus.new(access, url)
116
+ reader = Graph::GraphFocus.new(access, url)
117
117
 
118
118
  anneal(reader, &block)
119
119
  end
@@ -0,0 +1,4 @@
1
+ require 'roadforest/resource/leaf-item'
2
+ require 'roadforest/resource/parent-item'
3
+ require 'roadforest/resource/list'
4
+ require 'roadforest/resource/read-only'
@@ -1,4 +1,4 @@
1
- require 'roadforest/resource/rdf/read-only'
1
+ require 'roadforest/resource/read-only'
2
2
  require 'roadforest/resource/role/writable'
3
3
 
4
4
  module RoadForest
@@ -1,4 +1,4 @@
1
- require 'roadforest/resource/rdf/read-only'
1
+ require 'roadforest/resource/read-only'
2
2
  require 'roadforest/resource/role/has-children'
3
3
  module RoadForest
4
4
  module Resource
@@ -1,4 +1,4 @@
1
- require 'roadforest/resource/rdf/read-only'
1
+ require 'roadforest/resource/read-only'
2
2
  require 'roadforest/resource/role/writable'
3
3
  require 'roadforest/resource/role/has-children'
4
4
  module RoadForest
@@ -15,7 +15,7 @@ module RoadForest
15
15
 
16
16
  register :read_only
17
17
 
18
- attr_accessor :model, :trace
18
+ attr_accessor :interface, :trace, :content_engine
19
19
 
20
20
  ### RoadForest interface
21
21
 
@@ -43,17 +43,17 @@ module RoadForest
43
43
  response.body = body
44
44
  end
45
45
 
46
- def retrieve_model
47
- absolutize(@model.canonical_host, @model.retrieve)
46
+ def retrieve_interface
47
+ absolutize(@interface.canonical_host, @interface.retrieve)
48
48
  end
49
- alias retreive_model retrieve_model
49
+ alias retreive_interface retrieve_interface
50
50
 
51
51
  # def known_methods
52
52
  # super + ["PATCH"]
53
53
  # end
54
54
 
55
- def model_supports(action)
56
- @model.respond_to?(action)
55
+ def interface_supports(action)
56
+ @interface.respond_to?(action)
57
57
  end
58
58
  ### Webmachine interface
59
59
 
@@ -63,8 +63,8 @@ module RoadForest
63
63
 
64
64
  #Overridden rather than metaprogram content type methods
65
65
  def send(*args)
66
- if args.length == 1 and not model.nil?
67
- model.type_handling.fetch(args.first).call(self)
66
+ if args.length == 1 and not interface.nil?
67
+ content_engine.fetch(args.first).call(self)
68
68
  else
69
69
  super
70
70
  end
@@ -73,47 +73,47 @@ module RoadForest
73
73
  end
74
74
 
75
75
  def method(name)
76
- if model.nil?
76
+ if interface.nil?
77
77
  super
78
78
  else
79
- model.type_handling.fetch(name).method(:call)
79
+ content_engine.fetch(name).method(:call)
80
80
  end
81
81
  rescue KeyError
82
82
  super
83
83
  end
84
84
 
85
85
  def content_types_provided
86
- model.type_handling.renderers.type_map
86
+ content_engine.renderers.type_map
87
87
  rescue => ex
88
88
  super
89
89
  end
90
90
 
91
91
  def is_authorized?(header)
92
- @authorization = @model.authorization(request.method, header)
92
+ @authorization = @interface.authorization(request.method, header)
93
93
  if(@authorization == :public || @authorization == :granted)
94
94
  return true
95
95
  end
96
- @model.authentication_challenge
96
+ @interface.authentication_challenge
97
97
  end
98
98
 
99
- #Add cache-control headers here
99
+ #XXX Add cache-control headers here
100
100
  def finish_request
101
101
  end
102
102
 
103
103
  def resource_exists?
104
- @model.exists?
104
+ @interface.exists?
105
105
  end
106
106
 
107
107
  def generate_etag
108
- @model.etag
108
+ @interface.etag
109
109
  end
110
110
 
111
111
  def last_modified
112
- @model.last_modified
112
+ @interface.last_modified
113
113
  end
114
114
 
115
115
  def expires
116
- @model.expires
116
+ @interface.expires
117
117
  end
118
118
  end
119
119
  end
@@ -11,7 +11,7 @@ module RoadForest
11
11
  end
12
12
 
13
13
  def process_post
14
- parser = model.type_handling.choose_parser(request.content_type || 'application/octet-stream')
14
+ parser = content_engine.choose_parser(request.content_type || 'application/octet-stream')
15
15
 
16
16
  parser.add_child(self)
17
17
  return true
@@ -22,7 +22,7 @@ module RoadForest
22
22
  end
23
23
 
24
24
  def content_types_accepted
25
- model.type_handling.parsers.type_map
25
+ content_engine.parsers.type_map
26
26
  end
27
27
 
28
28
  def request_body
@@ -35,7 +35,7 @@ module RoadForest
35
35
  end
36
36
 
37
37
  def delete_resource
38
- @model.delete(params)
38
+ @interface.delete(params)
39
39
  end
40
40
  end
41
41
  end
@@ -1,6 +1,6 @@
1
1
  #This file is intended as the single entry point for RoadForest server code
2
2
  require 'roadforest/application'
3
- require 'roadforest/models'
3
+ require 'roadforest/interfaces'
4
4
 
5
5
  module RoadForest
6
6
  def self.serve(application, services)
@@ -0,0 +1,9 @@
1
+ require 'roadforest'
2
+
3
+ module RoadForest
4
+ module SourceRigor
5
+ end
6
+ end
7
+
8
+ require 'roadforest/source-rigor/engine'
9
+ require 'roadforest/source-rigor/rigorous-access.rb'
@@ -1,6 +1,6 @@
1
- require 'roadforest/rdf'
1
+ require 'roadforest/graph'
2
2
 
3
- class RoadForest::RDF::SourceRigor
3
+ module RoadForest::SourceRigor
4
4
  class CredenceAnnealer
5
5
  def initialize(graph)
6
6
  @graph = graph
@@ -1,9 +1,5 @@
1
- class RoadForest::RDF::SourceRigor
1
+ module RoadForest::SourceRigor
2
2
  module Credence
3
- require 'roadforest/rdf/source-rigor/credence/role-if-available'
4
- require 'roadforest/rdf/source-rigor/credence/any'
5
- require 'roadforest/rdf/source-rigor/credence/none-if-role-absent'
6
-
7
3
  def self.policies
8
4
  @policies ||= {
9
5
  :any => Any.new,
@@ -27,3 +23,7 @@ class RoadForest::RDF::SourceRigor
27
23
  end
28
24
  end
29
25
  end
26
+
27
+ require 'roadforest/source-rigor/credence/role-if-available'
28
+ require 'roadforest/source-rigor/credence/any'
29
+ require 'roadforest/source-rigor/credence/none-if-role-absent'
@@ -1,4 +1,4 @@
1
- class RoadForest::RDF::SourceRigor
1
+ module RoadForest::SourceRigor
2
2
  module Credence
3
3
  class Any
4
4
  def credible(contexts, results)
@@ -1,4 +1,4 @@
1
- class RoadForest::RDF::SourceRigor
1
+ module RoadForest::SourceRigor
2
2
  module Credence
3
3
  #Unless we have results for the subject context, nothing is valid
4
4
  class NoneIfRoleAbsent
@@ -1,4 +1,4 @@
1
- class RoadForest::RDF::SourceRigor
1
+ module RoadForest::SourceRigor
2
2
  module Credence
3
3
  #If there are any results for the subject context, they're good
4
4
  class RoleIfAvailable
@@ -0,0 +1,45 @@
1
+ require 'roadforest/source-rigor'
2
+ require 'roadforest/source-rigor/investigator'
3
+ require 'roadforest/source-rigor/credence'
4
+
5
+ module RoadForest
6
+ module SourceRigor
7
+ class << self
8
+ def simple
9
+ rigor = Engine.new
10
+ rigor.policy_list(:must_local, :may_local)
11
+ rigor.investigator_list(:null)
12
+ rigor
13
+ end
14
+
15
+ def http
16
+ rigor = Engine.new
17
+ rigor.policy_list(:may_subject, :any) #XXX
18
+ rigor.investigator_list(:http, :null)
19
+ rigor
20
+ end
21
+ end
22
+
23
+ class Engine
24
+ def initialize
25
+ @investigators = []
26
+ @investigation_limit = 3
27
+ @credence_policies = []
28
+ end
29
+
30
+ attr_accessor :graph_transfer, :investigators, :investigation_limit, :credence_policies
31
+
32
+ def policy_list(*names)
33
+ self.credence_policies = names.map do |name|
34
+ Credence.policy(name)
35
+ end
36
+ end
37
+
38
+ def investigator_list(*names)
39
+ self.investigators = names.map do |name|
40
+ Investigator[name].new
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end