class RGen::ModelBuilder::ReferenceResolver
Constants
- ResolverJob
Public Class Methods
new()
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 23 def initialize @jobs = [] @elementName = {} end
Public Instance Methods
addJob(job)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 28 def addJob(job) @jobs << job end
resolve(ns=[])
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 36 def resolve(ns=[]) @toplevelNamespace = ToplevelNamespace.new(ns) (@jobs || []).each_with_index do |job, i| target = resolveReference(job.namespace || @toplevelNamespace, job.string.split(".")) raise ResolverException.new("Can not resolve reference #{job.string}") unless target if job.reference.many job.receiver.addGeneric(job.reference.name, target) else job.receiver.setGeneric(job.reference.name, target) end end end
setElementName(element, name)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 32 def setElementName(element, name) @elementName[element] = name end
Private Instance Methods
containmentRefs(element)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 138 def containmentRefs(element) @containmentRefs ||= {} @containmentRefs[element.class] ||= eAllReferences(element).select{|r| r.containment} end
eAllReferences(element)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 148 def eAllReferences(element) @eAllReferences ||= {} @eAllReferences[element.class] ||= element.class.ecore.eAllReferences end
elementChildren(element)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 120 def elementChildren(element) @elementChildren ||= {} return @elementChildren[element] if @elementChildren[element] children = containmentRefs(element).collect do |r| element.getGeneric(r.name) end.flatten.compact @elementChildren[element] = children end
elementName(element)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 116 def elementName(element) @elementName[element] end
elementParents(element)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 129 def elementParents(element) @elementParents ||= {} return @elementParents[element] if @elementParents[element] parents = parentRefs(element).collect do |r| element.getGeneric(r.name) end.flatten.compact @elementParents[element] = parents end
namespaceElementByName(namespace, name)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 73 def namespaceElementByName(namespace, name) @namespaceElementsByName ||= {} return @namespaceElementsByName[namespace][name] if @namespaceElementsByName[namespace] hash = {} namespaceElements(namespace).each do |e| raise ResolverException.new("Multiple elements named #{elementName(e)} found in #{nsToS(namespace)}") if hash[elementName(e)] hash[elementName(e)] = e if elementName(e) end @namespaceElementsByName[namespace] = hash hash[name] end
namespaceElements(namespace)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 96 def namespaceElements(namespace) if namespace.is_a?(ToplevelNamespace) namespace.elements elsif namespace.class.respond_to?(:ecore) elementChildren(namespace) else raise ResolverException.new("Element #{nsToS(namespace)} can not be used as a namespace") end end
nsToS(namespace)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 106 def nsToS(namespace) if namespace.is_a?(ToplevelNamespace) "toplevel namespace" else result = namespace.class.name result += ":\"#{elementName(namespace)}\"" if elementName(namespace) result end end
parentNamespace(namespace)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 85 def parentNamespace(namespace) if namespace.class.respond_to?(:ecore) parents = elementParents(namespace) raise ResolverException.new("Element #{nsToS(namespace)} has multiple parents") \ if parents.size > 1 parents.first || @toplevelNamespace else nil end end def namespaceElements(namespace) if namespace.is_a?(ToplevelNamespace) namespace.elements elsif namespace.class.respond_to?(:ecore) elementChildren(namespace) else raise ResolverException.new("Element #{nsToS(namespace)} can not be used as a namespace") end end def nsToS(namespace) if namespace.is_a?(ToplevelNamespace) "toplevel namespace" else result = namespace.class.name result += ":\"#{elementName(namespace)}\"" if elementName(namespace) result end end def elementName(element) @elementName[element] end def elementChildren(element) @elementChildren ||= {} return @elementChildren[element] if @elementChildren[element] children = containmentRefs(element).collect do |r| element.getGeneric(r.name) end.flatten.compact @elementChildren[element] = children end def elementParents(element) @elementParents ||= {} return @elementParents[element] if @elementParents[element] parents = parentRefs(element).collect do |r| element.getGeneric(r.name) end.flatten.compact @elementParents[element] = parents end def containmentRefs(element) @containmentRefs ||= {} @containmentRefs[element.class] ||= eAllReferences(element).select{|r| r.containment} end def parentRefs(element) @parentRefs ||= {} @parentRefs[element.class] ||= eAllReferences(element).select{|r| r.eOpposite && r.eOpposite.containment} end def eAllReferences(element) @eAllReferences ||= {} @eAllReferences[element.class] ||= element.class.ecore.eAllReferences end end
parentRefs(element)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 143 def parentRefs(element) @parentRefs ||= {} @parentRefs[element.class] ||= eAllReferences(element).select{|r| r.eOpposite && r.eOpposite.containment} end
resolveReference(namespace, nameParts)
click to toggle source
TODO: if a reference can not be fully resolved, but a prefix can be found, the exception reported is that its first path element can not be found on toplevel
# File lib/rgen/model_builder/reference_resolver.rb, line 54 def resolveReference(namespace, nameParts) element = resolveReferenceDownwards(namespace, nameParts) if element.nil? && parentNamespace(namespace) element = resolveReference(parentNamespace(namespace), nameParts) end element end
resolveReferenceDownwards(namespace, nameParts)
click to toggle source
# File lib/rgen/model_builder/reference_resolver.rb, line 62 def resolveReferenceDownwards(namespace, nameParts) firstPart, *restParts = nameParts element = namespaceElementByName(namespace, firstPart) return nil unless element if restParts.size > 0 resolveReferenceDownwards(element, restParts) else element end end