bcl 0.1.4 → 0.1.5

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.
@@ -38,13 +38,19 @@ module BCL
38
38
  TagStruct = Struct.new(:level_hierarchy, :name, :description, :parent_tag, :child_tags, :terms)
39
39
 
40
40
  # each TermStruct represents a row in the master taxonomy
41
- TermStruct = Struct.new(:first_level, :second_level, :third_level, :level_hierarchy, :name, :description)
41
+ TermStruct = Struct.new(:first_level, :second_level, :third_level, :level_hierarchy, :name, :description,
42
+ :abbr, :data_type, :enums, :ip_written, :ip_symbol, :ip_mask, :si_written, :si_symbol, :si_mask, :allow_multiple, :row, :tp_include, :tp_required, :tp_use_in_search, :tp_use_in_facets, :tp_hide_from_data_users, :tp_third_party_testing, :tp_additional_web_dev_info, :tp_additional_data_user_info, :tp_additional_data_submitter_info)
43
+
44
+
45
+
46
+
42
47
 
43
48
  # class for parsing, validating, and querying the master taxonomy document
44
49
  class MasterTaxonomy
45
50
 
46
51
  # parse the master taxonomy document
47
- def initialize(xlsx_path = nil)
52
+ def initialize(xlsx_path = nil, sort_alpha = false)
53
+ @sort_alphabetical = sort_alpha
48
54
 
49
55
  # hash of level_taxonomy to tag
50
56
  @tag_hash = Hash.new
@@ -89,13 +95,14 @@ class MasterTaxonomy
89
95
  path = current_taxonomy_path
90
96
  end
91
97
  puts "Saving current taxonomy to #{path}"
98
+ # this is really not JSON... it is a persisted format of ruby
92
99
  File.open(path, 'w') do |file|
93
100
  Marshal.dump(@tag_hash, file)
94
101
  end
95
102
  end
96
103
 
97
104
  # write taxonomy to xml
98
- def write_xml(path)
105
+ def write_xml(path, output_type = 'tpex')
99
106
 
100
107
  root_tag = @tag_hash[""]
101
108
 
@@ -110,7 +117,7 @@ class MasterTaxonomy
110
117
  #setup the xml file
111
118
  xml.instruct!(:xml, :version=>"1.0", :encoding=>"UTF-8")
112
119
  xml.schema("xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance") {
113
- write_tag_to_xml(root_tag, xml)
120
+ write_tag_to_xml(root_tag, 0, xml, output_type)
114
121
  }
115
122
  end
116
123
 
@@ -122,20 +129,28 @@ class MasterTaxonomy
122
129
  def get_terms(tag)
123
130
 
124
131
  terms = tag.terms
125
-
132
+
126
133
  parent_tag = tag.parent_tag
127
134
  while not parent_tag.nil?
128
- terms.concat(parent_tag.terms)
135
+ terms.concat(parent_tag.terms)
129
136
  parent_tag = parent_tag.parent_tag
130
137
  end
131
-
132
- return terms.reverse.uniq
138
+
139
+
140
+ #sort the terms as they come out
141
+ result = terms.uniq
142
+ if !@sort_alphabetical
143
+ result = result.sort {|x, y| x.row <=> y.row}
144
+ else
145
+ result = result.sort {|x, y| x.name <=> y.name}
146
+ end
147
+
148
+ return result
133
149
  end
134
150
 
135
151
  # check that the given component is conforms with the master taxonomy
136
152
  def check_component(component)
137
153
  valid = true
138
-
139
154
  tag = nil
140
155
 
141
156
  # see if we can find the component's tag in the taxonomy
@@ -208,6 +223,8 @@ class MasterTaxonomy
208
223
  # add root tag
209
224
  root_terms = []
210
225
  root_terms << TermStruct.new("", "", "", "", "OpenStudio Type", "Type of OpenStudio Object")
226
+ root_terms[0].row = 0
227
+ #root_terms << TermStruct.new()
211
228
  root_tag = TagStruct.new("", "root", "Root of the taxonomy", nil, [], root_terms)
212
229
  @tag_hash[""] = root_tag
213
230
 
@@ -234,39 +251,89 @@ class MasterTaxonomy
234
251
 
235
252
 
236
253
  def validate_terms_header(terms_worksheet)
237
- header_error = false
238
-
239
- first_level = terms_worksheet.Range("A2").Value
240
- second_level = terms_worksheet.Range("B2").Value
241
- third_level = terms_worksheet.Range("C2").Value
242
- level_hierarchy = terms_worksheet.Range("D2").Value
243
- name = terms_worksheet.Range("E2").Value
244
- abbr = terms_worksheet.Range("F2").Value
245
- description = terms_worksheet.Range("G2").Value
246
-
247
- header_error = true if not first_level == "First Level"
248
- header_error = true if not second_level == "Second Level"
249
- header_error = true if not third_level == "Third Level"
250
- header_error = true if not level_hierarchy == "Level Hierarchy"
251
- header_error = true if not name == "Term"
252
- header_error = true if not abbr == "Abbr."
253
- header_error = true if not description == "Description"
254
-
255
- return header_error
254
+ test_arr = []
255
+ test_arr << "First Level"
256
+ test_arr << "Second Level"
257
+ test_arr << "Third Level"
258
+ test_arr << "Level Hierarchy"
259
+ test_arr << "Term"
260
+ test_arr << "Abbr"
261
+ test_arr << "Description"
262
+ test_arr << "Data Type"
263
+ test_arr << "Allow Multiple"
264
+ test_arr << "Enumerations"
265
+ test_arr << "IP Units Written Out"
266
+ test_arr << "IP Units Symbol"
267
+ test_arr << "IP Display Mask"
268
+ test_arr << "SI Units Written Out"
269
+ test_arr << "SI Units Symbol"
270
+ test_arr << "SI Display Mask"
271
+ test_arr << "Unit Conversion"
272
+ test_arr << "Default"
273
+ test_arr << "Min"
274
+ test_arr << "Max"
275
+ test_arr << "Source"
276
+ test_arr << "Review State"
277
+ test_arr << "General Comments"
278
+ test_arr << "Requested By / Project"
279
+ test_arr << "Include in TPE"
280
+ test_arr << "Required for Adding a New Product"
281
+ test_arr << "Use in Search Results"
282
+ test_arr << "Use in Search Facets"
283
+ test_arr << "Show/Hide Data from Data Users"
284
+ test_arr << "Additional Instructions for Web Developers"
285
+ test_arr << "Related Third Party Testing Standards"
286
+ test_arr << "Additional Guidance to Data Submitters"
287
+ test_arr << "Additional Guidance to Data Users"
288
+
289
+
290
+ parse = true
291
+ col = 1
292
+ while parse
293
+ if terms_worksheet.Columns(col).Rows(2).Value.nil? || col > test_arr.size
294
+ parse = false
295
+ else
296
+ if not terms_worksheet.Columns(col).Rows(2).Value == test_arr[col-1]
297
+ raise "Header does not match: #{col}: '#{terms_worksheet.Columns(col).Rows(2).Value} <> #{test_arr[col-1]}'"
298
+ end
299
+ end
300
+ col += 1
301
+ end
256
302
  end
257
303
 
258
304
  def parse_term(terms_worksheet, row)
259
305
 
260
306
  term = TermStruct.new
261
- term.first_level = terms_worksheet.Range("A#{row}").Value
262
- term.second_level = terms_worksheet.Range("B#{row}").Value
263
- term.third_level = terms_worksheet.Range("C#{row}").Value
264
- term.level_hierarchy = terms_worksheet.Range("D#{row}").Value
265
- term.name = terms_worksheet.Range("E#{row}").Value
266
- #term.abbr = terms_worksheet.Range("F#{row}").Value
267
- term.description = terms_worksheet.Range("G#{row}").Value
268
-
269
- # trigger to quit parsing the xcel doc
307
+ term.row = row
308
+ term.first_level = terms_worksheet.Columns(1).Rows(row).Value
309
+ term.second_level = terms_worksheet.Columns(2).Rows(row).Value
310
+ term.third_level = terms_worksheet.Columns(3).Rows(row).Value
311
+ term.level_hierarchy = terms_worksheet.Columns(4).Rows(row).Value
312
+ term.name = terms_worksheet.Columns(5).Rows(row).Value
313
+ term.abbr = terms_worksheet.Columns(6).Rows(row).Value
314
+ term.description = terms_worksheet.Columns(7).Rows(row).Value
315
+ term.data_type = terms_worksheet.Columns(8).Rows(row).Value
316
+ term.allow_multiple = terms_worksheet.Columns(9).Rows(row).Value
317
+ term.enums = terms_worksheet.Columns(10).Rows(row).Value
318
+ term.ip_written = terms_worksheet.Columns(11).Rows(row).Value
319
+ term.ip_symbol = terms_worksheet.Columns(12).Rows(row).Value
320
+ term.ip_mask = terms_worksheet.Columns(13).Rows(row).Value
321
+ term.si_written = terms_worksheet.Columns(14).Rows(row).Value
322
+ term.si_symbol = terms_worksheet.Columns(15).Rows(row).Value
323
+ term.si_mask = terms_worksheet.Columns(16).Rows(row).Value
324
+
325
+ #custom TPex Columns
326
+ term.tp_include = terms_worksheet.Columns(25).Rows(row).Value
327
+ term.tp_required = terms_worksheet.Columns(26).Rows(row).Value
328
+ term.tp_use_in_search = terms_worksheet.Columns(27).Rows(row).Value
329
+ term.tp_use_in_facets = terms_worksheet.Columns(28).Rows(row).Value
330
+ term.tp_hide_from_data_users = terms_worksheet.Columns(29).Rows(row).Value
331
+ term.tp_third_party_testing = terms_worksheet.Columns(30).Rows(row).Value
332
+ term.tp_additional_web_dev_info = terms_worksheet.Columns(31).Rows(row).Value
333
+ term.tp_additional_data_user_info = terms_worksheet.Columns(32).Rows(row).Value
334
+ term.tp_additional_data_submitter_info = terms_worksheet.Columns(33).Rows(row).Value
335
+
336
+ # trigger to quit parsing the xcel doc
270
337
  if term.first_level.nil? or term.first_level.empty?
271
338
  return nil
272
339
  end
@@ -327,17 +394,21 @@ class MasterTaxonomy
327
394
  end
328
395
 
329
396
  def sort_tag(tag)
330
- tag.terms = tag.terms.sort {|x, y| x.name <=> y.name}
331
- tag.child_tags = tag.child_tags.sort {|x, y| x.name <=> y.name}
397
+ #tag.terms = tag.terms.sort {|x, y| x.level_hierarchy <=> y.level_hierarchy}
398
+ tag.child_tags = tag.child_tags.sort {|x, y| x.level_hierarchy <=> y.level_hierarchy}
332
399
  tag.child_tags.each {|child_tag| sort_tag(child_tag) }
400
+
401
+ #tag.terms = tag.terms.sort {|x, y| x.name <=> y.name}
402
+ #tag.child_tags = tag.child_tags.sort {|x, y| x.name <=> y.name}
403
+ #tag.child_tags.each {|child_tag| sort_tag(child_tag) }
333
404
  end
334
405
 
335
406
  def check_tag(tag)
336
407
 
337
408
  if tag.description.nil? or tag.description.empty?
338
- puts "tag '#{tag.level_hierarchy}' has no description"
409
+ #puts "tag '#{tag.level_hierarchy}' has no description"
339
410
  end
340
-
411
+
341
412
  tag.terms.each {|term| check_term(term) }
342
413
  tag.child_tags.each {|child_tag| check_tag(child_tag) }
343
414
  end
@@ -372,34 +443,92 @@ class MasterTaxonomy
372
443
  valid = false
373
444
  end
374
445
 
375
- # todo: check description, data type, enumerations, units, source, author
446
+ if !term.data_type.nil?
447
+ valid_types = ["double", "integer", "enum", "file", "string"]
448
+ if (term.data_type.downcase != term.data_type) || !valid_types.include?(term.data_type)
449
+ puts "[ERROR] Term '#{term.name}' does not have a valid data type with '#{term.data_type}'"
450
+ end
451
+
452
+ if term.data_type.downcase == "enum"
453
+ if term.enums.nil? || term.enums == "" || term.enums.downcase == "no enum found"
454
+ puts "[ERROR] Term '#{term.name}' does not have valid enumerations"
455
+ end
456
+ end
457
+ end
376
458
 
377
459
  return valid
378
460
  end
379
461
 
380
462
  def check_term(term)
381
463
  if term.description.nil? or term.description.empty?
382
- puts "term '#{term.level_hierarchy}.#{term.name}' has no description"
464
+ #puts "term '#{term.level_hierarchy}.#{term.name}' has no description"
383
465
  end
384
466
  end
385
467
 
468
+ # write term to xml
469
+ def write_terms_to_xml(tag, xml, output_type)
470
+ terms = get_terms(tag)
471
+ if terms.size > 0
472
+ terms.each do |term|
473
+ xml.term {
474
+ xml.name term.name
475
+ xml.abbr term.abbr if !term.abbr.nil?
476
+ xml.description term.description if !term.description.nil?
477
+ xml.data_type term.data_type if !term.data_type.nil?
478
+ xml.allow_multiple term.allow_multiple if !term.allow_multiple.nil?
479
+
480
+ if !term.enums.nil? && term.enums != ""
481
+ xml.enumerations {
482
+ out = term.enums.split("|")
483
+ out.sort! if @sort_alphabetical
484
+ out.each do |enum|
485
+ xml.enumeration enum
486
+ end
487
+ }
488
+ end
489
+ xml.ip_written term.ip_written if !term.ip_written.nil?
490
+ xml.ip_symbol term.ip_symbol if !term.ip_symbol.nil?
491
+ xml.ip_mask term.ip_mask if !term.ip_mask.nil?
492
+ xml.si_written term.si_written if !term.si_written.nil?
493
+ xml.si_symbol term.si_symbol if !term.si_symbol.nil?
494
+ xml.si_mask term.si_mask if !term.si_mask.nil?
495
+ xml.row term.row if !term.row.nil?
496
+
497
+ if output_type == 'tpex'
498
+ xml.tp_include term.tp_include if !term.tp_include.nil?
499
+ xml.tp_required term.tp_required if !term.tp_required.nil?
500
+ xml.tp_use_in_search term.tp_use_in_search if !term.tp_use_in_search.nil?
501
+ xml.tp_use_in_facets term.tp_use_in_facets if !term.tp_use_in_facets.nil?
502
+ xml.tp_hide_from_data_users term.tp_hide_from_data_users if !term.tp_hide_from_data_users.nil?
503
+ xml.tp_third_party_testing term.tp_third_party_testing if !term.tp_third_party_testing.nil?
504
+ xml.tp_additional_web_dev_info term.tp_additional_web_dev_info if !term.tp_additional_web_dev_info.nil?
505
+ xml.tp_additional_data_user_info term.tp_additional_data_user_info if !term.tp_additional_data_user_info.nil?
506
+ xml.tp_additional_data_submitter_info term.tp_additional_data_submitter_info if !term.tp_additional_data_submitter_info.nil?
507
+ end
508
+ }
509
+ end
510
+ end
511
+ end
512
+
386
513
  # write a tag to xml
387
- def write_tag_to_xml(tag, xml)
388
- xml.tag(:name => "#{tag.name}") {
389
- #xml.terms {
390
- #terms = tag.terms # only direct terms
391
- terms = get_terms(tag) # all terms, ordered by inheritence
392
- terms.each do |term|
393
- xml.term(:name => "#{term.name}")
394
- end
395
- #}
396
- #xml.tags {
397
- child_tags = tag.child_tags
398
- child_tags.each do |child_tag|
399
- write_tag_to_xml(child_tag, xml)
400
- end
401
- #}
402
- }
514
+ def write_tag_to_xml(tag, level, xml, output_type)
515
+ level_string = "level_#{level}"
516
+ xml.tag!(level_string) {
517
+ s_temp = tag.name
518
+ xml.name s_temp
519
+
520
+ level += 1
521
+
522
+ if tag.child_tags.size == 0
523
+ write_terms_to_xml(tag, xml, output_type)
524
+ end
525
+
526
+ child_tags = tag.child_tags
527
+ child_tags.each do |child_tag|
528
+ write_tag_to_xml(child_tag, level, xml, output_type)
529
+ end
530
+
531
+ }
403
532
  end
404
533
 
405
534
  end
Binary file