Class: Ea::Diagram::Configuration
- Inherits:
-
Object
- Object
- Ea::Diagram::Configuration
- Defined in:
- lib/ea/diagram/configuration.rb
Overview
Configuration management for diagram styling
This class provides hierarchical style resolution with the following priority:
- EA Data (QEA/XMI) - Highest priority
- Class-specific overrides (user config)
- Package-based styling (wildcard support)
- Stereotype-based styling
- Global defaults - Lowest priority
Constant Summary collapse
- DEFAULT_CONFIG_PATHS =
Default configuration file paths in order of preference
[ "config/diagram_styles.yml", File.("~/.lutaml/diagram_styles.yml"), ].freeze
Instance Attribute Summary collapse
-
#config_data ⇒ Object
readonly
Returns the value of attribute config_data.
Instance Method Summary collapse
-
#connector_style(connector_type, property) ⇒ Object
Get connector style.
-
#deep_merge(hash1, hash2) ⇒ Hash
Deep merge two hashes.
-
#dig_hash(hash, path) ⇒ Object
Navigate hash using dot notation.
-
#initialize(config_path = nil) ⇒ Configuration
constructor
Initialize configuration with optional custom path.
-
#legend_config ⇒ Hash
Get legend configuration.
-
#matches_package?(package_name, pattern) ⇒ Boolean
Check if package name matches pattern (supports wildcards).
-
#style_for(element, property) ⇒ Object
Get style for a specific element.
-
#to_h ⇒ Hash
Get the entire configuration data.
Constructor Details
#initialize(config_path = nil) ⇒ Configuration
Initialize configuration with optional custom path
33 34 35 |
# File 'lib/ea/diagram/configuration.rb', line 33 def initialize(config_path = nil) @config_data = load_configuration(config_path) end |
Instance Attribute Details
#config_data ⇒ Object (readonly)
Returns the value of attribute config_data.
22 23 24 |
# File 'lib/ea/diagram/configuration.rb', line 22 def config_data @config_data end |
Instance Method Details
#connector_style(connector_type, property) ⇒ Object
Get connector style
Type of connector (generalization, association, etc.)
106 107 108 |
# File 'lib/ea/diagram/configuration.rb', line 106 def connector_style(connector_type, property) dig_config("connectors.#{connector_type}.#{property}") end |
#deep_merge(hash1, hash2) ⇒ Hash
Deep merge two hashes
164 165 166 167 168 169 170 171 172 |
# File 'lib/ea/diagram/configuration.rb', line 164 def deep_merge(hash1, hash2) hash1.merge(hash2) do |_key, old_val, new_val| if old_val.is_a?(Hash) && new_val.is_a?(Hash) deep_merge(old_val, new_val) else new_val end end end |
#dig_hash(hash, path) ⇒ Object
Navigate hash using dot notation
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/ea/diagram/configuration.rb', line 129 def dig_hash(hash, path) # rubocop:disable Metrics/CyclomaticComplexity return nil if path.nil? || path.empty? return nil unless hash.is_a?(Hash) keys = path.split(".") return nil if keys.empty? keys.reduce(hash) do |h, key| return nil unless h.is_a?(Hash) h[key] end end |
#legend_config ⇒ Hash
Get legend configuration
113 114 115 |
# File 'lib/ea/diagram/configuration.rb', line 113 def legend_config config_data["legend"] || {} end |
#matches_package?(package_name, pattern) ⇒ Boolean
Check if package name matches pattern (supports wildcards)
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/ea/diagram/configuration.rb', line 148 def matches_package?(package_name, pattern) return false unless package_name && pattern # Support wildcards: "CityGML::*" matches "CityGML::Core" regex_pattern = pattern.gsub("*", ".*") Regexp.new("^#{regex_pattern}$").match?(package_name) rescue RegexpError => e warn "Warning: Invalid package pattern '#{pattern}': #{e.}" false end |
#style_for(element, property) ⇒ Object
Get style for a specific element
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 |
# File 'lib/ea/diagram/configuration.rb', line 42 def style_for(element, property) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity return nil if property.nil? || property.empty? # Priority: Class-specific > Package > Stereotype > Defaults value = nil # 1. Try class-specific override (highest priority) if element.is_a?(Lutaml::Uml::TopElement) && element.name class_config = dig_config("classes.#{element.name}.#{property}") value = class_config if class_config end # 2. Try package-based styling if !value && element.is_a?(Lutaml::Uml::Diagram) && element.package_name # Support wildcards: "CityGML::*" package_configs = config_data["packages"] || {} package_configs.each do |pattern, pkg_config| if matches_package?(element.package_name, pattern) pkg_value = dig_hash(pkg_config, property) value = pkg_value if pkg_value break end end end # 3. Try stereotype-based styling if !value && element.is_a?(Lutaml::Uml::TopElement) && element.stereotype stereotypes = Array(element.stereotype) stereotypes.each do |stereo| stereo_value = dig_config("stereotypes.#{stereo}.#{property}") if stereo_value value = stereo_value break end end end # 4. Fall back to defaults (lowest priority) # Handle property name aliases # (e.g., "colors.fill" -> "colors.default_fill") unless value value = dig_config("defaults.#{property}") # If not found, try with "default_" prefix for certain properties unless value if property.start_with?("colors.fill") value = dig_config("defaults.colors.default_fill") elsif property.start_with?("colors.stroke") && !property.include?("stroke_") value = dig_config("defaults.colors.default_stroke") end end end value end |
#to_h ⇒ Hash
Get the entire configuration data
120 121 122 |
# File 'lib/ea/diagram/configuration.rb', line 120 def to_h config_data end |