lutaml 0.10.4 → 0.10.6
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.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +218 -94
- data/TODO.cleanups/01-resolve-production-todos.md +65 -0
- data/TODO.cleanups/02-reduce-metrics-offenses.md +37 -0
- data/TODO.cleanups/03-reduce-rspec-multiple-expectations.md +54 -0
- data/TODO.cleanups/04-reduce-rspec-example-length.md +45 -0
- data/TODO.cleanups/05-replace-marshal-load.md +37 -0
- data/TODO.cleanups/06-replace-eval-in-tests.md +41 -0
- data/TODO.cleanups/07-fix-lint-offenses.md +74 -0
- data/TODO.cleanups/08-reduce-memoized-helpers-and-nesting.md +43 -0
- data/TODO.cleanups/09-reduce-verified-doubles-and-rspec-style.md +57 -0
- data/TODO.cleanups/10-split-large-files.md +47 -0
- data/bin/console +0 -1
- data/exe/lutaml +1 -0
- data/lib/lutaml/cli/element_identifier.rb +3 -6
- data/lib/lutaml/cli/interactive_shell/bookmark_commands.rb +88 -0
- data/lib/lutaml/cli/interactive_shell/command_base.rb +32 -0
- data/lib/lutaml/cli/interactive_shell/export_handler.rb +67 -0
- data/lib/lutaml/cli/interactive_shell/help_display.rb +114 -0
- data/lib/lutaml/cli/interactive_shell/navigation_commands.rb +135 -0
- data/lib/lutaml/cli/interactive_shell/query_commands.rb +185 -0
- data/lib/lutaml/cli/interactive_shell.rb +116 -802
- data/lib/lutaml/cli/uml/build_command.rb +5 -5
- data/lib/lutaml/cli/uml/verify_command.rb +0 -1
- data/lib/lutaml/converter/xmi_to_uml.rb +3 -153
- data/lib/lutaml/converter/xmi_to_uml_generalization.rb +193 -0
- data/lib/lutaml/formatter/graphviz.rb +1 -2
- data/lib/lutaml/qea/database.rb +1 -47
- data/lib/lutaml/qea/factory/association_builder.rb +188 -0
- data/lib/lutaml/qea/factory/base_transformer.rb +0 -1
- data/lib/lutaml/qea/factory/class_transformer.rb +40 -590
- data/lib/lutaml/qea/factory/diagram_transformer.rb +0 -3
- data/lib/lutaml/qea/factory/generalization_builder.rb +211 -0
- data/lib/lutaml/qea/factory/package_transformer.rb +1 -2
- data/lib/lutaml/qea/factory/stereotype_loader.rb +34 -0
- data/lib/lutaml/qea/lookup_indexes.rb +54 -0
- data/lib/lutaml/qea/models/ea_datatype.rb +0 -2
- data/lib/lutaml/qea/validation/validation_engine.rb +0 -2
- data/lib/lutaml/uml/has_members.rb +0 -1
- data/lib/lutaml/uml/inheritance_walker.rb +92 -0
- data/lib/lutaml/uml/model_helpers.rb +129 -0
- data/lib/lutaml/uml/node/attribute.rb +3 -1
- data/lib/lutaml/uml/node/class_node.rb +3 -3
- data/lib/lutaml/uml/operation.rb +2 -0
- data/lib/lutaml/uml_repository/class_lookup_index.rb +40 -0
- data/lib/lutaml/uml_repository/exporters/markdown/class_page_builder.rb +179 -0
- data/lib/lutaml/uml_repository/exporters/markdown/formatting.rb +36 -0
- data/lib/lutaml/uml_repository/exporters/markdown/index_page_builder.rb +73 -0
- data/lib/lutaml/uml_repository/exporters/markdown/link_resolver.rb +40 -0
- data/lib/lutaml/uml_repository/exporters/markdown/package_page_builder.rb +107 -0
- data/lib/lutaml/uml_repository/exporters/markdown_exporter.rb +26 -538
- data/lib/lutaml/uml_repository/index_builder.rb +3 -271
- data/lib/lutaml/uml_repository/index_builders/association_index.rb +141 -0
- data/lib/lutaml/uml_repository/index_builders/class_index.rb +94 -0
- data/lib/lutaml/uml_repository/index_builders/package_index.rb +57 -0
- data/lib/lutaml/uml_repository/package_exporter.rb +10 -20
- data/lib/lutaml/uml_repository/package_loader.rb +37 -17
- data/lib/lutaml/uml_repository/repository/deprecated.rb +39 -0
- data/lib/lutaml/uml_repository/repository/loader.rb +112 -0
- data/lib/lutaml/uml_repository/repository.rb +7 -57
- data/lib/lutaml/uml_repository/static_site/association_serialization.rb +142 -0
- data/lib/lutaml/uml_repository/static_site/configuration.rb +0 -2
- data/lib/lutaml/uml_repository/static_site/data_transformer.rb +52 -873
- data/lib/lutaml/uml_repository/static_site/generator.rb +29 -8
- data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +1 -4
- data/lib/lutaml/uml_repository/static_site/serializers/attribute_serializer.rb +78 -0
- data/lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb +124 -0
- data/lib/lutaml/uml_repository/static_site/serializers/diagram_serializer.rb +60 -0
- data/lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb +258 -0
- data/lib/lutaml/uml_repository/static_site/serializers/metadata_builder.rb +48 -0
- data/lib/lutaml/uml_repository/static_site/serializers/operation_serializer.rb +57 -0
- data/lib/lutaml/uml_repository/static_site/serializers/package_serializer.rb +94 -0
- data/lib/lutaml/uml_repository/static_site/serializers/package_tree_builder.rb +93 -0
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/liquid_drops/association_drop.rb +13 -35
- data/lib/lutaml/xmi/liquid_drops/attribute_drop.rb +12 -18
- data/lib/lutaml/xmi/liquid_drops/cardinality_drop.rb +14 -6
- data/lib/lutaml/xmi/liquid_drops/connector_drop.rb +0 -3
- data/lib/lutaml/xmi/liquid_drops/constraint_drop.rb +1 -3
- data/lib/lutaml/xmi/liquid_drops/data_type_drop.rb +13 -70
- data/lib/lutaml/xmi/liquid_drops/dependency_drop.rb +2 -5
- data/lib/lutaml/xmi/liquid_drops/diagram_drop.rb +5 -11
- data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +8 -16
- data/lib/lutaml/xmi/liquid_drops/enum_owned_literal_drop.rb +3 -9
- data/lib/lutaml/xmi/liquid_drops/generalization_attribute_drop.rb +11 -13
- data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +27 -85
- data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +39 -91
- data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +3 -9
- data/lib/lutaml/xmi/liquid_drops/package_drop.rb +16 -44
- data/lib/lutaml/xmi/liquid_drops/root_drop.rb +3 -11
- data/lib/lutaml/xmi/liquid_drops/source_target_drop.rb +2 -5
- data/lib/lutaml/xmi/parsers/xmi_base.rb +2 -749
- data/lib/lutaml/xmi/parsers/xmi_class_members.rb +45 -0
- data/lib/lutaml/xmi/parsers/xmi_connector.rb +251 -0
- data/lib/lutaml/xmi/parsers/xml.rb +7 -120
- data/lib/lutaml/xmi/xmi_lookup_service.rb +42 -0
- data/lib/lutaml.rb +0 -1
- metadata +48 -21
- data/lib/lutaml/cli/commands/base_command.rb +0 -118
- data/lib/lutaml/command_line.rb +0 -272
- data/lib/lutaml/sysml/allocate.rb +0 -9
- data/lib/lutaml/sysml/allocated.rb +0 -9
- data/lib/lutaml/sysml/binding_connector.rb +0 -9
- data/lib/lutaml/sysml/block.rb +0 -32
- data/lib/lutaml/sysml/constraint_block.rb +0 -14
- data/lib/lutaml/sysml/copy.rb +0 -8
- data/lib/lutaml/sysml/derive_requirement.rb +0 -9
- data/lib/lutaml/sysml/nested_connector_end.rb +0 -13
- data/lib/lutaml/sysml/refine.rb +0 -9
- data/lib/lutaml/sysml/requirement.rb +0 -44
- data/lib/lutaml/sysml/requirement_related.rb +0 -9
- data/lib/lutaml/sysml/satisfy.rb +0 -9
- data/lib/lutaml/sysml/test_case.rb +0 -25
- data/lib/lutaml/sysml/trace.rb +0 -9
- data/lib/lutaml/sysml/verify.rb +0 -8
- data/lib/lutaml/sysml/xmi_file.rb +0 -486
- data/lib/lutaml/sysml.rb +0 -11
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module UmlRepository
|
|
5
|
+
module Exporters
|
|
6
|
+
module Markdown
|
|
7
|
+
class ClassPageBuilder
|
|
8
|
+
include Formatting
|
|
9
|
+
|
|
10
|
+
def initialize(repository, link_resolver)
|
|
11
|
+
@repository = repository
|
|
12
|
+
@link_resolver = link_resolver
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def build(klass, qname)
|
|
16
|
+
type = klass.class.name.split("::").last
|
|
17
|
+
pkg_path = @link_resolver.extract_package_path(qname)
|
|
18
|
+
|
|
19
|
+
<<~MARKDOWN
|
|
20
|
+
# #{type}: #{klass.name}
|
|
21
|
+
|
|
22
|
+
**Qualified Name**: `#{qname}`
|
|
23
|
+
|
|
24
|
+
**Package**: [#{pkg_path}](#{@link_resolver.package_link(pkg_path)})
|
|
25
|
+
|
|
26
|
+
#{build_stereotypes_section(klass)}
|
|
27
|
+
|
|
28
|
+
#{build_definition_section(klass)}
|
|
29
|
+
|
|
30
|
+
#{build_inheritance_section(klass)}
|
|
31
|
+
|
|
32
|
+
#{build_attributes_section(klass)}
|
|
33
|
+
|
|
34
|
+
#{build_operations_section(klass)}
|
|
35
|
+
|
|
36
|
+
#{build_associations_section(klass)}
|
|
37
|
+
|
|
38
|
+
#{build_enum_literals_section(klass)}
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
[Back to Package](#{@link_resolver.package_link(pkg_path)}) | [Back to Index](../index.md)
|
|
43
|
+
MARKDOWN
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def build_stereotypes_section(klass)
|
|
49
|
+
stereotypes_array = normalize_stereotypes(klass.stereotype)
|
|
50
|
+
return "" if stereotypes_array.empty?
|
|
51
|
+
|
|
52
|
+
"**Stereotypes**: #{stereotypes_array.map do |s|
|
|
53
|
+
"`#{s}`"
|
|
54
|
+
end.join(', ')}\n\n"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_definition_section(klass)
|
|
58
|
+
return "" unless klass.respond_to?(:definition) && klass.definition
|
|
59
|
+
|
|
60
|
+
"## Description\n\n#{klass.definition}\n\n"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def build_inheritance_section(klass)
|
|
64
|
+
parent = @repository.supertype_of(klass)
|
|
65
|
+
children = @repository.subtypes_of(klass)
|
|
66
|
+
|
|
67
|
+
return "" if parent.nil? && children.empty?
|
|
68
|
+
|
|
69
|
+
content = "## Inheritance\n\n"
|
|
70
|
+
|
|
71
|
+
if parent
|
|
72
|
+
parent_qname = @link_resolver.qualified_name(parent)
|
|
73
|
+
content += "**Extends**: [#{parent.name}](#{@link_resolver.class_link(parent_qname)})\n\n"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if children.any?
|
|
77
|
+
content += "**Extended by**:\n\n"
|
|
78
|
+
children.each do |child|
|
|
79
|
+
child_qname = @link_resolver.qualified_name(child)
|
|
80
|
+
content += "- [#{child.name}](#{@link_resolver.class_link(child_qname)})\n"
|
|
81
|
+
end
|
|
82
|
+
content += "\n"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
content
|
|
86
|
+
rescue StandardError
|
|
87
|
+
""
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def build_attributes_section(klass)
|
|
91
|
+
return "" unless klass.attributes&.any?
|
|
92
|
+
|
|
93
|
+
content = "## Attributes\n\n"
|
|
94
|
+
content += "| Name | Type | Visibility | Cardinality |\n"
|
|
95
|
+
content += "|------|------|------------|-------------|\n"
|
|
96
|
+
|
|
97
|
+
klass.attributes.each do |attr|
|
|
98
|
+
visibility = attr.visibility || ""
|
|
99
|
+
cardinality = format_cardinality(attr.cardinality)
|
|
100
|
+
content += "| #{attr.name} | `#{attr.type}` | #{visibility} | " \
|
|
101
|
+
"#{cardinality} |\n"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
"#{content}\n"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def build_operations_section(klass)
|
|
108
|
+
return "" unless klass.respond_to?(:operations) && klass.operations&.any?
|
|
109
|
+
|
|
110
|
+
content = "## Operations\n\n"
|
|
111
|
+
content += "| Name | Return Type | Visibility |\n"
|
|
112
|
+
content += "|------|-------------|------------|\n"
|
|
113
|
+
|
|
114
|
+
klass.operations.each do |op|
|
|
115
|
+
visibility = op.visibility || ""
|
|
116
|
+
return_type = op.return_type || "void"
|
|
117
|
+
content += "| #{op.name} | `#{return_type}` | #{visibility} |\n"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
"#{content}\n"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def build_associations_section(klass)
|
|
124
|
+
associations = @repository.associations_of(klass)
|
|
125
|
+
return "" if associations.empty?
|
|
126
|
+
|
|
127
|
+
content = "## Associations\n\n"
|
|
128
|
+
content += "| Name | Target Class | Cardinality | Navigable |\n"
|
|
129
|
+
content += "|------|--------------|-------------|-----------|\n"
|
|
130
|
+
|
|
131
|
+
associations.each do |assoc|
|
|
132
|
+
content += format_association_row(assoc, klass)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
"#{content}\n"
|
|
136
|
+
rescue StandardError
|
|
137
|
+
""
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def format_association_row(association, klass)
|
|
141
|
+
source_end = association.member_end&.first
|
|
142
|
+
target_end = association.member_end&.last
|
|
143
|
+
|
|
144
|
+
end_obj = if source_end&.type&.xmi_id == klass.xmi_id
|
|
145
|
+
target_end
|
|
146
|
+
else
|
|
147
|
+
source_end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
return "" unless end_obj&.type
|
|
151
|
+
|
|
152
|
+
target_qname = @link_resolver.qualified_name(end_obj.type)
|
|
153
|
+
name = association.name || end_obj.name || ""
|
|
154
|
+
cardinality = format_cardinality(end_obj.cardinality)
|
|
155
|
+
navigable = end_obj.navigable? ? "Yes" : "No"
|
|
156
|
+
|
|
157
|
+
"| #{name} | [#{end_obj.type.name}](#{@link_resolver.class_link(target_qname)}) | " \
|
|
158
|
+
"#{cardinality} | #{navigable} |\n"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def build_enum_literals_section(klass)
|
|
162
|
+
unless klass.is_a?(Lutaml::Uml::Enum) && klass.owned_literal&.any?
|
|
163
|
+
return ""
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
content = "## Literals\n\n"
|
|
167
|
+
klass.owned_literal.each do |literal|
|
|
168
|
+
content += "- `#{literal.name}`"
|
|
169
|
+
content += ": #{literal.definition}" if literal.definition
|
|
170
|
+
content += "\n"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
"#{content}\n"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../uml/model_helpers"
|
|
4
|
+
|
|
5
|
+
module Lutaml
|
|
6
|
+
module UmlRepository
|
|
7
|
+
module Exporters
|
|
8
|
+
module Markdown
|
|
9
|
+
module Formatting
|
|
10
|
+
include Lutaml::Uml::ModelHelpers
|
|
11
|
+
|
|
12
|
+
def format_cardinality(cardinality)
|
|
13
|
+
return "" unless cardinality
|
|
14
|
+
|
|
15
|
+
min = cardinality.min || "0"
|
|
16
|
+
max = cardinality.max || "*"
|
|
17
|
+
"#{min}..#{max}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def format_stereotypes(stereotype)
|
|
21
|
+
return "" unless stereotype
|
|
22
|
+
|
|
23
|
+
case stereotype
|
|
24
|
+
when Array
|
|
25
|
+
stereotype.join(", ")
|
|
26
|
+
when String
|
|
27
|
+
stereotype
|
|
28
|
+
else
|
|
29
|
+
""
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module UmlRepository
|
|
5
|
+
module Exporters
|
|
6
|
+
module Markdown
|
|
7
|
+
class IndexPageBuilder
|
|
8
|
+
def initialize(repository, options, link_resolver)
|
|
9
|
+
@repository = repository
|
|
10
|
+
@options = options
|
|
11
|
+
@link_resolver = link_resolver
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def build
|
|
15
|
+
title = @options.fetch(:title, "UML Model Documentation")
|
|
16
|
+
stats = @repository.statistics
|
|
17
|
+
|
|
18
|
+
<<~MARKDOWN
|
|
19
|
+
# #{title}
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
This documentation provides comprehensive information about the UML model.
|
|
24
|
+
|
|
25
|
+
## Statistics
|
|
26
|
+
|
|
27
|
+
- **Total Packages**: #{stats&.dig(:total_packages) || 0}
|
|
28
|
+
- **Total Classes**: #{stats&.dig(:total_classes) || 0}
|
|
29
|
+
- **Total Associations**: #{stats&.dig(:total_associations) || 0}
|
|
30
|
+
- **Total Diagrams**: #{stats&.dig(:total_diagrams) || 0}
|
|
31
|
+
|
|
32
|
+
## Package Structure
|
|
33
|
+
|
|
34
|
+
#{build_package_tree_markdown}
|
|
35
|
+
|
|
36
|
+
## Navigation
|
|
37
|
+
|
|
38
|
+
- [Packages](packages/)
|
|
39
|
+
- [Classes](classes/)
|
|
40
|
+
MARKDOWN
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def build_package_tree_markdown
|
|
46
|
+
root_path = @options[:package] || "ModelRoot"
|
|
47
|
+
tree = @repository.package_tree(root_path)
|
|
48
|
+
return "No packages found." unless tree
|
|
49
|
+
|
|
50
|
+
build_tree_node(tree, 0)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def build_tree_node(node, depth)
|
|
54
|
+
indent = " " * depth
|
|
55
|
+
path = node[:path]
|
|
56
|
+
link = @link_resolver.package_link(path)
|
|
57
|
+
result = "#{indent}- [#{node[:name]}](#{link})"
|
|
58
|
+
result += " (#{node[:classes_count]} classes)" if node[:classes_count].positive?
|
|
59
|
+
result += "\n"
|
|
60
|
+
|
|
61
|
+
if node[:children]&.any?
|
|
62
|
+
node[:children].each do |child|
|
|
63
|
+
result += build_tree_node(child, depth + 1)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
result
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module UmlRepository
|
|
5
|
+
module Exporters
|
|
6
|
+
module Markdown
|
|
7
|
+
class LinkResolver
|
|
8
|
+
def initialize(indexes)
|
|
9
|
+
@indexes = indexes
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def package_link(path)
|
|
13
|
+
"../packages/#{sanitize_filename(path)}.md"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def class_link(qname)
|
|
17
|
+
"../classes/#{sanitize_filename(qname)}.md"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def package_path(package)
|
|
21
|
+
@indexes&.dig(:package_to_path, package.xmi_id) || package.name
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def qualified_name(klass)
|
|
25
|
+
@indexes&.dig(:class_to_qname, klass.xmi_id) || klass.name
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def extract_package_path(qname)
|
|
29
|
+
parts = qname.split("::")
|
|
30
|
+
parts.size > 1 ? parts[0..-2].join("::") : "ModelRoot"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def sanitize_filename(name)
|
|
34
|
+
name.gsub("::", "_").gsub(/[^a-zA-Z0-9_\-.]/, "_")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module UmlRepository
|
|
5
|
+
module Exporters
|
|
6
|
+
module Markdown
|
|
7
|
+
class PackagePageBuilder
|
|
8
|
+
include Formatting
|
|
9
|
+
|
|
10
|
+
def initialize(repository, link_resolver)
|
|
11
|
+
@repository = repository
|
|
12
|
+
@link_resolver = link_resolver
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def build(package, path)
|
|
16
|
+
classes = @repository.classes_in_package(path, recursive: false)
|
|
17
|
+
sub_packages = package.packages || []
|
|
18
|
+
|
|
19
|
+
<<~MARKDOWN
|
|
20
|
+
# Package: #{package.name}
|
|
21
|
+
|
|
22
|
+
**Qualified Path**: `#{path}`
|
|
23
|
+
|
|
24
|
+
## Description
|
|
25
|
+
|
|
26
|
+
#{package.definition || 'No description available.'}
|
|
27
|
+
|
|
28
|
+
## Statistics
|
|
29
|
+
|
|
30
|
+
- **Direct Classes**: #{classes.size}
|
|
31
|
+
- **Sub-packages**: #{sub_packages.size}
|
|
32
|
+
|
|
33
|
+
#{build_sub_packages_section(sub_packages)}
|
|
34
|
+
|
|
35
|
+
#{build_classes_section(classes)}
|
|
36
|
+
|
|
37
|
+
#{build_diagrams_section(path)}
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
[Back to Index](../index.md)
|
|
42
|
+
MARKDOWN
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def build_sub_packages_section(packages)
|
|
48
|
+
return "" if packages.empty?
|
|
49
|
+
|
|
50
|
+
content = "## Sub-packages\n\n"
|
|
51
|
+
packages.each do |pkg|
|
|
52
|
+
pkg_path = @link_resolver.package_path(pkg)
|
|
53
|
+
link = @link_resolver.package_link(pkg_path)
|
|
54
|
+
content += "- [#{pkg.name}](#{link})\n"
|
|
55
|
+
end
|
|
56
|
+
"#{content}\n"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def build_classes_section(classes)
|
|
60
|
+
return "## Classes\n\nNo classes in this package.\n" if classes.empty?
|
|
61
|
+
|
|
62
|
+
content = "## Classes\n\n"
|
|
63
|
+
content += "| Name | Type | Stereotypes | Attributes | Associations |\n"
|
|
64
|
+
content += "|------|------|-------------|------------|--------------|\n"
|
|
65
|
+
|
|
66
|
+
classes.sort_by(&:name).each do |klass|
|
|
67
|
+
content += format_class_table_row(klass)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
"#{content}\n"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def format_class_table_row(klass)
|
|
74
|
+
qname = @link_resolver.qualified_name(klass)
|
|
75
|
+
link = @link_resolver.class_link(qname)
|
|
76
|
+
type = klass.class.name.split("::").last
|
|
77
|
+
stereotypes = format_stereotypes(klass.stereotype)
|
|
78
|
+
attrs_count = klass.attributes&.size || 0
|
|
79
|
+
assocs_count = count_associations(klass)
|
|
80
|
+
|
|
81
|
+
"| [#{klass.name}](#{link}) | #{type} | #{stereotypes} | " \
|
|
82
|
+
"#{attrs_count} | #{assocs_count} |\n"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def build_diagrams_section(package_path)
|
|
86
|
+
diagrams = @repository.diagrams_in_package(package_path)
|
|
87
|
+
return "" if diagrams.empty?
|
|
88
|
+
|
|
89
|
+
content = "## Diagrams\n\n"
|
|
90
|
+
diagrams.each do |diagram|
|
|
91
|
+
content += "- **#{diagram.name}** (#{diagram.diagram_type})\n"
|
|
92
|
+
end
|
|
93
|
+
"#{content}\n"
|
|
94
|
+
rescue StandardError
|
|
95
|
+
""
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def count_associations(klass)
|
|
99
|
+
@repository.associations_of(klass).size
|
|
100
|
+
rescue StandardError
|
|
101
|
+
0
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|