File: uml13_to_ecore.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 (127 lines) | stat: -rw-r--r-- 4,549 bytes parent folder | download | duplicates (11)
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
require 'metamodels/uml13_metamodel'
require 'rgen/transformer'
require 'rgen/ecore/ecore'
require 'rgen/array_extensions'

class UML13ToECore < RGen::Transformer
  include RGen::ECore

  # Options:
  #
  # :reference_filter:
  #   a proc which receives an AssociationEnd or a Dependency and should return
  #   true or false, depending on if a referece should be created for it or not
  #
  def initialize(*args)
    options = {}
    if args.last.is_a?(Hash)
      options = args.pop
    end
    @reference_filter = options[:reference_filter] || proc do |e|
      if e.is_a?(UML13::AssociationEnd)
        otherEnd = e.association.connection.find{|ae| ae != e}
        otherEnd.name && otherEnd.name.size > 0
      else
        false
      end
    end
    super(*args)
  end

  def transform
    trans(:class => UML13::Class)
  end

  transform UML13::Model, :to => EPackage do
      trans(ownedClassOrPackage)
    { :name => name && name.strip }
  end
    
  transform UML13::Package, :to => EPackage do
      trans(ownedClassOrPackage)
    { :name => name && name.strip, 
      :eSuperPackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil) }
  end
  
  method :ownedClassOrPackage do
   ownedElement.select{|e| e.is_a?(UML13::Package) || e.is_a?(UML13::Class)}
  end
  
  transform UML13::Class, :to => EClass do
    { :name => name && name.strip,
      :abstract => isAbstract,
      :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil),
      :eStructuralFeatures => trans(feature.select{|f| f.is_a?(UML13::Attribute)} + 
        associationEnd + clientDependency),
      :eOperations => trans(feature.select{|f| f.is_a?(UML13::Operation)}),
      :eSuperTypes =>  trans(generalization.parent + clientDependency.select{|d| d.stereotype && d.stereotype.name == "implements"}.supplier),
      :eAnnotations => createAnnotations(taggedValue) }
  end

  transform UML13::Interface, :to => EClass do
    { :name => name && name.strip,
      :abstract => isAbstract,
      :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil),
      :eStructuralFeatures => trans(feature.select{|f| f.is_a?(UML13::Attribute)} + associationEnd),
      :eOperations => trans(feature.select{|f| f.is_a?(UML13::Operation)}),
      :eSuperTypes =>  trans(generalization.parent)}
  end

  transform UML13::Attribute, :to => EAttribute do
    { :name => name && name.strip, :eType => trans(getType),
      :lowerBound => (multiplicity && multiplicity.range.first.lower &&
        multiplicity.range.first.lower.to_i) || 0,
      :upperBound => (multiplicity && multiplicity.range.first.upper && 
        multiplicity.range.first.upper.gsub('*','-1').to_i) || 1,
      :eAnnotations => createAnnotations(taggedValue) }
  end

  transform UML13::DataType, :to => EDataType do
    { :name => name && name.strip,
      :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil),
      :eAnnotations => createAnnotations(taggedValue) }
  end
  
  transform UML13::Operation, :to => EOperation do
    { :name => name && name.strip }
  end
  
  transform UML13::AssociationEnd, :to => EReference, :if => :isReference do
      otherEnd = association.connection.find{|ae| ae != @current_object}
    { :eType => trans(otherEnd.type),
      :name => otherEnd.name && otherEnd.name.strip,
      :eOpposite => trans(otherEnd),
      :lowerBound => (otherEnd.multiplicity && otherEnd.multiplicity.range.first.lower &&
        otherEnd.multiplicity.range.first.lower.to_i) || 0,
      :upperBound => (otherEnd.multiplicity && otherEnd.multiplicity.range.first.upper && 
        otherEnd.multiplicity.range.first.upper.gsub('*','-1').to_i) || 1,
      :containment => (aggregation == :composite),
      :eAnnotations => createAnnotations(association.taggedValue) }
  end

  transform UML13::Dependency, :to => EReference, :if => :isReference do
    { :eType => trans(supplier.first),
      :name => name,
      :lowerBound => 0,
      :upperBound => 1,
      :containment => false,
      :eAnnotations => createAnnotations(taggedValue)
    }
  end
  
  method :isReference do
    @reference_filter.call(@current_object)
  end      
  
  def createAnnotations(taggedValues)
    if taggedValues.size > 0
      [ EAnnotation.new(:details => trans(taggedValues)) ]
    else
      []
    end
  end

  transform UML13::TaggedValue, :to => EStringToStringMapEntry do
   { :key => tag, :value => value}
  end
end