Module: Opencdd::Parcel::LayoutDetector
- Defined in:
- lib/opencdd/parcel/layout_detector.rb
Overview
Single source of truth for Parcel on-disk layout detection.
Three layouts exist in the wild:
[legacy single] one export_*.xls file per type
(CLASS, PROPERTY, RELATION, UNIT, VALUELIST,
VALUETERMS).
[flat dir] a directory containing those six files at the
top level.
[sharded dir] a directory containing one subdir per class
code, each subdir holding 1-6 export_*.xls
files either directly (flat sharded) or under
a UNID-named version subfolder (per-version
sharded, identified by _entity.json).
Previously Reader, FlatDirReader,
ShardedDirReader, and ScrapeVerifier
each held their own copies of the regexes and detection
helpers. Layout drift meant patching N files. Now they all
delegate here.
Constant Summary collapse
- CLASS_CODE_PATTERN =
Class-code shape per IEC CDD conventions: 2-6 uppercase letters, 1-6 digits, optional alnum suffix.
/\A[A-Z]{2,6}[0-9]{1,6}[A-Z0-9-]*\z/.freeze
- UNID_PATTERN =
Harvester per-version subfolder name (Lotus Notes UNID).
/\A[0-9A-F]{32}\z/i.freeze
- FILE_PATTERN =
Per-type export filename produced by cdd.iec.ch's download endpoint.
/\Aexport_(CLASS|PROPERTY|RELATION|UNIT|VALUELIST|VALUETERMS)_[^\.]+\.(xls|xlsx)\z/i.freeze
Class Method Summary collapse
-
.active_xls_dir(code_dir) ⇒ Object
Returns the directory holding the active
export_*.xlsfiles for a given class-code dir, ornilwhen no XLS is present. -
.class_code?(name) ⇒ Boolean
True if
namelooks like a class code (AAA001, UAC696, ...). -
.legacy_export?(filename) ⇒ Boolean
True if
filenameis one of the harvester's export_* files. -
.sharded_class_subdir?(path) ⇒ Boolean
True if
pathis a sharded class-code subdir (contains XLS directly or via the per-version layout). -
.unid?(name) ⇒ Boolean
True if
nameis a UNID-named subfolder.
Class Method Details
.active_xls_dir(code_dir) ⇒ Object
Returns the directory holding the active export_*.xls files
for a given class-code dir, or nil when no XLS is present.
Resolution order:
1. Per-version: +_entity.json+ names a UNID subfolder.
2. Per-version (no manifest): a single UNID subfolder with XLS.
3. Flat sharded: XLS files directly under +code_dir+.
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 |
# File 'lib/opencdd/parcel/layout_detector.rb', line 64 def active_xls_dir(code_dir) return nil unless File.directory?(code_dir) # Per-version with manifest. manifest = File.join(code_dir, "_entity.json") if File.file?(manifest) current = read_current_version_dir(manifest) if current && unid?(current) candidate = File.join(code_dir, current) return candidate if File.directory?(candidate) end end # Per-version without manifest: unique UNID subfolder with XLS. unid_subdirs = Dir.children(code_dir) .select { |n| unid?(n) } .map { |n| File.join(code_dir, n) } .select { |p| File.directory?(p) } if unid_subdirs.size == 1 active = unid_subdirs.first return active if Dir.children(active).any? { |f| legacy_export?(f) } end # Flat sharded. return code_dir if Dir.children(code_dir).any? { |f| legacy_export?(f) } nil end |
.class_code?(name) ⇒ Boolean
True if name looks like a class code (AAA001, UAC696, ...).
40 41 42 43 |
# File 'lib/opencdd/parcel/layout_detector.rb', line 40 def class_code?(name) return false if name.nil? name.match?(CLASS_CODE_PATTERN) end |
.legacy_export?(filename) ⇒ Boolean
True if filename is one of the harvester's export_* files.
46 47 48 49 |
# File 'lib/opencdd/parcel/layout_detector.rb', line 46 def legacy_export?(filename) return false if filename.nil? filename.match?(FILE_PATTERN) end |
.sharded_class_subdir?(path) ⇒ Boolean
True if path is a sharded class-code subdir (contains XLS
directly or via the per-version layout).
95 96 97 98 99 |
# File 'lib/opencdd/parcel/layout_detector.rb', line 95 def sharded_class_subdir?(path) return false unless File.directory?(path) return false unless class_code?(File.basename(path)) !active_xls_dir(path).nil? end |
.unid?(name) ⇒ Boolean
True if name is a UNID-named subfolder.
52 53 54 55 |
# File 'lib/opencdd/parcel/layout_detector.rb', line 52 def unid?(name) return false if name.nil? name.match?(UNID_PATTERN) end |