Class: AMEE::DataAbstraction::CalculationSet

Inherits:
Object
  • Object
show all
Defined in:
lib/amee-data-abstraction/calculation_set.rb

Overview

The CalculationSet class represents a collection of prototype calculations (of the class ProtptypeCalculation.

Prototype calculations are contained within the @calculations instance variable ordered hash. Calculations can be added manually to the @calculations hash or initialized in place using the #calculation method which takes an options hash or block for specifying the prototype calculation properties.

Typical usage is to initialize the CalculationSet and its daughter prototype calculations together using block syntax, thus:

Calculations = CalculationSet.new {

  calculation {
    label :electricity
    path "/some/path/for/electricity"
    ...
  }

  calculation {
    label :transport
    path "a/transport/path"
    ...
  }

  ...
}

Constant Summary collapse

DEFAULT_RAILS_CONFIG_DIR =
"config/calculations"
@@sets =

Class variable holding all instantiated calculation sets keyed on the set name.

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options = {}, &block) ⇒ CalculationSet

Initialise a new Calculation set. Specify the name of the calculation set as the first argument. This name is used as the set key within the class variable @@sets hash.

Raises:

  • (ArgumentError)


127
128
129
130
131
132
133
134
135
136
# File 'lib/amee-data-abstraction/calculation_set.rb', line 127

def initialize(name,options={},&block)
  raise ArgumentError, "Calculation set must have a name" unless name
  @name = name
  @file = CalculationSet.find_config_file(options[:file]) if options[:file]
  @calculations = ActiveSupport::OrderedHash.new
  @all_blocks=[]
  @all_options={}
  instance_eval(&block) if block
  @@sets[@name.to_sym] = self
end

Instance Attribute Details

#calculationsObject

Returns the value of attribute calculations.



121
122
123
# File 'lib/amee-data-abstraction/calculation_set.rb', line 121

def calculations
  @calculations
end

#fileObject

Returns the value of attribute file.



121
122
123
# File 'lib/amee-data-abstraction/calculation_set.rb', line 121

def file
  @file
end

#nameObject

Returns the value of attribute name.



121
122
123
# File 'lib/amee-data-abstraction/calculation_set.rb', line 121

def name
  @name
end

Class Method Details

.find(name) ⇒ Object

Retrieve a calculation set on the basis of a configuration file name or relatiev/absolute file path. If configuration files are location within the default Rails location under ‘/config/calculations’ then the path and the .rb extenstion can be omitted from the name.



54
55
56
# File 'lib/amee-data-abstraction/calculation_set.rb', line 54

def self.find(name)
  @@sets[name.to_sym] or load_set(name)
end

.find_prototype_calculation(label) ⇒ Object

Find a specific prototype calculation instance without specifying the set to which it belongs.



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/amee-data-abstraction/calculation_set.rb', line 73

def self.find_prototype_calculation(label)
  # Make sure all sets are loaded first
  default_config_dir = defined?(::Rails) ? "#{::Rails.root}/#{DEFAULT_RAILS_CONFIG_DIR}" : DEFAULT_RAILS_CONFIG_DIR
  Dir.glob(default_config_dir + "/*.rb").each do |name|
    find(name)
  end
  # Then search them
  @@sets.each_pair do |name,set|
    set = find(name)
    return set[label] if set[label]
  end
  return nil
end

.regenerate_lock_file(name, output_path = nil) ⇒ Object

Regenerate a configuration lock file assocaited with the master configuration file name. Optionally set a custom path for the lock file as output_path, otherwise the lock file path and filename will be based upon the master file with the extension .lock.rb.



63
64
65
66
# File 'lib/amee-data-abstraction/calculation_set.rb', line 63

def self.regenerate_lock_file(name,output_path=nil)
  set = load_set(name, :lock => false)
  set.generate_lock_file(output_path)
end

.setsObject

Convenience method for accessing the @@sets class variable



45
46
47
# File 'lib/amee-data-abstraction/calculation_set.rb', line 45

def self.sets
  @@sets
end

Instance Method Details

#[](sym) ⇒ Object

Shorthand method for returning the prototype calculation which is represented by a label matching sym



141
142
143
# File 'lib/amee-data-abstraction/calculation_set.rb', line 141

def [](sym)
  @calculations[sym.to_sym]
end

#all_calculations(options = {}, &dsl_block) ⇒ Object

Append the supplied block to the DSL block of ALL calculations in this calculation set. This is useful for configuration which is required across all calculations (e.g. overriding human readable names or adding globally applicable metadatum)



161
162
163
164
# File 'lib/amee-data-abstraction/calculation_set.rb', line 161

def all_calculations(options={},&dsl_block)
  @all_blocks.push dsl_block
  @all_options.merge(options)
end

#calculation(options = {}, &block) ⇒ Object

Instantiate a PrototypeCalculation within this calculation set, initializing with the supplied DSL block to be evaluated in the context of the newly created calculation



149
150
151
152
153
154
# File 'lib/amee-data-abstraction/calculation_set.rb', line 149

def calculation(options={},&block)
  new_content=PrototypeCalculation.new(options.merge(@all_options),&block)
  @all_blocks.each {|all_block| new_content.instance_eval(&all_block) }
  new_content.name new_content.label.to_s.humanize unless new_content.name
  @calculations[new_content.label]=new_content
end

#calculations_all_usages(apath, options = {}, &dsl_block) ⇒ Object

Instantiate several prototype calculations, by loading each possible usage for the category with path given in apath.

Each instantiated calculation is customised on the basis of the supplied DSL block. The usage is given as a parameter to the DSL block



172
173
174
175
176
177
178
179
180
181
# File 'lib/amee-data-abstraction/calculation_set.rb', line 172

def calculations_all_usages(apath,options={},&dsl_block)
  dummycalc=PrototypeCalculation.new{path apath}
  
  dummycalc.amee_usages.each do |usage|
    calculation(options){
      path apath
      instance_exec(usage,&dsl_block)
    }
  end
end

#config_path(options = {}) ⇒ Object

Returns the path to the configuration file for self. If a .lock file exists, this takes precedence, otherwise the master config file described by the #file attribute is returned. This arrangement can be overridden by passing :lock => false



188
189
190
191
# File 'lib/amee-data-abstraction/calculation_set.rb', line 188

def config_path(options={})
  options[:lock] = true unless options[:lock] == false
  lock_file_exists? && options[:lock] ? lock_file_path : @file
end

#generate_lock_file(output_path = nil) ⇒ Object

Generates a lock file for the calcuation set configuration. If no argument is provided the, the lock file is generated using the filename and path described by the #lock_file_path method. If a custom output location is required, this can be provided optionally as an argument.



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/amee-data-abstraction/calculation_set.rb', line 210

def generate_lock_file(output_path=nil)
  file = output_path || lock_file_path or raise ArgumentError,
    "No path for lock file known. Either set path for the master config file using the #file accessor method or provide as an argument"
  string = ""
  @calculations.values.each do |prototype_calculation|
    string += "calculation {\n\n"
    string += "  name \"#{prototype_calculation.name}\"\n"
    string += "  label :#{prototype_calculation.label}\n"
    string += "  path \"#{prototype_calculation.path}\"\n\n"
    prototype_calculation.terms.each do |term|
      string += "  #{term.class.to_s.split("::").last.downcase} {\n"
      string += "    name \"#{term.name}\"\n" unless term.name.blank?
      string += "    label :#{term.label}\n" unless term.label.blank?
      string += "    path \"#{term.path}\"\n" unless term.path.blank?
      string += "    value \"#{term.value}\"\n" unless term.value.blank?

      if term.is_a?(AMEE::DataAbstraction::Input)
        string += "    fixed \"#{term.value}\"\n" if term.fixed? && !term.value.blank?
        if term.is_a?(AMEE::DataAbstraction::Drill)
          string += "    choices \"#{term.choices.join('","')}\"\n" if term.instance_variable_defined?("@choices")  && !term.choices.blank?
        elsif term.is_a?(AMEE::DataAbstraction::Profile)
          string += "    choices [\"#{term.choices.join('","')}\"]\n" if term.instance_variable_defined?("@choices")  && !term.choices.blank?
        end
        string += "    optional!\n" if term.optional?
      end

      string += "    default_unit :#{term.default_unit.label}\n" unless term.default_unit.blank?
      string += "    default_per_unit :#{term.default_per_unit.label}\n" unless term.default_per_unit.blank?
      string += "    alternative_units :#{term.alternative_units.map(&:label).join(', :')}\n" unless term.alternative_units.blank?
      string += "    alternative_per_units :#{term.alternative_per_units.map(&:label).join(', :')}\n" unless term.alternative_per_units.blank?
      string += "    unit :#{term.unit.label}\n" unless term.unit.blank?
      string += "    per_unit :#{term.per_unit.label}\n" unless term.per_unit.blank?
      string += "    type :#{term.type}\n" unless term.type.blank?
      string += "    interface :#{term.interface}\n" unless term.interface.blank?
      string += "    note \"#{term.note}\"\n" unless term.note.blank?
      string += "    disable!\n" if !term.is_a?(AMEE::DataAbstraction::Drill) && term.disabled?
      string += "    hide!\n" if term.hidden?
      string += "  }\n\n"
    end
    string += "}\n\n"
  end
  File.open(file,'w') { |f| f.write string }
end

#lock_file_exists?Boolean

Returns true if a configuration lock file exists. Otherwise, returns false.

Returns:

  • (Boolean)


201
202
203
# File 'lib/amee-data-abstraction/calculation_set.rb', line 201

def lock_file_exists?
  File.exists?(lock_file_path)
end

#lock_file_pathObject

Returns the path to the configuration lock file



194
195
196
# File 'lib/amee-data-abstraction/calculation_set.rb', line 194

def lock_file_path
  @file.gsub(".rb",".lock.rb") rescue nil
end