Class: Lutaml::ModelTransformations::Parsers::BaseParser Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/model_transformations/parsers/base_parser.rb

Overview

This class is abstract.

Subclass and implement the abstract methods

Base parser interface defining the contract for all model format parsers.

This abstract base class implements the Template Method pattern and follows the Liskov Substitution Principle - all concrete parsers must be substitutable for this base class.

Concrete parsers must implement:

  • parse_internal: Core parsing logic

  • supported_extensions: List of supported file extensions

  • format_name: Human-readable format name

Direct Known Subclasses

QeaParser, XmiParser

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration: nil, options: {}) ⇒ BaseParser

Initialize parser with configuration and options

Parameters:

  • configuration (Configuration) (defaults to: nil)

    Transformation configuration

  • options (Hash) (defaults to: {})

    Parsing options



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 33

def initialize(configuration: nil, options: {})
  @configuration = configuration
  @options = default_options.merge(options)
  @errors = []
  @warnings = []
  @parse_stats = {
    total_parses: 0,
    successful_parses: 0,
    failed_parses: 0,
    total_duration: 0,
    durations: [],
  }
  @last_duration = nil
  @stats_mutex = Mutex.new
end

Instance Attribute Details

#configurationConfiguration (readonly)

Returns Parser configuration.

Returns:



21
22
23
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 21

def configuration
  @configuration
end

#last_durationFloat? (readonly)

Returns Duration of last parse in seconds.

Returns:

  • (Float, nil)

    Duration of last parse in seconds



27
28
29
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 27

def last_duration
  @last_duration
end

#optionsHash (readonly)

Returns Parsing options.

Returns:

  • (Hash)

    Parsing options



24
25
26
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 24

def options
  @options
end

Instance Method Details

#can_parse?(file_path) ⇒ Boolean

Check if this parser can handle the given file

Parameters:

  • file_path (String)

    Path to the file

Returns:

  • (Boolean)

    true if parser can handle the file



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 106

def can_parse?(file_path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  extension = File.extname(file_path).downcase
  return true if supported_extensions.include?(extension)

  if respond_to?(:content_patterns) && File.exist?(file_path)
    File.open(file_path, "rb") do |file|
      header = file.read(1024) # Read first 1KB
      return false if header.nil? || header.empty?

      content_patterns.each do |pattern|
        return true if header.match?(pattern)
      end
    end
  end

  false
end

#errorsArray<String>

Get all parsing errors

Returns:

  • (Array<String>)

    List of error messages



163
164
165
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 163

def errors
  @errors.dup
end

#format_nameString

This method is abstract.

Implement in subclass

Get parser format name

Returns:

  • (String)

    Human-readable format name

Raises:

  • (NotImplementedError)


128
129
130
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 128

def format_name
  raise NotImplementedError, "Subclasses must implement #format_name"
end

#has_errors?Boolean

Check if parser has any errors

Returns:

  • (Boolean)

    true if there are parsing errors



149
150
151
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 149

def has_errors?
  !@errors.empty?
end

#has_warnings?Boolean

Check if parser has any warnings

Returns:

  • (Boolean)

    true if there are parsing warnings



156
157
158
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 156

def has_warnings?
  !@warnings.empty?
end

#parse(file_path) ⇒ Lutaml::Uml::Document

Parse a model file into a UML document

This is the main public interface method that implements the Template Method pattern. It handles common concerns like validation, error handling, and post-processing.

Parameters:

  • file_path (String)

    Path to the model file

Returns:

Raises:



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
99
100
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 58

def parse(file_path) # rubocop:disable Metrics/MethodLength
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  @stats_mutex.synchronize { @parse_stats[:total_parses] += 1 }
  parse_succeeded = false
  parse_handled = false

  begin
    validate_file!(file_path) if should_validate_input?
    clear_errors_and_warnings

    begin
      # Pre-parsing hook
      before_parse(file_path)

      # Core parsing (implemented by subclasses)
      document = parse_internal(file_path)

      # Post-parsing processing
      document = after_parse(document, file_path)

      # Validate output if requested
      validate_output!(document) if should_validate_output?

      parse_succeeded = true
      @stats_mutex.synchronize { @parse_stats[:successful_parses] += 1 }
      document
    rescue StandardError => e
      parse_handled = true
      @stats_mutex.synchronize { @parse_stats[:failed_parses] += 1 }
      handle_parsing_error(e, file_path)
    end
  ensure
    unless parse_succeeded || parse_handled
      @stats_mutex.synchronize { @parse_stats[:failed_parses] += 1 }
    end
    duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
    @last_duration = duration
    @stats_mutex.synchronize do
      @parse_stats[:total_duration] += duration
      @parse_stats[:durations] << duration
    end
  end
end

#priorityObject

Default parser priority



142
143
144
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 142

def priority
  100
end

#reset_statisticsvoid

This method returns an undefined value.

Reset all parsing statistics



197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 197

def reset_statistics
  @stats_mutex.synchronize do
    @parse_stats = {
      total_parses: 0,
      successful_parses: 0,
      failed_parses: 0,
      total_duration: 0,
      durations: [],
    }
  end
  @last_duration = nil
end

#statisticsHash

Get parsing statistics

Returns:

  • (Hash)

    Statistics about the parsing process



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 177

def statistics
  stats = @stats_mutex.synchronize { @parse_stats.dup }
  durations = stats[:durations]
  {
    format: format_name,
    errors: @errors.size,
    warnings: @warnings.size,
    options: @options,
    total_parses: stats[:total_parses],
    successful_parses: stats[:successful_parses],
    failed_parses: stats[:failed_parses],
    success_rate: calculate_success_rate(stats),
    average_duration: calculate_average_duration(durations),
    total_duration: stats[:total_duration],
  }
end

#supported_extensionsArray<String>

This method is abstract.

Implement in subclass

Get list of supported file extensions

Returns:

  • (Array<String>)

    List of extensions (e.g., [“.xmi”, “.xml”])

Raises:

  • (NotImplementedError)


136
137
138
139
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 136

def supported_extensions
  raise NotImplementedError,
        "Subclasses must implement #supported_extensions"
end

#warningsArray<String>

Get all parsing warnings

Returns:

  • (Array<String>)

    List of warning messages



170
171
172
# File 'lib/lutaml/model_transformations/parsers/base_parser.rb', line 170

def warnings
  @warnings.dup
end