Class: Archimate::FileFormats::ArchiFileReader

Inherits:
Object
  • Object
show all
Defined in:
lib/archimate/file_formats/archi_file_reader.rb

Instance Method Summary collapse

Constructor Details

#initializeArchiFileReader

Returns a new instance of ArchiFileReader.



7
8
9
10
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 7

def initialize
  @progress = nil
  @random ||= Random.new
end

Instance Method Details

#child_element_ids(node) ⇒ Object



98
99
100
101
102
103
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 98

def child_element_ids(node)
  node.css(">element[id]").each_with_object([]) do |i, a|
    tick
    a << i.attr("id")
  end
end

#parse(doc) ⇒ Object



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
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 12

def parse(doc)
  @size = 0
  doc.traverse { |_n| @size += 1 }
  @progress = ProgressIndicator.new(total: @size, title: "Parsing")
  @property_defs = {}
  tick
  diagrams = parse_diagrams(doc.root)
  DataModel::Model.new(
    id: doc.root["id"],
    name: doc.root["name"],
    documentation: parse_documentation(doc.root, "purpose"),
    properties: parse_properties(doc.root),
    elements: parse_elements(doc.root),
    organizations: parse_organizations(doc.root),
    relationships: parse_relationships(doc.root),
    diagrams: diagrams,
    viewpoints: [],
    property_definitions: @property_defs.values,
    namespaces: {},
    schema_locations: []
  )
ensure
  @progress&.finish
  @progress = nil
end

#parse_access_type(val) ⇒ Object



121
122
123
124
125
126
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 121

def parse_access_type(val)
  return nil unless val && val.size > 0
  i = val.to_i
  return nil unless i >= 0 && i < DataModel::AccessType.size
  DataModel::AccessType[i]
end

#parse_all_connections(node) ⇒ Object



207
208
209
210
211
212
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 207

def parse_all_connections(node)
  node.css("sourceConnection").each_with_object([]) do |i, a|
    tick
    a << parse_connection(i)
  end
end

#parse_bendpoints(node) ⇒ Object

startX = location.x - source_attachment.x startY = location.y - source_attachment.y endX = location.x - target_attachment.x endY = location.y - source_attachment.y



237
238
239
240
241
242
243
244
245
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 237

def parse_bendpoints(node)
  node.css("bendpoint").each_with_object([]) do |i, a|
    tick
    a << DataModel::Location.new(
      x: i.attr("startX") || 0, y: i.attr("startY") || 0,
      end_x: i.attr("endX"), end_y: i.attr("endY")
    )
  end
end

#parse_bounds(node) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 194

def parse_bounds(node)
  bounds = node.at_css("> bounds")
  tick
  unless bounds.nil?
    DataModel::Bounds.new(
      x: bounds.attr("x"),
      y: bounds.attr("y"),
      width: bounds.attr("width"),
      height: bounds.attr("height")
    )
  end
end

#parse_connection(i) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 218

def parse_connection(i)
  DataModel::Connection.new(
    id: i["id"],
    type: i.attr("xsi:type"),
    source: i["source"],
    target: i["target"],
    relationship: i["relationship"] || i["archimateRelationship"],
    name: i["name"],
    style: parse_style(i),
    bendpoints: parse_bendpoints(i),
    documentation: parse_documentation(i),
    properties: parse_properties(i)
    )
end

#parse_connections(node) ⇒ Object



214
215
216
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 214

def parse_connections(node)
  node.css("> sourceConnection").each_with_object([]) { |i, a| a << parse_connection(i) }
end

#parse_diagrams(model) ⇒ Object



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
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 128

def parse_diagrams(model)
  model.css(ArchiFileFormat::DIAGRAM_XPATHS.join(",")).css(
    'element[xsi|type="archimate:ArchimateDiagramModel"]',
    'element[xsi|type="archimate:SketchModel"]'
  ).map do |i|
    tick
    viewpoint_idx = i["viewpoint"]
    viewpoint_idx = viewpoint_idx.to_i unless viewpoint_idx.nil?
    viewpoint_type = viewpoint_idx.nil? ? nil : ArchiFileFormat::VIEWPOINTS[viewpoint_idx]
    DataModel::Diagram.new(
      id: i["id"],
      name: i["name"],
      viewpoint_type: viewpoint_type,
      viewpoint: nil,
      documentation: parse_documentation(i),
      properties: parse_properties(i),
      nodes: parse_nodes(i),
      connections: parse_all_connections(i),
      connection_router_type: i["connectionRouterType"],
      type: i.attr("xsi:type"),
      background: i.attr("background"),
      organization_id: nil
    )
  end
end

#parse_documentation(node, element_name = "documentation") ⇒ Object



38
39
40
41
42
43
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 38

def parse_documentation(node, element_name = "documentation")
  node.css(">#{element_name}").each_with_object([]) do |i, a|
    tick
    a << DataModel::Documentation.new(text: i.content)
  end
end

#parse_elements(model) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 69

def parse_elements(model)
  model.css(ArchiFileFormat::FOLDER_XPATHS.join(",")).css('element[id]').map do |i|
    tick
    DataModel::Element.new(
      id: i["id"],
      name: i["name"],
      organization_id: i.parent["id"],
      type: i["xsi:type"].sub("archimate:", ""),
      documentation: parse_documentation(i),
      properties: parse_properties(i)
    )
  end
end

#parse_nodes(node) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 154

def parse_nodes(node)
  node.css("> child").each_with_object([]) do |child_node, a|
    tick
    a << DataModel::ViewNode.new(
      id: child_node.attr("id"),
      type: child_node.attr("xsi:type"),
      model: child_node.attr("model"),
      name: child_node.attr("name"),
      target_connections: parse_target_connections(child_node.attr("targetConnections")),
      archimate_element: child_node.attr("archimateElement"),
      bounds: parse_bounds(child_node),
      nodes: parse_nodes(child_node),
      connections: parse_connections(child_node),
      documentation: parse_documentation(child_node),
      properties: parse_properties(child_node),
      style: parse_style(child_node),
      content: child_node.at_css("> content")&.text,
      child_type: child_node.attr("type")
    )
  end
end

#parse_organizations(node) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 83

def parse_organizations(node)
  node.css("> folder").each_with_object([]) do |i, a|
    tick
    a << DataModel::Organization.new(
      id: i.attr("id"),
      name: i.attr("name"),
      type: i.attr("type"),
      documentation: parse_documentation(i),
      properties: parse_properties(i),
      items: child_element_ids(i),
      organizations: parse_organizations(i)
    )
  end
end

#parse_properties(node) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 45

def parse_properties(node)
  node.css(">property").each_with_object([]) do |i, a|
    tick
    key = i["key"]
    next unless key
    if @property_defs.key?(key)
      prop_def = @property_defs[key]
    else
      @property_defs[key] = prop_def = DataModel::PropertyDefinition.new(
        id: DataModel::PropertyDefinition.identifier_for_key(key),
        name: key,
        documentation: [],
        value_type: "string"
      )
    end
    a << DataModel::Property.new(
      values: [
        DataModel::LangString.new(text: i["value"] || "en")
      ],
      property_definition: prop_def
    )
  end
end

#parse_relationships(model) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 105

def parse_relationships(model)
  model.css(ArchiFileFormat::RELATION_XPATHS.join(",")).css("element").map do |i|
    tick
    DataModel::Relationship.new(
      id: i["id"],
      type: i.attr("xsi:type").sub("archimate:", ""),
      source: i.attr("source"),
      target: i.attr("target"),
      name: i["name"],
      access_type: parse_access_type(i["accessType"]),
      documentation: parse_documentation(i),
      properties: parse_properties(i)
    )
  end
end

#parse_style(style) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 181

def parse_style(style)
  tick
  DataModel::Style.new(
    text_alignment: style["textAlignment"],
    fill_color: DataModel::Color.rgba(style["fillColor"]),
    line_color: DataModel::Color.rgba(style["lineColor"]),
    font_color: DataModel::Color.rgba(style["fontColor"]),
    font: DataModel::Font.archi_font_string(style["font"]),
    line_width: style["lineWidth"],
    text_position: style["textPosition"]
  )
end

#parse_target_connections(str) ⇒ Object



176
177
178
179
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 176

def parse_target_connections(str)
  return [] if str.nil?
  str.split(" ")
end

#tickObject



247
248
249
# File 'lib/archimate/file_formats/archi_file_reader.rb', line 247

def tick
  @progress&.increment
end