Included Modules

Class/Module Index [+]

Quicksearch

RGen::MetamodelBuilder::BuilderExtensions

This module provides methods which can be used to setup a metamodel element. The module is used to extend MetamodelBuilder::MMBase, i.e. add the module's methods as class methods.

MetamodelBuilder::MMBase should be used as a start for new metamodel elements. See MetamodelBuilder for an example.

Public Instance Methods

_abstract_class() click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 263
def _abstract_class
  @abstract || false
end
_add_metamodel_description(desc) click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 251
def _add_metamodel_description(desc) # :nodoc
  @metamodel_description ||= []
  @metamodelDescriptionByName ||= {}
  @metamodel_description.delete(@metamodelDescriptionByName[desc.value(:name)])
  @metamodel_description << desc 
  @metamodelDescriptionByName[desc.value(:name)] = desc
end
abstract() click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 259
def abstract
  @abstract = true
end
contains_many(target_role, target_class, own_role, raw_props={}, &block) click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 161
def contains_many(target_role, target_class, own_role, raw_props={}, &block)
  props1 = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
    :name=>target_role, :containment=>true})))
  props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({
    :name=>own_role, :upperBound=>1, :containment=>false}))
  FeatureBlockEvaluator.eval(block, props1, props2)
  _build_internal(props1, props2)
end
contains_many_uni(role, target_class=nil, raw_props={}, &block) click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 123
def contains_many_uni(role, target_class=nil, raw_props={}, &block)
  props = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
    :name=>role, :containment=>true})))
  raise "No opposite available" unless _oppositeProps(raw_props).empty?
  FeatureBlockEvaluator.eval(block, props)
  _build_internal(props)
end
contains_one(target_role, target_class, own_role, raw_props={}, &block) click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 238
def contains_one(target_role, target_class, own_role, raw_props={}, &block)
  props1 = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({
    :name=>target_role, :upperBound=>1, :containment=>true}))
  props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({
    :name=>own_role, :upperBound=>1, :containment=>false}))
  FeatureBlockEvaluator.eval(block, props1, props2)
  _build_internal(props1, props2)
end
contains_one_uni(role, target_class=nil, raw_props={}, &block) click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 115
def contains_one_uni(role, target_class=nil, raw_props={}, &block)
  props = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({
    :name=>role, :upperBound=>1, :containment=>true}))
  raise "No opposite available" unless _oppositeProps(raw_props).empty?
  FeatureBlockEvaluator.eval(block, props)
  _build_internal(props)
end
has_attr(role, target_class=nil, raw_props={}, &block) click to toggle source

Add an attribute which can hold a single value. 'role' specifies the name which is used to access the attribute. 'target_class' specifies the type of objects which can be held by this attribute. If no target class is given, String will be default.

This class method adds the following instance methods, where 'role' is to be replaced by the given role name:

class#role  # getter
class#role=(value)  # setter
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 48
def has_attr(role, target_class=nil, raw_props={}, &block)
  props = Intermediate::Attribute.new(target_class, _ownProps(raw_props).merge({
    :name=>role, :upperBound=>1}))
  raise "No opposite available" unless _oppositeProps(raw_props).empty?
  FeatureBlockEvaluator.eval(block, props)
  _build_internal(props)
end
has_many(role, target_class=nil, raw_props={}, &block) click to toggle source

Add an unidirectional many association. 'role' specifies the name which is used to access the attribute. 'target_class' is optional and can be used to fix the type of objects which can be referenced by this association.

This class method adds the following instance methods, where 'role' is to be replaced by the given role name:

class#addRole(value, index=-1)  
class#removeRole(value)
class#role  # getter, returns an array

Note that the first letter of the role name is turned into an uppercase for the add and remove methods.

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 107
def has_many(role, target_class=nil, raw_props={}, &block)
  props = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
    :name=>role, :containment=>false})))
  raise "No opposite available" unless _oppositeProps(raw_props).empty?
  FeatureBlockEvaluator.eval(block, props)
  _build_internal(props)
end
has_many_attr(role, target_class=nil, raw_props={}, &block) click to toggle source

Add an attribute which can hold multiple values. 'role' specifies the name which is used to access the attribute. 'target_class' specifies the type of objects which can be held by this attribute. If no target class is given, String will be default.

This class method adds the following instance methods, where 'role' is to be replaced by the given role name:

class#addRole(value, index=-1)  
class#removeRole(value)
class#role  # getter, returns an array
class#role= # setter, sets multiple values at once

Note that the first letter of the role name is turned into an uppercase for the add and remove methods.

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 69
def has_many_attr(role, target_class=nil, raw_props={}, &block)
  props = Intermediate::Attribute.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
    :name=>role})))
  raise "No opposite available" unless _oppositeProps(raw_props).empty?
  FeatureBlockEvaluator.eval(block, props)
  _build_internal(props)
end
has_one(role, target_class=nil, raw_props={}, &block) click to toggle source

Add a single unidirectional association. 'role' specifies the name which is used to access the association. 'target_class' specifies the type of objects which can be held by this association.

This class method adds the following instance methods, where 'role' is to be replaced by the given role name:

class#role  # getter
class#role=(value)  # setter
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 86
def has_one(role, target_class=nil, raw_props={}, &block)
  props = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({
    :name=>role, :upperBound=>1, :containment=>false}))
  raise "No opposite available" unless _oppositeProps(raw_props).empty?
  FeatureBlockEvaluator.eval(block, props)
  _build_internal(props)
end
inherited(c) click to toggle source
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 267
def inherited(c)
  c.send(:include, c.const_set(:ClassModule, Module.new))
  MetamodelBuilder::ConstantOrderHelper.classCreated(c)
end
many_to_many(target_role, target_class, own_role, raw_props={}, &block) click to toggle source

Add a bidirectional many-to-many association between two classes. The class this method is called on is refered to as own_class in the following.

Instances of own_class can use 'own_role' to access many associated instances of type 'target_class'. Instances of 'target_class' can use 'target_role' to access many associated instances of own_class.

This class method adds the following instance methods where 'ownRole' and 'targetRole' are to be replaced by the given role names:

own_class#addOwnRole(value, index=-1)
own_class#removeOwnRole(value)
own_class#ownRole
target_class#addTargetRole
target_class#removeTargetRole=(value)
target_class#targetRole

Note that the first letter of the role name is turned into an uppercase for the add and remove methods.

When an element is added on either side, this element also receives the element is is added to as a new element.

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 202
def many_to_many(target_role, target_class, own_role, raw_props={}, &block)
  props1 = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
    :name=>target_role, :containment=>false})))
  props2 = Intermediate::Reference.new(self, _setManyUpperBound(_oppositeProps(raw_props).merge({
    :name=>own_role, :containment=>false})))
  FeatureBlockEvaluator.eval(block, props1, props2)
  _build_internal(props1, props2)
end
many_to_one(target_role, target_class, own_role, raw_props={}, &block) click to toggle source

This is the inverse of one_to_many provided for convenience.

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 171
def many_to_one(target_role, target_class, own_role, raw_props={}, &block)
  props1 = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({
    :name=>target_role, :upperBound=>1, :containment=>false}))
  props2 = Intermediate::Reference.new(self, _setManyUpperBound(_oppositeProps(raw_props).merge({
    :name=>own_role, :containment=>false})))
  FeatureBlockEvaluator.eval(block, props1, props2)
  _build_internal(props1, props2)
end
one_to_many(target_role, target_class, own_role, raw_props={}, &block) click to toggle source

Add a bidirectional one-to-many association between two classes. The class this method is called on is refered to as own_class in the following.

Instances of own_class can use 'own_role' to access many associated instances of type 'target_class'. Instances of 'target_class' can use 'target_role' to access one associated instance of own_class.

This class method adds the following instance methods where 'ownRole' and 'targetRole' are to be replaced by the given role names:

own_class#addOwnRole(value, index=-1)
own_class#removeOwnRole(value)
own_class#ownRole
target_class#targetRole
target_class#targetRole=(value)

Note that the first letter of the role name is turned into an uppercase for the add and remove methods.

When an element is added/set on either side, this element also receives the element is is added to as a new element.

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 152
def one_to_many(target_role, target_class, own_role, raw_props={}, &block)
  props1 = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
    :name=>target_role, :containment=>false})))
  props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({
    :name=>own_role, :upperBound=>1, :containment=>false}))
  FeatureBlockEvaluator.eval(block, props1, props2)
  _build_internal(props1, props2)
end
one_to_one(target_role, target_class, own_role, raw_props={}, &block) click to toggle source

Add a bidirectional one-to-one association between two classes. The class this method is called on is refered to as own_class in the following.

Instances of own_class can use 'own_role' to access one associated instance of type 'target_class'. Instances of 'target_class' can use 'target_role' to access one associated instance of own_class.

This class method adds the following instance methods where 'ownRole' and 'targetRole' are to be replaced by the given role names:

own_class#ownRole
own_class#ownRole=(value)
target_class#targetRole
target_class#targetRole=(value)

When an element is set on either side, this element also receives the element is is added to as the new element.

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 229
def one_to_one(target_role, target_class, own_role, raw_props={}, &block)
  props1 = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({
    :name=>target_role, :upperBound=>1, :containment=>false}))
  props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({
    :name=>own_role, :upperBound=>1, :containment=>false}))
  FeatureBlockEvaluator.eval(block, props1, props2)
  _build_internal(props1, props2)
end

Protected Instance Methods

_build_internal(props1, props2=nil) click to toggle source

Central builder method

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 276
def _build_internal(props1, props2=nil)
  _add_metamodel_description(props1)
  if props1.many?
    _build_many_methods(props1, props2)
  else
    _build_one_methods(props1, props2)
  end
  if props2
    # this is a bidirectional reference
    props1.opposite, props2.opposite = props2, props1
    other_class = props1.impl_type      
    other_class._add_metamodel_description(props2)
    raise "Internal error: second description must be a reference description"          unless props2.reference?
    if props2.many?
      other_class._build_many_methods(props2, props1)
    else
      other_class._build_one_methods(props2, props1)
    end
  end
end
_build_many_methods(props, other_props=nil) click to toggle source

To-Many association methods

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 362
def _build_many_methods(props, other_props=nil)
  name = props.value(:name)
  other_role = other_props && other_props.value(:name)

  if props.value(:derived)
    build_derived_method(name, props, :many)
  else
    @@many_read_builder ||= ERB.new               def get<%= firstToUpper(name) %>          ( @<%= name %> ? @<%= name %>.dup : [] )        end        <% if name != "class" %>          alias <%= name %> get<%= firstToUpper(name) %>        <% end %>              
    self::ClassModule.module_eval(@@many_read_builder.result(binding))
  end
  
  if props.value(:changeable)
    @@many_write_builder ||= ERB.new             def add<%= firstToUpper(name) %>(val, index=-1)          @<%= name %> = [] unless @<%= name %>          return if val.nil? || (@<%= name %>.any?{|e| e.object_id == val.object_id} && (val.is_a?(MMBase) || val.is_a?(MMGeneric)))          <%= type_check_code("val", props) %>          @<%= name %>.insert(index, val)          <% if other_role %>            val._register<%= firstToUpper(other_role) %>(self) unless val.is_a?(MMGeneric)          <% end %>        end                def remove<%= firstToUpper(name) %>(val)          @<%= name %> = [] unless @<%= name %>          @<%= name %>.each_with_index do |e,i|            if e.object_id == val.object_id              @<%= name %>.delete_at(i)              <% if other_role %>                val._unregister<%= firstToUpper(other_role) %>(self) unless val.is_a?(MMGeneric)              <% end %>              return            end          end            end                def set<%= firstToUpper(name) %>(val)          return if val.nil?          raise _assignmentTypeError(self, val, Enumerable) unless val.is_a? Enumerable          get<%= firstToUpper(name) %>.each {|e|            remove<%= firstToUpper(name) %>(e)          }          val.each {|v|            add<%= firstToUpper(name) %>(v)          }        end        alias <%= name %>= set<%= firstToUpper(name) %>                def _register<%= firstToUpper(name) %>(val)          @<%= name %> = [] unless @<%= name %>          @<%= name %>.push val        end        def _unregister<%= firstToUpper(name) %>(val)          @<%= name %>.delete val        end        
    self::ClassModule.module_eval(@@many_write_builder.result(binding))
  end    
      
end
_build_one_methods(props, other_props=nil) click to toggle source

To-One association methods

# File lib/rgen/metamodel_builder/builder_extensions.rb, line 300
def _build_one_methods(props, other_props=nil)
  name = props.value(:name)
  other_role = other_props && other_props.value(:name)

  if props.value(:derived)
    build_derived_method(name, props, :one)
  else
    @@one_read_builder ||= ERB.new               def get<%= firstToUpper(name) %>          <% if !props.reference? && props.value(:defaultValueLiteral) %>            <% defVal = props.value(:defaultValueLiteral) %>            <% check_default_value_literal(defVal, props) %>            <% defVal = '"'+defVal+'"' if props.impl_type == String %>            <% defVal = ':'+defVal if props.impl_type.is_a?(DataTypes::Enum) && props.impl_type != DataTypes::Boolean %>            @<%= name %>.nil? ? <%= defVal %> : @<%= name %>          <% else %>            @<%= name %>          <% end %>        end        <% if name != "class" %>          alias <%= name %> get<%= firstToUpper(name) %>        <% end %>
    self::ClassModule.module_eval(@@one_read_builder.result(binding))
  end
  
  if props.value(:changeable)
    @@one_write_builder ||= ERB.new                 def set<%= firstToUpper(name) %>(val)          return if val == @<%= name %>          <%= type_check_code("val", props) %>          oldval = @<%= name %>          @<%= name %> = val          <% if other_role %>            oldval._unregister<%= firstToUpper(other_role) %>(self) unless oldval.nil? || oldval.is_a?(MMGeneric)            val._register<%= firstToUpper(other_role) %>(self) unless val.nil? || val.is_a?(MMGeneric)          <% end %>        end         alias <%= name %>= set<%= firstToUpper(name) %>        def _register<%= firstToUpper(name) %>(val)          <% if other_role %>            @<%= name %>._unregister<%= firstToUpper(other_role) %>(self) unless @<%= name %>.nil? || @<%= name %>.is_a?(MMGeneric)          <% end %>          @<%= name %> = val        end                def _unregister<%= firstToUpper(name) %>(val)          @<%= name %> = nil        end        
    self::ClassModule.module_eval(@@one_write_builder.result(binding))

  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.