require 'rgen/transformer' require 'rgen/ecore/ecore' require 'rgen/array_extensions' require 'xml_instantiator_test/simple_xmi_metamodel' class SimpleXmiToECore < RGen::Transformer include RGen::ECore class MapHelper def initialize(keyMethod,valueMethod,elements) @keyMethod, @valueMethod, @elements = keyMethod, valueMethod, elements end def [](key) return @elements.select{|e| e.send(@keyMethod) == key}.first.send(@valueMethod) rescue NoMethodError nil end end class TaggedValueHelper < MapHelper def initialize(element) super('tag','value',element.modelElement_taggedValue.taggedValue) end end # Do the actual transformation. # Input and output environment have to be provided to the transformer constructor. def transform trans(:class => SimpleXMIMetaModel::UML::Clazz) end transform SimpleXMIMetaModel::UML::Package, :to => EPackage do { :name => name, :eSuperPackage => trans(parent.parent.is_a?(SimpleXMIMetaModel::UML::Package) ? parent.parent : nil) } end transform SimpleXMIMetaModel::UML::Clazz, :to => EClass do { :name => name, :ePackage => trans(parent.parent.is_a?(SimpleXMIMetaModel::UML::Package) ? parent.parent : nil), :eStructuralFeatures => trans(classifier_feature.attribute + associationEnds), :eOperations => trans(classifier_feature.operation), :eSuperTypes => trans(generalizationsAsSubtype.supertypeClass), :eAnnotations => [ EAnnotation.new(:details => trans(modelElement_taggedValue.taggedValue)) ] } end transform SimpleXMIMetaModel::UML::TaggedValue, :to => EStringToStringMapEntry do { :key => tag, :value => value} end transform SimpleXMIMetaModel::UML::Attribute, :to => EAttribute do typemap = { "String" => EString, "boolean" => EBoolean, "int" => EInt, "long" => ELong, "float" => EFloat } tv = TaggedValueHelper.new(@current_object) { :name => name, :eType => typemap[tv['type']], :eAnnotations => [ EAnnotation.new(:details => trans(modelElement_taggedValue.taggedValue)) ] } end transform SimpleXMIMetaModel::UML::Operation, :to => EOperation do { :name => name } end transform SimpleXMIMetaModel::UML::AssociationEnd, :to => EReference, :if => :isReference do { :eType => trans(otherEnd.typeClass), :name => otherEnd.name, :eOpposite => trans(otherEnd), :lowerBound => (otherEnd.multiplicity || '0').split('..').first.to_i, :upperBound => (otherEnd.multiplicity || '1').split('..').last.gsub('*','-1').to_i, :containment => (aggregation == 'composite'), :eAnnotations => [ EAnnotation.new(:details => trans(modelElement_taggedValue.taggedValue)) ] } end method :isReference do otherEnd.isNavigable == 'true' || # composite assocations are bidirectional aggregation == 'composite' || otherEnd.aggregation == 'composite' end end