Class: Udb::Architecture
- Inherits:
-
Object
- Object
- Udb::Architecture
- Extended by:
- T::Sig
- Defined in:
- lib/udb/architecture.rb
Direct Known Subclasses
Constant Summary collapse
- OBJS =
[ { fn_name: "extension", arch_dir: "ext", klass: Extension, kind: DatabaseObject::Kind::Extension }, { fn_name: "instruction", arch_dir: "inst", klass: Instruction, kind: DatabaseObject::Kind::Instruction }, { fn_name: "instruction_type", arch_dir: "inst_type", klass: InstructionType, kind: DatabaseObject::Kind::InstructionType }, { fn_name: "instruction_subtype", arch_dir: "inst_subtype", klass: InstructionSubtype, kind: DatabaseObject::Kind::InstructionSubtype }, { fn_name: "csr", arch_dir: "csr", klass: Csr, kind: DatabaseObject::Kind::Csr }, { fn_name: "proc_cert_class", arch_dir: "proc_cert_class", klass: ProcCertClass, kind: DatabaseObject::Kind::ProcessorCertificateClass }, { fn_name: "proc_cert_model", arch_dir: "proc_cert_model", klass: ProcCertModel, kind: DatabaseObject::Kind::ProcessorCertificateModel }, { fn_name: "manual", arch_dir: "manual", klass: Manual, kind: DatabaseObject::Kind::Manual }, { fn_name: "manual_version", arch_dir: "manual_version", klass: ManualVersion, kind: DatabaseObject::Kind::ManualVersion }, { fn_name: "profile_release", arch_dir: "profile_release", klass: ProfileRelease, kind: DatabaseObject::Kind::ProfileRelease }, { fn_name: "profile_family", arch_dir: "profile_family", klass: ProfileFamily, kind: DatabaseObject::Kind::ProfileFamily }, { fn_name: "profile", arch_dir: "profile", klass: Profile, kind: DatabaseObject::Kind::Profile }, { fn_name: "prm", arch_dir: "prm", klass: Prm, kind: DatabaseObject::Kind::Prm } ].freeze
Instance Attribute Summary collapse
-
#path ⇒ Pathname
readonly
Path to the directory with the standard YAML files.
Class Method Summary collapse
-
.generate_obj_methods(fn_name, arch_dir, obj_class)
These instance methods are create when this Architecture class is first loaded.
Instance Method Summary collapse
-
#exception_codes ⇒ Array<ExceptionCode>
All exception codes defined by the spec.
-
#initialize(arch_dir) ⇒ Architecture
constructor
A new instance of Architecture.
-
#interrupt_codes ⇒ Array<InteruptCode>
All interrupt codes defined by extensions.
-
#objs ⇒ Array<TopLevelDatabaseObject>
All known objects.
- #param(name) ⇒ nil, Parameter
-
#param_hash ⇒ Hash<String, Parameter>
Hash of all extension parameters defined in the architecture.
-
#params ⇒ Array<Parameter>
Alphabetical list of all parameters defined in the architecture.
- #portfolio(name) ⇒ PortfolioClass?
- #portfolio_class(name) ⇒ PortfolioClass?
-
#portfolio_class_hash ⇒ Hash<String, PortfolioClass>
Hash of all portfolio classes defined in the architecture.
-
#portfolio_classes ⇒ Array<PortfolioClass>
Alphabetical list of all portfolio classes defined in the architecture.
-
#portfolio_hash ⇒ Hash<String, Portfolio>
Hash of all portfolios defined in the architecture.
-
#portfolios ⇒ Array<Portfolio>
Alphabetical list of all portfolios defined in the architecture.
-
#ref(uri) ⇒ DatabaseObject
given a ‘$ref` target, return the Ruby object.
-
#validate(resolver, show_progress: true)
validate the architecture against JSON Schema and any object-specific verification.
Constructor Details
#initialize(arch_dir) ⇒ Architecture
Returns a new instance of Architecture.
70 71 72 73 74 75 76 77 78 |
# File 'lib/udb/architecture.rb', line 70 def initialize(arch_dir) @arch_dir = Pathname.new(arch_dir) raise "Arch directory not found: #{arch_dir}" unless @arch_dir.exist? @arch_dir = @arch_dir.realpath @path = @arch_dir # alias @objects = Concurrent::Hash.new @object_hashes = Concurrent::Hash.new end |
Instance Attribute Details
#path ⇒ Pathname (readonly)
Returns Path to the directory with the standard YAML files.
67 68 69 |
# File 'lib/udb/architecture.rb', line 67 def path @path end |
Class Method Details
.generate_obj_methods(fn_name, arch_dir, obj_class)
This method returns an undefined value.
These instance methods are create when this Architecture class is first loaded. This is a Ruby “class” method and so self is the entire Architecture class, not an instance it. However, this class method creates normal instance methods and when they are called self is an instance of the Architecture class.
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 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/udb/architecture.rb', line 111 def self.generate_obj_methods(fn_name, arch_dir, obj_class) plural_fn = ActiveSupport::Inflector.pluralize(fn_name) define_method(plural_fn) do return @objects[arch_dir] unless @objects[arch_dir].nil? @objects[arch_dir] = Concurrent::Array.new @object_hashes[arch_dir] = Concurrent::Hash.new Dir.glob(@arch_dir / arch_dir / "**" / "*.yaml") do |obj_path| f = File.open(obj_path) f.flock(File::LOCK_EX) obj_yaml = YAML.load(f.read, filename: obj_path, permitted_classes: [Date]) f.flock(File::LOCK_UN) @objects[arch_dir] << obj_class.new(obj_yaml, Pathname.new(obj_path).realpath, self) @object_hashes[arch_dir][@objects[arch_dir].last.name] = @objects[arch_dir].last end @objects[arch_dir] end define_method("#{fn_name}_hash") do return @object_hashes[arch_dir] unless @object_hashes[arch_dir].nil? send(plural_fn) # create the hash @object_hashes[arch_dir] end define_method(fn_name) do |name| return @object_hashes[arch_dir][name] unless @object_hashes[arch_dir].nil? send(plural_fn) # create the hash @object_hashes[arch_dir][name] end end |
Instance Method Details
#exception_codes ⇒ Array<ExceptionCode>
Returns All exception codes defined by the spec.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/udb/architecture.rb', line 316 def exception_codes return @exception_codes unless @exception_codes.nil? @exception_codes = extensions.reduce([]) do |list, ext| ecodes = extension(ext.name).data["exception_codes"] next list if ecodes.nil? ecodes.each do |ecode| # double check that all the codes are unique raise "Duplicate exception code" if list.any? { |e| e.num == ecode["num"] || e.name == ecode["name"] || e.var == ecode["var"] } list << ExceptionCode.new(ecode["name"], ecode["var"], ecode["num"], ext) end list end end |
#interrupt_codes ⇒ Array<InteruptCode>
Returns All interrupt codes defined by extensions.
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/udb/architecture.rb', line 335 def interrupt_codes return @interrupt_codes unless @interrupt_codes.nil? @interupt_codes = extensions.reduce([]) do |list, ext| icodes = extension(ext.name).data["interrupt_codes"] next list if icodes.nil? icodes.each do |icode| # double check that all the codes are unique if list.any? { |i| i.num == icode["num"] || i.name == icode["name"] || i.var == icode["var"] } raise "Duplicate interrupt code" end list << InterruptCode.new(icode["name"], icode["var"], icode["num"], ext) end list end end |
#objs ⇒ Array<TopLevelDatabaseObject>
Returns All known objects.
234 235 236 237 238 239 240 241 242 |
# File 'lib/udb/architecture.rb', line 234 def objs return @objs unless @objs.nil? @objs = [] OBJS.each do |obj_info| @objs.concat(send(ActiveSupport::Inflector.pluralize(obj_info[:fn_name]))) end @objs.freeze end |
#param(name) ⇒ nil, Parameter
265 266 267 |
# File 'lib/udb/architecture.rb', line 265 def param(name) param_hash[name] end |
#param_hash ⇒ Hash<String, Parameter>
Returns Hash of all extension parameters defined in the architecture.
252 253 254 255 256 257 258 259 260 |
# File 'lib/udb/architecture.rb', line 252 def param_hash return @param_hash unless @param_hash.nil? @param_hash = {} params.each do |param| @param_hash[param.name] = param end @param_hash end |
#params ⇒ Array<Parameter>
Returns Alphabetical list of all parameters defined in the architecture.
245 246 247 248 249 |
# File 'lib/udb/architecture.rb', line 245 def params return @params unless @params.nil? @params = extensions.map(&:params).flatten.uniq(&:name).sort_by!(&:name) end |
#portfolio(name) ⇒ PortfolioClass?
311 312 313 |
# File 'lib/udb/architecture.rb', line 311 def portfolio(name) portfolio_hash[name] end |
#portfolio_class(name) ⇒ PortfolioClass?
289 |
# File 'lib/udb/architecture.rb', line 289 def portfolio_class(name) = portfolio_class_hash[name] |
#portfolio_class_hash ⇒ Hash<String, PortfolioClass>
Returns Hash of all portfolio classes defined in the architecture.
277 278 279 280 281 282 283 284 285 |
# File 'lib/udb/architecture.rb', line 277 def portfolio_class_hash return @portfolio_class_hash unless @portfolio_class_hash.nil? @portfolio_class_hash = {} portfolio_classes.each do |portfolio_class| @portfolio_class_hash[portfolio_class.name] = portfolio_class end @portfolio_class_hash end |
#portfolio_classes ⇒ Array<PortfolioClass>
Returns Alphabetical list of all portfolio classes defined in the architecture.
270 271 272 273 274 |
# File 'lib/udb/architecture.rb', line 270 def portfolio_classes return @portfolio_classes unless @portfolio_classes.nil? @portfolio_classes = profile_families.concat(proc_cert_classes).sort_by!(&:name) end |
#portfolio_hash ⇒ Hash<String, Portfolio>
Returns Hash of all portfolios defined in the architecture.
299 300 301 302 303 304 305 306 307 |
# File 'lib/udb/architecture.rb', line 299 def portfolio_hash return @portfolio_hash unless @portfolio_hash.nil? @portfolio_hash = {} portfolios.each do |portfolio| @portfolio_hash[portfolio.name] = portfolio end @portfolio_hash end |
#portfolios ⇒ Array<Portfolio>
Returns Alphabetical list of all portfolios defined in the architecture.
292 293 294 295 296 |
# File 'lib/udb/architecture.rb', line 292 def portfolios return @portfolios unless @portfolios.nil? @portfolios = @profiles.concat(@certificates).sort_by!(&:name) end |
#ref(uri) ⇒ DatabaseObject
given a ‘$ref` target, return the Ruby object
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/udb/architecture.rb', line 360 def ref(uri) raise ArgumentError, "JSON Reference (#{uri}) must contain one '#'" unless uri.count("#") == 1 file_path, obj_path = uri.split("#") obj = case file_path when /^proc_cert_class.*/ proc_cert_class_name = File.basename(file_path, ".yaml") proc_cert_class(proc_cert_class_name) when /^proc_cert_model.*/ proc_cert_model_name = File.basename(file_path, ".yaml") proc_cert_model(proc_cert_model_name) when /^csr.*/ csr_name = File.basename(file_path, ".yaml") csr(csr_name) when /^ext.*/ ext_name = File.basename(file_path, ".yaml") extension(ext_name) when %r{^inst/.*} inst_name = File.basename(file_path, ".yaml") instruction(inst_name) when /^manual.*/ manual_name = File.basename(file_path, ".yaml") manual(manual_name) when /^manual_version.*/ manual_name = File.basename(file_path, ".yaml") manual_version(manual_name) when /^profile_family.*/ profile_family_name = File.basename(file_path, ".yaml") profile_family(profile_family_name) when /^profile_release.*/ profile_release_name = File.basename(file_path, ".yaml") profile_release(profile_release_name) when /^profile.*/ profile_name = File.basename(file_path, ".yaml") profile(profile_name) when %r{^inst_subtype/.*/.*} inst_subtype_name = File.basename(file_path, ".yaml") instruction_subtype(inst_subtype_name) when %r{^inst_type/[^/]+} # type inst_type_name = File.basename(file_path, ".yaml") instruction_type(inst_type_name) else raise "Unhandled ref object: #{file_path}" end unless obj_path.nil? parts = obj_path.split("/") parts.each do |part| raise "Error in $ref. There is no method '#{part}' for a #{obj.class.name}" unless obj.respond_to?(part.to_sym) obj = obj.send(part) end end obj end |
#validate(resolver, show_progress: true)
This method returns an undefined value.
validate the architecture against JSON Schema and any object-specific verification
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/udb/architecture.rb', line 83 def validate(resolver, show_progress: true) = ProgressBar.create(total: objs.size) if show_progress objs.each do |obj| next unless obj.is_a?(TopLevelDatabaseObject) .increment if show_progress obj.validate(resolver) end end |