amee-data-abstraction 1.0.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.
- data/.rvmrc +1 -0
- data/CHANGELOG.txt +4 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +27 -0
- data/README.txt +188 -0
- data/Rakefile +102 -0
- data/VERSION +1 -0
- data/amee-data-abstraction.gemspec +115 -0
- data/examples/_calculator_form.erb +27 -0
- data/examples/calculation_controller.rb +16 -0
- data/init.rb +4 -0
- data/lib/amee-data-abstraction.rb +30 -0
- data/lib/amee-data-abstraction/calculation.rb +236 -0
- data/lib/amee-data-abstraction/calculation_set.rb +101 -0
- data/lib/amee-data-abstraction/drill.rb +63 -0
- data/lib/amee-data-abstraction/exceptions.rb +47 -0
- data/lib/amee-data-abstraction/input.rb +197 -0
- data/lib/amee-data-abstraction/metadatum.rb +58 -0
- data/lib/amee-data-abstraction/ongoing_calculation.rb +545 -0
- data/lib/amee-data-abstraction/output.rb +16 -0
- data/lib/amee-data-abstraction/profile.rb +108 -0
- data/lib/amee-data-abstraction/prototype_calculation.rb +350 -0
- data/lib/amee-data-abstraction/term.rb +506 -0
- data/lib/amee-data-abstraction/terms_list.rb +150 -0
- data/lib/amee-data-abstraction/usage.rb +90 -0
- data/lib/config/amee_units.rb +129 -0
- data/lib/core-extensions/class.rb +27 -0
- data/lib/core-extensions/hash.rb +43 -0
- data/lib/core-extensions/ordered_hash.rb +21 -0
- data/lib/core-extensions/proc.rb +15 -0
- data/rails/init.rb +32 -0
- data/spec/amee-data-abstraction/calculation_set_spec.rb +54 -0
- data/spec/amee-data-abstraction/calculation_spec.rb +75 -0
- data/spec/amee-data-abstraction/drill_spec.rb +38 -0
- data/spec/amee-data-abstraction/input_spec.rb +77 -0
- data/spec/amee-data-abstraction/metadatum_spec.rb +17 -0
- data/spec/amee-data-abstraction/ongoing_calculation_spec.rb +494 -0
- data/spec/amee-data-abstraction/profile_spec.rb +39 -0
- data/spec/amee-data-abstraction/prototype_calculation_spec.rb +256 -0
- data/spec/amee-data-abstraction/term_spec.rb +385 -0
- data/spec/amee-data-abstraction/terms_list_spec.rb +53 -0
- data/spec/config/amee_units_spec.rb +71 -0
- data/spec/core-extensions/class_spec.rb +25 -0
- data/spec/core-extensions/hash_spec.rb +44 -0
- data/spec/core-extensions/ordered_hash_spec.rb +12 -0
- data/spec/core-extensions/proc_spec.rb +12 -0
- data/spec/fixtures/electricity.rb +35 -0
- data/spec/fixtures/electricity_and_transport.rb +55 -0
- data/spec/fixtures/transport.rb +26 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +244 -0
- metadata +262 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
<% form_id = "drill-form-#{rand(1e8)}" %>
|
2
|
+
<% form_tag({:action=>nil},{:id=>form_id}) do%>
|
3
|
+
<%= hidden_field_tag 'form_id', form_id %>
|
4
|
+
<table>
|
5
|
+
<%@calculation.drills.each_value do |input|%>
|
6
|
+
<tr>
|
7
|
+
<td><%=label :entry,input.label,input.name%></td>
|
8
|
+
<td>
|
9
|
+
<%= select_tag "entry[#{input.label}]",
|
10
|
+
options_for_select(input.options_for_select,input.set? ? input.value : nil),:disabled=>input.disabled?%>
|
11
|
+
</td>
|
12
|
+
</tr>
|
13
|
+
<%end%>
|
14
|
+
<%@calculation.profiles.each_value do |input|%>
|
15
|
+
<tr><td><%=label :entry,input.label,input.name%></td><td><%= text_field :entry, input.label, "size" => 20, :value => input.value_if_given %></td></tr>
|
16
|
+
<%end%>
|
17
|
+
<%@calculation.chosen_outputs.each_value do |result|%>
|
18
|
+
<tr><td><%=label :entry,result.label,result.name%></td><td><%= result.value_if_given %></td></tr>
|
19
|
+
<%end%>
|
20
|
+
</table>
|
21
|
+
<%end%>
|
22
|
+
<%= observe_form form_id, :url => {:action => 'result'}%>
|
23
|
+
<% javascript_tag do %>
|
24
|
+
$('#<%=form_id%>').submit(function() {
|
25
|
+
return false;
|
26
|
+
});
|
27
|
+
<%end%>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CalculationController < ApplicationController
|
2
|
+
def index
|
3
|
+
@calculations=Calculations.calculations.values
|
4
|
+
end
|
5
|
+
|
6
|
+
def enter
|
7
|
+
@calculation=Calculations[params[:calculation]]
|
8
|
+
end
|
9
|
+
|
10
|
+
def result
|
11
|
+
@calculation=Calculations[params[:calculation]].clone
|
12
|
+
@calculation.choose!(params['entry'])
|
13
|
+
@calculation.calculate!
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright (C) 2011 AMEE UK Ltd. - http://www.amee.com
|
2
|
+
# Released as Open Source Software under the BSD 3-Clause license. See LICENSE.txt for details.
|
3
|
+
|
4
|
+
require 'amee'
|
5
|
+
require 'uuidtools'
|
6
|
+
require 'quantify'
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/core-extensions/class'
|
9
|
+
require File.dirname(__FILE__) + '/core-extensions/ordered_hash'
|
10
|
+
require File.dirname(__FILE__) + '/core-extensions/hash'
|
11
|
+
require File.dirname(__FILE__) + '/core-extensions/proc'
|
12
|
+
require File.dirname(__FILE__) + '/config/amee_units'
|
13
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/exceptions'
|
14
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/terms_list'
|
15
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/calculation'
|
16
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/ongoing_calculation'
|
17
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/prototype_calculation'
|
18
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/calculation_set'
|
19
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/term'
|
20
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/input'
|
21
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/drill'
|
22
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/profile'
|
23
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/usage'
|
24
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/output'
|
25
|
+
require File.dirname(__FILE__) + '/amee-data-abstraction/metadatum'
|
26
|
+
|
27
|
+
module AMEE::DataAbstraction
|
28
|
+
# Connection to AMEE server.
|
29
|
+
mattr_accessor :connection
|
30
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
# Copyright (C) 2011 AMEE UK Ltd. - http://www.amee.com
|
2
|
+
# Released as Open Source Software under the BSD 3-Clause license. See LICENSE.txt for details.
|
3
|
+
|
4
|
+
# :title: Class: AMEE::DataAbstraction::Calculation
|
5
|
+
|
6
|
+
module AMEE
|
7
|
+
module DataAbstraction
|
8
|
+
|
9
|
+
# Base class providing attributes and methods for representing a calculation
|
10
|
+
# which can be made using the AMEE platform. An instance of <i>Calculation</i>
|
11
|
+
# will typically be associated with a specific AMEE category.
|
12
|
+
#
|
13
|
+
# Instances of <i>Calculation</i> are represented by several primary attributes:
|
14
|
+
#
|
15
|
+
# label:: Symbol representing the unique, machine-readable name for the
|
16
|
+
# calculation
|
17
|
+
#
|
18
|
+
# name:: String representing a human-readable name for the calculation
|
19
|
+
#
|
20
|
+
# path:: String representing the AMEE platform path to the data category
|
21
|
+
# which is associated with <tt>self</tt>
|
22
|
+
#
|
23
|
+
# fixed_usage:: String representing the AMEE platform path for the usage to
|
24
|
+
# be used by <tt>self</tt>, if defined
|
25
|
+
#
|
26
|
+
# An instance of <i>Calculation</i> also holds an arbitrary number of objects
|
27
|
+
# of the class <i>Term</i>. These represent values associated with the
|
28
|
+
# calculation, e.g. inputs, outputs, metadatum, etc. These can be accessed
|
29
|
+
# using the <tt>#terms</tt> methods or the term subset methods provided by
|
30
|
+
# the <tt>TermsList</tt> class (e.g. <tt>#profiles</tt>, <tt>#visible</tt>)
|
31
|
+
#
|
32
|
+
# Two classes inherit the <i>Calculation</i> class:
|
33
|
+
# * <i>PrototypeCalculation</i> : provides a templating for a specific calculation
|
34
|
+
# type with defined, but blank, terms (i.e. inputs, outputs, etc.)
|
35
|
+
#
|
36
|
+
# * <i>OngoingCalculation</i> : represents a particular calculation - possibly
|
37
|
+
# incomplete - which can be updated, submitted for calculation, and saved
|
38
|
+
#
|
39
|
+
class Calculation
|
40
|
+
|
41
|
+
public
|
42
|
+
|
43
|
+
# Symbol representing the unique, machine-readable name for <tt>self</tt>.
|
44
|
+
# Set a value by passing an argument. Retrieve a value by calling without
|
45
|
+
# an argument, e.g.,
|
46
|
+
#
|
47
|
+
# my_calculation.label :fuel
|
48
|
+
#
|
49
|
+
# my_calculation.label #=> :fuel
|
50
|
+
#
|
51
|
+
attr_property :label
|
52
|
+
|
53
|
+
# String representing a human-readable name for <tt>self</tt>. Set a
|
54
|
+
# value by passing an argument. Retrieve a value by calling without an
|
55
|
+
# argument, e.g.,
|
56
|
+
#
|
57
|
+
# my_calculation.name 'Domestic fuel consumption'
|
58
|
+
#
|
59
|
+
# my_calculation.name #=> 'Domestic fuel consumption'
|
60
|
+
#
|
61
|
+
attr_property :name
|
62
|
+
|
63
|
+
# String representing the AMEE platform path to the data category which is
|
64
|
+
# associated with <tt>self</tt>. Set a value by passing an argument. Retrieve
|
65
|
+
# a value by calling without an argument, e.g.,
|
66
|
+
#
|
67
|
+
# my_calculation.path '/some/path/in/amee/'
|
68
|
+
#
|
69
|
+
# my_calculation.path #=> '/some/path/in/amee/'
|
70
|
+
#
|
71
|
+
attr_property :path
|
72
|
+
|
73
|
+
# String representing the AMEE platform path for the usage to be used by
|
74
|
+
# <tt>self</tt>, if defined. Set a value by passing an argument. Retrieve
|
75
|
+
# a value by calling without an argument, e.g.,
|
76
|
+
#
|
77
|
+
# my_calculation.fixed_usage 'byMass'
|
78
|
+
#
|
79
|
+
# my_calculation.fixed_usage #=> 'byMass'
|
80
|
+
#
|
81
|
+
attr_property :fixed_usage
|
82
|
+
|
83
|
+
# Calculations contain a list of "terms" of the base class <i>Term</i>,
|
84
|
+
# representing inputs, outputs, metadatum, etc. which are associated with
|
85
|
+
# <tt>self</tt>.
|
86
|
+
#
|
87
|
+
# Returns all associated terms as an instance of the <i>TermsList</i> class
|
88
|
+
#
|
89
|
+
def terms
|
90
|
+
TermsList.new(@contents.values)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Retrieve the terms associated with <tt>self</tt> as a hash from labels to terms.
|
94
|
+
attr_accessor :contents
|
95
|
+
|
96
|
+
# Shorthand method for retrieving the term assocaited with <tt>self</tt> which has a
|
97
|
+
# label matching <tt>sym</tt>
|
98
|
+
#
|
99
|
+
def [](sym)
|
100
|
+
@contents[sym.to_sym]
|
101
|
+
end
|
102
|
+
|
103
|
+
# Syntactic sugar to enable the return of a subset of associated terms according
|
104
|
+
# to their type or status (e.g. drills, profiles, set, unset, visible). See
|
105
|
+
# <i>TermsList::Selectors</i> for valid variants
|
106
|
+
#
|
107
|
+
TermsList::Selectors.each do |sel|
|
108
|
+
delegate sel,:to=>:terms
|
109
|
+
end
|
110
|
+
|
111
|
+
# Prettyprint a string representation of <tt>self</tt>, together with associated terms
|
112
|
+
def inspect
|
113
|
+
elements = {:label => label.inspect, :terms => terms.map{|t| "<#{t.class.name.demodulize} label:#{t.label}, value:#{t.value.inspect}>"}}
|
114
|
+
attr_list = elements.map {|k,v| "#{k}: #{v}" } * ', '
|
115
|
+
"<#{self.class.name} #{attr_list}>"
|
116
|
+
end
|
117
|
+
|
118
|
+
def initialize_copy(source)
|
119
|
+
super
|
120
|
+
@contents=ActiveSupport::OrderedHash.new
|
121
|
+
source.contents.each do |k,v|
|
122
|
+
@contents[k]=v.clone
|
123
|
+
@contents[k].parent=self
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Return a string representing the AMEE Explorer URL which is assocaited
|
128
|
+
# with <tt>self</tt>
|
129
|
+
#
|
130
|
+
def explorer_url
|
131
|
+
"http://explorer.amee.com/categories#{path}"
|
132
|
+
end
|
133
|
+
|
134
|
+
protected
|
135
|
+
|
136
|
+
def initialize
|
137
|
+
@contents=ActiveSupport::OrderedHash.new
|
138
|
+
end
|
139
|
+
|
140
|
+
# Methods which will be memoized at application start, as they do not
|
141
|
+
# change over application instance lifetime
|
142
|
+
#
|
143
|
+
AmeeMemoised=[:amee_data_category, :amee_item_definition, :amee_ivds,
|
144
|
+
:amee_return_values, :amee_usages]
|
145
|
+
|
146
|
+
# Return all the values of the memoized quantities
|
147
|
+
def saved_amee
|
148
|
+
AmeeMemoised.map{|x|instance_variable_get("@#{x.to_s}")}
|
149
|
+
end
|
150
|
+
|
151
|
+
# Save the memoized quantities
|
152
|
+
def save_amee(values)
|
153
|
+
AmeeMemoised.zip(values).each do |prop,val|
|
154
|
+
instance_variable_set("@#{prop.to_s}",val)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
# Return the global <i>AMEE::Connection</i> object. This is configured in
|
161
|
+
# /config/amee.yml
|
162
|
+
#
|
163
|
+
def connection
|
164
|
+
AMEE::DataAbstraction.connection
|
165
|
+
end
|
166
|
+
|
167
|
+
# Return the <i>AMEE::Data::Category</i> object associated with <tt>self</tt>
|
168
|
+
def amee_data_category
|
169
|
+
@amee_data_category||=AMEE::Data::Category.get(connection, "/data#{path}")
|
170
|
+
end
|
171
|
+
|
172
|
+
# Return the <i>AMEE::Admin::ItemDefinition</i> object associated with <tt>self</tt>
|
173
|
+
def amee_item_definition
|
174
|
+
@amee_item_definition||=amee_data_category.item_definition
|
175
|
+
end
|
176
|
+
|
177
|
+
# Return the <i>AMEE::Admin::ReturnValueDefinitionList</i> object associated
|
178
|
+
# with <tt>self</tt>. This represents each of the return value definitions which are
|
179
|
+
# associated with the calculation
|
180
|
+
#
|
181
|
+
def amee_return_values
|
182
|
+
@amee_return_values||=AMEE::Admin::ReturnValueDefinitionList.new(connection,amee_item_definition.uid)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Return the instance of <i>Term</i> class associated with <tt>self</tt> and contains
|
186
|
+
# a path attribute matching <tt>path</tt>, e.g.
|
187
|
+
#
|
188
|
+
# my_calculation.by_path('distance') #=> <AMEE::DataAbstraction::Profile ... >
|
189
|
+
#
|
190
|
+
# my_calculation.by_path('type') #=> <AMEE::DataAbstraction::Drill ... >
|
191
|
+
#
|
192
|
+
def by_path(path)
|
193
|
+
terms.detect { |v| v.path==path }
|
194
|
+
end
|
195
|
+
|
196
|
+
# Return the instance of <i>Drill</i> class associated with <tt>self</tt> and contains
|
197
|
+
# a path attribute matching <tt>path</tt>, e.g.
|
198
|
+
#
|
199
|
+
# my_calculation.by_path('type') #=> <AMEE::DataAbstraction::Drill ... >
|
200
|
+
#
|
201
|
+
def drill_by_path(path)
|
202
|
+
drills.detect { |v| v.path==path }
|
203
|
+
end
|
204
|
+
|
205
|
+
public
|
206
|
+
|
207
|
+
# Return the <i>AMEE::Admin::ItemValueDefinitionList</i> object associated
|
208
|
+
# with <tt>self</tt>. This represents each of the item value definitions which are
|
209
|
+
# associated with the calculation
|
210
|
+
#
|
211
|
+
def amee_ivds
|
212
|
+
@amee_ivds||=amee_item_definition.item_value_definition_list.select{|x|x.versions.include?("2.0")}
|
213
|
+
end
|
214
|
+
|
215
|
+
# Returns a String representing the AMEE platform path for the usage currently
|
216
|
+
# used by <tt>self</tt>. If not usage is defined, returns nil
|
217
|
+
#
|
218
|
+
# my_calculation.current_usage #=> 'byMass'
|
219
|
+
#
|
220
|
+
def current_usage
|
221
|
+
usages.empty? ? fixed_usage : usages.first.value
|
222
|
+
end
|
223
|
+
|
224
|
+
# Returns an Array containing the AMEE platform paths for all valid usage
|
225
|
+
# available to <tt>self</tt> according to those defined under #item_definition. If
|
226
|
+
# no usage(s) is defined, returns nil, e.g.
|
227
|
+
#
|
228
|
+
# my_calculation.amee_usages #=> [ 'byMass', 'byEnergy' ]
|
229
|
+
#
|
230
|
+
def amee_usages
|
231
|
+
@amee_usages||=amee_item_definition.usages
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Copyright (C) 2011 AMEE UK Ltd. - http://www.amee.com
|
2
|
+
# Released as Open Source Software under the BSD 3-Clause license. See LICENSE.txt for details.
|
3
|
+
|
4
|
+
# :title: Class: AMEE::DataAbstraction::CalculationSet
|
5
|
+
|
6
|
+
module AMEE
|
7
|
+
module DataAbstraction
|
8
|
+
|
9
|
+
# The <i>CalculationSet</i> class represents a collection of prototype
|
10
|
+
# calculations (of the class <i>ProtptypeCalculation</i>.
|
11
|
+
#
|
12
|
+
# Prototype calculations are contained within the @calculations instance variable
|
13
|
+
# ordered hash. Calculations can be added manually to the @calculations hash or
|
14
|
+
# initialized in place using the <tt>#calculation</tt> method which takes an
|
15
|
+
# options hash or block for specifying the prototype calculation properties.
|
16
|
+
#
|
17
|
+
# Typical usage is to initialize the <i>CalculationSet</i> and its daughter
|
18
|
+
# prototype calculations together using block syntax, thus:
|
19
|
+
#
|
20
|
+
# Calculations = CalculationSet.new {
|
21
|
+
#
|
22
|
+
# calculation {
|
23
|
+
# label :electricity
|
24
|
+
# path "/some/path/for/electricity"
|
25
|
+
# ...
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
# calculation {
|
29
|
+
# label :transport
|
30
|
+
# path "a/transport/path"
|
31
|
+
# ...
|
32
|
+
# }
|
33
|
+
#
|
34
|
+
# ...
|
35
|
+
# }
|
36
|
+
#
|
37
|
+
class CalculationSet
|
38
|
+
|
39
|
+
# Initialize a <i>CalculationSet</i> with a "DSL" block, i.e. a block to be
|
40
|
+
# evaluated in the context of the instantiated CalculationSet
|
41
|
+
#
|
42
|
+
def initialize(options={},&block)
|
43
|
+
@calculations=ActiveSupport::OrderedHash.new
|
44
|
+
@all_blocks=[]
|
45
|
+
@all_options={}
|
46
|
+
instance_eval(&block) if block
|
47
|
+
end
|
48
|
+
|
49
|
+
# Access the @calculations instance variable ordered hash. Keys are labels
|
50
|
+
# assocaited with each prototype calculation; values are the instantiated
|
51
|
+
# <i>PrototypeCalculation</i> objects
|
52
|
+
#
|
53
|
+
attr_accessor :calculations
|
54
|
+
|
55
|
+
# Shorthand method for returning the prototype calculation which is represented
|
56
|
+
# by a label matching <tt>sym</tt>
|
57
|
+
#
|
58
|
+
def [](sym)
|
59
|
+
@calculations[sym.to_sym]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Instantiate a <i>PrototypeCalculation</i> within this calculation set,
|
63
|
+
# initializing with the supplied DSL block to be evaluated in the context
|
64
|
+
# of the newly created calculation
|
65
|
+
#
|
66
|
+
def calculation(options={},&block)
|
67
|
+
new_content=PrototypeCalculation.new(options.merge(@all_options),&block)
|
68
|
+
@all_blocks.each {|all_block| new_content.instance_eval(&all_block) }
|
69
|
+
new_content.name new_content.label.to_s.humanize unless new_content.name
|
70
|
+
@calculations[new_content.label]=new_content
|
71
|
+
end
|
72
|
+
|
73
|
+
# Append the supplied block to the DSL block of ALL calculations in this
|
74
|
+
# calculation set. This is useful for configuration which is required
|
75
|
+
# across all calculations (e.g. overriding human readable names or adding
|
76
|
+
# globally applicable metadatum)
|
77
|
+
#
|
78
|
+
def all_calculations(options={},&dsl_block)
|
79
|
+
@all_blocks.push dsl_block
|
80
|
+
@all_options.merge(options)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Instantiate several prototype calculations, by loading each possible usage
|
84
|
+
# for the category with path given in <tt>apath</tt>.
|
85
|
+
#
|
86
|
+
# Each instantiated calculation is customised on the basis of the supplied
|
87
|
+
# DSL block. The usage is given as a parameter to the DSL block
|
88
|
+
#
|
89
|
+
def calculations_all_usages(apath,options={},&dsl_block)
|
90
|
+
dummycalc=PrototypeCalculation.new{path apath}
|
91
|
+
dummycalc.amee_usages.each do |usage|
|
92
|
+
calculation(options){
|
93
|
+
path apath
|
94
|
+
instance_exec(usage,&dsl_block)
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright (C) 2011 AMEE UK Ltd. - http://www.amee.com
|
2
|
+
# Released as Open Source Software under the BSD 3-Clause license. See LICENSE.txt for details.
|
3
|
+
|
4
|
+
# :title: Class: AMEE::DataAbstraction::Drill
|
5
|
+
|
6
|
+
module AMEE
|
7
|
+
module DataAbstraction
|
8
|
+
|
9
|
+
# Subclass of <tt>Input</tt> providing methods and attributes appropriate for
|
10
|
+
# representing AMEE drill down choices and selections specifically
|
11
|
+
#
|
12
|
+
class Drill < Input
|
13
|
+
|
14
|
+
public
|
15
|
+
|
16
|
+
# Returns <tt>true</tt> if the UI element of <tt>self</tt> is disabled.
|
17
|
+
# Otherwise, returns <tt>false</tt>.
|
18
|
+
#
|
19
|
+
# A drill is considered disabled if it either (1) explicitly set using the
|
20
|
+
# <tt>#disable!</tt> method; (2) has a <i>fixed</i> value; or (3) is not the
|
21
|
+
# next drill (because drill should be chosen in order).
|
22
|
+
#
|
23
|
+
def disabled?
|
24
|
+
super || (!set? && !next?)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Initialization of <i>Drill</i> objects follows that of the parent
|
28
|
+
# <i>Input</i> class. The <tt>interface</tt> attribute of <tt>self</tt> is
|
29
|
+
# set to <tt>:drop_down</tt> by default for <tt>Drill</tt> instances, but
|
30
|
+
# can be manually configured if required.
|
31
|
+
#
|
32
|
+
def initialize(options={},&block)
|
33
|
+
interface :drop_down
|
34
|
+
super
|
35
|
+
choice_validation_message
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Returns <tt>true</tt> if the value set for <tt>self</tt> is one of the
|
41
|
+
# available choices. Otherwise, returns <tt>false</tt>.
|
42
|
+
#
|
43
|
+
def valid?
|
44
|
+
super && (choices.include? value)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the list of available choices for <tt>self</tt>.
|
48
|
+
def choices
|
49
|
+
c=parent.amee_drill(:before=>label).choices
|
50
|
+
c.length==1 ? [value] : c #Intention is to get autodrilled, drill will result in a UID
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns <tt>true</tt> if <tt>self</tt> is the "first unset" drill, i.e.
|
54
|
+
# the one which should be set next
|
55
|
+
#
|
56
|
+
def next?
|
57
|
+
unset? && parent.drills.before(label).all?(&:set?)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|