archimate 1.2.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +47 -0
  3. data/TODOs.org +219 -0
  4. data/archimate.gemspec +2 -1
  5. data/exe/archidiff +7 -0
  6. data/exe/archidiff-summary +7 -0
  7. data/exe/archimerge +7 -0
  8. data/exe/fmtxml +7 -0
  9. data/lib/archimate.rb +10 -21
  10. data/lib/archimate/cli/archi.rb +2 -1
  11. data/lib/archimate/cli/cleanup.rb +8 -9
  12. data/lib/archimate/cli/convert.rb +3 -1
  13. data/lib/archimate/cli/mapper.rb +1 -1
  14. data/lib/archimate/cli/stats.rb +1 -1
  15. data/lib/archimate/config.rb +4 -1
  16. data/lib/archimate/data_model.rb +11 -24
  17. data/lib/archimate/data_model/any_attribute.rb +18 -5
  18. data/lib/archimate/data_model/any_element.rb +30 -7
  19. data/lib/archimate/data_model/bounds.rb +34 -7
  20. data/lib/archimate/data_model/color.rb +32 -7
  21. data/lib/archimate/data_model/comparison.rb +87 -0
  22. data/lib/archimate/data_model/concern.rb +20 -7
  23. data/lib/archimate/data_model/connection.rb +71 -51
  24. data/lib/archimate/data_model/connector_type.rb +23 -0
  25. data/lib/archimate/data_model/diagram.rb +72 -10
  26. data/lib/archimate/data_model/diagram_type.rb +17 -0
  27. data/lib/archimate/data_model/differentiable.rb +142 -0
  28. data/lib/archimate/data_model/element.rb +39 -45
  29. data/lib/archimate/data_model/element_type.rb +89 -0
  30. data/lib/archimate/data_model/font.rb +30 -12
  31. data/lib/archimate/data_model/lang_string.rb +89 -16
  32. data/lib/archimate/data_model/layer.rb +55 -0
  33. data/lib/archimate/data_model/layers.rb +62 -0
  34. data/lib/archimate/data_model/location.rb +27 -11
  35. data/lib/archimate/data_model/metadata.rb +10 -3
  36. data/lib/archimate/data_model/model.rb +188 -121
  37. data/lib/archimate/data_model/modeling_note.rb +14 -3
  38. data/lib/archimate/data_model/organization.rb +44 -13
  39. data/lib/archimate/data_model/{documentation.rb → preserved_lang_string.rb} +1 -5
  40. data/lib/archimate/data_model/property.rb +17 -11
  41. data/lib/archimate/data_model/property_definition.rb +34 -4
  42. data/lib/archimate/data_model/referenceable.rb +0 -9
  43. data/lib/archimate/data_model/referenceable_collection.rb +201 -0
  44. data/lib/archimate/data_model/relationship.rb +52 -33
  45. data/lib/archimate/data_model/relationship_type.rb +43 -0
  46. data/lib/archimate/data_model/schema_info.rb +17 -6
  47. data/lib/archimate/data_model/style.rb +41 -11
  48. data/lib/archimate/data_model/view_node.rb +153 -59
  49. data/lib/archimate/data_model/viewpoint.rb +56 -80
  50. data/lib/archimate/data_model/viewpoint_type.rb +429 -0
  51. data/lib/archimate/export/csv_export.rb +2 -2
  52. data/lib/archimate/export/cypher.rb +2 -2
  53. data/lib/archimate/export/graph_ml.rb +7 -5
  54. data/lib/archimate/export/jsonl.rb +166 -0
  55. data/lib/archimate/export/n_quads.rb +8 -5
  56. data/lib/archimate/file_format.rb +4 -5
  57. data/lib/archimate/file_formats/archi_file_reader.rb +7 -240
  58. data/lib/archimate/file_formats/archi_file_writer.rb +16 -188
  59. data/lib/archimate/file_formats/model_exchange_file_reader.rb +7 -225
  60. data/lib/archimate/file_formats/model_exchange_file_writer_21.rb +22 -114
  61. data/lib/archimate/file_formats/model_exchange_file_writer_30.rb +22 -122
  62. data/lib/archimate/file_formats/sax.rb +55 -0
  63. data/lib/archimate/file_formats/sax/any_element.rb +64 -0
  64. data/lib/archimate/file_formats/sax/archi/archi_handler_factory.rb +48 -0
  65. data/lib/archimate/file_formats/sax/archi/bounds.rb +25 -0
  66. data/lib/archimate/file_formats/sax/archi/connection.rb +47 -0
  67. data/lib/archimate/file_formats/sax/archi/content.rb +28 -0
  68. data/lib/archimate/file_formats/sax/archi/diagram.rb +66 -0
  69. data/lib/archimate/file_formats/sax/archi/element.rb +36 -0
  70. data/lib/archimate/file_formats/sax/archi/location.rb +25 -0
  71. data/lib/archimate/file_formats/sax/archi/model.rb +109 -0
  72. data/lib/archimate/file_formats/sax/archi/organization.rb +60 -0
  73. data/lib/archimate/file_formats/sax/archi/property.rb +54 -0
  74. data/lib/archimate/file_formats/sax/archi/relationship.rb +50 -0
  75. data/lib/archimate/file_formats/sax/archi/style.rb +35 -0
  76. data/lib/archimate/file_formats/sax/archi/view_node.rb +76 -0
  77. data/lib/archimate/file_formats/sax/capture_content.rb +20 -0
  78. data/lib/archimate/file_formats/sax/capture_documentation.rb +19 -0
  79. data/lib/archimate/file_formats/sax/capture_properties.rb +20 -0
  80. data/lib/archimate/file_formats/sax/content_element.rb +19 -0
  81. data/lib/archimate/file_formats/sax/document.rb +80 -0
  82. data/lib/archimate/file_formats/sax/handler.rb +54 -0
  83. data/lib/archimate/file_formats/sax/lang_string.rb +28 -0
  84. data/lib/archimate/file_formats/sax/model_exchange_file/color.rb +36 -0
  85. data/lib/archimate/file_formats/sax/model_exchange_file/connection.rb +67 -0
  86. data/lib/archimate/file_formats/sax/model_exchange_file/diagram.rb +60 -0
  87. data/lib/archimate/file_formats/sax/model_exchange_file/element.rb +43 -0
  88. data/lib/archimate/file_formats/sax/model_exchange_file/font.rb +44 -0
  89. data/lib/archimate/file_formats/sax/model_exchange_file/item.rb +64 -0
  90. data/lib/archimate/file_formats/sax/model_exchange_file/location.rb +23 -0
  91. data/lib/archimate/file_formats/sax/model_exchange_file/metadata.rb +66 -0
  92. data/lib/archimate/file_formats/sax/model_exchange_file/model.rb +124 -0
  93. data/lib/archimate/file_formats/sax/model_exchange_file/model_exchange_handler_factory.rb +53 -0
  94. data/lib/archimate/file_formats/sax/model_exchange_file/property.rb +32 -0
  95. data/lib/archimate/file_formats/sax/model_exchange_file/property_definition.rb +36 -0
  96. data/lib/archimate/file_formats/sax/model_exchange_file/relationship.rb +49 -0
  97. data/lib/archimate/file_formats/sax/model_exchange_file/schema_info.rb +47 -0
  98. data/lib/archimate/file_formats/sax/model_exchange_file/style.rb +66 -0
  99. data/lib/archimate/file_formats/sax/model_exchange_file/view_node.rb +86 -0
  100. data/lib/archimate/file_formats/sax/no_op.rb +17 -0
  101. data/lib/archimate/file_formats/sax/preserved_lang_string.rb +28 -0
  102. data/lib/archimate/file_formats/serializer.rb +57 -0
  103. data/lib/archimate/file_formats/serializer/archi/bounds.rb +23 -0
  104. data/lib/archimate/file_formats/serializer/archi/connection.rb +33 -0
  105. data/lib/archimate/file_formats/serializer/archi/diagram.rb +28 -0
  106. data/lib/archimate/file_formats/serializer/archi/documentation.rb +16 -0
  107. data/lib/archimate/file_formats/serializer/archi/element.rb +24 -0
  108. data/lib/archimate/file_formats/serializer/archi/location.rb +26 -0
  109. data/lib/archimate/file_formats/serializer/archi/model.rb +25 -0
  110. data/lib/archimate/file_formats/serializer/archi/organization.rb +21 -0
  111. data/lib/archimate/file_formats/serializer/archi/property.rb +15 -0
  112. data/lib/archimate/file_formats/serializer/archi/relationship.rb +36 -0
  113. data/lib/archimate/file_formats/serializer/archi/view_node.rb +52 -0
  114. data/lib/archimate/file_formats/serializer/archi/viewpoint_type.rb +45 -0
  115. data/lib/archimate/file_formats/serializer/model_exchange_file/element.rb +25 -0
  116. data/lib/archimate/file_formats/serializer/model_exchange_file/location.rb +15 -0
  117. data/lib/archimate/file_formats/serializer/model_exchange_file/model_exchange_file_writer.rb +32 -0
  118. data/lib/archimate/file_formats/serializer/model_exchange_file/organization.rb +23 -0
  119. data/lib/archimate/file_formats/serializer/model_exchange_file/properties.rb +15 -0
  120. data/lib/archimate/file_formats/serializer/model_exchange_file/relationship.rb +19 -0
  121. data/lib/archimate/file_formats/serializer/model_exchange_file/style.rb +48 -0
  122. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/connection.rb +25 -0
  123. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/diagram.rb +27 -0
  124. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/item.rb +17 -0
  125. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/label.rb +17 -0
  126. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/model.rb +36 -0
  127. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/organization_body.rb +25 -0
  128. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/property.rb +19 -0
  129. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/view_node.rb +44 -0
  130. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/connection.rb +26 -0
  131. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/diagram.rb +27 -0
  132. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/item.rb +17 -0
  133. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/label.rb +17 -0
  134. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/model.rb +41 -0
  135. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/organization_body.rb +25 -0
  136. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/property.rb +19 -0
  137. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/property_definitions.rb +34 -0
  138. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/view_node.rb +45 -0
  139. data/lib/archimate/file_formats/serializer/named_collection.rb +21 -0
  140. data/lib/archimate/file_formats/serializer/writer.rb +56 -0
  141. data/lib/archimate/file_formats/serializer/xml_lang_string.rb +30 -0
  142. data/lib/archimate/file_formats/serializer/xml_metadata.rb +64 -0
  143. data/lib/archimate/file_formats/{model_exchange_file → serializer}/xml_property_defs.rb +2 -2
  144. data/lib/archimate/lint/duplicate_entities.rb +3 -3
  145. data/lib/archimate/lint/linter.rb +24 -29
  146. data/lib/archimate/svg/connection.rb +13 -103
  147. data/lib/archimate/svg/diagram.rb +1 -1
  148. data/lib/archimate/svg/entity/base_entity.rb +12 -8
  149. data/lib/archimate/svg/entity/data_entity.rb +2 -2
  150. data/lib/archimate/svg/entity/diagram_model_reference.rb +1 -1
  151. data/lib/archimate/svg/entity/event_entity.rb +2 -2
  152. data/lib/archimate/svg/entity/gap.rb +1 -1
  153. data/lib/archimate/svg/entity/group.rb +1 -1
  154. data/lib/archimate/svg/entity/motivation_entity.rb +1 -1
  155. data/lib/archimate/svg/entity/node.rb +1 -1
  156. data/lib/archimate/svg/entity/rect_entity.rb +1 -1
  157. data/lib/archimate/svg/entity/rounded_rect_entity.rb +1 -1
  158. data/lib/archimate/svg/entity/service_entity.rb +2 -2
  159. data/lib/archimate/svg/entity/value.rb +2 -2
  160. data/lib/archimate/svg/path.rb +153 -0
  161. data/lib/archimate/svg/point.rb +8 -1
  162. data/lib/archimate/version.rb +1 -1
  163. metadata +118 -36
  164. data/lib/archimate/data_model/archimate_node.rb +0 -181
  165. data/lib/archimate/data_model/concept.rb +0 -14
  166. data/lib/archimate/data_model/constants.rb +0 -82
  167. data/lib/archimate/data_model/container.rb +0 -17
  168. data/lib/archimate/data_model/diffable_array.rb +0 -213
  169. data/lib/archimate/data_model/diffable_primitive.rb +0 -83
  170. data/lib/archimate/data_model/label.rb +0 -19
  171. data/lib/archimate/data_model/named_referenceable.rb +0 -14
  172. data/lib/archimate/data_model/view.rb +0 -12
  173. data/lib/archimate/data_model/view_concept.rb +0 -18
  174. data/lib/archimate/file_formats/archi_file_format.rb +0 -151
  175. data/lib/archimate/file_formats/archimate_v2.rb +0 -461
  176. data/lib/archimate/file_formats/model_exchange_file/xml_lang_string.rb +0 -35
  177. data/lib/archimate/file_formats/model_exchange_file/xml_metadata.rb +0 -115
  178. data/lib/archimate/file_formats/model_exchange_file/xml_property_definitions.rb +0 -28
  179. data/lib/archimate/file_formats/model_exchange_file_reader_21.rb +0 -73
  180. data/lib/archimate/file_formats/model_exchange_file_reader_30.rb +0 -134
  181. data/lib/archimate/file_formats/model_exchange_file_writer.rb +0 -157
  182. data/lib/archimate/file_formats/writer.rb +0 -56
@@ -5,7 +5,7 @@ module Archimate
5
5
  class Convert
6
6
  include Archimate::Logging
7
7
 
8
- SUPPORTED_FORMATS = %w[meff2.1 meff3.0 archi nquads graphml csv cypher].freeze
8
+ SUPPORTED_FORMATS = %w[meff2.1 meff3.0 archi nquads graphml csv cypher jsonl].freeze
9
9
 
10
10
  attr_reader :model
11
11
 
@@ -30,6 +30,8 @@ module Archimate
30
30
  Archimate::Export::CSVExport.new(model).to_csv(output_dir: output_dir)
31
31
  when "cypher"
32
32
  Archimate::Export::Cypher.new(output_io).to_cypher(model)
33
+ when "jsonl"
34
+ Archimate::Export::Jsonl.new(output_io).to_jsonl(model)
33
35
  else
34
36
  error { "Export to '#{export_format}' is not supported yet." }
35
37
  end
@@ -28,7 +28,7 @@ module Archimate
28
28
  when "archimate:SketchModel"
29
29
  "Sketch"
30
30
  when "archimate:ArchimateDiagramModel"
31
- DataModel::Constants::VIEWPOINTS[(row[2] || 0).to_i]
31
+ DataModel::ViewpointType.values[(row[2] || 0).to_i].to_s
32
32
  else
33
33
  row[3]
34
34
  end
@@ -28,7 +28,7 @@ module Archimate
28
28
  end
29
29
 
30
30
  def title_width
31
- @title_width ||= (elements_by_layer.keys + ["Total Elements"]).map(&:size).max
31
+ @title_width ||= (elements_by_layer.keys + ["Total Elements"]).map(&:to_s).map(&:size).max
32
32
  end
33
33
 
34
34
  def row(title, size, color)
@@ -3,6 +3,7 @@
3
3
  require "logger"
4
4
  require "singleton"
5
5
  require "observer"
6
+ require "irb"
6
7
 
7
8
  module Archimate
8
9
  # This is the singleton class that contains application configuration.
@@ -12,10 +13,12 @@ module Archimate
12
13
 
13
14
  attr_reader :interactive
14
15
  attr_reader :logger
16
+ attr_reader :default_lang
15
17
 
16
18
  def initialize
17
19
  @interactive = true
18
- @logger ||= Logger.new(STDERR, progname: "archimate")
20
+ @logger = Logger.new(STDERR, progname: "archimate")
21
+ @default_lang = IRB::Locale.new.lang
19
22
  end
20
23
 
21
24
  def interactive=(interactive)
@@ -2,53 +2,40 @@
2
2
 
3
3
  module Archimate
4
4
  module DataModel
5
- include Dry::Types.module
6
-
7
- Coercible = Archimate::DataModel::Coercible
8
- Strict = Archimate::DataModel::Strict
9
-
10
- # Identifiers in the ArchiMate exchange format standard are of
11
- Identifier = Strict::String # .constrained(format: /[[[:alpha:]]_][\w\-\.]*/)
12
-
13
- # An enumeration of data types.
14
- DataType = Strict::String.default("string").enum("string", "boolean", "currency", "date", "time", "number")
15
-
16
5
  # Enumeration of Influence Strength types. These are suggestions.
17
- InfluenceStrengthEnum = Strict::String.enum(%w[+ ++ - -- 0 1 2 3 4 5 6 7 8 9 10])
6
+ # InfluenceStrengthEnum = String # Strict::String.enum(%w[+ ++ - -- 0 1 2 3 4 5 6 7 8 9 10])
18
7
 
19
- require 'archimate/data_model/diffable_primitive'
20
- require 'archimate/data_model/diffable_array'
21
- require 'archimate/data_model/constants'
22
- require 'archimate/data_model/archimate_node'
8
+ require 'archimate/data_model/connector_type'
9
+ require 'archimate/data_model/diagram_type'
10
+ require 'archimate/data_model/element_type'
11
+ require 'archimate/data_model/relationship_type'
12
+ require 'archimate/data_model/comparison'
13
+ require 'archimate/data_model/differentiable'
14
+ require 'archimate/data_model/layer'
15
+ require 'archimate/data_model/layers'
16
+ require 'archimate/data_model/viewpoint_type'
23
17
  require 'archimate/data_model/any_attribute'
24
18
  require 'archimate/data_model/any_element'
25
19
  require 'archimate/data_model/lang_string'
20
+ require 'archimate/data_model/preserved_lang_string'
26
21
  require 'archimate/data_model/schema_info'
27
22
  require 'archimate/data_model/metadata'
28
23
  require 'archimate/data_model/color'
29
24
  require 'archimate/data_model/font'
30
25
  require 'archimate/data_model/style'
31
26
  require 'archimate/data_model/bounds'
32
- require 'archimate/data_model/documentation'
33
27
  require 'archimate/data_model/modeling_note'
34
- require 'archimate/data_model/referenceable'
35
- require 'archimate/data_model/named_referenceable'
36
28
  require 'archimate/data_model/property_definition'
37
29
  require 'archimate/data_model/property'
38
- require 'archimate/data_model/concept'
39
30
  require 'archimate/data_model/organization'
40
31
  require 'archimate/data_model/element'
41
32
  require 'archimate/data_model/relationship'
42
33
  require 'archimate/data_model/concern'
43
34
  require 'archimate/data_model/viewpoint'
44
- require 'archimate/data_model/view'
45
- require 'archimate/data_model/view_concept'
46
35
  require 'archimate/data_model/location'
47
36
  require 'archimate/data_model/connection'
48
37
  require 'archimate/data_model/view_node'
49
- require 'archimate/data_model/container'
50
38
  require 'archimate/data_model/diagram'
51
- require 'archimate/data_model/label'
52
39
  require 'archimate/data_model/model'
53
40
  end
54
41
  end
@@ -3,11 +3,24 @@
3
3
  module Archimate
4
4
  module DataModel
5
5
  # An instance of any XML attribute for arbitrary content like metadata
6
- class AnyAttribute < ArchimateNode
7
- attribute :attribute, Strict::String
8
- attribute :prefix, Strict::String
9
- attribute :value, Strict::String
6
+ class AnyAttribute
7
+ include Comparison
8
+
9
+ # @!attribute [r] attribute
10
+ # @return [String]
11
+ model_attr :attribute
12
+ # @!attribute [r] prefix
13
+ # @return [String]
14
+ model_attr :prefix
15
+ # @!attribute [r] value
16
+ # @return [String]
17
+ model_attr :value
18
+
19
+ def initialize(attribute, value, prefix: "")
20
+ @attribute = attribute
21
+ @prefix = prefix
22
+ @value = value
23
+ end
10
24
  end
11
- Dry::Types.register_class(AnyAttribute)
12
25
  end
13
26
  end
@@ -3,13 +3,36 @@
3
3
  module Archimate
4
4
  module DataModel
5
5
  # An instance of any XML element for arbitrary content like metadata
6
- class AnyElement < ArchimateNode
7
- attribute :element, Strict::String
8
- attribute :prefix, Strict::String.optional
9
- attribute :attributes, Strict::Array.member(AnyAttribute).default([])
10
- attribute :content, Strict::String.optional
11
- attribute :children, Strict::Array.member(AnyElement).default([])
6
+ class AnyElement
7
+ include Comparison
8
+
9
+ # @!attribute [r] element
10
+ # @return [String]
11
+ model_attr :element
12
+ # @!attribute [r] prefix
13
+ # @return [String, NilClass]
14
+ model_attr :prefix
15
+ # @!attribute [r] attributes
16
+ # @return [Array<AnyAttribute>]
17
+ model_attr :attributes
18
+ # @!attribute [r] content
19
+ # @return [String, NilClass]
20
+ model_attr :content
21
+ # @!attribute [r] children
22
+ # @return [Array<AnyElement>]
23
+ model_attr :children
24
+
25
+ def initialize(element:, prefix: "", attributes: [], content: nil, children: [])
26
+ @element = element
27
+ @prefix = prefix
28
+ @attributes = attributes
29
+ @content = content
30
+ @children = children
31
+ end
32
+
33
+ def to_sym
34
+ element&.to_sym
35
+ end
12
36
  end
13
- Dry::Types.register_class(AnyElement)
14
37
  end
15
38
  end
@@ -1,16 +1,36 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Archimate
3
4
  module DataModel
4
- class Bounds < ArchimateNode
5
- attribute :x, Coercible::Float.optional
6
- attribute :y, Coercible::Float.optional
7
- attribute :width, Coercible::Float
8
- attribute :height, Coercible::Float
5
+ class Bounds
6
+ include Comparison
7
+
8
+ # @!attribute [r] x
9
+ # @return [Float, NilClass]
10
+ model_attr :x
11
+ # @!attribute [r] y
12
+ # @return [Float, NilClass]
13
+ model_attr :y
14
+ # @!attribute [r] width
15
+ # @return [Float]
16
+ model_attr :width
17
+ # @!attribute [r] height
18
+ # @return [Float]
19
+ model_attr :height
9
20
 
10
21
  def self.zero
11
22
  Archimate::DataModel::Bounds.new(x: 0, y: 0, width: 0, height: 0)
12
23
  end
13
24
 
25
+ def initialize(x: nil, y: nil, width:, height:)
26
+ raise "Width expected" unless width
27
+ raise "Height expected" unless height
28
+ @x = x.nil? ? nil : x.to_f
29
+ @y = y.nil? ? nil : y.to_f
30
+ @width = width.to_f
31
+ @height = height.to_f
32
+ end
33
+
14
34
  def to_s
15
35
  "Bounds(x: #{x}, y: #{y}, width: #{width}, height: #{height})"
16
36
  end
@@ -39,6 +59,15 @@ module Archimate
39
59
  x || 0
40
60
  end
41
61
 
62
+ def center
63
+ DataModel::Bounds.new(
64
+ x: left + width / 2.0,
65
+ y: top + height / 2.0,
66
+ width: 0,
67
+ height: 0
68
+ )
69
+ end
70
+
42
71
  def is_above?(other)
43
72
  bottom < other.top
44
73
  end
@@ -66,7 +95,5 @@ module Archimate
66
95
  bottom < other.bottom
67
96
  end
68
97
  end
69
-
70
- Dry::Types.register_class(Bounds)
71
98
  end
72
99
  end
@@ -1,16 +1,30 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Archimate
3
4
  module DataModel
4
5
  # RGBColorType in the XSD
5
6
  # RGB Color type.
6
7
  # The r, g, b attributes range from 0 - 255.
7
8
  # The a (alpha) transparency attribute is optional. 0 = full transparency, 100 = opaque.
8
- class Color < ArchimateNode
9
- attribute :r, Coercible::Int.constrained(lt: 256, gt: -1)
10
- attribute :g, Coercible::Int.constrained(lt: 256, gt: -1)
11
- attribute :b, Coercible::Int.constrained(lt: 256, gt: -1)
12
- attribute :a, Coercible::Int.constrained(lt: 101, gt: -1).optional
9
+ class Color
10
+ include Comparison
11
+
12
+ # @!attribute [r] r
13
+ # @return [Int] red component, value 0-255
14
+ model_attr :r
15
+ # @!attribute [r] g
16
+ # @return [Int] green component, value 0-255
17
+ model_attr :g
18
+ # @!attribute [r] b
19
+ # @return [Int] blue component, value 0-255
20
+ model_attr :b
21
+ # @!attribute [r] a
22
+ # @return [Int, NilClass] optional alpha component, value 0-100
23
+ model_attr :a
13
24
 
25
+ # Parses a CSS style color string into a color object
26
+ # @param str [String] CSS color string
27
+ # @return [Color]
14
28
  def self.rgba(str)
15
29
  return nil if str.nil?
16
30
  md = str.match(/#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})?/)
@@ -23,10 +37,22 @@ module Archimate
23
37
  )
24
38
  end
25
39
 
40
+ # Results in a Color instance for the color black
41
+ # @return [Color]
26
42
  def self.black
27
43
  new(r: 0, g: 0, b: 0, a: 100)
28
44
  end
29
45
 
46
+ def initialize(r:, g:, b:, a: nil)
47
+ raise "r, g, b cannot be nil" if [r, g, b].any?(&:nil?)
48
+ raise "r, g, b must be between 0 and 255" if [r, g, b].any? { |v| v < 0 || v > 255 }
49
+ raise "a must be between 0 and 100" if a && (a < 0 || a > 100)
50
+ @r = r
51
+ @g = g
52
+ @b = b
53
+ @a = a
54
+ end
55
+
30
56
  def to_s
31
57
  "Color(r: #{r}, g: #{g}, b: #{b}, a: #{a})"
32
58
  end
@@ -38,10 +64,9 @@ module Archimate
38
64
  private
39
65
 
40
66
  def scaled_alpha(max = 255)
67
+ return max unless a
41
68
  (max * (a / 100.0)).round
42
69
  end
43
70
  end
44
-
45
- Dry::Types.register_class(Color)
46
71
  end
47
72
  end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ module Comparison
6
+ def hash
7
+ @hash_key ||=
8
+ self.class.attr_names.reduce(self.class.hash) { |ha, attr| ha ^ send(attr).hash }
9
+ end
10
+
11
+ def ==(other)
12
+ return true if equal?(other)
13
+ other.is_a?(self.class) &&
14
+ self.class.comparison_attr_paths.all? do |attr|
15
+ dig(*attr) == other.dig(*attr)
16
+ end
17
+ end
18
+
19
+ def [](sym)
20
+ send(sym)
21
+ end
22
+
23
+ def dig(*args)
24
+ return self if args.empty?
25
+ val = send(args.shift)
26
+ return val if args.empty?
27
+ val&.dig(*args)
28
+ end
29
+
30
+ def to_h
31
+ self.class.attr_names.each_with_object({}) { |i, a| a[i] = send(i) }
32
+ end
33
+
34
+ def each(&blk)
35
+ self.class.comparison_attr_paths.each(&blk)
36
+ end
37
+
38
+ def pretty_print(pp)
39
+ pp.object_address_group(self) do
40
+ pp.seplist(self.class.comparison_attr_paths, proc { pp.text ',' }) do |attr|
41
+ column_value = dig(*attr)
42
+ pp.breakable ' '
43
+ pp.group(1) do
44
+ pp.text Array(attr).map(&:to_s).join(".")
45
+ pp.text ':'
46
+ pp.breakable
47
+ pp.pp column_value
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def self.included(base)
54
+ base.extend ClassMethods
55
+ end
56
+
57
+ module ClassMethods
58
+ # Define the reader method (or call model_attr)
59
+ # Append the attr_sym to the @@attrs for the class
60
+ def model_attr(attr_sym, comparison_attr: nil, writable: false)
61
+ send(:attr_reader, attr_sym)
62
+ attrs = attr_names << attr_sym
63
+ class_variable_set(:@@attr_names, attrs.uniq)
64
+
65
+ if comparison_attr != :no_compare
66
+ attrs = comparison_attr_paths << (comparison_attr ? [attr_sym, comparison_attr] : attr_sym)
67
+ class_variable_set(:@@comparison_attr_paths, attrs.uniq)
68
+ end
69
+ if writable
70
+ define_method("#{attr_sym}=".to_sym) do |val|
71
+ instance_variable_set(:@hash_key, nil)
72
+ instance_variable_set("@#{attr_sym}".to_sym, val)
73
+ end
74
+ end
75
+ end
76
+
77
+ def attr_names
78
+ class_variable_defined?(:@@attr_names) ? class_variable_get(:@@attr_names) : []
79
+ end
80
+
81
+ def comparison_attr_paths
82
+ class_variable_defined?(:@@comparison_attr_paths) ? class_variable_get(:@@comparison_attr_paths) : []
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -5,13 +5,26 @@ module Archimate
5
5
  # document attribute holds all the concern information.
6
6
  #
7
7
  # This is ConcernType in the XSD
8
- class Concern < ArchimateNode
9
- attribute :labels, Strict::Array.member(LangString).constrained(min_size: 1)
10
- attribute :documentation, DocumentationGroup
11
- attribute :stakeholders, Strict::Array.member(LangString)
12
- end
8
+ class Concern
9
+ include Comparison
10
+
11
+ # @!attribute [r] label
12
+ # @return [LangString] one label is required
13
+ model_attr :label
14
+ # @!attribute [r] documentation
15
+ # @return [PreservedLangString]
16
+ model_attr :documentation
17
+ # @!attribute [r] stakeholders
18
+ # @return [Array<LangString>]
19
+ model_attr :stakeholders
13
20
 
14
- Dry::Types.register_class(Concern)
15
- ConcernList = Strict::Array.member(Concern).default([])
21
+ def initialize(label:, documentation: nil, stakeholders: [])
22
+ raise "label is required" unless label
23
+ raise "stakeholders is a list" unless stakeholders.is_a?(Array)
24
+ @label = label
25
+ @documentation = documentation
26
+ @stakeholders = stakeholders
27
+ end
28
+ end
16
29
  end
17
30
  end