Class: Archimate::DataModel::Model

Inherits:
NamedReferenceable show all
Defined in:
lib/archimate/data_model/model.rb

Overview

This is the root model type. It is a container for the elements, relationships, diagrams and organizations of the model.

Constant Summary collapse

ARRAY_RE =
Regexp.compile(/\[(\d+)\]/)

Instance Attribute Summary

Attributes inherited from ArchimateNode

#parent_attribute_name, #struct_instance_variables

Instance Method Summary collapse

Methods inherited from ArchimateNode

#ancestors, #build_index, #clone, #compact!, #delete, #diff, #dup, #element_by_id, #id, #in_model, #in_model=, #parent, #parent=, #path, #primitive?, #set

Constructor Details

#initialize(attributes) ⇒ Model

Returns a new instance of Model.



30
31
32
33
34
35
# File 'lib/archimate/data_model/model.rb', line 30

def initialize(attributes)
  super
  self.in_model = self
  self.parent = nil
  rebuild_index
end

Instance Method Details

#add_organization(type, name) ⇒ Object



166
167
168
169
170
171
172
# File 'lib/archimate/data_model/model.rb', line 166

def add_organization(type, name)
  raise "Program Error: #{organizations.inspect}" unless organizations.none? { |f| f.type == type || f.name == name }
  organization = Organization.new(id: make_unique_id, name: name, type: type, items: [], organizations: [])
  register(organization, organizations)
  organizations.push(organization)
  organization
end

#all_propertiesObject

TODO: make these DSL like things added dynamically



88
89
90
91
92
# File 'lib/archimate/data_model/model.rb', line 88

def all_properties
  @index_hash.values.each_with_object([]) do |i, a|
    a.concat(i.properties) if i.respond_to?(:properties)
  end
end

#application_componentsObject

TODO: make these DSL like things added dynamically



75
76
77
# File 'lib/archimate/data_model/model.rb', line 75

def application_components
  elements.select { |element| element.type == "ApplicationComponent" }
end

#default_organization_for(item) ⇒ Object



126
127
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
153
154
155
156
# File 'lib/archimate/data_model/model.rb', line 126

def default_organization_for(item)
  case item
  when Element
    case item.layer
    when "Strategy"
      find_default_organization("strategy", "Strategy")
    when "Business"
      find_default_organization("business", "Business")
    when "Application"
      find_default_organization("application", "Application")
    when "Technology"
      find_default_organization("technology", "Technology")
    when "Physical"
      find_default_organization("physical", "Physical")
    when "Motivation"
      find_default_organization("motivation", "Motivation")
    when "Implementation and Migration"
      find_default_organization("implementation_migration", "Implementation & Migration")
    when "Connectors"
      find_default_organization("connectors", "Connectors")
    else
      raise StandardError, "Unexpected Element Layer: #{item.layer.inspect} for item type #{item.type.inspect}"
    end
  when Relationship
    find_default_organization("relations", "Relations")
  when Diagram
    find_default_organization("diagrams", "Views")
  else
    raise StandardError, "Unexpected item type #{item.class}"
  end
end

#deregister(node) ⇒ Object



62
63
64
# File 'lib/archimate/data_model/model.rb', line 62

def deregister(node)
  @index_hash.delete(node.id)
end

#element_type_namesObject



79
80
81
# File 'lib/archimate/data_model/model.rb', line 79

def element_type_names
  elements.map(&:type).uniq
end

#elements_with_type(el_type) ⇒ Object



83
84
85
# File 'lib/archimate/data_model/model.rb', line 83

def elements_with_type(el_type)
  elements.select { |element| element.type == el_type }
end

#entitiesObject



46
47
48
# File 'lib/archimate/data_model/model.rb', line 46

def entities
  @index_hash.values
end

#find_by_class(klass) ⇒ Object



66
67
68
# File 'lib/archimate/data_model/model.rb', line 66

def find_by_class(klass)
  @index_hash.values.select { |item| item.is_a?(klass) }
end

#find_default_organization(type, name) ⇒ Object



158
159
160
161
162
163
164
# File 'lib/archimate/data_model/model.rb', line 158

def find_default_organization(type, name)
  result = organizations.find { |f| f.type == type }
  return result unless result.nil?
  result = organizations.find { |f| f.name == name }
  return result unless result.nil?
  add_organization(type, name)
end

#find_in_organizations(item, _fs = nil) ⇒ Object



120
121
122
123
124
# File 'lib/archimate/data_model/model.rb', line 120

def find_in_organizations(item, _fs = nil)
  result = find_by_class(DataModel::Organization).select { |f| f.items.include?(item.id) }
  # raise "Program Error! #{item.id} is located in more than one organization. #{result.map(&:to_s).inspect}\n#{item}\n" if result.size > 1
  result.empty? ? nil : result.first
end

#identified_nodesObject



184
185
186
# File 'lib/archimate/data_model/model.rb', line 184

def identified_nodes
  @index_hash.values.select { |node| node.is_a? Referenceable }
end

#lookup(id) ⇒ Object



41
42
43
44
# File 'lib/archimate/data_model/model.rb', line 41

def lookup(id)
  rebuild_index(id) unless @index_hash.include?(id)
  @index_hash[id]
end

#make_unique_idObject



174
175
176
177
178
# File 'lib/archimate/data_model/model.rb', line 174

def make_unique_id
  unique_id = random_id
  unique_id = random_id while @index_hash.key?(unique_id)
  unique_id
end

#merge_entities(master_entity, copies) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/archimate/data_model/model.rb', line 192

def merge_entities(master_entity, copies)
  copies.delete(master_entity)
  copies.each do |copy|
    entities.each do |entity|
      case entity
      when entity == master_entity
        master_entity.merge(copy)
      when Organization
        entity.remove(copy.id)
      when ViewNode, Relationship, Connection
        entity.replace(copy, master_entity)
      end
    end
    deregister(copy)
  end
end

#organizeObject

Iterate through the model and ensure that elements, relationships, and diagrams are all present in the model’s organizations. If an item is missing then move it into the default top-level element for the item type.



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/archimate/data_model/model.rb', line 107

def organize
  []
    .concat(elements)
    .concat(relationships)
    .concat(diagrams).each do |item|
      if find_in_organizations(item).nil?
        default_organization = default_organization_for(item)
        default_organization.items.push(item.id) unless default_organization.items.include?(item.id)
      end
    end
  self
end

#property_def_id(key) ⇒ Object

TODO: refactor to use property def structure instead of separate property objects



100
101
102
# File 'lib/archimate/data_model/model.rb', line 100

def property_def_id(key)
  "propid-#{property_keys.index(key) + 1}"
end

#property_keysObject

TODO: refactor to use property def structure instead of separate property objects



95
96
97
# File 'lib/archimate/data_model/model.rb', line 95

def property_keys
  all_properties.map(&:key).uniq
end

#rebuild_index(missing_id = :model_creation_event) ⇒ Object



50
51
52
53
54
# File 'lib/archimate/data_model/model.rb', line 50

def rebuild_index(missing_id = :model_creation_event)
  return self unless missing_id
  @index_hash = build_index
  self
end

#referenced_identified_nodesObject



180
181
182
# File 'lib/archimate/data_model/model.rb', line 180

def referenced_identified_nodes
  super.uniq
end

#register(node, parent) ⇒ Object



56
57
58
59
60
# File 'lib/archimate/data_model/model.rb', line 56

def register(node, parent)
  node.in_model = self
  node.parent = parent
  @index_hash[node.id] = node
end

#to_sObject



70
71
72
# File 'lib/archimate/data_model/model.rb', line 70

def to_s
  "#{Archimate::Color.data_model('Model')}<#{id}>[#{Archimate::Color.color(name, [:white, :underline])}]"
end

#unreferenced_nodesObject



188
189
190
# File 'lib/archimate/data_model/model.rb', line 188

def unreferenced_nodes
  identified_nodes - referenced_identified_nodes
end

#with(options = {}) ⇒ Object



37
38
39
# File 'lib/archimate/data_model/model.rb', line 37

def with(options = {})
  super.organize
end