Class: Circuitdata::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/circuitdata/schema.rb

Constant Summary collapse

CACHE_PATH =
File.expand_path(File.join(__dir__, "..", "..", "data"))
CACHE =
{}
BASE_PATH =
[
  :properties,
  :open_trade_transfer_package,
  :properties,
]
TYPE_PATH =
{
  profiles: BASE_PATH + [:profiles] + [:properties,
                                       :enforced,
                                       :properties,
                                       :circuitdata,
                                       :properties],
  products: BASE_PATH + [:products] + [:patternProperties,
                                       :".*",
                                       :properties,
                                       :circuitdata,
                                       :properties],
}

Class Method Summary collapse

Class Method Details

.add_questions_to_category(category, question_id, question_schema, path) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/circuitdata/schema.rb', line 82

def self.add_questions_to_category(category, question_id, question_schema, path)
  category_questions = category[:questions]
  id = :"#{category.fetch(:id)}/#{question_id}"

  if question_schema.fetch(:type) == "object"
    category_questions << build_category(id, question_schema, path)
    return
  end

  question = {
    id: id,
    code: question_id,
    name: question_id.to_s.humanize,
    description: "",
  }
  category_questions << question

  [:default, :enforced, :restricted].each do |question_type|
    schema = question_schema.dup
    question[:description] = schema.delete(:description) || question[:description]

    question[question_type] = {
      schema: schema,
      path: json_pointer(path + [category[:id], question_id], question_type),
    }
    question[:uom] ||= schema[:uom]
  end
end

.build_category(category_id, category_schema, pointer_path) ⇒ Object



40
41
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
# File 'lib/circuitdata/schema.rb', line 40

def self.build_category(category_id, category_schema, pointer_path)
  category = {
    id: category_id,
    name: name_from_id(category_id),
    questions: [],
    array?: category_schema[:type] == "array",
  }
  if category_schema.has_key?(:properties)
    questions = category_schema.fetch(:properties)
  elsif category_schema.has_key?(:patternProperties)
    questions = category_schema.fetch(:patternProperties)
  elsif category_schema.fetch(:type) == "array"
    questions = category_schema.fetch(:items)
    if questions.has_key?(:oneOf)
      questions = questions.fetch(:oneOf)
      return one_of_category(category, questions, pointer_path)
    elsif questions.has_key?(:properties)
      questions = questions.fetch(:properties)
    end
  else
    raise "Unknown type"
  end

  questions.each do |question_id, question_schema|
    add_questions_to_category(category, question_id, question_schema, pointer_path)
  end
  category
end

.cached(*path) ⇒ Object



139
140
141
142
143
# File 'lib/circuitdata/schema.rb', line 139

def self.cached(*path)
  file_path = File.join(CACHE_PATH, *path.map(&:to_s)) + ".json"

  CACHE[file_path] ||= JSON.parse(File.read(file_path), symbolize_names: true)
end

.json_pointer(path_parts, type) ⇒ Object



111
112
113
114
115
# File 'lib/circuitdata/schema.rb', line 111

def self.json_pointer(path_parts, type)
  ([""] + path_parts - [:properties, :patternProperties])
    .join("/")
    .sub("enforced", type.to_s)
end

.layer_kindsObject



117
118
119
120
121
# File 'lib/circuitdata/schema.rb', line 117

def self.layer_kinds
  product_schema = type_schema(:products)
  kinds = product_schema.dig(:layers, :items, :oneOf).map { |of| of.dig(:properties, :function, :enum).first }
  kinds.sort
end

.name_from_id(id) ⇒ Object



135
136
137
# File 'lib/circuitdata/schema.rb', line 135

def self.name_from_id(id)
  id.to_s.split("/").last.humanize
end

.one_of_category(category, questions, pointer_path) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/circuitdata/schema.rb', line 69

def self.one_of_category(category, questions, pointer_path)
  category.delete(:questions)
  category[:one_of] = questions.map do |question_set|
    {
      match_attributes: {
        function: question_set.fetch(:properties).fetch(:function).fetch(:enum).first,
      },
      group: build_category(category.fetch(:id), question_set, pointer_path),
    }
  end
  category
end

.process_kindsObject



123
124
125
126
127
# File 'lib/circuitdata/schema.rb', line 123

def self.process_kinds
  product_schema = type_schema(:products)
  kinds = product_schema.dig(:processes, :items, :oneOf).map { |of| of.dig(:properties, :function, :enum).first }
  kinds.sort
end

.product_questions(cached: true) ⇒ Object



22
23
24
# File 'lib/circuitdata/schema.rb', line 22

def self.product_questions(cached: true)
  cached ? cached(:questions, :product) : questions_for_type(:products)
end

.profile_questions(cached: true) ⇒ Object



26
27
28
# File 'lib/circuitdata/schema.rb', line 26

def self.profile_questions(cached: true)
  cached ? cached(:questions, :profile) : questions_for_type(:profiles)
end

.questions_for_type(type) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/circuitdata/schema.rb', line 30

def self.questions_for_type(type)
  pointer_path = TYPE_PATH.fetch(type)
  result = []
  type_schema(type).each do |category_id, category_schema|
    next if category_id == :version
    result << build_category(category_id, category_schema, pointer_path)
  end
  result
end

.type_schema(type) ⇒ Object



129
130
131
132
133
# File 'lib/circuitdata/schema.rb', line 129

def self.type_schema(type)
  schema = Circuitdata.dereferenced_schema
  pointer_path = TYPE_PATH.fetch(type)
  schema.dig(*pointer_path)
end