File: xmi11_serializer.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 (116 lines) | stat: -rw-r--r-- 3,043 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
require 'rgen/serializer/xml_serializer'

module RGen

module Serializer

class XMI11Serializer < XMLSerializer

  def initialize(file)
    super
    @namespacePrefix = ""
    @contentLevelElements = []
  end
  
  def setNamespace(shortcut, url)
    @namespaceShortcut = shortcut
    @namespaceUrl = url
    @namespacePrefix = shortcut+":"
  end
  
  def serialize(rootElement, headerInfo=nil)
    attrs = []
    attrs << ['xmi.version', "1.1"]
    attrs << ['xmlns:'+@namespaceShortcut, @namespaceUrl] if @namespaceUrl
    attrs << ['timestamp', Time.now.to_s]
    startTag("XMI", attrs)
    if headerInfo
      startTag("XMI.header")
      writeHeaderInfo(headerInfo)
      endTag("XMI.header")
    end
    startTag("XMI.content")
    @contentLevelElements = []
    writeElement(rootElement)
    # write remaining toplevel elements, each of which could have
    # more toplevel elements as childs
    while @contentLevelElements.size > 0
      writeElement(@contentLevelElements.shift)
    end
    endTag("XMI.content") 
    endTag("XMI") 
  end
  
  def writeHeaderInfo(hash)
    hash.each_pair do |k,v|
      tag = "XMI." + k.to_s
      startTag(tag)
      if v.is_a?(Hash)
        writeHeaderInfo(v)
      else
        writeText(v.to_s)
      end
      endTag(tag)
    end
  end
  
  def writeElement(element)
    tag = @namespacePrefix + element.class.ecore.name
    attrs = attributeValues(element)
    startTag(tag, attrs)
    containmentReferences(element).each do |r|
      roletag = @namespacePrefix + r.eContainingClass.name + "." + r.name
      targets = element.getGeneric(r.name)
      targets = [ targets ] unless targets.is_a?(Array)
      targets.compact!
      next if targets.empty?
      startTag(roletag)
      targets.each do |t|
        if xmiLevel(t) == :content
          @contentLevelElements << t
        else
          writeElement(t)
        end
      end
      endTag(roletag)
    end
    endTag(tag)
  end

  def attributeValues(element)
    result = [["xmi.id", xmiId(element)]]
    eAllAttributes(element).select{|a| !a.derived}.each do |a|
      val = element.getGeneric(a.name)
      result << [a.name, val] unless val.nil? || val == ""
    end
    eAllReferences(element).each do |r|
      next if r.derived
      next if r.containment
      next if r.eOpposite && r.eOpposite.containment && xmiLevel(element).nil?
      next if r.eOpposite && r.many && !r.eOpposite.many
      targetElements = element.getGenericAsArray(r.name)
      targetElements.compact!
      val = targetElements.collect{|te| xmiId(te)}.compact.join(' ')
      result << [r.name, val] unless val == ""
    end
    result  
  end
  
  def xmiId(element)
    if element.respond_to?(:_xmi_id) && element._xmi_id
      element._xmi_id.to_s
    else
      element.object_id.to_s
    end
  end
  
  def xmiLevel(element)
    return nil unless element.respond_to?(:_xmi_level) 
    element._xmi_level
  end
  
end

end

end