rgen 0.4.1 → 0.4.2
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/CHANGELOG +7 -0
- data/lib/rgen/array_extensions.rb +11 -3
- data/lib/rgen/environment.rb +81 -12
- data/lib/rgen/metamodel_builder/builder_extensions.rb +27 -22
- data/lib/rgen/transformer.rb +5 -2
- data/test/environment_test.rb +56 -18
- data/test/metamodel_builder_test.rb +2 -1
- data/test/transformer_test.rb +33 -0
- metadata +48 -49
- data/lib/rgen/find_helper.rb +0 -68
    
        data/CHANGELOG
    CHANGED
    
    | @@ -50,3 +50,10 @@ | |
| 50 50 | 
             
            * Major performance improvement: AbstractXMLInstantiator optionally controls the garbage collector
         | 
| 51 51 | 
             
            * Major performance improvement: ERB templates are reused in metamodel_builder
         | 
| 52 52 | 
             
            * Added delete method to Environment
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            =0.4.2 (Mar 2nd, 2008)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            * Performance improvement: collection feature of array extension uses hashes now to speed up array union
         | 
| 57 | 
            +
            * Performance improvement: find on environment hashes elements by class
         | 
| 58 | 
            +
            * Extended Transformer to allow sharing of result maps between several Transformer instances
         | 
| 59 | 
            +
            * Bugfix: User defined upper bound values are no longer overwritten by -1 in all "many" metamodel builder methods
         | 
| @@ -11,13 +11,21 @@ class Array | |
| 11 11 |  | 
| 12 12 | 
             
            	def method_missing(m, *args)
         | 
| 13 13 | 
             
            		super unless size == 0 or compact.any?{|e| e.is_a? RGen::MetamodelBuilder::MMBase}
         | 
| 14 | 
            -
            		 | 
| 14 | 
            +
            		# use an array to build the result to achiev similar ordering
         | 
| 15 | 
            +
            		result = []
         | 
| 16 | 
            +
            		inResult = {}
         | 
| 17 | 
            +
            		compact.each do |e|
         | 
| 15 18 | 
             
            			if e.is_a? RGen::MetamodelBuilder::MMBase				
         | 
| 16 | 
            -
            				 | 
| 19 | 
            +
            				((o=e.send(m)).is_a?(Array) ? o : [o] ).each do |v|
         | 
| 20 | 
            +
            					next if inResult[v.object_id]
         | 
| 21 | 
            +
            					inResult[v.object_id] = true
         | 
| 22 | 
            +
            					result << v
         | 
| 23 | 
            +
            				end
         | 
| 17 24 | 
             
            			else
         | 
| 18 25 | 
             
            				raise StandardError.new("Trying to call a method on an array element not a RGen MMBase")
         | 
| 19 26 | 
             
            			end
         | 
| 20 | 
            -
            		 | 
| 27 | 
            +
            		end
         | 
| 28 | 
            +
            		result.compact
         | 
| 21 29 | 
             
            	end
         | 
| 22 30 |  | 
| 23 31 | 
             
            end
         | 
    
        data/lib/rgen/environment.rb
    CHANGED
    
    | @@ -1,47 +1,116 @@ | |
| 1 | 
            -
            require 'rgen/find_helper'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module RGen
         | 
| 4 2 |  | 
| 5 3 | 
             
            # An Environment is used to hold model elements.
         | 
| 6 4 | 
             
            #
         | 
| 7 5 | 
             
            class Environment
         | 
| 8 | 
            -
            	include RGen::FindHelper
         | 
| 9 6 |  | 
| 10 7 | 
             
            	def initialize
         | 
| 11 | 
            -
            		@elements =  | 
| 8 | 
            +
            		@elements = {}
         | 
| 9 | 
            +
            		@subClasses = {}
         | 
| 10 | 
            +
            		@subClassesUpdated = {}
         | 
| 12 11 | 
             
            	end
         | 
| 13 12 |  | 
| 14 13 | 
             
            	# Add a model element. Returns the environment so <code><<</code> can be chained.
         | 
| 15 14 | 
             
            	# 
         | 
| 16 15 | 
             
            	def <<(el)
         | 
| 17 | 
            -
            		 | 
| 16 | 
            +
            		clazz = el.class
         | 
| 17 | 
            +
            		@elements[clazz] ||= []
         | 
| 18 | 
            +
            		@elements[clazz] << el
         | 
| 19 | 
            +
            		updateSubClasses(clazz)
         | 
| 18 20 | 
             
            		self
         | 
| 19 21 | 
             
            	end
         | 
| 20 | 
            -
             | 
| 22 | 
            +
             | 
| 21 23 | 
             
            	# Removes model element from environment.
         | 
| 22 24 | 
             
            	def delete(el)
         | 
| 23 | 
            -
            		@elements. | 
| 25 | 
            +
            		return unless @elements[el.class]
         | 
| 26 | 
            +
            		@elements[el.class].delete(el)
         | 
| 24 27 | 
             
            	end
         | 
| 25 28 |  | 
| 26 29 | 
             
            	# Iterates each element
         | 
| 27 30 | 
             
            	#
         | 
| 28 31 | 
             
            	def each(&b)
         | 
| 29 | 
            -
            		@elements.each(&b)
         | 
| 32 | 
            +
            		@elements.values.flatten.each(&b)
         | 
| 30 33 | 
             
            	end
         | 
| 31 34 |  | 
| 32 35 | 
             
            	# Return the elements of the environment as an array
         | 
| 33 36 | 
             
            	#
         | 
| 34 37 | 
             
            	def elements
         | 
| 35 | 
            -
            		@elements. | 
| 38 | 
            +
            		@elements.values.flatten
         | 
| 36 39 | 
             
            	end
         | 
| 37 40 |  | 
| 38 41 | 
             
            	# This method can be used to instantiate a class and automatically put it into
         | 
| 39 42 | 
             
            	# the environment. The new instance is returned.
         | 
| 40 43 | 
             
            	#
         | 
| 41 44 | 
             
            	def new(clazz, *args)
         | 
| 42 | 
            -
            		 | 
| 43 | 
            -
            		 | 
| 45 | 
            +
            		obj = clazz.new(*args)
         | 
| 46 | 
            +
            		self << obj
         | 
| 47 | 
            +
            		obj
         | 
| 48 | 
            +
            	end
         | 
| 49 | 
            +
            	
         | 
| 50 | 
            +
            	# Finds and returns model elements in the environment.
         | 
| 51 | 
            +
            	# 
         | 
| 52 | 
            +
            	# The search description argument must be a hash specifying attribute/value pairs.
         | 
| 53 | 
            +
            	# Only model elements are returned which respond to the specified attribute methods
         | 
| 54 | 
            +
            	# and return the specified values as result of these attribute methods.
         | 
| 55 | 
            +
            	# 
         | 
| 56 | 
            +
            	# As a special hash key :class can be used to look for model elements of a specific
         | 
| 57 | 
            +
            	# class. In this case an array of possible classes can optionally be given.
         | 
| 58 | 
            +
            	# 
         | 
| 59 | 
            +
            	def find(desc)
         | 
| 60 | 
            +
            		result = []
         | 
| 61 | 
            +
            		classes = desc[:class] if desc[:class] and desc[:class].is_a?(Array)
         | 
| 62 | 
            +
            		classes = [ desc[:class] ] if !classes and desc[:class]
         | 
| 63 | 
            +
            		if classes
         | 
| 64 | 
            +
            			hashKeys = classesWithSubClasses(classes)
         | 
| 65 | 
            +
            		else
         | 
| 66 | 
            +
            			hashKeys = @elements.keys
         | 
| 67 | 
            +
            		end
         | 
| 68 | 
            +
            		hashKeys.each do |clazz|
         | 
| 69 | 
            +
            			next unless @elements[clazz]
         | 
| 70 | 
            +
            			@elements[clazz].each do |e|
         | 
| 71 | 
            +
            				failed = false
         | 
| 72 | 
            +
            				desc.each_pair { |k,v|
         | 
| 73 | 
            +
            					failed = true if k != :class and ( !e.respond_to?(k) or e.send(k) != v )
         | 
| 74 | 
            +
            				}
         | 
| 75 | 
            +
            				result << e unless failed
         | 
| 76 | 
            +
            			end
         | 
| 77 | 
            +
            		end
         | 
| 78 | 
            +
            		result
         | 
| 44 79 | 
             
            	end
         | 
| 45 | 
            -
            end
         | 
| 46 80 |  | 
| 81 | 
            +
            	private
         | 
| 82 | 
            +
            	
         | 
| 83 | 
            +
            	def updateSubClasses(clazz)
         | 
| 84 | 
            +
            		return if @subClassesUpdated[clazz]
         | 
| 85 | 
            +
            		if clazz.respond_to?( :ecore )
         | 
| 86 | 
            +
            			superClasses = clazz.ecore.eAllSuperTypes.collect{|c| c.instanceClass}
         | 
| 87 | 
            +
            		else
         | 
| 88 | 
            +
            			superClasses = superclasses(clazz)
         | 
| 89 | 
            +
            		end
         | 
| 90 | 
            +
            		superClasses.each do |c|
         | 
| 91 | 
            +
            			next if c == Object
         | 
| 92 | 
            +
            			@subClasses[c] ||= []
         | 
| 93 | 
            +
            			@subClasses[c] << clazz
         | 
| 94 | 
            +
            		end
         | 
| 95 | 
            +
            		@subClassesUpdated[clazz] = true
         | 
| 96 | 
            +
            	end	
         | 
| 97 | 
            +
            	
         | 
| 98 | 
            +
            	def classesWithSubClasses(classes)
         | 
| 99 | 
            +
            		result = classes
         | 
| 100 | 
            +
            		classes.each do |c|
         | 
| 101 | 
            +
            			result += @subClasses[c] if @subClasses[c]
         | 
| 102 | 
            +
            		end
         | 
| 103 | 
            +
            		result.uniq
         | 
| 104 | 
            +
            	end
         | 
| 105 | 
            +
            	
         | 
| 106 | 
            +
            	def superclasses(clazz)
         | 
| 107 | 
            +
            		if clazz == Object
         | 
| 108 | 
            +
            			[]
         | 
| 109 | 
            +
            		else
         | 
| 110 | 
            +
            			superclasses(clazz.superclass) << clazz.superclass
         | 
| 111 | 
            +
            		end
         | 
| 112 | 
            +
            	end
         | 
| 113 | 
            +
            	
         | 
| 114 | 
            +
            end
         | 
| 115 | 
            +
             | 
| 47 116 | 
             
            end
         | 
| @@ -76,8 +76,8 @@ module BuilderExtensions | |
| 76 76 | 
             
            	# for the add and remove methods.
         | 
| 77 77 | 
             
            	# 
         | 
| 78 78 | 
             
            	def has_many(role, target_class=nil, raw_props={}, &block)
         | 
| 79 | 
            -
            		props = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
         | 
| 80 | 
            -
            			:name=>role, : | 
| 79 | 
            +
            		props = ReferenceDescription.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
         | 
| 80 | 
            +
            			:name=>role, :containment=>false})))
         | 
| 81 81 | 
             
            		raise "No opposite available" unless _oppositeProps(raw_props).empty?
         | 
| 82 82 | 
             
            		FeatureBlockEvaluator.eval(block, props)
         | 
| 83 83 | 
             
            		_build_internal(props)
         | 
| @@ -92,8 +92,8 @@ module BuilderExtensions | |
| 92 92 | 
             
            	end
         | 
| 93 93 |  | 
| 94 94 | 
             
            	def contains_many_uni(role, target_class=nil, raw_props={}, &block)
         | 
| 95 | 
            -
            		props = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
         | 
| 96 | 
            -
            			:name=>role, : | 
| 95 | 
            +
            		props = ReferenceDescription.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
         | 
| 96 | 
            +
            			:name=>role, :containment=>true})))
         | 
| 97 97 | 
             
            		raise "No opposite available" unless _oppositeProps(raw_props).empty?
         | 
| 98 98 | 
             
            		FeatureBlockEvaluator.eval(block, props)
         | 
| 99 99 | 
             
            		_build_internal(props)
         | 
| @@ -121,8 +121,8 @@ module BuilderExtensions | |
| 121 121 | 
             
            	# is is added to as a new element.
         | 
| 122 122 | 
             
            	# 
         | 
| 123 123 | 
             
            	def one_to_many(target_role, target_class, own_role, raw_props={}, &block)
         | 
| 124 | 
            -
            		props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
         | 
| 125 | 
            -
            			:name=>target_role, : | 
| 124 | 
            +
            		props1 = ReferenceDescription.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
         | 
| 125 | 
            +
            			:name=>target_role, :containment=>false})))
         | 
| 126 126 | 
             
            		props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
         | 
| 127 127 | 
             
            			:name=>own_role, :upperBound=>1, :containment=>false}))
         | 
| 128 128 | 
             
            		FeatureBlockEvaluator.eval(block, props1, props2)
         | 
| @@ -130,8 +130,8 @@ module BuilderExtensions | |
| 130 130 | 
             
            	end
         | 
| 131 131 |  | 
| 132 132 | 
             
            	def contains_many(target_role, target_class, own_role, raw_props={}, &block)
         | 
| 133 | 
            -
            		props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
         | 
| 134 | 
            -
            			:name=>target_role, : | 
| 133 | 
            +
            		props1 = ReferenceDescription.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
         | 
| 134 | 
            +
            			:name=>target_role, :containment=>true})))
         | 
| 135 135 | 
             
            		props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
         | 
| 136 136 | 
             
            			:name=>own_role, :upperBound=>1, :containment=>false}))
         | 
| 137 137 | 
             
            		FeatureBlockEvaluator.eval(block, props1, props2)
         | 
| @@ -142,8 +142,8 @@ module BuilderExtensions | |
| 142 142 | 
             
            	def many_to_one(target_role, target_class, own_role, raw_props={}, &block)
         | 
| 143 143 | 
             
            		props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
         | 
| 144 144 | 
             
            			:name=>target_role, :upperBound=>1, :containment=>false}))
         | 
| 145 | 
            -
            		props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
         | 
| 146 | 
            -
            			:name=>own_role, : | 
| 145 | 
            +
            		props2 = ReferenceDescription.new(self, _setManyUpperBound(_oppositeProps(raw_props).merge({
         | 
| 146 | 
            +
            			:name=>own_role, :containment=>false})))
         | 
| 147 147 | 
             
            		FeatureBlockEvaluator.eval(block, props1, props2)
         | 
| 148 148 | 
             
            		_build_internal(props1, props2)
         | 
| 149 149 | 
             
            	end
         | 
| @@ -171,10 +171,10 @@ module BuilderExtensions | |
| 171 171 | 
             
            	# is is added to as a new element.
         | 
| 172 172 | 
             
            	# 
         | 
| 173 173 | 
             
            	def many_to_many(target_role, target_class, own_role, raw_props={}, &block)
         | 
| 174 | 
            -
            		props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
         | 
| 175 | 
            -
            			:name=>target_role, : | 
| 176 | 
            -
            		props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
         | 
| 177 | 
            -
            			:name=>own_role, : | 
| 174 | 
            +
            		props1 = ReferenceDescription.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({
         | 
| 175 | 
            +
            			:name=>target_role, :containment=>false})))
         | 
| 176 | 
            +
            		props2 = ReferenceDescription.new(self, _setManyUpperBound(_oppositeProps(raw_props).merge({
         | 
| 177 | 
            +
            			:name=>own_role, :containment=>false})))
         | 
| 178 178 | 
             
            		FeatureBlockEvaluator.eval(block, props1, props2)
         | 
| 179 179 | 
             
            		_build_internal(props1, props2)
         | 
| 180 180 | 
             
            	end
         | 
| @@ -413,17 +413,22 @@ module BuilderExtensions | |
| 413 413 |  | 
| 414 414 | 
             
            	def _ownProps(props)
         | 
| 415 415 | 
             
            	  Hash[*(props.select{|k,v| !(k.to_s =~ /^opposite_/)}.flatten)]
         | 
| 416 | 
            -
             | 
| 416 | 
            +
              end
         | 
| 417 417 |  | 
| 418 418 | 
             
            	def _oppositeProps(props)
         | 
| 419 | 
            -
             | 
| 420 | 
            -
             | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
                   end
         | 
| 425 | 
            -
                   r
         | 
| 419 | 
            +
                r = {}
         | 
| 420 | 
            +
            	  props.each_pair do |k,v|
         | 
| 421 | 
            +
                  if k.to_s =~ /^opposite_(.*)$/
         | 
| 422 | 
            +
                    r[$1.to_sym] = v
         | 
| 423 | 
            +
                  end
         | 
| 426 424 | 
             
                end
         | 
| 425 | 
            +
                r
         | 
| 426 | 
            +
              end
         | 
| 427 | 
            +
             | 
| 428 | 
            +
              def _setManyUpperBound(props)
         | 
| 429 | 
            +
                props[:upperBound] = -1 unless props[:upperBound].is_a?(Integer) && props[:upperBound] > 1
         | 
| 430 | 
            +
                props
         | 
| 431 | 
            +
              end
         | 
| 427 432 |  | 
| 428 433 | 
             
            end
         | 
| 429 434 |  | 
    
        data/lib/rgen/transformer.rb
    CHANGED
    
    | @@ -227,11 +227,14 @@ class Transformer | |
| 227 227 |  | 
| 228 228 | 
             
            	# Creates a new transformer
         | 
| 229 229 | 
             
            	# Optionally an input and output Environment can be specified.
         | 
| 230 | 
            +
              # If an elementMap is provided (normally a Hash) this map will be used to lookup 
         | 
| 231 | 
            +
              # and store transformation results. This way results can be predefined
         | 
| 232 | 
            +
              # and it is possible to have several transformers work on the same result map.
         | 
| 230 233 | 
             
            	# 
         | 
| 231 | 
            -
            	def initialize(env_in=nil, env_out=nil)
         | 
| 234 | 
            +
            	def initialize(env_in=nil, env_out=nil, elementMap=nil)
         | 
| 232 235 | 
             
            		@env_in = env_in
         | 
| 233 236 | 
             
            		@env_out = env_out
         | 
| 234 | 
            -
            		@transformer_results = {}
         | 
| 237 | 
            +
            		@transformer_results = elementMap || {}
         | 
| 235 238 | 
             
            		@transformer_jobs = []
         | 
| 236 239 | 
             
            	end
         | 
| 237 240 |  | 
    
        data/test/environment_test.rb
    CHANGED
    
    | @@ -2,6 +2,7 @@ $:.unshift File.join(File.dirname(__FILE__),"..","lib") | |
| 2 2 |  | 
| 3 3 | 
             
            require 'test/unit'
         | 
| 4 4 | 
             
            require 'rgen/environment'
         | 
| 5 | 
            +
            require 'rgen/metamodel_builder'
         | 
| 5 6 |  | 
| 6 7 | 
             
            class EnvironmentTest < Test::Unit::TestCase
         | 
| 7 8 |  | 
| @@ -11,7 +12,48 @@ class EnvironmentTest < Test::Unit::TestCase | |
| 11 12 |  | 
| 12 13 | 
             
            	class ModelSub < Model
         | 
| 13 14 | 
             
            	end
         | 
| 15 | 
            +
            	
         | 
| 16 | 
            +
            	class ClassSuperA < RGen::MetamodelBuilder::MMBase
         | 
| 17 | 
            +
            	end
         | 
| 18 | 
            +
            	
         | 
| 19 | 
            +
            	class ClassSuperB < RGen::MetamodelBuilder::MMBase
         | 
| 20 | 
            +
            	end
         | 
| 21 | 
            +
            	
         | 
| 22 | 
            +
            	class ClassC < RGen::MetamodelBuilder::MMMultiple(ClassSuperA, ClassSuperB)
         | 
| 23 | 
            +
            		has_attr 'name', String
         | 
| 24 | 
            +
            	end
         | 
| 25 | 
            +
            	
         | 
| 26 | 
            +
            	class ClassSubD < ClassC
         | 
| 27 | 
            +
            	end
         | 
| 28 | 
            +
            	
         | 
| 29 | 
            +
            	class ClassSubE < ClassC
         | 
| 30 | 
            +
            	end
         | 
| 14 31 |  | 
| 32 | 
            +
            	def test_find_mmbase
         | 
| 33 | 
            +
            		env = RGen::Environment.new
         | 
| 34 | 
            +
            		mA1 = env.new(ClassSuperA)
         | 
| 35 | 
            +
            		mB1 = env.new(ClassSuperB)
         | 
| 36 | 
            +
            		mD1 = env.new(ClassSubD, :name => "mD1")
         | 
| 37 | 
            +
            		mD2 = env.new(ClassSubD, :name => "mD2")
         | 
| 38 | 
            +
            		mE = env.new(ClassSubE, :name => "mE")
         | 
| 39 | 
            +
            		
         | 
| 40 | 
            +
            		resultA = env.find(:class => ClassSuperA)
         | 
| 41 | 
            +
            		assert_equal sortById([mA1,mD1,mD2,mE]), sortById(resultA)
         | 
| 42 | 
            +
            		resultNamedA = env.find(:class => ClassSuperA, :name => "mD1")
         | 
| 43 | 
            +
            		assert_equal sortById([mD1]), sortById(resultNamedA)
         | 
| 44 | 
            +
            		
         | 
| 45 | 
            +
            		resultB = env.find(:class => ClassSuperB)
         | 
| 46 | 
            +
            		assert_equal sortById([mB1,mD1,mD2,mE]), sortById(resultB)
         | 
| 47 | 
            +
            		resultNamedB = env.find(:class => ClassSuperB, :name => "mD1")
         | 
| 48 | 
            +
            		assert_equal sortById([mD1]), sortById(resultNamedB)
         | 
| 49 | 
            +
            		
         | 
| 50 | 
            +
            		resultC = env.find(:class => ClassC)
         | 
| 51 | 
            +
            		assert_equal sortById([mD1,mD2,mE]), sortById(resultC)
         | 
| 52 | 
            +
            		
         | 
| 53 | 
            +
            		resultD = env.find(:class => ClassSubD)
         | 
| 54 | 
            +
            		assert_equal sortById([mD1,mD2]), sortById(resultD)
         | 
| 55 | 
            +
            	end
         | 
| 56 | 
            +
            	
         | 
| 15 57 | 
             
            	def test_find
         | 
| 16 58 | 
             
            		m1 = Model.new
         | 
| 17 59 | 
             
            		m1.name = "M1"
         | 
| @@ -19,34 +61,30 @@ class EnvironmentTest < Test::Unit::TestCase | |
| 19 61 | 
             
            		m2.name = "M2"
         | 
| 20 62 | 
             
            		m3 = "justAString"
         | 
| 21 63 | 
             
            		env = RGen::Environment.new << m1 << m2 << m3
         | 
| 22 | 
            -
            		 | 
| 23 | 
            -
            		 | 
| 24 | 
            -
            		assertFind(idx, m1, m2, m3)
         | 
| 25 | 
            -
            	end
         | 
| 26 | 
            -
            	
         | 
| 27 | 
            -
            	def assertFind(context, m1, m2, m3)
         | 
| 28 | 
            -
            		result = context.find(:class => Model, :name => "M1")
         | 
| 64 | 
            +
            		
         | 
| 65 | 
            +
            		result = env.find(:class => Model, :name => "M1")
         | 
| 29 66 | 
             
            		assert result.is_a?(Array)
         | 
| 30 67 | 
             
            		assert_equal 1, result.size
         | 
| 31 68 | 
             
            		assert_equal m1, result.first
         | 
| 32 69 |  | 
| 33 | 
            -
            		result =  | 
| 70 | 
            +
            		result = env.find(:class => Model)
         | 
| 34 71 | 
             
            		assert result.is_a?(Array)
         | 
| 35 | 
            -
            		assert_equal  | 
| 36 | 
            -
            		assert_equal m1, result[0]
         | 
| 37 | 
            -
            		assert_equal m2, result[1]
         | 
| 72 | 
            +
            		assert_equal sortById([m1,m2]), sortById(result)
         | 
| 38 73 |  | 
| 39 | 
            -
            		result =  | 
| 74 | 
            +
            		result = env.find(:name => "M2")
         | 
| 40 75 | 
             
            		assert result.is_a?(Array)
         | 
| 41 76 | 
             
            		assert_equal 1, result.size
         | 
| 42 | 
            -
            		assert_equal m2, result | 
| 77 | 
            +
            		assert_equal m2, result.first		
         | 
| 43 78 |  | 
| 44 | 
            -
            		result =  | 
| 79 | 
            +
            		result = env.find(:class => [Model, String])
         | 
| 45 80 | 
             
            		assert result.is_a?(Array)
         | 
| 46 | 
            -
            		assert_equal  | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 81 | 
            +
            		assert_equal sortById([m1,m2,m3]), sortById(result)
         | 
| 82 | 
            +
            	end
         | 
| 83 | 
            +
            	
         | 
| 84 | 
            +
            	private
         | 
| 85 | 
            +
            	
         | 
| 86 | 
            +
            	def sortById(array)
         | 
| 87 | 
            +
            		array.sort{|a,b| a.object_id <=> b.object_id}
         | 
| 50 88 | 
             
            	end
         | 
| 51 89 |  | 
| 52 90 | 
             
            end
         | 
| @@ -144,7 +144,7 @@ class MetamodelBuilderTest < Test::Unit::TestCase | |
| 144 144 | 
             
              end
         | 
| 145 145 | 
             
              class ManyClass < RGen::MetamodelBuilder::MMBase
         | 
| 146 146 | 
             
              end
         | 
| 147 | 
            -
              OneClass.one_to_many 'manyClasses', ManyClass, 'oneClass'
         | 
| 147 | 
            +
              OneClass.one_to_many 'manyClasses', ManyClass, 'oneClass', :upperBound => 5
         | 
| 148 148 |  | 
| 149 149 | 
             
              def test_one_to_many
         | 
| 150 150 | 
             
                oc = OneClass.new
         | 
| @@ -178,6 +178,7 @@ class MetamodelBuilderTest < Test::Unit::TestCase | |
| 178 178 |  | 
| 179 179 | 
             
                assert_equal [], OneClass.ecore.eReferences.select{|r| r.many == false}
         | 
| 180 180 | 
             
                assert_equal ["manyClasses"], OneClass.ecore.eReferences.select{|r| r.many == true}.name
         | 
| 181 | 
            +
                assert_equal 5, OneClass.ecore.eReferences.find{|r| r.many == true}.upperBound
         | 
| 181 182 | 
             
                assert_equal ["oneClass"], ManyClass.ecore.eReferences.select{|r| r.many == false}.name
         | 
| 182 183 | 
             
                assert_equal [], ManyClass.ecore.eReferences.select{|r| r.many == true}
         | 
| 183 184 | 
             
              end
         | 
    
        data/test/transformer_test.rb
    CHANGED
    
    | @@ -112,6 +112,39 @@ class TransformerTest < Test::Unit::TestCase | |
| 112 112 | 
             
            		assert_equal env_out.elements.first, t.trans(from)
         | 
| 113 113 | 
             
            		assert_equal 1, t.modelInTrans_count
         | 
| 114 114 | 
             
            	end
         | 
| 115 | 
            +
              
         | 
| 116 | 
            +
              def test_transformer_chain
         | 
| 117 | 
            +
                from = ModelIn.new
         | 
| 118 | 
            +
                from.name = "Test1"
         | 
| 119 | 
            +
                from2 = ModelIn.new
         | 
| 120 | 
            +
                from2.name = "Test2"
         | 
| 121 | 
            +
                from3 = ModelIn.new
         | 
| 122 | 
            +
                from3.name = "Test3"
         | 
| 123 | 
            +
                env_out = RGen::Environment.new
         | 
| 124 | 
            +
                elementMap = {}
         | 
| 125 | 
            +
                t1 = MyTransformer.new(:env_in, env_out, elementMap)
         | 
| 126 | 
            +
            		assert t1.trans(from).is_a?(ModelOut)
         | 
| 127 | 
            +
            		assert_equal "Test1", t1.trans(from).name
         | 
| 128 | 
            +
            		assert_equal 1, t1.modelInTrans_count
         | 
| 129 | 
            +
                # modifying the element map means that following calls of +trans+ will be affected
         | 
| 130 | 
            +
                assert_equal( {from => t1.trans(from)}, elementMap )
         | 
| 131 | 
            +
                elementMap.merge!({from2 => :dummy})
         | 
| 132 | 
            +
                assert_equal :dummy, t1.trans(from2)
         | 
| 133 | 
            +
                # second transformer based on the element map of the first
         | 
| 134 | 
            +
                t2 = MyTransformer.new(:env_in, env_out, elementMap)
         | 
| 135 | 
            +
                # second transformer returns same objects
         | 
| 136 | 
            +
                assert_equal t1.trans(from).object_id, t2.trans(from).object_id
         | 
| 137 | 
            +
                assert_equal :dummy, t2.trans(from2)
         | 
| 138 | 
            +
                # and no transformer rule is evaluated at this point
         | 
| 139 | 
            +
            		assert_equal nil, t2.modelInTrans_count
         | 
| 140 | 
            +
                # now transform a new object in second transformer
         | 
| 141 | 
            +
            		assert t2.trans(from3).is_a?(ModelOut)
         | 
| 142 | 
            +
            		assert_equal "Test3", t2.trans(from3).name
         | 
| 143 | 
            +
            		assert_equal 1, t2.modelInTrans_count
         | 
| 144 | 
            +
                # the first transformer returns the same object without evaluation of a transformer rule
         | 
| 145 | 
            +
                assert_equal t1.trans(from3).object_id, t2.trans(from3).object_id
         | 
| 146 | 
            +
            		assert_equal 1, t1.modelInTrans_count
         | 
| 147 | 
            +
              end
         | 
| 115 148 |  | 
| 116 149 | 
             
            	def test_transformer_subclass
         | 
| 117 150 | 
             
            		from = ModelInSub.new
         | 
    
        metadata
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            -
            rubygems_version: 0.9. | 
| 2 | 
            +
            rubygems_version: 0.9.2
         | 
| 3 3 | 
             
            specification_version: 1
         | 
| 4 4 | 
             
            name: rgen
         | 
| 5 5 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 6 | 
            -
              version: 0.4. | 
| 7 | 
            -
            date:  | 
| 6 | 
            +
              version: 0.4.2
         | 
| 7 | 
            +
            date: 2008-03-02 00:00:00 +01:00
         | 
| 8 8 | 
             
            summary: Ruby Modelling and Generator Framework
         | 
| 9 9 | 
             
            require_paths: 
         | 
| 10 10 | 
             
            - lib
         | 
| @@ -30,59 +30,58 @@ authors: | |
| 30 30 | 
             
            - Martin Thiede
         | 
| 31 31 | 
             
            files: 
         | 
| 32 32 | 
             
            - lib/instantiators
         | 
| 33 | 
            -
            - lib/metamodels
         | 
| 34 | 
            -
            - lib/mmgen
         | 
| 35 | 
            -
            - lib/rgen
         | 
| 36 | 
            -
            - lib/transformers
         | 
| 37 33 | 
             
            - lib/instantiators/ea_instantiator.rb
         | 
| 34 | 
            +
            - lib/metamodels
         | 
| 38 35 | 
             
            - lib/metamodels/uml13_metamodel.rb
         | 
| 39 36 | 
             
            - lib/metamodels/uml13_metamodel_ext.rb
         | 
| 37 | 
            +
            - lib/mmgen
         | 
| 40 38 | 
             
            - lib/mmgen/metamodel_generator.rb
         | 
| 41 39 | 
             
            - lib/mmgen/mmgen.rb
         | 
| 42 40 | 
             
            - lib/mmgen/mm_ext
         | 
| 43 | 
            -
            - lib/mmgen/templates
         | 
| 44 41 | 
             
            - lib/mmgen/mm_ext/ecore_ext.rb
         | 
| 42 | 
            +
            - lib/mmgen/templates
         | 
| 45 43 | 
             
            - lib/mmgen/templates/annotations.tpl
         | 
| 46 44 | 
             
            - lib/mmgen/templates/metamodel_generator.tpl
         | 
| 45 | 
            +
            - lib/rgen
         | 
| 47 46 | 
             
            - lib/rgen/array_extensions.rb
         | 
| 48 47 | 
             
            - lib/rgen/auto_class_creator.rb
         | 
| 49 48 | 
             
            - lib/rgen/ecore
         | 
| 50 | 
            -
            - lib/rgen/environment.rb
         | 
| 51 | 
            -
            - lib/rgen/environment.rb.bak
         | 
| 52 | 
            -
            - lib/rgen/find_helper.rb
         | 
| 53 | 
            -
            - lib/rgen/instantiator
         | 
| 54 | 
            -
            - lib/rgen/metamodel_builder
         | 
| 55 | 
            -
            - lib/rgen/metamodel_builder.rb
         | 
| 56 | 
            -
            - lib/rgen/model_comparator.rb
         | 
| 57 | 
            -
            - lib/rgen/model_dumper.rb
         | 
| 58 | 
            -
            - lib/rgen/name_helper.rb
         | 
| 59 | 
            -
            - lib/rgen/serializer
         | 
| 60 | 
            -
            - lib/rgen/template_language
         | 
| 61 | 
            -
            - lib/rgen/template_language.rb
         | 
| 62 | 
            -
            - lib/rgen/transformer.rb
         | 
| 63 49 | 
             
            - lib/rgen/ecore/ecore.rb
         | 
| 64 50 | 
             
            - lib/rgen/ecore/ecore_instantiator.rb
         | 
| 65 51 | 
             
            - lib/rgen/ecore/ecore_transformer.rb
         | 
| 52 | 
            +
            - lib/rgen/environment.rb
         | 
| 53 | 
            +
            - lib/rgen/environment.rb.bak
         | 
| 54 | 
            +
            - lib/rgen/instantiator
         | 
| 66 55 | 
             
            - lib/rgen/instantiator/abstract_instantiator.rb
         | 
| 67 56 | 
             
            - lib/rgen/instantiator/abstract_xml_instantiator.rb
         | 
| 68 57 | 
             
            - lib/rgen/instantiator/default_xml_instantiator.rb
         | 
| 69 58 | 
             
            - lib/rgen/instantiator/ecore_xml_instantiator.rb
         | 
| 70 59 | 
             
            - lib/rgen/instantiator/nodebased_xml_instantiator.rb
         | 
| 71 60 | 
             
            - lib/rgen/instantiator/xmi11_instantiator.rb
         | 
| 61 | 
            +
            - lib/rgen/metamodel_builder
         | 
| 72 62 | 
             
            - lib/rgen/metamodel_builder/builder_extensions.rb
         | 
| 73 63 | 
             
            - lib/rgen/metamodel_builder/builder_runtime.rb
         | 
| 74 64 | 
             
            - lib/rgen/metamodel_builder/data_types.rb
         | 
| 75 65 | 
             
            - lib/rgen/metamodel_builder/intermediate
         | 
| 66 | 
            +
            - lib/rgen/metamodel_builder/intermediate/annotation.rb
         | 
| 76 67 | 
             
            - lib/rgen/metamodel_builder/metamodel_description.rb
         | 
| 77 68 | 
             
            - lib/rgen/metamodel_builder/mm_multiple.rb
         | 
| 78 69 | 
             
            - lib/rgen/metamodel_builder/module_extension.rb
         | 
| 79 | 
            -
            - lib/rgen/metamodel_builder | 
| 70 | 
            +
            - lib/rgen/metamodel_builder.rb
         | 
| 71 | 
            +
            - lib/rgen/model_comparator.rb
         | 
| 72 | 
            +
            - lib/rgen/model_dumper.rb
         | 
| 73 | 
            +
            - lib/rgen/name_helper.rb
         | 
| 74 | 
            +
            - lib/rgen/serializer
         | 
| 80 75 | 
             
            - lib/rgen/serializer/xmi20_serializer.rb
         | 
| 81 76 | 
             
            - lib/rgen/serializer/xml_serializer.rb
         | 
| 77 | 
            +
            - lib/rgen/template_language
         | 
| 82 78 | 
             
            - lib/rgen/template_language/directory_template_container.rb
         | 
| 83 79 | 
             
            - lib/rgen/template_language/output_handler.rb
         | 
| 84 80 | 
             
            - lib/rgen/template_language/template_container.rb
         | 
| 85 81 | 
             
            - lib/rgen/template_language/template_helper.rb
         | 
| 82 | 
            +
            - lib/rgen/template_language.rb
         | 
| 83 | 
            +
            - lib/rgen/transformer.rb
         | 
| 84 | 
            +
            - lib/transformers
         | 
| 86 85 | 
             
            - lib/transformers/uml13_to_ecore.rb
         | 
| 87 86 | 
             
            - test/array_extensions_test.rb
         | 
| 88 87 | 
             
            - test/ea_instantiator_test.rb
         | 
| @@ -90,33 +89,30 @@ files: | |
| 90 89 | 
             
            - test/environment_test.rb
         | 
| 91 90 | 
             
            - test/metamodel_builder_test.rb
         | 
| 92 91 | 
             
            - test/metamodel_roundtrip_test
         | 
| 93 | 
            -
            - test/metamodel_roundtrip_test.rb
         | 
| 94 | 
            -
            - test/output_handler_test.rb
         | 
| 95 | 
            -
            - test/rgen_test.rb
         | 
| 96 | 
            -
            - test/template_language_test
         | 
| 97 | 
            -
            - test/template_language_test.rb
         | 
| 98 | 
            -
            - test/testmodel
         | 
| 99 | 
            -
            - test/transformer_test.rb
         | 
| 100 | 
            -
            - test/xml_instantiator_test
         | 
| 101 | 
            -
            - test/xml_instantiator_test.rb
         | 
| 102 92 | 
             
            - test/metamodel_roundtrip_test/houseMetamodel.ecore
         | 
| 103 93 | 
             
            - test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb
         | 
| 104 94 | 
             
            - test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore
         | 
| 105 95 | 
             
            - test/metamodel_roundtrip_test/TestModel.rb
         | 
| 106 96 | 
             
            - test/metamodel_roundtrip_test/TestModel_Regenerated.rb
         | 
| 97 | 
            +
            - test/metamodel_roundtrip_test.rb
         | 
| 98 | 
            +
            - test/output_handler_test.rb
         | 
| 99 | 
            +
            - test/rgen_test.rb
         | 
| 100 | 
            +
            - test/template_language_test
         | 
| 107 101 | 
             
            - test/template_language_test/expected_result.txt
         | 
| 108 102 | 
             
            - test/template_language_test/templates
         | 
| 109 | 
            -
            - test/template_language_test/testout.txt
         | 
| 110 103 | 
             
            - test/template_language_test/templates/code
         | 
| 111 | 
            -
            - test/template_language_test/templates/content
         | 
| 112 | 
            -
            - test/template_language_test/templates/index
         | 
| 113 | 
            -
            - test/template_language_test/templates/root.tpl
         | 
| 114 104 | 
             
            - test/template_language_test/templates/code/array.tpl
         | 
| 105 | 
            +
            - test/template_language_test/templates/content
         | 
| 115 106 | 
             
            - test/template_language_test/templates/content/author.tpl
         | 
| 116 107 | 
             
            - test/template_language_test/templates/content/chapter.tpl
         | 
| 108 | 
            +
            - test/template_language_test/templates/index
         | 
| 117 109 | 
             
            - test/template_language_test/templates/index/c
         | 
| 118 | 
            -
            - test/template_language_test/templates/index/chapter.tpl
         | 
| 119 110 | 
             
            - test/template_language_test/templates/index/c/cmod.tpl
         | 
| 111 | 
            +
            - test/template_language_test/templates/index/chapter.tpl
         | 
| 112 | 
            +
            - test/template_language_test/templates/root.tpl
         | 
| 113 | 
            +
            - test/template_language_test/testout.txt
         | 
| 114 | 
            +
            - test/template_language_test.rb
         | 
| 115 | 
            +
            - test/testmodel
         | 
| 120 116 | 
             
            - test/testmodel/class_model_checker.rb
         | 
| 121 117 | 
             
            - test/testmodel/ea_testmodel.eap
         | 
| 122 118 | 
             
            - test/testmodel/ea_testmodel.xml
         | 
| @@ -124,38 +120,35 @@ files: | |
| 124 120 | 
             
            - test/testmodel/ecore_model_checker.rb
         | 
| 125 121 | 
             
            - test/testmodel/manual_testmodel.xml
         | 
| 126 122 | 
             
            - test/testmodel/object_model_checker.rb
         | 
| 123 | 
            +
            - test/transformer_test.rb
         | 
| 124 | 
            +
            - test/xml_instantiator_test
         | 
| 127 125 | 
             
            - test/xml_instantiator_test/simple_ecore_model_checker.rb
         | 
| 128 126 | 
             
            - test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb
         | 
| 129 127 | 
             
            - test/xml_instantiator_test/simple_xmi_metamodel.rb
         | 
| 130 128 | 
             
            - test/xml_instantiator_test/simple_xmi_to_ecore.rb
         | 
| 129 | 
            +
            - test/xml_instantiator_test.rb
         | 
| 131 130 | 
             
            - redist/xmlscan
         | 
| 132 131 | 
             
            - redist/xmlscan/ChangeLog
         | 
| 133 132 | 
             
            - redist/xmlscan/doc
         | 
| 134 | 
            -
            - redist/xmlscan/install.rb
         | 
| 135 | 
            -
            - redist/xmlscan/lib
         | 
| 136 | 
            -
            - redist/xmlscan/memo
         | 
| 137 | 
            -
            - redist/xmlscan/README
         | 
| 138 | 
            -
            - redist/xmlscan/samples
         | 
| 139 | 
            -
            - redist/xmlscan/test.rb
         | 
| 140 | 
            -
            - redist/xmlscan/tests
         | 
| 141 | 
            -
            - redist/xmlscan/THANKS
         | 
| 142 133 | 
             
            - redist/xmlscan/doc/changes.html
         | 
| 143 134 | 
             
            - redist/xmlscan/doc/changes.rd
         | 
| 144 135 | 
             
            - redist/xmlscan/doc/en
         | 
| 145 | 
            -
            - redist/xmlscan/doc/ja
         | 
| 146 | 
            -
            - redist/xmlscan/doc/src
         | 
| 147 136 | 
             
            - redist/xmlscan/doc/en/conformance.html
         | 
| 148 137 | 
             
            - redist/xmlscan/doc/en/conformance.rd
         | 
| 149 138 | 
             
            - redist/xmlscan/doc/en/manual.html
         | 
| 150 139 | 
             
            - redist/xmlscan/doc/en/manual.rd
         | 
| 140 | 
            +
            - redist/xmlscan/doc/ja
         | 
| 151 141 | 
             
            - redist/xmlscan/doc/ja/conformance.ja.html
         | 
| 152 142 | 
             
            - redist/xmlscan/doc/ja/conformance.ja.rd
         | 
| 153 143 | 
             
            - redist/xmlscan/doc/ja/manual.ja.html
         | 
| 154 144 | 
             
            - redist/xmlscan/doc/ja/manual.ja.rd
         | 
| 145 | 
            +
            - redist/xmlscan/doc/src
         | 
| 155 146 | 
             
            - redist/xmlscan/doc/src/conformance.rd.src
         | 
| 156 147 | 
             
            - redist/xmlscan/doc/src/langsplit.rb
         | 
| 157 148 | 
             
            - redist/xmlscan/doc/src/Makefile
         | 
| 158 149 | 
             
            - redist/xmlscan/doc/src/manual.rd.src
         | 
| 150 | 
            +
            - redist/xmlscan/install.rb
         | 
| 151 | 
            +
            - redist/xmlscan/lib
         | 
| 159 152 | 
             
            - redist/xmlscan/lib/xmlscan
         | 
| 160 153 | 
             
            - redist/xmlscan/lib/xmlscan/encoding.rb
         | 
| 161 154 | 
             
            - redist/xmlscan/lib/xmlscan/htmlscan.rb
         | 
| @@ -165,17 +158,17 @@ files: | |
| 165 158 | 
             
            - redist/xmlscan/lib/xmlscan/version.rb
         | 
| 166 159 | 
             
            - redist/xmlscan/lib/xmlscan/visitor.rb
         | 
| 167 160 | 
             
            - redist/xmlscan/lib/xmlscan/xmlchar.rb
         | 
| 161 | 
            +
            - redist/xmlscan/memo
         | 
| 168 162 | 
             
            - redist/xmlscan/memo/CONFORMANCE
         | 
| 169 163 | 
             
            - redist/xmlscan/memo/contentspec.ry
         | 
| 170 164 | 
             
            - redist/xmlscan/memo/PRODUCTIONS
         | 
| 165 | 
            +
            - redist/xmlscan/README
         | 
| 166 | 
            +
            - redist/xmlscan/samples
         | 
| 171 167 | 
             
            - redist/xmlscan/samples/chibixml.rb
         | 
| 172 168 | 
             
            - redist/xmlscan/samples/getxmlchar.rb
         | 
| 173 169 | 
             
            - redist/xmlscan/samples/rexml.rb
         | 
| 174 170 | 
             
            - redist/xmlscan/samples/xmlbench
         | 
| 175 | 
            -
            - redist/xmlscan/samples/xmlbench.rb
         | 
| 176 | 
            -
            - redist/xmlscan/samples/xmlconftest.rb
         | 
| 177 171 | 
             
            - redist/xmlscan/samples/xmlbench/parser
         | 
| 178 | 
            -
            - redist/xmlscan/samples/xmlbench/xmlbench-lib.rb
         | 
| 179 172 | 
             
            - redist/xmlscan/samples/xmlbench/parser/chibixml.rb
         | 
| 180 173 | 
             
            - redist/xmlscan/samples/xmlbench/parser/nqxml.rb
         | 
| 181 174 | 
             
            - redist/xmlscan/samples/xmlbench/parser/rexml.rb
         | 
| @@ -184,6 +177,11 @@ files: | |
| 184 177 | 
             
            - redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb
         | 
| 185 178 | 
             
            - redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb
         | 
| 186 179 | 
             
            - redist/xmlscan/samples/xmlbench/parser/xmlscan.rb
         | 
| 180 | 
            +
            - redist/xmlscan/samples/xmlbench/xmlbench-lib.rb
         | 
| 181 | 
            +
            - redist/xmlscan/samples/xmlbench.rb
         | 
| 182 | 
            +
            - redist/xmlscan/samples/xmlconftest.rb
         | 
| 183 | 
            +
            - redist/xmlscan/test.rb
         | 
| 184 | 
            +
            - redist/xmlscan/tests
         | 
| 187 185 | 
             
            - redist/xmlscan/tests/deftestcase.rb
         | 
| 188 186 | 
             
            - redist/xmlscan/tests/runtest.rb
         | 
| 189 187 | 
             
            - redist/xmlscan/tests/testall.rb
         | 
| @@ -194,6 +192,7 @@ files: | |
| 194 192 | 
             
            - redist/xmlscan/tests/testscanner.rb
         | 
| 195 193 | 
             
            - redist/xmlscan/tests/testxmlchar.rb
         | 
| 196 194 | 
             
            - redist/xmlscan/tests/visitor.rb
         | 
| 195 | 
            +
            - redist/xmlscan/THANKS
         | 
| 197 196 | 
             
            - README
         | 
| 198 197 | 
             
            - CHANGELOG
         | 
| 199 198 | 
             
            - MIT-LICENSE
         | 
    
        data/lib/rgen/find_helper.rb
    DELETED
    
    | @@ -1,68 +0,0 @@ | |
| 1 | 
            -
            module RGen
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module FindHelper
         | 
| 4 | 
            -
            	
         | 
| 5 | 
            -
            	# Finds and returns model elements in the environment.
         | 
| 6 | 
            -
            	# 
         | 
| 7 | 
            -
            	# The search description argument must be a hash specifying attribute/value pairs.
         | 
| 8 | 
            -
            	# Only model elements are returned which respond to the specified attribute methods
         | 
| 9 | 
            -
            	# and return the specified values as result of these attribute methods.
         | 
| 10 | 
            -
            	# 
         | 
| 11 | 
            -
            	# As a special hash key :class can be used to look for model elements of a specific
         | 
| 12 | 
            -
            	# class. In this case an array of possible classes can optionally be given.
         | 
| 13 | 
            -
            	# 
         | 
| 14 | 
            -
            	def find(desc)
         | 
| 15 | 
            -
            		result = []
         | 
| 16 | 
            -
            		classes = desc[:class] if desc[:class] and desc[:class].is_a?(Array)
         | 
| 17 | 
            -
            		classes = [ desc[:class] ] if !classes and desc[:class]
         | 
| 18 | 
            -
            		each {|e|
         | 
| 19 | 
            -
            			failed = false
         | 
| 20 | 
            -
            			failed = true if classes and !classes.any?{ |c| e.is_a?(c) }
         | 
| 21 | 
            -
            			desc.each_pair { |k,v|
         | 
| 22 | 
            -
            				failed = true if k != :class and ( !e.respond_to?(k) or e.send(k) != v )
         | 
| 23 | 
            -
            			}
         | 
| 24 | 
            -
            			result << e unless failed
         | 
| 25 | 
            -
            		}
         | 
| 26 | 
            -
            		result
         | 
| 27 | 
            -
            	end
         | 
| 28 | 
            -
            	
         | 
| 29 | 
            -
            	def findIndex(index_method)
         | 
| 30 | 
            -
            		index = FindIndex.new(index_method)
         | 
| 31 | 
            -
            		each { |e|
         | 
| 32 | 
            -
            			index.add(e)
         | 
| 33 | 
            -
            		}
         | 
| 34 | 
            -
            		index
         | 
| 35 | 
            -
            	end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            	class FindIndex
         | 
| 38 | 
            -
            	
         | 
| 39 | 
            -
            		def initialize(index_method)
         | 
| 40 | 
            -
            			@index_method = index_method.to_sym
         | 
| 41 | 
            -
            			@index = {}
         | 
| 42 | 
            -
            			@non_indexed = [].extend(FindHelper)
         | 
| 43 | 
            -
            		end
         | 
| 44 | 
            -
            		
         | 
| 45 | 
            -
            		def add(element)
         | 
| 46 | 
            -
            			if element.respond_to?(@index_method)
         | 
| 47 | 
            -
            				val = element.send(@index_method)
         | 
| 48 | 
            -
            				@index[val] ||= [].extend(FindHelper)
         | 
| 49 | 
            -
            				@index[val] << element
         | 
| 50 | 
            -
            			end
         | 
| 51 | 
            -
            			@non_indexed << element
         | 
| 52 | 
            -
            		end
         | 
| 53 | 
            -
            		
         | 
| 54 | 
            -
            		def find(desc)
         | 
| 55 | 
            -
            			if (desc.keys.include?(@index_method))
         | 
| 56 | 
            -
            				val = desc.delete(@index_method)		
         | 
| 57 | 
            -
            				return [] unless @index[val]
         | 
| 58 | 
            -
            				return @index[val].find(desc)
         | 
| 59 | 
            -
            			else
         | 
| 60 | 
            -
            				return @non_indexed.find(desc)
         | 
| 61 | 
            -
            			end
         | 
| 62 | 
            -
            		end
         | 
| 63 | 
            -
            		
         | 
| 64 | 
            -
            	end
         | 
| 65 | 
            -
            	
         | 
| 66 | 
            -
            end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
            end
         |