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.
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 263 def _abstract_class @abstract || false end
# 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
# File lib/rgen/metamodel_builder/builder_extensions.rb, line 259 def abstract @abstract = true end
# 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
# 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
# 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
# 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
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
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
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
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
# 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
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
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
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
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
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
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
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
Generated with the Darkfish Rdoc Generator 2.