bcl 0.1.9 → 0.2.2

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.
@@ -39,517 +39,517 @@ end
39
39
 
40
40
  module BCL
41
41
 
42
- # each TagStruct represents a node in the taxonomy tree
43
- TagStruct = Struct.new(:level_hierarchy, :name, :description, :parent_tag, :child_tags, :terms)
44
-
45
- # each TermStruct represents a row in the master taxonomy
46
- TermStruct = Struct.new(:first_level, :second_level, :third_level, :level_hierarchy, :name, :description,
47
- :abbr, :data_type, :enums, :ip_written, :ip_symbol, :ip_mask, :si_written, :si_symbol, :si_mask, :unit_conversion, :default_val, :min_val, :max_val, :allow_multiple, :row, :tp_include, :tp_required, :tp_use_in_search, :tp_use_in_facets, :tp_show_data_to_data_users, :tp_third_party_testing, :tp_additional_web_dev_info, :tp_additional_data_user_info, :tp_additional_data_submitter_info)
48
-
49
-
50
- # class for parsing, validating, and querying the master taxonomy document
51
- class MasterTaxonomy
52
-
53
- # parse the master taxonomy document
54
- def initialize(xlsx_path = nil, sort_alpha = false)
55
- @sort_alphabetical = sort_alpha
56
-
57
- # hash of level_taxonomy to tag
58
- @tag_hash = Hash.new
59
-
60
- if xlsx_path.nil?
61
- # load from the current taxonomy
62
- path = current_taxonomy_path
63
- puts "Loading current taxonomy from #{path}"
64
- File.open(path, 'r') do |file|
65
- @tag_hash = Marshal.load(file)
66
- end
67
- else
68
- xlsx_path = Pathname.new(xlsx_path).realpath.to_s
69
- puts "Loading taxonomy file #{xlsx_path}"
70
-
71
- # WINDOWS ONLY SECTION BECAUSE THIS USES WIN32OLE
72
- if $have_win32ole
73
- begin
74
- excel = WIN32OLE::new('Excel.Application')
75
- xlsx = excel.Workbooks.Open(xlsx_path)
76
- terms_worksheet = xlsx.Worksheets("Terms")
77
- parse_terms(terms_worksheet)
78
- ensure
79
- # not really saving just pretending so don't get prompted on quit
80
- xlsx.saved = true
81
- excel.Quit
82
- WIN32OLE.ole_free(excel)
83
- excel.ole_free
84
- xlsx=nil
85
- excel=nil
86
- GC.start
42
+ # each TagStruct represents a node in the taxonomy tree
43
+ TagStruct = Struct.new(:level_hierarchy, :name, :description, :parent_tag, :child_tags, :terms)
44
+
45
+ # each TermStruct represents a row in the master taxonomy
46
+ TermStruct = Struct.new(:first_level, :second_level, :third_level, :level_hierarchy, :name, :description,
47
+ :abbr, :data_type, :enums, :ip_written, :ip_symbol, :ip_mask, :si_written, :si_symbol, :si_mask, :unit_conversion, :default_val, :min_val, :max_val, :allow_multiple, :row, :tp_include, :tp_required, :tp_use_in_search, :tp_use_in_facets, :tp_show_data_to_data_users, :tp_third_party_testing, :tp_additional_web_dev_info, :tp_additional_data_user_info, :tp_additional_data_submitter_info)
48
+
49
+
50
+ # class for parsing, validating, and querying the master taxonomy document
51
+ class MasterTaxonomy
52
+
53
+ # parse the master taxonomy document
54
+ def initialize(xlsx_path = nil, sort_alpha = false)
55
+ @sort_alphabetical = sort_alpha
56
+
57
+ # hash of level_taxonomy to tag
58
+ @tag_hash = Hash.new
59
+
60
+ if xlsx_path.nil?
61
+ # load from the current taxonomy
62
+ path = current_taxonomy_path
63
+ puts "Loading current taxonomy from #{path}"
64
+ File.open(path, 'r') do |file|
65
+ @tag_hash = Marshal.load(file)
87
66
  end
88
- else # if $have_win32ole
89
- puts "MasterTaxonomy class requires 'win32ole' to parse master taxonomy document."
90
- puts "MasterTaxonomy may also be stored and loaded from JSON if your platform does not support win32ole."
91
- end # if $have_win32ole
92
- end
93
- end
67
+ else
68
+ xlsx_path = Pathname.new(xlsx_path).realpath.to_s
69
+ puts "Loading taxonomy file #{xlsx_path}"
94
70
 
95
- # save the current taxonomy
96
- def save_as_current_taxonomy(path = nil)
97
- if not path
98
- path = current_taxonomy_path
99
- end
100
- puts "Saving current taxonomy to #{path}"
101
- # this is really not JSON... it is a persisted format of ruby
102
- File.open(path, 'w') do |file|
103
- Marshal.dump(@tag_hash, file)
71
+ # WINDOWS ONLY SECTION BECAUSE THIS USES WIN32OLE
72
+ if $have_win32ole
73
+ begin
74
+ excel = WIN32OLE::new('Excel.Application')
75
+ xlsx = excel.Workbooks.Open(xlsx_path)
76
+ terms_worksheet = xlsx.Worksheets("Terms")
77
+ parse_terms(terms_worksheet)
78
+ ensure
79
+ # not really saving just pretending so don't get prompted on quit
80
+ xlsx.saved = true
81
+ excel.Quit
82
+ WIN32OLE.ole_free(excel)
83
+ excel.ole_free
84
+ xlsx=nil
85
+ excel=nil
86
+ GC.start
87
+ end
88
+ else # if $have_win32ole
89
+ puts "MasterTaxonomy class requires 'win32ole' to parse master taxonomy document."
90
+ puts "MasterTaxonomy may also be stored and loaded from JSON if your platform does not support win32ole."
91
+ end # if $have_win32ole
92
+ end
104
93
  end
105
- end
106
-
107
- # write taxonomy to xml
108
- def write_xml(path, output_type = 'tpex')
109
-
110
- root_tag = @tag_hash[""]
111
-
112
- if root_tag.nil?
113
- puts "Cannot find root tag"
114
- return false
94
+
95
+ # save the current taxonomy
96
+ def save_as_current_taxonomy(path = nil)
97
+ if not path
98
+ path = current_taxonomy_path
99
+ end
100
+ puts "Saving current taxonomy to #{path}"
101
+ # this is really not JSON... it is a persisted format of ruby
102
+ File.open(path, 'w') do |file|
103
+ Marshal.dump(@tag_hash, file)
104
+ end
115
105
  end
116
106
 
117
- File.open(path, 'w') do |file|
118
- xml = Builder::XmlMarkup.new(:target => file, :indent=>2)
107
+ # write taxonomy to xml
108
+ def write_xml(path, output_type = 'tpex')
119
109
 
120
- #setup the xml file
121
- xml.instruct!(:xml, :version=>"1.0", :encoding=>"UTF-8")
122
- xml.schema("xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance") {
123
- write_tag_to_xml(root_tag, 0, xml, output_type)
124
- }
125
- end
126
-
127
- end
128
-
129
- # get all terms for a given tag
130
- # this includes terms that are inherited from parent levels
131
- # e.g. master_taxonomy.get_terms("Space Use.Lighting.Lamp Ballast")
132
- def get_terms(tag)
133
-
134
- terms = tag.terms
135
-
136
- parent_tag = tag.parent_tag
137
- while not parent_tag.nil?
138
- terms.concat(parent_tag.terms)
139
- parent_tag = parent_tag.parent_tag
140
- end
141
-
142
-
143
- #sort the terms as they come out
144
- result = terms.uniq
145
- if !@sort_alphabetical
146
- result = result.sort {|x, y| x.row <=> y.row}
147
- else
148
- result = result.sort {|x, y| x.name <=> y.name}
149
- end
150
-
151
- return result
152
- end
153
-
154
- # check that the given component is conforms with the master taxonomy
155
- def check_component(component)
156
- valid = true
157
- tag = nil
158
-
159
- # see if we can find the component's tag in the taxonomy
160
- tags = component.tags
161
- if tags.empty?
162
- puts "[Check Component ERROR] Component does not have any tags"
163
- valid = false
164
- elsif tags.size > 1
165
- puts "[Check Component ERROR] Component has multiple tags"
166
- valid = false
167
- else
168
- tag = @tag_hash[tags[0].descriptor]
169
- if not tag
170
- puts "[Check Component ERROR] Cannot find #{tags[0].descriptor} in the master taxonomy"
171
- valid = false
110
+ root_tag = @tag_hash[""]
111
+
112
+ if root_tag.nil?
113
+ puts "Cannot find root tag"
114
+ return false
115
+ end
116
+
117
+ File.open(path, 'w') do |file|
118
+ xml = Builder::XmlMarkup.new(:target => file, :indent=>2)
119
+
120
+ #setup the xml file
121
+ xml.instruct!(:xml, :version=>"1.0", :encoding=>"UTF-8")
122
+ xml.schema("xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance") {
123
+ write_tag_to_xml(root_tag, 0, xml, output_type)
124
+ }
172
125
  end
126
+
173
127
  end
174
-
175
- if not tag
176
- return false
128
+
129
+ # get all terms for a given tag
130
+ # this includes terms that are inherited from parent levels
131
+ # e.g. master_taxonomy.get_terms("Space Use.Lighting.Lamp Ballast")
132
+ def get_terms(tag)
133
+
134
+ terms = tag.terms
135
+
136
+ parent_tag = tag.parent_tag
137
+ while not parent_tag.nil?
138
+ terms.concat(parent_tag.terms)
139
+ parent_tag = parent_tag.parent_tag
140
+ end
141
+
142
+
143
+ #sort the terms as they come out
144
+ result = terms.uniq
145
+ if !@sort_alphabetical
146
+ result = result.sort {|x, y| x.row <=> y.row}
147
+ else
148
+ result = result.sort {|x, y| x.name <=> y.name}
177
149
  end
178
-
179
- terms = get_terms(tag)
180
-
181
- # todo: check for all required attributes
182
- terms.each do |term|
183
- #if term.required
184
- # make sure we find attribute
185
- #end
150
+
151
+ return result
186
152
  end
187
-
188
- # check that all attributes are allowed
189
- component.attributes.each do |attribute|
190
-
191
- term = nil
192
- terms.each do |t|
193
- if t.name == attribute.name
194
- term = t
195
- break
153
+
154
+ # check that the given component is conforms with the master taxonomy
155
+ def check_component(component)
156
+ valid = true
157
+ tag = nil
158
+
159
+ # see if we can find the component's tag in the taxonomy
160
+ tags = component.tags
161
+ if tags.empty?
162
+ puts "[Check Component ERROR] Component does not have any tags"
163
+ valid = false
164
+ elsif tags.size > 1
165
+ puts "[Check Component ERROR] Component has multiple tags"
166
+ valid = false
167
+ else
168
+ tag = @tag_hash[tags[0].descriptor]
169
+ if not tag
170
+ puts "[Check Component ERROR] Cannot find #{tags[0].descriptor} in the master taxonomy"
171
+ valid = false
196
172
  end
197
173
  end
198
-
199
- if not term
200
- puts "[Check Component ERROR] Cannot find term for #{attribute.name} in #{tag.level_hierarchy}"
201
- valid = false
202
- next
174
+
175
+ if not tag
176
+ return false
177
+ end
178
+
179
+ terms = get_terms(tag)
180
+
181
+ # todo: check for all required attributes
182
+ terms.each do |term|
183
+ #if term.required
184
+ # make sure we find attribute
185
+ #end
186
+ end
187
+
188
+ # check that all attributes are allowed
189
+ component.attributes.each do |attribute|
190
+
191
+ term = nil
192
+ terms.each do |t|
193
+ if t.name == attribute.name
194
+ term = t
195
+ break
196
+ end
197
+ end
198
+
199
+ if not term
200
+ puts "[Check Component ERROR] Cannot find term for #{attribute.name} in #{tag.level_hierarchy}"
201
+ valid = false
202
+ next
203
+ end
204
+
205
+ # todo: validate value, datatype, units
206
+
203
207
  end
204
-
205
- # todo: validate value, datatype, units
206
-
208
+
209
+ return valid
207
210
  end
208
-
209
- return valid
210
- end
211
-
212
- private
213
-
214
- def current_taxonomy_path
215
- return File.dirname(__FILE__) + "/current_taxonomy.json"
216
- end
217
211
 
218
- def parse_terms(terms_worksheet)
219
-
220
- # check header
221
- header_error = validate_terms_header(terms_worksheet)
222
- if header_error
223
- raise "Header Error on Terms Worksheet"
212
+ private
213
+
214
+ def current_taxonomy_path
215
+ return File.dirname(__FILE__) + "/current_taxonomy.json"
224
216
  end
225
-
226
- # add root tag
227
- root_terms = []
228
- root_terms << TermStruct.new("", "", "", "", "OpenStudio Type", "Type of OpenStudio Object")
229
- root_terms[0].row = 0
230
- #root_terms << TermStruct.new()
231
- root_tag = TagStruct.new("", "root", "Root of the taxonomy", nil, [], root_terms)
232
- @tag_hash[""] = root_tag
233
-
234
- ### puts "**** tag hash: #{@tag_hash}"
235
-
236
- # find number of rows by parsing until hit empty value in first column
237
- row_num = 3
238
- while true do
239
- term = parse_term(terms_worksheet, row_num)
240
- if term.nil?
241
- break
217
+
218
+ def parse_terms(terms_worksheet)
219
+
220
+ # check header
221
+ header_error = validate_terms_header(terms_worksheet)
222
+ if header_error
223
+ raise "Header Error on Terms Worksheet"
224
+ end
225
+
226
+ # add root tag
227
+ root_terms = []
228
+ root_terms << TermStruct.new("", "", "", "", "OpenStudio Type", "Type of OpenStudio Object")
229
+ root_terms[0].row = 0
230
+ #root_terms << TermStruct.new()
231
+ root_tag = TagStruct.new("", "root", "Root of the taxonomy", nil, [], root_terms)
232
+ @tag_hash[""] = root_tag
233
+
234
+ ### puts "**** tag hash: #{@tag_hash}"
235
+
236
+ # find number of rows by parsing until hit empty value in first column
237
+ row_num = 3
238
+ while true do
239
+ term = parse_term(terms_worksheet, row_num)
240
+ if term.nil?
241
+ break
242
+ end
243
+
244
+ add_term(term)
245
+
246
+ row_num += 1
242
247
  end
243
-
244
- add_term(term)
245
248
 
246
- row_num += 1
249
+ # sort the tag tree
250
+ sort_tag(root_tag)
251
+
252
+ # check the tag tree
253
+ check_tag(root_tag)
254
+
247
255
  end
248
-
249
- # sort the tag tree
250
- sort_tag(root_tag)
251
-
252
- # check the tag tree
253
- check_tag(root_tag)
254
-
255
- end
256
-
257
-
258
- def validate_terms_header(terms_worksheet)
259
- test_arr = []
260
- test_arr << {"name"=>"First Level", "strict"=>true}
261
- test_arr << {"name"=>"Second Level", "strict"=>true}
262
- test_arr << {"name"=>"Third Level", "strict"=>true}
263
- test_arr << {"name"=>"Level Hierarchy", "strict"=>true}
264
- test_arr << {"name"=>"Term", "strict"=>true}
265
- test_arr << {"name"=>"Abbr", "strict"=>true}
266
- test_arr << {"name"=>"Description", "strict"=>true}
267
- test_arr << {"name"=>"Data Type", "strict"=>true}
268
- test_arr << {"name"=>"Allow Multiple", "strict"=>true}
269
- test_arr << {"name"=>"Enumerations", "strict"=>true}
270
- test_arr << {"name"=>"IP Units Written Out", "strict"=>true}
271
- test_arr << {"name"=>"IP Units Symbol", "strict"=>true}
272
- test_arr << {"name"=>"IP Display Mask", "strict"=>true}
273
- test_arr << {"name"=>"SI Units Written Out", "strict"=>true}
274
- test_arr << {"name"=>"SI Units Symbol", "strict"=>true}
275
- test_arr << {"name"=>"SI Display Mask", "strict"=>true}
276
- test_arr << {"name"=>"Unit Conversion", "strict"=>true}
277
- test_arr << {"name"=>"Default", "strict"=>true}
278
- test_arr << {"name"=>"Min", "strict"=>true}
279
- test_arr << {"name"=>"Max", "strict"=>true}
280
- test_arr << {"name"=>"Source", "strict"=>true}
281
- test_arr << {"name"=>"Review State", "strict"=>true}
282
- test_arr << {"name"=>"General Comments", "strict"=>true}
283
- test_arr << {"name"=>"Requested By / Project", "strict"=>true}
284
- test_arr << {"name"=>"Include in TPE", "strict"=>false}
285
- test_arr << {"name"=>"Required for Adding a New Product", "strict"=>false}
286
- test_arr << {"name"=>"Use as a Column Header in Search Results", "strict"=>false}
287
- test_arr << {"name"=>"Allow Users to Filter with this Facet", "strict"=>false}
288
- test_arr << {"name"=>"Show Data to Data Users", "strict"=>false}
289
- test_arr << {"name"=>"Additional Instructions for Web Developers", "strict"=>false}
290
- test_arr << {"name"=>"Related Third Party Testing Standards", "strict"=>false}
291
- test_arr << {"name"=>"Additional Guidance to Data Submitters", "strict"=>false}
292
- test_arr << {"name"=>"Additional Guidance to Data Users", "strict"=>false}
293
-
294
-
295
- parse = true
296
- col = 1
297
- while parse
298
- if terms_worksheet.Columns(col).Rows(2).Value.nil? || col > test_arr.size
299
- parse = false
300
- else
301
- if not terms_worksheet.Columns(col).Rows(2).Value == test_arr[col-1]["name"]
302
- if test_arr[col-1]["strict"]
303
- raise "[ERROR] Header does not match: #{col}: '#{terms_worksheet.Columns(col).Rows(2).Value} <> #{test_arr[col-1]["name"]}'"
304
- else
305
- puts "[WARNING] Header does not match: #{col}: '#{terms_worksheet.Columns(col).Rows(2).Value} <> #{test_arr[col-1]["name"]}'"
306
- end
307
- end
308
- end
309
- col += 1
310
- end
311
- end
312
-
313
- def parse_term(terms_worksheet, row)
314
-
315
- term = TermStruct.new
316
- term.row = row
317
- term.first_level = terms_worksheet.Columns(1).Rows(row).Value
318
- term.second_level = terms_worksheet.Columns(2).Rows(row).Value
319
- term.third_level = terms_worksheet.Columns(3).Rows(row).Value
320
- term.level_hierarchy = terms_worksheet.Columns(4).Rows(row).Value
321
- term.name = terms_worksheet.Columns(5).Rows(row).Value
322
- term.abbr = terms_worksheet.Columns(6).Rows(row).Value
323
- term.description = terms_worksheet.Columns(7).Rows(row).Value
324
- term.data_type = terms_worksheet.Columns(8).Rows(row).Value
325
- term.allow_multiple = terms_worksheet.Columns(9).Rows(row).Value
326
- term.enums = terms_worksheet.Columns(10).Rows(row).Value
327
- term.ip_written = terms_worksheet.Columns(11).Rows(row).Value
328
- term.ip_symbol = terms_worksheet.Columns(12).Rows(row).Value
329
- term.ip_mask = terms_worksheet.Columns(13).Rows(row).Value
330
- term.si_written = terms_worksheet.Columns(14).Rows(row).Value
331
- term.si_symbol = terms_worksheet.Columns(15).Rows(row).Value
332
- term.si_mask = terms_worksheet.Columns(16).Rows(row).Value
333
- term.unit_conversion = terms_worksheet.Columns(17).Rows(row).Value
334
- term.default_val = terms_worksheet.Columns(18).Rows(row).Value
335
- term.min_val = terms_worksheet.Columns(19).Rows(row).Value
336
- term.max_val = terms_worksheet.Columns(20).Rows(row).Value
337
-
338
- #custom TPex Columns
339
- term.tp_include = terms_worksheet.Columns(25).Rows(row).Value
340
- term.tp_required = terms_worksheet.Columns(26).Rows(row).Value
341
- term.tp_use_in_search = terms_worksheet.Columns(27).Rows(row).Value
342
- term.tp_use_in_facets = terms_worksheet.Columns(28).Rows(row).Value
343
- term.tp_show_data_to_data_users = terms_worksheet.Columns(29).Rows(row).Value
344
- term.tp_additional_web_dev_info = terms_worksheet.Columns(30).Rows(row).Value
345
- term.tp_third_party_testing = terms_worksheet.Columns(31).Rows(row).Value
346
- term.tp_additional_data_submitter_info = terms_worksheet.Columns(32).Rows(row).Value
347
- term.tp_additional_data_user_info = terms_worksheet.Columns(33).Rows(row).Value
348
-
349
- # trigger to quit parsing the xcel doc
350
- if term.first_level.nil? or term.first_level.empty?
351
- return nil
256
+
257
+
258
+ def validate_terms_header(terms_worksheet)
259
+ test_arr = []
260
+ test_arr << {"name"=>"First Level", "strict"=>true}
261
+ test_arr << {"name"=>"Second Level", "strict"=>true}
262
+ test_arr << {"name"=>"Third Level", "strict"=>true}
263
+ test_arr << {"name"=>"Level Hierarchy", "strict"=>true}
264
+ test_arr << {"name"=>"Term", "strict"=>true}
265
+ test_arr << {"name"=>"Abbr", "strict"=>true}
266
+ test_arr << {"name"=>"Description", "strict"=>true}
267
+ test_arr << {"name"=>"Data Type", "strict"=>true}
268
+ test_arr << {"name"=>"Allow Multiple", "strict"=>true}
269
+ test_arr << {"name"=>"Enumerations", "strict"=>true}
270
+ test_arr << {"name"=>"IP Units Written Out", "strict"=>true}
271
+ test_arr << {"name"=>"IP Units Symbol", "strict"=>true}
272
+ test_arr << {"name"=>"IP Display Mask", "strict"=>true}
273
+ test_arr << {"name"=>"SI Units Written Out", "strict"=>true}
274
+ test_arr << {"name"=>"SI Units Symbol", "strict"=>true}
275
+ test_arr << {"name"=>"SI Display Mask", "strict"=>true}
276
+ test_arr << {"name"=>"Unit Conversion", "strict"=>true}
277
+ test_arr << {"name"=>"Default", "strict"=>true}
278
+ test_arr << {"name"=>"Min", "strict"=>true}
279
+ test_arr << {"name"=>"Max", "strict"=>true}
280
+ test_arr << {"name"=>"Source", "strict"=>true}
281
+ test_arr << {"name"=>"Review State", "strict"=>true}
282
+ test_arr << {"name"=>"General Comments", "strict"=>true}
283
+ test_arr << {"name"=>"Requested By / Project", "strict"=>true}
284
+ test_arr << {"name"=>"Include in TPE", "strict"=>false}
285
+ test_arr << {"name"=>"Required for Adding a New Product", "strict"=>false}
286
+ test_arr << {"name"=>"Use as a Column Header in Search Results", "strict"=>false}
287
+ test_arr << {"name"=>"Allow Users to Filter with this Facet", "strict"=>false}
288
+ test_arr << {"name"=>"Show Data to Data Users", "strict"=>false}
289
+ test_arr << {"name"=>"Additional Instructions for Web Developers", "strict"=>false}
290
+ test_arr << {"name"=>"Related Third Party Testing Standards", "strict"=>false}
291
+ test_arr << {"name"=>"Additional Guidance to Data Submitters", "strict"=>false}
292
+ test_arr << {"name"=>"Additional Guidance to Data Users", "strict"=>false}
293
+
294
+
295
+ parse = true
296
+ col = 1
297
+ while parse
298
+ if terms_worksheet.Columns(col).Rows(2).Value.nil? || col > test_arr.size
299
+ parse = false
300
+ else
301
+ if not terms_worksheet.Columns(col).Rows(2).Value == test_arr[col-1]["name"]
302
+ if test_arr[col-1]["strict"]
303
+ raise "[ERROR] Header does not match: #{col}: '#{terms_worksheet.Columns(col).Rows(2).Value} <> #{test_arr[col-1]["name"]}'"
304
+ else
305
+ puts "[WARNING] Header does not match: #{col}: '#{terms_worksheet.Columns(col).Rows(2).Value} <> #{test_arr[col-1]["name"]}'"
306
+ end
307
+ end
308
+ end
309
+ col += 1
352
310
  end
353
-
354
- return term
355
- end
356
-
357
- def add_term(term)
358
-
359
- level_hierarchy = term.level_hierarchy
360
-
361
- # create the tag
362
- tag = @tag_hash[level_hierarchy]
363
-
364
- if tag.nil?
365
- tag = create_tag(level_hierarchy, term.description)
366
311
  end
367
-
368
- if term.name.nil? or term.name.strip.empty?
369
- # this row is really about the tag
370
- tag.description = term.description
371
312
 
372
- else
373
- # this row is about a term
374
- if not validate_term(term)
313
+ def parse_term(terms_worksheet, row)
314
+
315
+ term = TermStruct.new
316
+ term.row = row
317
+ term.first_level = terms_worksheet.Columns(1).Rows(row).Value
318
+ term.second_level = terms_worksheet.Columns(2).Rows(row).Value
319
+ term.third_level = terms_worksheet.Columns(3).Rows(row).Value
320
+ term.level_hierarchy = terms_worksheet.Columns(4).Rows(row).Value
321
+ term.name = terms_worksheet.Columns(5).Rows(row).Value
322
+ term.abbr = terms_worksheet.Columns(6).Rows(row).Value
323
+ term.description = terms_worksheet.Columns(7).Rows(row).Value
324
+ term.data_type = terms_worksheet.Columns(8).Rows(row).Value
325
+ term.allow_multiple = terms_worksheet.Columns(9).Rows(row).Value
326
+ term.enums = terms_worksheet.Columns(10).Rows(row).Value
327
+ term.ip_written = terms_worksheet.Columns(11).Rows(row).Value
328
+ term.ip_symbol = terms_worksheet.Columns(12).Rows(row).Value
329
+ term.ip_mask = terms_worksheet.Columns(13).Rows(row).Value
330
+ term.si_written = terms_worksheet.Columns(14).Rows(row).Value
331
+ term.si_symbol = terms_worksheet.Columns(15).Rows(row).Value
332
+ term.si_mask = terms_worksheet.Columns(16).Rows(row).Value
333
+ term.unit_conversion = terms_worksheet.Columns(17).Rows(row).Value
334
+ term.default_val = terms_worksheet.Columns(18).Rows(row).Value
335
+ term.min_val = terms_worksheet.Columns(19).Rows(row).Value
336
+ term.max_val = terms_worksheet.Columns(20).Rows(row).Value
337
+
338
+ #custom TPex Columns
339
+ term.tp_include = terms_worksheet.Columns(25).Rows(row).Value
340
+ term.tp_required = terms_worksheet.Columns(26).Rows(row).Value
341
+ term.tp_use_in_search = terms_worksheet.Columns(27).Rows(row).Value
342
+ term.tp_use_in_facets = terms_worksheet.Columns(28).Rows(row).Value
343
+ term.tp_show_data_to_data_users = terms_worksheet.Columns(29).Rows(row).Value
344
+ term.tp_additional_web_dev_info = terms_worksheet.Columns(30).Rows(row).Value
345
+ term.tp_third_party_testing = terms_worksheet.Columns(31).Rows(row).Value
346
+ term.tp_additional_data_submitter_info = terms_worksheet.Columns(32).Rows(row).Value
347
+ term.tp_additional_data_user_info = terms_worksheet.Columns(33).Rows(row).Value
348
+
349
+ # trigger to quit parsing the xcel doc
350
+ if term.first_level.nil? or term.first_level.empty?
375
351
  return nil
376
352
  end
377
-
378
- tag.terms = [] if tag.terms.nil?
379
- tag.terms << term
353
+
354
+ return term
380
355
  end
381
- end
382
-
383
- def create_tag(level_hierarchy, tag_description="")
384
-
385
- #puts "create_tag called for #{level_hierarchy}"
386
-
387
- parts = level_hierarchy.split('.')
388
-
389
- name = parts[-1]
390
- parent_level = parts[0..-2].join('.')
391
-
392
- parent_tag = @tag_hash[parent_level]
393
- if parent_tag.nil?
394
- parent_tag = create_tag(parent_level)
356
+
357
+ def add_term(term)
358
+
359
+ level_hierarchy = term.level_hierarchy
360
+
361
+ # create the tag
362
+ tag = @tag_hash[level_hierarchy]
363
+
364
+ if tag.nil?
365
+ tag = create_tag(level_hierarchy, term.description)
366
+ end
367
+
368
+ if term.name.nil? or term.name.strip.empty?
369
+ # this row is really about the tag
370
+ tag.description = term.description
371
+
372
+ else
373
+ # this row is about a term
374
+ if not validate_term(term)
375
+ return nil
376
+ end
377
+
378
+ tag.terms = [] if tag.terms.nil?
379
+ tag.terms << term
380
+ end
395
381
  end
396
-
397
- description = tag_description
398
- child_tags = []
399
- terms = []
400
- tag = TagStruct.new(level_hierarchy, name, description, parent_tag, child_tags, terms)
401
-
402
- parent_tag.child_tags << tag
403
-
404
- @tag_hash[level_hierarchy] = tag
405
-
406
- return tag
407
- end
408
-
409
- def sort_tag(tag)
410
- #tag.terms = tag.terms.sort {|x, y| x.level_hierarchy <=> y.level_hierarchy}
411
- tag.child_tags = tag.child_tags.sort {|x, y| x.level_hierarchy <=> y.level_hierarchy}
412
- tag.child_tags.each {|child_tag| sort_tag(child_tag) }
413
-
414
- #tag.terms = tag.terms.sort {|x, y| x.name <=> y.name}
415
- #tag.child_tags = tag.child_tags.sort {|x, y| x.name <=> y.name}
416
- #tag.child_tags.each {|child_tag| sort_tag(child_tag) }
417
- end
418
-
419
- def check_tag(tag)
420
-
421
- if tag.description.nil? or tag.description.empty?
422
- puts "[check_tag] tag '#{tag.level_hierarchy}' has no description"
382
+
383
+ def create_tag(level_hierarchy, tag_description="")
384
+
385
+ #puts "create_tag called for #{level_hierarchy}"
386
+
387
+ parts = level_hierarchy.split('.')
388
+
389
+ name = parts[-1]
390
+ parent_level = parts[0..-2].join('.')
391
+
392
+ parent_tag = @tag_hash[parent_level]
393
+ if parent_tag.nil?
394
+ parent_tag = create_tag(parent_level)
395
+ end
396
+
397
+ description = tag_description
398
+ child_tags = []
399
+ terms = []
400
+ tag = TagStruct.new(level_hierarchy, name, description, parent_tag, child_tags, terms)
401
+
402
+ parent_tag.child_tags << tag
403
+
404
+ @tag_hash[level_hierarchy] = tag
405
+
406
+ return tag
423
407
  end
424
-
425
- tag.terms.each {|term| check_term(term) }
426
- tag.child_tags.each {|child_tag| check_tag(child_tag) }
427
- end
428
-
429
- def validate_term(term)
430
- valid = true
431
-
432
- parts = term.level_hierarchy.split('.')
433
-
434
- if parts.empty?
435
- puts "Hierarchy parts empty, #{term.level_hierarchy}"
436
- valid = false
408
+
409
+ def sort_tag(tag)
410
+ #tag.terms = tag.terms.sort {|x, y| x.level_hierarchy <=> y.level_hierarchy}
411
+ tag.child_tags = tag.child_tags.sort {|x, y| x.level_hierarchy <=> y.level_hierarchy}
412
+ tag.child_tags.each {|child_tag| sort_tag(child_tag) }
413
+
414
+ #tag.terms = tag.terms.sort {|x, y| x.name <=> y.name}
415
+ #tag.child_tags = tag.child_tags.sort {|x, y| x.name <=> y.name}
416
+ #tag.child_tags.each {|child_tag| sort_tag(child_tag) }
437
417
  end
438
-
439
- if parts.size >= 1 and not term.first_level == parts[0]
440
- puts "First level '#{term.first_level}' does not match level hierarchy '#{term.level_hierarchy}', skipping term"
441
- valid = false
418
+
419
+ def check_tag(tag)
420
+
421
+ if tag.description.nil? or tag.description.empty?
422
+ puts "[check_tag] tag '#{tag.level_hierarchy}' has no description"
423
+ end
424
+
425
+ tag.terms.each {|term| check_term(term) }
426
+ tag.child_tags.each {|child_tag| check_tag(child_tag) }
442
427
  end
443
-
444
- if parts.size >= 2 and not term.second_level == parts[1]
445
- puts "Second level '#{term.second_level}' does not match level hierarchy '#{term.level_hierarchy}', skipping term"
446
- valid = false
428
+
429
+ def validate_term(term)
430
+ valid = true
431
+
432
+ parts = term.level_hierarchy.split('.')
433
+
434
+ if parts.empty?
435
+ puts "Hierarchy parts empty, #{term.level_hierarchy}"
436
+ valid = false
437
+ end
438
+
439
+ if parts.size >= 1 and not term.first_level == parts[0]
440
+ puts "First level '#{term.first_level}' does not match level hierarchy '#{term.level_hierarchy}', skipping term"
441
+ valid = false
442
+ end
443
+
444
+ if parts.size >= 2 and not term.second_level == parts[1]
445
+ puts "Second level '#{term.second_level}' does not match level hierarchy '#{term.level_hierarchy}', skipping term"
446
+ valid = false
447
+ end
448
+
449
+ if parts.size >= 3 and not term.third_level == parts[2]
450
+ puts "Third level '#{term.third_level}' does not match level hierarchy '#{term.level_hierarchy}', skipping term"
451
+ valid = false
452
+ end
453
+
454
+ if parts.size > 3
455
+ puts "Hierarchy cannot have more than 3 parts '#{term.level_hierarchy}', skipping term"
456
+ valid = false
457
+ end
458
+
459
+ if !term.data_type.nil?
460
+ valid_types = ["double", "integer", "enum", "file", "string", "autocomplete"]
461
+ if (term.data_type.downcase != term.data_type) || !valid_types.include?(term.data_type)
462
+ puts "[ERROR] Term '#{term.name}' does not have a valid data type with '#{term.data_type}'"
463
+ end
464
+
465
+ if term.data_type.downcase == "enum"
466
+ if term.enums.nil? || term.enums == "" || term.enums.downcase == "no enum found"
467
+ puts "[ERROR] Term '#{term.name}' does not have valid enumerations"
468
+ end
469
+ end
447
470
  end
448
-
449
- if parts.size >= 3 and not term.third_level == parts[2]
450
- puts "Third level '#{term.third_level}' does not match level hierarchy '#{term.level_hierarchy}', skipping term"
451
- valid = false
471
+
472
+ return valid
473
+ end
474
+
475
+ def check_term(term)
476
+ if term.description.nil? or term.description.empty?
477
+ #puts "[check_term] term '#{term.level_hierarchy}.#{term.name}' has no description"
478
+ end
452
479
  end
453
-
454
- if parts.size > 3
455
- puts "Hierarchy cannot have more than 3 parts '#{term.level_hierarchy}', skipping term"
456
- valid = false
480
+
481
+ # write term to xml
482
+ def write_terms_to_xml(tag, xml, output_type)
483
+ terms = get_terms(tag)
484
+ if terms.size > 0
485
+ terms.each do |term|
486
+ xml.term {
487
+ xml.name term.name
488
+ xml.abbr term.abbr if !term.abbr.nil?
489
+ xml.description term.description if !term.description.nil?
490
+ xml.data_type term.data_type if !term.data_type.nil?
491
+ xml.allow_multiple term.allow_multiple if !term.allow_multiple.nil?
492
+
493
+ if !term.enums.nil? && term.enums != ""
494
+ xml.enumerations {
495
+ out = term.enums.split("|")
496
+ out.sort! if @sort_alphabetical
497
+ out.each do |enum|
498
+ xml.enumeration enum
499
+ end
500
+ }
501
+ end
502
+ xml.ip_written term.ip_written if !term.ip_written.nil?
503
+ xml.ip_symbol term.ip_symbol if !term.ip_symbol.nil?
504
+ xml.ip_mask term.ip_mask if !term.ip_mask.nil?
505
+ xml.si_written term.si_written if !term.si_written.nil?
506
+ xml.si_symbol term.si_symbol if !term.si_symbol.nil?
507
+ xml.si_mask term.si_mask if !term.si_mask.nil?
508
+ xml.row term.row if !term.row.nil?
509
+ xml.unit_conversion term.unit_conversion if !term.unit_conversion.nil?
510
+ xml.default_val term.default_val if !term.default_val.nil?
511
+ xml.min_val term.min_val if !term.min_val.nil?
512
+ xml.max_val term.max_val if !term.max_val.nil?
513
+
514
+ if output_type == 'tpex'
515
+ xml.tp_include term.tp_include if !term.tp_include.nil?
516
+ xml.tp_required term.tp_required if !term.tp_required.nil?
517
+ xml.tp_use_in_search term.tp_use_in_search if !term.tp_use_in_search.nil?
518
+ xml.tp_use_in_facets term.tp_use_in_facets if !term.tp_use_in_facets.nil?
519
+ xml.tp_show_data_to_data_users term.tp_show_data_to_data_users if !term.tp_show_data_to_data_users.nil?
520
+ xml.tp_third_party_testing term.tp_third_party_testing if !term.tp_third_party_testing.nil?
521
+ xml.tp_additional_web_dev_info term.tp_additional_web_dev_info if !term.tp_additional_web_dev_info.nil?
522
+ xml.tp_additional_data_user_info term.tp_additional_data_user_info if !term.tp_additional_data_user_info.nil?
523
+ xml.tp_additional_data_submitter_info term.tp_additional_data_submitter_info if !term.tp_additional_data_submitter_info.nil?
524
+ end
525
+ }
526
+ end
457
527
  end
458
-
459
- if !term.data_type.nil?
460
- valid_types = ["double", "integer", "enum", "file", "string", "autocomplete"]
461
- if (term.data_type.downcase != term.data_type) || !valid_types.include?(term.data_type)
462
- puts "[ERROR] Term '#{term.name}' does not have a valid data type with '#{term.data_type}'"
463
- end
464
-
465
- if term.data_type.downcase == "enum"
466
- if term.enums.nil? || term.enums == "" || term.enums.downcase == "no enum found"
467
- puts "[ERROR] Term '#{term.name}' does not have valid enumerations"
468
- end
469
- end
470
- end
471
-
472
- return valid
473
- end
474
-
475
- def check_term(term)
476
- if term.description.nil? or term.description.empty?
477
- #puts "[check_term] term '#{term.level_hierarchy}.#{term.name}' has no description"
478
528
  end
479
- end
480
-
481
- # write term to xml
482
- def write_terms_to_xml(tag, xml, output_type)
483
- terms = get_terms(tag)
484
- if terms.size > 0
485
- terms.each do |term|
486
- xml.term {
487
- xml.name term.name
488
- xml.abbr term.abbr if !term.abbr.nil?
489
- xml.description term.description if !term.description.nil?
490
- xml.data_type term.data_type if !term.data_type.nil?
491
- xml.allow_multiple term.allow_multiple if !term.allow_multiple.nil?
492
-
493
- if !term.enums.nil? && term.enums != ""
494
- xml.enumerations {
495
- out = term.enums.split("|")
496
- out.sort! if @sort_alphabetical
497
- out.each do |enum|
498
- xml.enumeration enum
499
- end
500
- }
501
- end
502
- xml.ip_written term.ip_written if !term.ip_written.nil?
503
- xml.ip_symbol term.ip_symbol if !term.ip_symbol.nil?
504
- xml.ip_mask term.ip_mask if !term.ip_mask.nil?
505
- xml.si_written term.si_written if !term.si_written.nil?
506
- xml.si_symbol term.si_symbol if !term.si_symbol.nil?
507
- xml.si_mask term.si_mask if !term.si_mask.nil?
508
- xml.row term.row if !term.row.nil?
509
- xml.unit_conversion term.unit_conversion if !term.unit_conversion.nil?
510
- xml.default_val term.default_val if !term.default_val.nil?
511
- xml.min_val term.min_val if !term.min_val.nil?
512
- xml.max_val term.max_val if !term.max_val.nil?
513
-
514
- if output_type == 'tpex'
515
- xml.tp_include term.tp_include if !term.tp_include.nil?
516
- xml.tp_required term.tp_required if !term.tp_required.nil?
517
- xml.tp_use_in_search term.tp_use_in_search if !term.tp_use_in_search.nil?
518
- xml.tp_use_in_facets term.tp_use_in_facets if !term.tp_use_in_facets.nil?
519
- xml.tp_show_data_to_data_users term.tp_show_data_to_data_users if !term.tp_show_data_to_data_users.nil?
520
- xml.tp_third_party_testing term.tp_third_party_testing if !term.tp_third_party_testing.nil?
521
- xml.tp_additional_web_dev_info term.tp_additional_web_dev_info if !term.tp_additional_web_dev_info.nil?
522
- xml.tp_additional_data_user_info term.tp_additional_data_user_info if !term.tp_additional_data_user_info.nil?
523
- xml.tp_additional_data_submitter_info term.tp_additional_data_submitter_info if !term.tp_additional_data_submitter_info.nil?
524
- end
525
- }
526
- end
527
- end
528
- end
529
-
530
- # write a tag to xml
531
- def write_tag_to_xml(tag, level, xml, output_type)
532
- level_string = "level_#{level}"
533
- xml.tag!(level_string) {
534
- s_temp = tag.name
535
- xml.name s_temp
536
- xml.description tag.description
537
-
538
- level += 1
539
-
540
- if tag.child_tags.size == 0
541
- write_terms_to_xml(tag, xml, output_type)
542
- end
543
-
544
- child_tags = tag.child_tags
545
- child_tags.each do |child_tag|
546
- write_tag_to_xml(child_tag, level, xml, output_type)
529
+
530
+ # write a tag to xml
531
+ def write_tag_to_xml(tag, level, xml, output_type)
532
+ level_string = "level_#{level}"
533
+ xml.tag!(level_string) {
534
+ s_temp = tag.name
535
+ xml.name s_temp
536
+ xml.description tag.description
537
+
538
+ level += 1
539
+
540
+ if tag.child_tags.size == 0
541
+ write_terms_to_xml(tag, xml, output_type)
547
542
  end
548
-
549
- }
543
+
544
+ child_tags = tag.child_tags
545
+ child_tags.each do |child_tag|
546
+ write_tag_to_xml(child_tag, level, xml, output_type)
547
+ end
548
+
549
+ }
550
+ end
551
+
550
552
  end
551
-
552
- end
553
553
 
554
554
  end # module BCL
555
555