Class: Lutaml::Xsd::PackageBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/xsd/package_builder.rb

Overview

Orchestrates package creation using configuration, bundler, and resolver Implements the Strategy pattern for different package types

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ PackageBuilder

Returns a new instance of PackageBuilder.

Parameters:



11
12
13
14
15
16
# File 'lib/lutaml/xsd/package_builder.rb', line 11

def initialize(config)
  @config = config
  @bundler = XsdBundler.new
  @resolver = SchemaResolver.new
  @warnings = []
end

Instance Attribute Details

#bundlerObject (readonly)

Returns the value of attribute bundler.



8
9
10
# File 'lib/lutaml/xsd/package_builder.rb', line 8

def bundler
  @bundler
end

#configObject (readonly)

Returns the value of attribute config.



8
9
10
# File 'lib/lutaml/xsd/package_builder.rb', line 8

def config
  @config
end

#resolverObject (readonly)

Returns the value of attribute resolver.



8
9
10
# File 'lib/lutaml/xsd/package_builder.rb', line 8

def resolver
  @resolver
end

#warningsObject (readonly)

Returns the value of attribute warnings.



8
9
10
# File 'lib/lutaml/xsd/package_builder.rb', line 8

def warnings
  @warnings
end

Instance Method Details

#build(repository, additional_metadata = {}) ⇒ Hash

Build package metadata from repository

Parameters:

  • repository (SchemaRepository)

    Repository to package

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

    Additional metadata fields

Returns:

  • (Hash)

    Package data ready for ZIP creation



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/lutaml/xsd/package_builder.rb', line 22

def build(repository,  = {})
  # Collect XSD files based on configuration
  xsd_files = @bundler.collect_xsd_files(repository, @config)

  # Serialize schemas based on format
  serialized_schemas_data = if @config.resolved_package? && !@config.parse_format?
                              serialize_all_schemas(repository)
                            else
                              {}
                            end

  # Build metadata
   = (
    repository,
    ,
    serialized_schemas_data,
  )

  {
    metadata: ,
    xsd_files: xsd_files,
    serialized_schemas: serialized_schemas_data,
  }
end

#deserialize_schema(data, format) ⇒ Schema

Deserialize a schema based on format

Parameters:

  • data (String)

    Serialized data

  • format (Symbol)

    Serialization format

Returns:

  • (Schema)

    Deserialized schema



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/lutaml/xsd/package_builder.rb', line 83

def deserialize_schema(data, format)
  case format
  when :marshal
    Marshal.load(data)
  when :json
    Lutaml::Xml::Schema::Xsd::Schema.from_json(data)
  when :yaml
    Lutaml::Xml::Schema::Xsd::Schema.from_yaml(data)
  else
    raise ArgumentError, "Unknown serialization format: #{format}"
  end
end

#display_warnings(warnings) ⇒ Object

Display build warnings

Parameters:

  • warnings (Array<Hash>)

    Array of warning hashes



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/lutaml/xsd/package_builder.rb', line 158

def display_warnings(warnings)
  return if warnings.empty?

  puts
  puts "⚠ WARNINGS (#{warnings.size})"
  puts "" * 70

  warnings.each_with_index do |w, i|
    puts "#{i + 1}. #{w[:type]}: #{w[:reference]}"
    puts "   Location: #{w[:schema]}:#{w[:line]}" if w[:line]
    puts "   Namespace: #{w[:namespace]}" if w[:namespace]
    puts "   Hint: #{w[:hint]}" if w[:hint]
    puts
  end

  puts "" * 70
  puts "Status: ✓ Package created with #{warnings.size} warning(s)"
  puts "Action: Review warnings and update config if needed"
  puts
end

#load(repository, metadata_hash) ⇒ Object

Load package data into repository

Parameters:

  • repository (SchemaRepository)

    Repository to load into

  • metadata_hash (Hash)

    Metadata from package



50
51
52
53
54
55
56
57
58
# File 'lib/lutaml/xsd/package_builder.rb', line 50

def load(repository, )
  # Backward compatibility: check for old serialized_schemas format
  serialized_schemas = ["serialized_schemas"] ||
    [:serialized_schemas]

  return unless serialized_schemas&.any?

  @resolver.load_serialized_schemas(repository, serialized_schemas)
end

#resolve_schema_location_to_file(location, glob_mappings) ⇒ String?

Resolve a schema location (possibly HTTP URL) to actual file path

Parameters:

  • location (String)

    Schema location

  • glob_mappings (Array<Hash>)

    Schema mappings in Glob format

Returns:

  • (String, nil)

    Resolved file path or nil



141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/lutaml/xsd/package_builder.rb', line 141

def resolve_schema_location_to_file(location, glob_mappings)
  glob_mappings.each do |mapping|
    from = mapping[:from]
    to = mapping[:to]

    if from.is_a?(Regexp)
      return location.gsub(from, to) if location&.match?(from)
    elsif location == from
      return to
    end
  end

  nil
end

#serialize_all_schemas(repository) ⇒ Hash

Serialize all schemas from repository

Parameters:

Returns:

  • (Hash)

    Map of file_path => serialized data



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/lutaml/xsd/package_builder.rb', line 99

def serialize_all_schemas(repository)
  all_schemas = repository.send(:get_all_processed_schemas)
  glob_mappings = (repository.schema_location_mappings || []).map(&:to_glob_format)
  serialized = {}

  all_schemas.each do |schema_location, schema|
    # Resolve schema location to actual file path
    file_path = if schema_location.start_with?("/")
                  # Already an absolute file path
                  schema_location
                else
                  # Relative path or HTTP URL - resolve using mappings
                  resolve_schema_location_to_file(schema_location,
                                                  glob_mappings)
                end

    # Skip if we couldn't resolve to a file path
    next unless file_path && File.exist?(file_path)

    data = serialize_schema(schema, @config.serialization_format)
    serialized[file_path] = data if data
  end

  # Also serialize entry point schemas from repository.files
  (repository.files || []).each do |file_path|
    next if serialized.key?(file_path)
    next unless File.exist?(file_path)

    schema = repository.instance_variable_get(:@parsed_schemas)&.[](file_path)
    next unless schema

    data = serialize_schema(schema, @config.serialization_format)
    serialized[file_path] = data if data
  end

  serialized
end

#serialize_schema(schema, format) ⇒ String?

Serialize a single schema based on format

Parameters:

  • schema (Schema)

    Schema to serialize

  • format (Symbol)

    Serialization format

Returns:

  • (String, nil)

    Serialized data or nil for :parse format



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/lutaml/xsd/package_builder.rb', line 64

def serialize_schema(schema, format)
  case format
  when :marshal
    Marshal.dump(schema)
  when :json
    schema.to_json
  when :yaml
    schema.to_yaml
  when :parse
    nil
  else
    raise ArgumentError, "Unknown serialization format: #{format}"
  end
end

#suggest_fix(error) ⇒ String

Suggest fix for reference error

Parameters:

  • error (StandardError)

    Error that occurred

Returns:

  • (String)

    Suggestion text



182
183
184
185
186
187
188
189
190
191
192
# File 'lib/lutaml/xsd/package_builder.rb', line 182

def suggest_fix(error)
  message = error.message

  if message.include?("not found")
    "Check that all required schemas are included in dependencies"
  elsif message.include?("namespace")
    "Verify namespace URI is correct and schema is imported"
  else
    "Review schema dependencies and imports"
  end
end