onoma 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +93 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config/locales/arb.yml +5711 -0
- data/config/locales/eng.yml +5704 -0
- data/config/locales/fra.yml +5869 -0
- data/config/locales/jpn.yml +5713 -0
- data/config/locales/por.yml +5702 -0
- data/config/locales/spa.yml +5708 -0
- data/db/migrate/20150813022423_add_data.xml +5740 -0
- data/db/migrate/20150813224145_fix_zea.xml +14 -0
- data/db/migrate/20150813224155_fix_hordeum.xml +175 -0
- data/db/migrate/20150814104907_rename_charts_of_accounts.xml +4 -0
- data/db/migrate/20150817202608_rename_abaci.xml +19 -0
- data/db/migrate/20150818132801_add_vinifera_product_exchangers.xml +4 -0
- data/db/migrate/20150818152001_add_wine_bottles.xml +13 -0
- data/db/migrate/20150818232501_add_vinifera_sale_exchangers.xml +4 -0
- data/db/migrate/20150820212931_remove_abaci.xml +19 -0
- data/db/migrate/20150821082601_add_grain_variants.xml +4 -0
- data/db/migrate/20150821230800_rename_invalid_document_natures.xml +12 -0
- data/db/migrate/20150825180658_add_production_usages.xml +5 -0
- data/db/migrate/20150826091319_add_leguminous_crop.xml +11 -0
- data/db/migrate/20150826092813_add_cannabis_varieties.xml +51 -0
- data/db/migrate/20150826100013_add_thicket_varieties.xml +9 -0
- data/db/migrate/20150826103353_add_eis_plant.xml +31 -0
- data/db/migrate/20150902081701_add_garden_varieties.xml +7 -0
- data/db/migrate/20150905094701_add_milklic_individual_production_exchangers.xml +4 -0
- data/db/migrate/20150914095928_add_meteorological_analysis_nature.xml +46 -0
- data/db/migrate/20150916110501_add_grain_analysis.xml +5 -0
- data/db/migrate/20150916151652_fix_product_nature_variant_units.xml +515 -0
- data/db/migrate/20150919123840_fix_plant_varieties.xml +36 -0
- data/db/migrate/20150919223801_change_walnut_nature.xml +6 -0
- data/db/migrate/20150920212201_add_fruit_harvest.xml +4 -0
- data/db/migrate/20150921104001_add_fuel_consumption_indicator.xml +7 -0
- data/db/migrate/20150921110601_add_crumbs_exchangers.xml +4 -0
- data/db/migrate/20150921175601_add_units_liter_per_hour.xml +4 -0
- data/db/migrate/20151001154701_add_missing_variants.xml +9 -0
- data/db/migrate/20151019090110_add_json_exchange_natures.xml +11 -0
- data/db/migrate/20151021172901_add_missing_indicator_on_animals.xml +12 -0
- data/db/migrate/20151027095601_add_missing_issue_natures.xml +6 -0
- data/db/migrate/20151102110723_add_daily_nitrogen_production_indicator.xml +4 -0
- data/db/migrate/20151107122501_add_cap_statements_exchangers.xml +4 -0
- data/db/migrate/20151111212501_add_missing_cap_productions.xml +15 -0
- data/db/migrate/20151117192943_change_procedure_nomenclatures.xml +159 -0
- data/db/migrate/20151122101101_add_missing_tropical_cap_varieties.xml +33 -0
- data/db/migrate/20151125163801_add_missing_varieties.xml +7 -0
- data/db/migrate/20151209000401_add_missing_crop_sets.xml +12 -0
- data/db/migrate/20151209011801_add_missing_varieties.xml +45 -0
- data/db/migrate/20151209094701_add_oleaginous_missing_varieties.xml +11 -0
- data/db/migrate/20151209103601_add_proteaginous_missing_varieties.xml +6 -0
- data/db/migrate/20151210150144_add_daucus_carota_varieties.xml +38 -0
- data/db/migrate/20151210163440_add_phaseolus_varieties.xml +11 -0
- data/db/migrate/20151210164511_add_allium_porrum_varieties.xml +13 -0
- data/db/migrate/20151210170103_add_allium_cepa_varieties.xml +6 -0
- data/db/migrate/20151211114316_add_beta_varieties.xml +4 -0
- data/db/migrate/20151211115500_add_brassica_varieties.xml +50 -0
- data/db/migrate/20151211124757_add_allium_schoenoprasum_varieties.xml +4 -0
- data/db/migrate/20151211132045_add_cucurbita_varieties.xml +13 -0
- data/db/migrate/20151211143806_add_spinacia_oleracea_varieties.xml +5 -0
- data/db/migrate/20151211151402_add_lactuca_varieties.xml +6 -0
- data/db/migrate/20151211153218_add_zea_mays_varieties.xml +46 -0
- data/db/migrate/20151214084817_add_hordeum_varieties.xml +5 -0
- data/db/migrate/20151214085342_add_pastinaca_sativa_varieties.xml +4 -0
- data/db/migrate/20151214085721_add_pisum_sativum_varieties.xml +8 -0
- data/db/migrate/20151214090420_add_solanum_tuberosum_varieties.xml +4 -0
- data/db/migrate/20151214091020_add_raphanus_varieties.xml +8 -0
- data/db/migrate/20151214092727_add_glycine_max_varieties.xml +4 -0
- data/db/migrate/20151215132825_add_abilities.xml +7 -0
- data/db/migrate/20151215133320_add_equipment_variants.xml +43 -0
- data/db/migrate/20151215214901_add_openwheatermap_identifiers.xml +5 -0
- data/db/migrate/20151216095351_add_ridger_equipment_variants.xml +4 -0
- data/db/migrate/20151216100708_add_lifter_equipment_variants.xml +4 -0
- data/db/migrate/20151216160914_add_raphanus_sativus_varieties.xml +4 -0
- data/db/migrate/20151216182551_add_more_units.xml +7 -0
- data/db/migrate/20151218081701_add_crops_issue_natures.xml +11 -0
- data/db/migrate/20151222162657_add_varieties.xml +18 -0
- data/db/migrate/20151222180021_remove_population.xml +402 -0
- data/db/reference.xml +5727 -0
- data/lib/onoma/database.rb +171 -0
- data/lib/onoma/item.rb +272 -0
- data/lib/onoma/migration/actions/base.rb +19 -0
- data/lib/onoma/migration/actions/item_change.rb +35 -0
- data/lib/onoma/migration/actions/item_creation.rb +39 -0
- data/lib/onoma/migration/actions/item_merging.rb +19 -0
- data/lib/onoma/migration/actions/item_removal.rb +18 -0
- data/lib/onoma/migration/actions/nomenclature_change.rb +26 -0
- data/lib/onoma/migration/actions/nomenclature_creation.rb +24 -0
- data/lib/onoma/migration/actions/nomenclature_removal.rb +24 -0
- data/lib/onoma/migration/actions/property_creation.rb +43 -0
- data/lib/onoma/migration/actions.rb +9 -0
- data/lib/onoma/migration/base.rb +45 -0
- data/lib/onoma/migration.rb +11 -0
- data/lib/onoma/migrator/reference.rb +77 -0
- data/lib/onoma/migrator/translation.rb +30 -0
- data/lib/onoma/migrator.rb +3 -0
- data/lib/onoma/nomenclature.rb +507 -0
- data/lib/onoma/property.rb +98 -0
- data/lib/onoma/reference.rb +17 -0
- data/lib/onoma/reflection.rb +34 -0
- data/lib/onoma/relation.rb +9 -0
- data/lib/onoma/version.rb +3 -0
- data/lib/onoma.rb +133 -0
- data/onoma.gemspec +28 -0
- metadata +237 -0
@@ -0,0 +1,171 @@
|
|
1
|
+
module Onoma
|
2
|
+
# This class represents a set of nomenclature like the reference DB
|
3
|
+
class Database
|
4
|
+
attr_accessor :version
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@nomenclatures = ActiveSupport::HashWithIndifferentAccess.new
|
8
|
+
@version = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.load_file(file)
|
12
|
+
set = new
|
13
|
+
f = File.open(file, 'rb')
|
14
|
+
document = Nokogiri::XML(f) do |config|
|
15
|
+
config.strict.nonet.noblanks.noent
|
16
|
+
end
|
17
|
+
f.close
|
18
|
+
document.root.children.each do |nomenclature|
|
19
|
+
set.harvest_nomenclature(nomenclature)
|
20
|
+
end
|
21
|
+
set.version = document.root['version'].to_i
|
22
|
+
set
|
23
|
+
end
|
24
|
+
|
25
|
+
def nomenclature_names
|
26
|
+
@nomenclatures.keys
|
27
|
+
end
|
28
|
+
|
29
|
+
def nomenclatures
|
30
|
+
@nomenclatures.values
|
31
|
+
end
|
32
|
+
|
33
|
+
# Find nomenclature
|
34
|
+
def [](nomenclature_name)
|
35
|
+
@nomenclatures[nomenclature_name]
|
36
|
+
end
|
37
|
+
alias_method :find, :[]
|
38
|
+
alias_method :nomenclature, :[]
|
39
|
+
|
40
|
+
# Find item
|
41
|
+
def item(nomenclature_name, item_name)
|
42
|
+
nomenclature = find!(nomenclature_name)
|
43
|
+
nomenclature.item(item_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Find property
|
47
|
+
def property(nomenclature_name, property_name)
|
48
|
+
nomenclature = find!(nomenclature_name)
|
49
|
+
nomenclature.property(property_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
def find!(name)
|
53
|
+
unless nomenclature = @nomenclatures[name]
|
54
|
+
fail "Nomenclature #{name} does not exist"
|
55
|
+
end
|
56
|
+
nomenclature
|
57
|
+
end
|
58
|
+
|
59
|
+
def exist?(name)
|
60
|
+
@nomenclatures[name].present?
|
61
|
+
end
|
62
|
+
|
63
|
+
def each(&block)
|
64
|
+
if block.arity == 2
|
65
|
+
@nomenclatures.each(&block)
|
66
|
+
else
|
67
|
+
nomenclatures.each(&block)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns references between nomenclatures
|
72
|
+
def references
|
73
|
+
list = []
|
74
|
+
each do |nomenclature|
|
75
|
+
list += nomenclature.references
|
76
|
+
end
|
77
|
+
list
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_xml
|
81
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
82
|
+
xml.nomenclatures(xmlns: Onoma::XMLNS, version: @version) do
|
83
|
+
@nomenclatures.values.sort.each do |nomenclature|
|
84
|
+
xml.nomenclature(nomenclature.to_xml_attrs) do
|
85
|
+
xml.properties do
|
86
|
+
nomenclature.properties.values.sort.each do |property|
|
87
|
+
xml.property(property.to_xml_attrs)
|
88
|
+
end
|
89
|
+
end if nomenclature.properties.any?
|
90
|
+
xml.items do
|
91
|
+
nomenclature.items.values.sort { |a, b| a.name <=> b.name }.each do |item|
|
92
|
+
xml.item(item.to_xml_attrs)
|
93
|
+
end
|
94
|
+
end if nomenclature.items.any?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
builder.to_xml
|
100
|
+
end
|
101
|
+
|
102
|
+
def harvest_nomenclature(element)
|
103
|
+
nomenclature = Nomenclature.harvest(element, set: self)
|
104
|
+
@nomenclatures[nomenclature.name] = nomenclature
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_nomenclature(name, options = {})
|
108
|
+
fail "Nomenclature #{name} already exists" if @nomenclatures[name]
|
109
|
+
options[:set] = self
|
110
|
+
@nomenclatures[name] = Nomenclature.new(name, options)
|
111
|
+
end
|
112
|
+
|
113
|
+
def move_nomenclature(old_name, new_name)
|
114
|
+
unless @nomenclatures[old_name]
|
115
|
+
fail "Nomenclature #{old_name} does not exist"
|
116
|
+
end
|
117
|
+
fail "Nomenclature #{new_name} already exists" if @nomenclatures[new_name]
|
118
|
+
@nomenclatures[new_name] = @nomenclatures.delete(old_name)
|
119
|
+
@nomenclatures[new_name]
|
120
|
+
end
|
121
|
+
|
122
|
+
def change_nomenclature(nomenclature_name, updates = {})
|
123
|
+
nomenclature = find!(nomenclature_name)
|
124
|
+
nomenclature.update_attributes(updates)
|
125
|
+
if updates[:name]
|
126
|
+
nomenclature = move_nomenclature(nomenclature_name, updates[:name])
|
127
|
+
end
|
128
|
+
nomenclature
|
129
|
+
end
|
130
|
+
|
131
|
+
def remove_nomenclature(nomenclature_name)
|
132
|
+
nomenclature = find!(nomenclature_name)
|
133
|
+
@nomenclatures.delete(nomenclature_name)
|
134
|
+
end
|
135
|
+
|
136
|
+
def add_property(nomenclature_name, property_name, type, options = {})
|
137
|
+
nomenclature = find!(nomenclature_name)
|
138
|
+
nomenclature.add_property(property_name, type, options)
|
139
|
+
end
|
140
|
+
|
141
|
+
def change_property(_nomenclature_name, _property_name, _updates = {})
|
142
|
+
fail NotImplementedError
|
143
|
+
end
|
144
|
+
|
145
|
+
def remove_property(_nomenclature_name, _property_name, _options = {})
|
146
|
+
fail NotImplementedError
|
147
|
+
end
|
148
|
+
|
149
|
+
def add_item(nomenclature_name, item_name, options = {})
|
150
|
+
nomenclature = find!(nomenclature_name)
|
151
|
+
options = nomenclature.cast_options(options)
|
152
|
+
nomenclature.add_item(item_name, options)
|
153
|
+
end
|
154
|
+
|
155
|
+
def change_item(nomenclature_name, item_name, updates = {})
|
156
|
+
nomenclature = find!(nomenclature_name)
|
157
|
+
updates = nomenclature.cast_options(updates)
|
158
|
+
nomenclature.change_item(item_name, updates)
|
159
|
+
end
|
160
|
+
|
161
|
+
def merge_item(nomenclature_name, item_name, into)
|
162
|
+
nomenclature = find!(nomenclature_name)
|
163
|
+
nomenclature.merge_item(item_name, into)
|
164
|
+
end
|
165
|
+
|
166
|
+
def remove_item(nomenclature_name, item_name)
|
167
|
+
nomenclature = find!(nomenclature_name)
|
168
|
+
nomenclature.remove_item(item_name)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
data/lib/onoma/item.rb
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
module Onoma
|
2
|
+
# An item of a nomenclature is the core data.
|
3
|
+
class Item
|
4
|
+
attr_reader :nomenclature, :left, :right, :depth, :aliases, :parent_name
|
5
|
+
attr_accessor :name, :attributes
|
6
|
+
alias_method :properties, :attributes
|
7
|
+
|
8
|
+
# New item
|
9
|
+
def initialize(nomenclature, name, options = {})
|
10
|
+
@nomenclature = nomenclature
|
11
|
+
@name = name.to_s
|
12
|
+
@left, @right = @nomenclature.new_boundaries
|
13
|
+
@depth = 0
|
14
|
+
parent = options.delete(:parent)
|
15
|
+
if parent.is_a?(Symbol) || parent.is_a?(String)
|
16
|
+
@parent_name = parent.to_s
|
17
|
+
else
|
18
|
+
self.parent = parent
|
19
|
+
end
|
20
|
+
@attributes = ActiveSupport::HashWithIndifferentAccess.new
|
21
|
+
options.each do |k, v|
|
22
|
+
set(k, v)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def root?
|
27
|
+
!parent
|
28
|
+
end
|
29
|
+
|
30
|
+
def parent=(item)
|
31
|
+
old_parent_name = @parent_name
|
32
|
+
if item.nil?
|
33
|
+
@parent = nil
|
34
|
+
@parent_name = nil
|
35
|
+
else
|
36
|
+
if item.is_a?(Symbol) || item.is_a?(String)
|
37
|
+
item = nomenclature.find!(item.to_s)
|
38
|
+
end
|
39
|
+
if item.nomenclature != nomenclature
|
40
|
+
fail 'Item must come from same nomenclature'
|
41
|
+
end
|
42
|
+
if item.parents.include?(self) || item == self
|
43
|
+
fail 'Circular dependency. Item can be parent of itself.'
|
44
|
+
end
|
45
|
+
@parent = item
|
46
|
+
@parent_name = @parent.name.to_s
|
47
|
+
end
|
48
|
+
@nomenclature.rebuild_tree! if old_parent_name != @parent_name
|
49
|
+
end
|
50
|
+
|
51
|
+
# Changes parent without rebuilding
|
52
|
+
def parent_name=(name)
|
53
|
+
@parent = nil
|
54
|
+
@parent_name = name.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
def parent?
|
58
|
+
parent.present?
|
59
|
+
end
|
60
|
+
|
61
|
+
def parent
|
62
|
+
@parent ||= @nomenclature.find(@parent_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
def original_nomenclature_name
|
66
|
+
return parent.name.to_sym unless root?
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns children recursively by default
|
71
|
+
def children(options = {})
|
72
|
+
if options[:index].is_a?(FalseClass)
|
73
|
+
if options[:recursively].is_a?(FalseClass)
|
74
|
+
return nomenclature.list.select do |item|
|
75
|
+
(item.parent == self)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
return children(index: false, recursive: false).each_with_object([]) do |item, list|
|
79
|
+
list << item
|
80
|
+
list += item.children(index: false, recursive: true)
|
81
|
+
list
|
82
|
+
end
|
83
|
+
end
|
84
|
+
else
|
85
|
+
if options[:recursively].is_a?(FalseClass)
|
86
|
+
return nomenclature.list.select do |item|
|
87
|
+
@left < item.left && item.right < @right && item.depth == @depth + 1
|
88
|
+
end
|
89
|
+
else
|
90
|
+
# @children ||=
|
91
|
+
return nomenclature.list.select do |item|
|
92
|
+
@left < item.left && item.right < @right
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def root
|
99
|
+
self.parent? ? parent.root : self
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns direct parents from the closest to the farthest
|
103
|
+
def parents
|
104
|
+
@parents ||= (parent.nil? ? [] : [parent] + parent.parents)
|
105
|
+
end
|
106
|
+
|
107
|
+
def self_and_children(options = {})
|
108
|
+
[self] + children(options)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self_and_parents
|
112
|
+
[self] + parents
|
113
|
+
end
|
114
|
+
|
115
|
+
# Computes left/right value for nested set
|
116
|
+
# Returns right index
|
117
|
+
def rebuild_tree!
|
118
|
+
@nomenclature.forest_right = rebuild_tree(@nomenclature.forest_right + 1)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Computes left/right value for nested set
|
122
|
+
# Returns right index
|
123
|
+
def rebuild_tree(left = 0, depth = 0)
|
124
|
+
@depth = depth
|
125
|
+
@left = left
|
126
|
+
@right = @left + 1
|
127
|
+
children(index: false, recursively: false).each do |child|
|
128
|
+
@right = child.rebuild_tree(@right, @depth + 1) + 1
|
129
|
+
end
|
130
|
+
@right
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns true if the given item name match the current item or its children
|
134
|
+
def include?(other)
|
135
|
+
self >= other
|
136
|
+
end
|
137
|
+
|
138
|
+
# Return human name of item
|
139
|
+
def human_name(options = {})
|
140
|
+
"nomenclatures.#{nomenclature.name}.items.#{name}".t(options.merge(default: ["items.#{name}".to_sym, "enumerize.#{nomenclature.name}.#{name}".to_sym, "labels.#{name}".to_sym, name.humanize]))
|
141
|
+
end
|
142
|
+
alias_method :humanize, :human_name
|
143
|
+
|
144
|
+
def human_notion_name(notion_name, options = {})
|
145
|
+
"nomenclatures.#{nomenclature.name}.notions.#{notion_name}.#{name}".t(options.merge(default: ["labels.#{name}".to_sym]))
|
146
|
+
end
|
147
|
+
|
148
|
+
def ==(other)
|
149
|
+
other = item_for_comparison(other)
|
150
|
+
nomenclature == other.nomenclature && name == other.name
|
151
|
+
end
|
152
|
+
|
153
|
+
def <=>(other)
|
154
|
+
other = item_for_comparison(other)
|
155
|
+
nomenclature.name <=> other.nomenclature.name && name <=> other.name
|
156
|
+
end
|
157
|
+
|
158
|
+
def <(other)
|
159
|
+
other = item_for_comparison(other)
|
160
|
+
(other.left < @left && @right < other.right)
|
161
|
+
end
|
162
|
+
|
163
|
+
def >(other)
|
164
|
+
other = item_for_comparison(other)
|
165
|
+
(@left < other.left && other.right < @right)
|
166
|
+
end
|
167
|
+
|
168
|
+
def <=(other)
|
169
|
+
other = item_for_comparison(other)
|
170
|
+
(other.left <= @left && @right <= other.right)
|
171
|
+
end
|
172
|
+
|
173
|
+
def >=(other)
|
174
|
+
other = item_for_comparison(other)
|
175
|
+
(@left <= other.left && other.right <= @right)
|
176
|
+
end
|
177
|
+
|
178
|
+
def inspect
|
179
|
+
"#{@nomenclature.name}-#{@name}(#{@left}-#{@right})"
|
180
|
+
end
|
181
|
+
|
182
|
+
def tree(depth = 0)
|
183
|
+
text = "#{left.to_s.rjust(4)}-#{right.to_s.ljust(4)} #{' ' * depth}#{@name}:\n"
|
184
|
+
text << children(index: false, recursively: false).collect do |c|
|
185
|
+
c.tree(depth + 1)
|
186
|
+
end.join("\n")
|
187
|
+
text
|
188
|
+
end
|
189
|
+
|
190
|
+
def to_xml_attrs
|
191
|
+
attrs = {}
|
192
|
+
attrs[:name] = name
|
193
|
+
attrs[:parent] = @parent_name if self.parent?
|
194
|
+
properties.each do |pname, pvalue|
|
195
|
+
if p = nomenclature.properties[pname.to_s]
|
196
|
+
if p.type == :decimal
|
197
|
+
pvalue = pvalue.to_s.to_f
|
198
|
+
elsif p.list?
|
199
|
+
pvalue = pvalue.join(', ')
|
200
|
+
end
|
201
|
+
end
|
202
|
+
attrs[pname] = pvalue.to_s
|
203
|
+
end
|
204
|
+
attrs
|
205
|
+
end
|
206
|
+
|
207
|
+
# Returns property value
|
208
|
+
def property(name)
|
209
|
+
property = @nomenclature.properties[name]
|
210
|
+
value = @attributes[name]
|
211
|
+
if property
|
212
|
+
if value.nil? && property.fallbacks
|
213
|
+
for fallback in property.fallbacks
|
214
|
+
value ||= @attributes[fallback]
|
215
|
+
break if value
|
216
|
+
end
|
217
|
+
end
|
218
|
+
value ||= cast_property(name, property.default) if property.default
|
219
|
+
end
|
220
|
+
value
|
221
|
+
end
|
222
|
+
|
223
|
+
def selection(name)
|
224
|
+
property = @nomenclature.properties[name]
|
225
|
+
if property.list?
|
226
|
+
return property(name).collect do |i|
|
227
|
+
["nomenclatures.#{@nomenclature.name}.item_lists.#{self.name}.#{name}.#{i}".t, i]
|
228
|
+
end
|
229
|
+
elsif property.nomenclature?
|
230
|
+
return Onoma[property(name)].list.collect do |i|
|
231
|
+
[i.human_name, i.name]
|
232
|
+
end
|
233
|
+
else
|
234
|
+
fail StandardError, 'Cannot call selection for a non-list property'
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# Checks if item has property with given name
|
239
|
+
def has_property?(name)
|
240
|
+
!@nomenclature.properties[name].nil?
|
241
|
+
end
|
242
|
+
|
243
|
+
# Returns property descriptor
|
244
|
+
def method_missing(method_name, *args)
|
245
|
+
return property(method_name) if has_property?(method_name)
|
246
|
+
super
|
247
|
+
end
|
248
|
+
|
249
|
+
def set(name, value)
|
250
|
+
fail "Invalid property: #{name.inspect}" if [:name, :parent].include?(name.to_sym)
|
251
|
+
# TODO: check format
|
252
|
+
if property = nomenclature.properties[name]
|
253
|
+
value ||= [] if property.list?
|
254
|
+
end
|
255
|
+
@attributes[name] = value
|
256
|
+
end
|
257
|
+
|
258
|
+
private
|
259
|
+
|
260
|
+
def cast_property(name, value)
|
261
|
+
@nomenclature.cast_property(name, value)
|
262
|
+
end
|
263
|
+
|
264
|
+
def item_for_comparison(other)
|
265
|
+
item = nomenclature[other.is_a?(Item) ? other.name : other]
|
266
|
+
unless item
|
267
|
+
fail StandardError, "Invalid operand to compare: #{other.inspect} not in #{nomenclature.name}"
|
268
|
+
end
|
269
|
+
item
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class Base
|
5
|
+
def self.action_name
|
6
|
+
name.split('::').last.underscore
|
7
|
+
end
|
8
|
+
|
9
|
+
def action_name
|
10
|
+
self.class.action_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def label
|
14
|
+
action_name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class ItemChange < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :name, :changes
|
6
|
+
def initialize(element)
|
7
|
+
name = element['item'].split('#')
|
8
|
+
@nomenclature = name.first
|
9
|
+
@name = name.second
|
10
|
+
@changes = element.attributes.delete_if do |k, _v|
|
11
|
+
%w(item).include?(k)
|
12
|
+
end.each_with_object({}) do |(k, v), h|
|
13
|
+
h[k.to_sym] = v.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def new_name?
|
18
|
+
@changes[:name].present?
|
19
|
+
end
|
20
|
+
|
21
|
+
def new_name
|
22
|
+
@changes[:name]
|
23
|
+
end
|
24
|
+
|
25
|
+
def label
|
26
|
+
"change_item #{@nomenclature}##{@name}(" + changes.simple_print + ")"
|
27
|
+
end
|
28
|
+
|
29
|
+
def human_name
|
30
|
+
"Change item #{@nomenclature}##{@name} with " + changes.inspect
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class ItemCreation < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :name, :options
|
6
|
+
def initialize(element)
|
7
|
+
fail 'Need item attribute' unless element['item']
|
8
|
+
name = element['item'].split('#')
|
9
|
+
@nomenclature = name.first
|
10
|
+
@name = name.second
|
11
|
+
@options = element.attributes.delete_if do |k, _v|
|
12
|
+
k =~ /name(:[a-z]{3})?/ || %w(item parent nomenclature).include?(k)
|
13
|
+
end.each_with_object({}) do |(k, v), h|
|
14
|
+
h[k.to_sym] = v.to_s
|
15
|
+
end
|
16
|
+
@options[:parent] = element['parent'].to_sym if element.key?('parent')
|
17
|
+
end
|
18
|
+
|
19
|
+
def options?
|
20
|
+
@options.any?
|
21
|
+
end
|
22
|
+
|
23
|
+
def label
|
24
|
+
"create_item #{@nomenclature}##{@name}" + (@options.any? ? "(#{@options.simple_print})" : '')
|
25
|
+
end
|
26
|
+
|
27
|
+
def human_name
|
28
|
+
updates = []
|
29
|
+
updates << "#{@name} as name"
|
30
|
+
updates << "#{@parent} as parent" if parent?
|
31
|
+
@options.each do |k, v|
|
32
|
+
updates << "#{v} as #{k}"
|
33
|
+
end
|
34
|
+
sentence = "Create item #{@nomenclature}##{@name} with " + updates.to_sentence
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class ItemMerging < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :name, :into
|
6
|
+
def initialize(element)
|
7
|
+
name = element['item'].split('#')
|
8
|
+
@nomenclature = name.first
|
9
|
+
@name = name.second
|
10
|
+
@into = element['into'].to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def human_name
|
14
|
+
"Merge item #{@nomenclature}##{@name} into #{@into}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class ItemRemoval < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :name
|
6
|
+
def initialize(element)
|
7
|
+
name = element['item'].split('#')
|
8
|
+
@nomenclature = name.first
|
9
|
+
@name = name.second
|
10
|
+
end
|
11
|
+
|
12
|
+
def human_name
|
13
|
+
"Remove item #{@nomenclature}##{@name}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class NomenclatureChange < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :changes
|
6
|
+
|
7
|
+
def initialize(element)
|
8
|
+
fail 'No given name' unless element.key?('nomenclature')
|
9
|
+
@nomenclature = element['nomenclature'].to_s
|
10
|
+
@changes = {}
|
11
|
+
@changes[:name] = element['name'].to_s if element.key?('name')
|
12
|
+
if element.key?('notions')
|
13
|
+
@changes[:notions] = element.attr('notions').to_s.split(/\s*\,\s*/).map(&:to_sym)
|
14
|
+
end
|
15
|
+
if element.key?('translateable')
|
16
|
+
@changes[:translateable] = !(element.attr('translateable').to_s == 'false')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def human_name
|
21
|
+
"Update nomenclature #{@name} with " + changes.inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class NomenclatureCreation < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :options
|
6
|
+
|
7
|
+
def initialize(element)
|
8
|
+
@nomenclature = element.key?('nomenclature') ? element['nomenclature'].to_s : element.key?('name') ? element['name'].to_s : nil
|
9
|
+
fail 'No given name' unless @nomenclature
|
10
|
+
@options = {}
|
11
|
+
notions = element.attr('notions').to_s.split(/\s*\,\s*/).map(&:to_sym)
|
12
|
+
@options[:notions] = notions if notions.any?
|
13
|
+
@options[:translateable] = !(element.attr('translateable').to_s == 'false')
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :name, :nomenclature
|
17
|
+
|
18
|
+
def human_name
|
19
|
+
"Create nomenclature #{@name}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class NomenclatureRemoval < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature
|
6
|
+
|
7
|
+
def initialize(element)
|
8
|
+
@nomenclature = element['nomenclature']
|
9
|
+
fail 'No given nomenclature' if @nomenclature.blank?
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method :name, :nomenclature
|
13
|
+
|
14
|
+
def label
|
15
|
+
"remove_nomenclature #{@name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def human_name
|
19
|
+
"Remove nomenclature #{@name}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Onoma
|
2
|
+
module Migration
|
3
|
+
module Actions
|
4
|
+
class PropertyCreation < Onoma::Migration::Actions::Base
|
5
|
+
attr_reader :nomenclature, :name, :type, :options
|
6
|
+
def initialize(element)
|
7
|
+
name = element['property'].split('.')
|
8
|
+
@nomenclature = name.first
|
9
|
+
@name = name.second
|
10
|
+
@type = element['type'].to_sym
|
11
|
+
unless Property::TYPES.include?(@type)
|
12
|
+
fail ArgumentError, "Property #{name} type is unknown: #{@type.inspect}"
|
13
|
+
end
|
14
|
+
@options = {}
|
15
|
+
if element.has_attribute?('fallbacks')
|
16
|
+
@options[:fallbacks] = element.attr('fallbacks').to_s.strip.split(/[[:space:]]*\,[[:space:]]*/).map(&:to_sym)
|
17
|
+
end
|
18
|
+
if element.has_attribute?('default')
|
19
|
+
@options[:default] = element.attr('default').to_sym
|
20
|
+
end
|
21
|
+
@options[:required] = !!(element.attr('required').to_s == 'true')
|
22
|
+
# @options[:inherit] = !!(element.attr('inherit').to_s == 'true')
|
23
|
+
if element.has_attribute?('choices')
|
24
|
+
if type == :choice || type == :choice_list
|
25
|
+
@options[:choices] = element.attr('choices').to_s.strip.split(/[[:space:]]*\,[[:space:]]*/).map(&:to_sym)
|
26
|
+
elsif type == :item || type == :item_list
|
27
|
+
@options[:choices] = element.attr('choices').to_s.strip.to_sym
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def human_name
|
33
|
+
updates = []
|
34
|
+
updates << "#{@name} as name"
|
35
|
+
@options.each do |k, v|
|
36
|
+
updates << "#{v} as #{k}"
|
37
|
+
end
|
38
|
+
sentence = "Create property #{@nomenclature}.#{@name} with " + updates.to_sentence
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|