File: builder_runtime.rb

package info (click to toggle)
ruby-rgen 0.10.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,428 kB
  • sloc: ruby: 11,344; xml: 1,368; yacc: 72; makefile: 10
file content (181 lines) | stat: -rw-r--r-- 4,828 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# RGen Framework
# (c) Martin Thiede, 2006

require 'rgen/util/name_helper'

module RGen

module MetamodelBuilder

# This module is mixed into MetamodelBuilder::MMBase.
# The methods provided by this module are used by the methods generated
# by the class methods of MetamodelBuilder::BuilderExtensions
module BuilderRuntime
	include Util::NameHelper
	
	def is_a?(c)
    return super unless c.const_defined?(:ClassModule)
    kind_of?(c::ClassModule)
	end
	
	def addGeneric(role, value, index=-1)
		send("add#{firstToUpper(role.to_s)}",value, index)
	end
	
	def removeGeneric(role, value)
		send("remove#{firstToUpper(role.to_s)}",value)
	end
	
	def setGeneric(role, value)
		send("set#{firstToUpper(role.to_s)}",value)
	end

  def hasManyMethods(role)
    respond_to?("add#{firstToUpper(role.to_s)}")
  end

  def setOrAddGeneric(role, value)
    if hasManyMethods(role)
      addGeneric(role, value)
    else
      setGeneric(role, value)
    end
  end

  def setNilOrRemoveGeneric(role, value)
    if hasManyMethods(role)
      removeGeneric(role, value)
    else
      setGeneric(role, nil)
    end
  end

  def setNilOrRemoveAllGeneric(role)
    if hasManyMethods(role)
      setGeneric(role, [])
    else
      setGeneric(role, nil)
    end
  end

  alias getGeneric send

  def getGenericAsArray(role)
    result = getGeneric(role)
    if result.nil?
      []
    elsif result.is_a?(Array)
      result
    else
      [result]
    end
  end

  def eIsSet(role)
    eval("defined? @#{role}") != nil
  end

  def eUnset(role)
    if respond_to?("add#{firstToUpper(role.to_s)}")
      setGeneric(role, [])
    else
      setGeneric(role, nil)
    end
    remove_instance_variable("@#{role}")
  end

  def eContainer
    @_container
  end

  def eContainingFeature
    @_containing_feature_name
  end

  # returns the contained elements in no particular order
  def eContents
    if @_contained_elements
      @_contained_elements.dup
    else
      []
    end
  end

  # if a block is given, calls the block on every contained element in depth first order. 
  # if the block returns :prune, recursion will stop at this point.
  # 
  # BEWARE of concurrent modification of contained elements while iterating!
  # (adding/removing containers or contained elements)
  # if you need to do such modifications, use the variant without a block instead.
  #
  # if no block is given builds and returns a list of all contained elements.
  #
  def eAllContents(&block)
    if block
      if @_contained_elements
        @_contained_elements.each do |e|
          res = block.call(e)
          e.eAllContents(&block) if res != :prune
        end
      end
      nil
    else
      result = []
      if @_contained_elements
        @_contained_elements.each do |e|
          result << e
          result.concat(e.eAllContents)
        end
      end
      result
    end
  end

  def disconnectContainer
    eContainer.setNilOrRemoveGeneric(eContainingFeature, self) if eContainer
  end

  def _set_container(container, containing_feature_name)
    # if a new container is set, make sure to disconnect from the old one.
    # note that _set_container will never be called for the container and the role
    # which are currently set because the accessor methods in BuilderExtensions
    # block setting/adding a value which is already present.
    # (it may be called for the same container with a different role, a different container
    # with the same role and a different container with a different role, though)
    # this ensures, that disconnecting for the current container doesn't break
    # a new connection which has just been set up in the accessor methods.
    disconnectContainer if container
    @_container._remove_contained_element(self) if @_container
    container._add_contained_element(self) if container
    @_container = container
    @_containing_feature_name = containing_feature_name
  end

  def _add_contained_element(element)
    @_contained_elements ||= []
    @_contained_elements << element
  end

  def _remove_contained_element(element)
    @_contained_elements.delete(element) if @_contained_elements
  end

	def _assignmentTypeError(target, value, expected)
		text = ""
		if target
			targetId = target.class.name
			targetId += "(" + target.name + ")" if target.respond_to?(:name) and target.name
			text += "In #{targetId} : "
		end
		valueId = value.class.name
		valueId += "(" + value.name + ")" if value.respond_to?(:name) and value.name
		valueId += "(:" + value.to_s + ")" if value.is_a?(Symbol)
		text += "Can not use a #{valueId} where a #{expected} is expected"
		StandardError.new(text)
	end

end

end

end