bcl 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bcl/component.rb CHANGED
@@ -1,390 +1,388 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2013, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- # Provides programmatic access to the component.xsd schema needed for
21
- # generating the component information that will be uploaded to
22
- # the Building Component Library.
23
-
24
- module BCL
25
- class Component < BaseXml
26
- attr_accessor :comment
27
- attr_accessor :source_manufacturer
28
- attr_accessor :source_model
29
- attr_accessor :source_serial_no
30
- attr_accessor :source_year
31
- attr_accessor :source_url
32
- attr_accessor :objects
33
- attr_accessor :name
34
- attr_accessor :uid
35
- attr_accessor :comp_version_id
36
- attr_accessor :description
37
- attr_accessor :modeler_description
38
- attr_accessor :fidelity_level
39
- attr_accessor :source_manufacturer
40
- attr_accessor :source_model
41
- attr_accessor :source_serial_no
42
- attr_accessor :source_year
43
- attr_accessor :source_url
44
-
45
- #the save path is where the component will be saved
46
- def initialize(save_path)
47
- super(save_path)
48
-
49
- @comment = ""
50
- @source_manufacturer = ""
51
- @source_model = ""
52
- @source_serial_no = ""
53
- @source_year = ""
54
- @source_url = ""
55
-
56
- #these items have multiple instances
57
-
58
- @costs = []
59
- @objects = [] #container for saving the idf/osm snippets
60
-
61
- @path = save_path
62
-
63
- #todo: validate against master taxonomy
64
- end
65
-
66
- # TODO This isn't implemented at the moment
67
- def open_component_xml(filename)
68
- read_component_xml(filename)
69
- end
70
-
71
- # savefile, save the component xml along with
72
- # the files that have been added to the object
73
- def save_tar_gz(delete_files = true)
74
- current_d = Dir.pwd
75
- paths = []
76
-
77
- save_component_xml
78
-
79
- paths << "./component.xml"
80
-
81
- #copy over the files to the directory
82
- @files.each do |file|
83
- src_path = Pathname.new(file.fqp_file)
84
- dest_path = Pathname.new("#{resolve_path}/#{file.filename}")
85
- if File.exists?(src_path)
86
- if src_path == dest_path
87
- #do nothing, file is already where it needs to be
88
- else
89
- #move the file where it needs to go
90
- FileUtils.cp(src_path, dest_path)
91
- end
92
- else
93
- puts "#{src_path} -> File does not exist"
94
- end
95
- paths << "./#{file.filename}"
96
- end
97
-
98
- #take all the files and tar.gz them -- name the file the same as
99
- #the directory
100
-
101
- Dir.chdir("#{resolve_path}")
102
- destination = "#{@name.gsub(/\W/,'_').gsub(/___/,'_').gsub(/__/,'_').chomp('_').strip}"
103
- # truncate filenames for paths that are longer than 256 characters (with .tar.gz appended)
104
- unless (@path + destination + destination).size < 249
105
- destination = "#{@uid}"
106
- puts "truncating filename...using uid instead of name"
107
- end
108
- destination = destination + ".tar.gz"
109
-
110
- File.delete(destination) if File.exists?(destination)
111
-
112
- BCL.tarball(destination, paths)
113
-
114
- Dir.chdir(current_d)
115
-
116
- if (delete_files)
117
- @files.each do |file|
118
- if File.exists?(File.dirname(file.fqp_file))
119
- puts "[ComponentXml] Deleting: #{File.dirname(file.fqp_file)}"
120
- FileUtils.rm_rf(File.dirname(file.fqp_file))
121
- end
122
- end
123
- end
124
-
125
- #puts "[ComponentXml] " + Dir.pwd
126
- end
127
-
128
- def add_cost(cost_name, cost_type, category, value, units, interval, interval_units, year, location, currency,
129
- source, reference_component_name, reference_component_id)
130
- cs = CostStruct.new
131
- cs.cost_name = cost_name
132
- cs.cost_type = cost_type
133
- cs.category = category
134
- cs.value = value
135
- cs.interval = interval
136
- cs.interval_units = interval_units
137
- cs.year = year
138
- cs.location = location
139
- cs.units = units
140
- cs.currency = currency
141
- cs.source = source
142
- cs.reference_component_name = reference_component_name
143
- cs.reference_component_id = reference_component_id
144
-
145
- @costs << cs
146
- end
147
-
148
- def add_object(object_type, object_instance)
149
- ob = ObjectStruct.new
150
- ob.obj_type = object_type
151
- ob.obj_instance = object_instance
152
-
153
- @objects << ob
154
- end
155
-
156
- def resolve_path
157
- FileUtils.mkdir_p(@path) unless File.directory?(@path)
158
-
159
- # TODO: should probably save all components with uid instead of name to avoid path length limitation issues
160
- # for now, switch to uid instead of name if larger than arbitrary number of characters
161
- if @name.size < 75
162
- new_path = "#{@path}/#{name.gsub(/\W/,'_').gsub(/___/,'_').gsub(/__/,'_').chomp('_').strip}"
163
- else
164
- new_path = "#{@path}/#{@uid}"
165
- end
166
-
167
- FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
168
- result = new_path
169
- end
170
-
171
- def osm_resolve_path
172
- FileUtils.mkdir_p(@path) unless File.directory?(@path)
173
- new_path = "#{@path}/osm_#{name.gsub(/\W/,'_').gsub(/___/,'_').gsub(/__/,'_').chomp('_').strip}"
174
- FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
175
- result = new_path
176
- end
177
-
178
- def osc_resolve_path
179
- FileUtils.mkdir_p(@path) unless File.directory?(@path)
180
- new_path = "#{@path}/osc_#{name.gsub(/\W/,'_').gsub(/___/,'_').gsub(/__/,'_').chomp('_').strip}"
181
- FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
182
- result = new_path
183
- end
184
-
185
- def resolve_component_path(component_type)
186
- FileUtils.mkdir_p(@path) unless File.directory?(@path)
187
- new_path = @path + '/OpenStudio'
188
- FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
189
- new_path = new_path + "/#{component_type}"
190
- FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
191
- return new_path
192
- end
193
-
194
- def tmp_resolve_path
195
- FileUtils.mkdir_p(@path) unless File.directory?(@path)
196
- new_path = "#{@path}/tmp_#{name.gsub(/\W/,'_').gsub(/___/,'_').gsub(/__/,'_').chomp('_').strip}"
197
- FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
198
- result = new_path
199
- end
200
-
201
-
202
- def create_os_component(osobj)
203
- osobj.getCostLineItems.each do |os|
204
- @costs.each do |cost|
205
- #figure out costs for constructions
206
- os.setMaterialCost(cost.value.to_f) if cost.category == "material"
207
- if cost.category == "installation"
208
- os.setInstallationCost(cost.value.to_f)
209
- os.setExpectedLife(cost.interval.to_i)
210
- end
211
- os.setFixedOM(cost.value.to_f) if cost.category == "operations and maintenance"
212
- os.setVariableOM(cost.value.to_f) if cost.category == "variable operations and maintenance"
213
- os.setSalvageCost(cost.value.to_f) if cost.category == "salvage"
214
- end
215
- end
216
- newcomp = osobj.createComponent
217
-
218
- cd = newcomp.componentData
219
- cd.setDescription(@description)
220
-
221
- at = newcomp.componentData.componentDataAttributes
222
- @attributes.each do |attrib|
223
- if (attrib.value.to_s != "") and (attrib.name.to_s != "")
224
- if attrib.units != ""
225
- at.addAttribute(tc(attrib.name), attrib.value, attrib.units)
226
- else
227
- at.addAttribute(tc(attrib.name), attrib.value)
228
- end
229
- end
230
- end
231
-
232
- tg = newcomp.componentData.componentDataTags
233
- comp_tag = ""
234
- @tags.each do |tag|
235
- tg.addTag(tc(tag.descriptor))
236
- if (tag.descriptor != "energyplus") and (tag.descriptor != "construction")
237
- #create a map of component tags to directories
238
- comp_tag = tag.descriptor
239
- if comp_tag == "interior wall"
240
- comp_tag = "interiorwalls"
241
- elsif comp_tag == "exterior wall"
242
- comp_tag = "exteriorwalls"
243
- elsif comp_tag == "exterior slab"
244
- comp_tag = "exteriorslabs"
245
- elsif comp_tag == "exposed floor"
246
- comp_tag = "exposedfloors"
247
- elsif comp_tag == "attic floor"
248
- comp_tag = "atticfloors"
249
- elsif comp_tag == "roof"
250
- comp_tag = "roofs"
251
- elsif comp_tag == "door"
252
- comp_tag = "doors"
253
- elsif comp_tag == "skylight"
254
- comp_tag = "skylights"
255
- elsif comp_tag == "window"
256
- comp_tag = "windows"
257
- end
258
- puts comp_tag
259
- end
260
- end
261
-
262
- return newcomp
263
- end
264
-
265
- def save_component_xml(dir_path = resolve_path)
266
- FileUtils.mkpath(dir_path) if !File.exists?(dir_path)
267
-
268
- #make sure the uid and vid are pulled in from the Component
269
- @uuid = @uid
270
- @vuid = @comp_version_id
271
-
272
- if @uuid.nil?
273
- puts "uid was missing; creating a new one"
274
- generate_uuid()
275
- end
276
-
277
- if @vuid.nil?
278
- puts "vid was missing; creating a new one"
279
- generate_vuid()
280
- end
281
-
282
- xmlfile = File.new(dir_path + '/component.xml', 'w')
283
- comp_xml = Builder::XmlMarkup.new(:target => xmlfile, :indent=>2)
284
-
285
- #setup the xml file
286
- comp_xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
287
- comp_xml.component("xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
288
- "xsi:noNamespaceSchemaLocation"=>"#{@schema_url}") {
289
- comp_xml.name @name
290
- comp_xml.uid @uuid
291
- comp_xml.version_id @vuid
292
- comp_xml.description @description if @description != ""
293
- comp_xml.modeler_description @modeler_description if @modeler_description != ""
294
- comp_xml.comment @comment if @comment != ""
295
-
296
- #comp_xml.fidelity_level @fidelity_level if @fidelity_level != ""
297
-
298
- comp_xml.provenances {
299
- @provenances.each do |prov|
300
- comp_xml.provenance {
301
- comp_xml.author prov.author
302
- comp_xml.datetime prov.datetime
303
- comp_xml.comment prov.comment
304
- }
305
- end
306
- }
307
-
308
- comp_xml.tags {
309
- @tags.each do |tag|
310
- comp_xml.tag tag.descriptor
311
- end
312
- }
313
-
314
- comp_xml.attributes {
315
- @attributes.each do |attrib|
316
- if (attrib.value.to_s != "") and (attrib.name.to_s != "") then
317
- comp_xml.attribute {
318
- comp_xml.name attrib.name
319
- comp_xml.value attrib.value
320
- comp_xml.datatype attrib.datatype
321
- comp_xml.units attrib.units if attrib.units != ""
322
- }
323
- end
324
- end
325
- }
326
-
327
- comp_xml.source {
328
- comp_xml.manufacturer @source_manufacturer if @source_manufacturer != ""
329
- comp_xml.model @source_model if @source_model != ""
330
- comp_xml.serial_no @source_serial_no if @source_serial_no != ""
331
- comp_xml.year @source_year if @source_year != ""
332
- comp_xml.url @source_url if @source_url != ""
333
- }
334
-
335
- if not @files.nil?
336
- comp_xml.files {
337
- @files.each do |file|
338
- comp_xml.file {
339
- comp_xml.version {
340
- comp_xml.software_program file.version_software_program
341
- comp_xml.identifier file.version_id
342
- }
343
-
344
- comp_xml.filename file.filename
345
- comp_xml.filetype file.filetype
346
- }
347
- end
348
- }
349
- end
350
-
351
- #check if we should write out costs, don't write if all values are 0 or nil
352
- #DLM: schema always expects costs
353
- write_costs = true
354
- #if not @costs.nil?
355
- # @costs.each do |cost|
356
- # if (cost.value.nil?) && (not cost.value == 0)
357
- # write_costs = true
358
- # break
359
- # end
360
- # end
361
- #end
362
-
363
- if write_costs
364
- comp_xml.costs {
365
- @costs.each do |cost|
366
- comp_xml.cost {
367
- comp_xml.instance_name cost.cost_name
368
- comp_xml.cost_type cost.cost_type
369
- comp_xml.category cost.category
370
- comp_xml.value cost.value
371
- comp_xml.units cost.units if cost.units != ""
372
- comp_xml.interval cost.interval if cost.interval != ""
373
- comp_xml.interval_units cost.interval_units if cost.interval_units != ""
374
- comp_xml.year cost.year if cost.year != ""
375
- comp_xml.currency cost.currency if cost.currency != ""
376
- comp_xml.source cost.source if cost.source != ""
377
- comp_xml.reference_component_name cost.reference_component_name if cost.reference_component_name != ""
378
- comp_xml.reference_component_id cost.reference_component_id if cost.reference_component_id != ""
379
- }
380
- end
381
- }
382
- end
383
-
384
- }
385
-
386
- xmlfile.close
387
- end
388
- end
389
-
390
- end # module BCL
1
+ ######################################################################
2
+ # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
+ # All rights reserved.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ######################################################################
19
+
20
+ # Provides programmatic access to the component.xsd schema needed for
21
+ # generating the component information that will be uploaded to
22
+ # the Building Component Library.
23
+
24
+ module BCL
25
+ class Component < BaseXml
26
+ attr_accessor :comment
27
+ attr_accessor :source_manufacturer
28
+ attr_accessor :source_model
29
+ attr_accessor :source_serial_no
30
+ attr_accessor :source_year
31
+ attr_accessor :source_url
32
+ attr_accessor :objects
33
+ attr_accessor :name
34
+ attr_accessor :uid
35
+ attr_accessor :comp_version_id
36
+ attr_accessor :description
37
+ attr_accessor :modeler_description
38
+ attr_accessor :fidelity_level
39
+ attr_accessor :source_manufacturer
40
+ attr_accessor :source_model
41
+ attr_accessor :source_serial_no
42
+ attr_accessor :source_year
43
+ attr_accessor :source_url
44
+
45
+ # the save path is where the component will be saved
46
+ def initialize(save_path)
47
+ super(save_path)
48
+
49
+ @comment = ''
50
+ @source_manufacturer = ''
51
+ @source_model = ''
52
+ @source_serial_no = ''
53
+ @source_year = ''
54
+ @source_url = ''
55
+
56
+ # these items have multiple instances
57
+
58
+ @costs = []
59
+ @objects = [] # container for saving the idf/osm snippets
60
+
61
+ @path = save_path
62
+
63
+ # todo: validate against master taxonomy
64
+ end
65
+
66
+ # TODO This isn't implemented at the moment
67
+ def open_component_xml(filename)
68
+ read_component_xml(filename)
69
+ end
70
+
71
+ # savefile, save the component xml along with
72
+ # the files that have been added to the object
73
+ def save_tar_gz(delete_files = true)
74
+ current_d = Dir.pwd
75
+ paths = []
76
+
77
+ save_component_xml
78
+
79
+ paths << './component.xml'
80
+
81
+ # copy over the files to the directory
82
+ @files.each do |file|
83
+ src_path = Pathname.new(file.fqp_file)
84
+ dest_path = Pathname.new("#{resolve_path}/#{file.filename}")
85
+ if File.exist?(src_path)
86
+ if src_path == dest_path
87
+ # do nothing, file is already where it needs to be
88
+ else
89
+ # move the file where it needs to go
90
+ FileUtils.cp(src_path, dest_path)
91
+ end
92
+ else
93
+ puts "#{src_path} -> File does not exist"
94
+ end
95
+ paths << "./#{file.filename}"
96
+ end
97
+
98
+ # take all the files and tar.gz them -- name the file the same as
99
+ # the directory
100
+
101
+ Dir.chdir("#{resolve_path}")
102
+ destination = "#{@name.gsub(/\W/, '_').gsub(/___/, '_').gsub(/__/, '_').chomp('_').strip}"
103
+ # truncate filenames for paths that are longer than 256 characters (with .tar.gz appended)
104
+ unless (@path + destination + destination).size < 249
105
+ destination = "#{@uid}"
106
+ puts 'truncating filename...using uid instead of name'
107
+ end
108
+ destination = destination + '.tar.gz'
109
+
110
+ File.delete(destination) if File.exist?(destination)
111
+
112
+ BCL.tarball(destination, paths)
113
+
114
+ Dir.chdir(current_d)
115
+
116
+ if delete_files
117
+ @files.each do |file|
118
+ if File.exist?(File.dirname(file.fqp_file))
119
+ puts "[ComponentXml] Deleting: #{File.dirname(file.fqp_file)}"
120
+ FileUtils.rm_rf(File.dirname(file.fqp_file))
121
+ end
122
+ end
123
+ end
124
+
125
+ # puts "[ComponentXml] " + Dir.pwd
126
+ end
127
+
128
+ def add_cost(cost_name, cost_type, category, value, units, interval, interval_units, year, location, currency,
129
+ source, reference_component_name, reference_component_id)
130
+ cs = CostStruct.new
131
+ cs.cost_name = cost_name
132
+ cs.cost_type = cost_type
133
+ cs.category = category
134
+ cs.value = value
135
+ cs.interval = interval
136
+ cs.interval_units = interval_units
137
+ cs.year = year
138
+ cs.location = location
139
+ cs.units = units
140
+ cs.currency = currency
141
+ cs.source = source
142
+ cs.reference_component_name = reference_component_name
143
+ cs.reference_component_id = reference_component_id
144
+
145
+ @costs << cs
146
+ end
147
+
148
+ def add_object(object_type, object_instance)
149
+ ob = ObjectStruct.new
150
+ ob.obj_type = object_type
151
+ ob.obj_instance = object_instance
152
+
153
+ @objects << ob
154
+ end
155
+
156
+ def resolve_path
157
+ FileUtils.mkdir_p(@path) unless File.directory?(@path)
158
+
159
+ # TODO: should probably save all components with uid instead of name to avoid path length limitation issues
160
+ # for now, switch to uid instead of name if larger than arbitrary number of characters
161
+ if @name.size < 75
162
+ new_path = "#{@path}/#{name.gsub(/\W/, '_').gsub(/___/, '_').gsub(/__/, '_').chomp('_').strip}"
163
+ else
164
+ new_path = "#{@path}/#{@uid}"
165
+ end
166
+
167
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
168
+ result = new_path
169
+ end
170
+
171
+ def osm_resolve_path
172
+ FileUtils.mkdir_p(@path) unless File.directory?(@path)
173
+ new_path = "#{@path}/osm_#{name.gsub(/\W/, '_').gsub(/___/, '_').gsub(/__/, '_').chomp('_').strip}"
174
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
175
+ result = new_path
176
+ end
177
+
178
+ def osc_resolve_path
179
+ FileUtils.mkdir_p(@path) unless File.directory?(@path)
180
+ new_path = "#{@path}/osc_#{name.gsub(/\W/, '_').gsub(/___/, '_').gsub(/__/, '_').chomp('_').strip}"
181
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
182
+ result = new_path
183
+ end
184
+
185
+ def resolve_component_path(component_type)
186
+ FileUtils.mkdir_p(@path) unless File.directory?(@path)
187
+ new_path = @path + '/OpenStudio'
188
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
189
+ new_path = new_path + "/#{component_type}"
190
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
191
+ new_path
192
+ end
193
+
194
+ def tmp_resolve_path
195
+ FileUtils.mkdir_p(@path) unless File.directory?(@path)
196
+ new_path = "#{@path}/tmp_#{name.gsub(/\W/, '_').gsub(/___/, '_').gsub(/__/, '_').chomp('_').strip}"
197
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
198
+ result = new_path
199
+ end
200
+
201
+ def create_os_component(osobj)
202
+ osobj.getCostLineItems.each do |os|
203
+ @costs.each do |cost|
204
+ # figure out costs for constructions
205
+ os.setMaterialCost(cost.value.to_f) if cost.category == 'material'
206
+ if cost.category == 'installation'
207
+ os.setInstallationCost(cost.value.to_f)
208
+ os.setExpectedLife(cost.interval.to_i)
209
+ end
210
+ os.setFixedOM(cost.value.to_f) if cost.category == 'operations and maintenance'
211
+ os.setVariableOM(cost.value.to_f) if cost.category == 'variable operations and maintenance'
212
+ os.setSalvageCost(cost.value.to_f) if cost.category == 'salvage'
213
+ end
214
+ end
215
+ newcomp = osobj.createComponent
216
+
217
+ cd = newcomp.componentData
218
+ cd.setDescription(@description)
219
+
220
+ at = newcomp.componentData.componentDataAttributes
221
+ @attributes.each do |attrib|
222
+ if (attrib.value.to_s != '') and (attrib.name.to_s != '')
223
+ if attrib.units != ''
224
+ at.addAttribute(tc(attrib.name), attrib.value, attrib.units)
225
+ else
226
+ at.addAttribute(tc(attrib.name), attrib.value)
227
+ end
228
+ end
229
+ end
230
+
231
+ tg = newcomp.componentData.componentDataTags
232
+ comp_tag = ''
233
+ @tags.each do |tag|
234
+ tg.addTag(tc(tag.descriptor))
235
+ if (tag.descriptor != 'energyplus') and (tag.descriptor != 'construction')
236
+ # create a map of component tags to directories
237
+ comp_tag = tag.descriptor
238
+ if comp_tag == 'interior wall'
239
+ comp_tag = 'interiorwalls'
240
+ elsif comp_tag == 'exterior wall'
241
+ comp_tag = 'exteriorwalls'
242
+ elsif comp_tag == 'exterior slab'
243
+ comp_tag = 'exteriorslabs'
244
+ elsif comp_tag == 'exposed floor'
245
+ comp_tag = 'exposedfloors'
246
+ elsif comp_tag == 'attic floor'
247
+ comp_tag = 'atticfloors'
248
+ elsif comp_tag == 'roof'
249
+ comp_tag = 'roofs'
250
+ elsif comp_tag == 'door'
251
+ comp_tag = 'doors'
252
+ elsif comp_tag == 'skylight'
253
+ comp_tag = 'skylights'
254
+ elsif comp_tag == 'window'
255
+ comp_tag = 'windows'
256
+ end
257
+ puts comp_tag
258
+ end
259
+ end
260
+
261
+ newcomp
262
+ end
263
+
264
+ def save_component_xml(dir_path = resolve_path)
265
+ FileUtils.mkpath(dir_path) unless File.exist?(dir_path)
266
+
267
+ # make sure the uid and vid are pulled in from the Component
268
+ @uuid = @uid
269
+ @vuid = @comp_version_id
270
+
271
+ if @uuid.nil?
272
+ puts 'uid was missing; creating a new one'
273
+ generate_uuid
274
+ end
275
+
276
+ if @vuid.nil?
277
+ puts 'vid was missing; creating a new one'
278
+ generate_vuid
279
+ end
280
+
281
+ xmlfile = File.new(dir_path + '/component.xml', 'w')
282
+ comp_xml = Builder::XmlMarkup.new(target: xmlfile, indent: 2)
283
+
284
+ # setup the xml file
285
+ comp_xml.instruct! :xml, version: '1.0', encoding: 'UTF-8'
286
+ comp_xml.component('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
287
+ 'xsi:noNamespaceSchemaLocation' => "#{@schema_url}") {
288
+ comp_xml.name @name
289
+ comp_xml.uid @uuid
290
+ comp_xml.version_id @vuid
291
+ comp_xml.description @description if @description != ''
292
+ comp_xml.modeler_description @modeler_description if @modeler_description != ''
293
+ comp_xml.comment @comment if @comment != ''
294
+
295
+ # comp_xml.fidelity_level @fidelity_level if @fidelity_level != ""
296
+
297
+ comp_xml.provenances {
298
+ @provenances.each do |prov|
299
+ comp_xml.provenance {
300
+ comp_xml.author prov.author
301
+ comp_xml.datetime prov.datetime
302
+ comp_xml.comment prov.comment
303
+ }
304
+ end
305
+ }
306
+
307
+ comp_xml.tags {
308
+ @tags.each do |tag|
309
+ comp_xml.tag tag.descriptor
310
+ end
311
+ }
312
+
313
+ comp_xml.attributes {
314
+ @attributes.each do |attrib|
315
+ if (attrib.value.to_s != '') and (attrib.name.to_s != '') then
316
+ comp_xml.attribute {
317
+ comp_xml.name attrib.name
318
+ comp_xml.value attrib.value
319
+ comp_xml.datatype attrib.datatype
320
+ comp_xml.units attrib.units if attrib.units != ''
321
+ }
322
+ end
323
+ end
324
+ }
325
+
326
+ comp_xml.source {
327
+ comp_xml.manufacturer @source_manufacturer if @source_manufacturer != ''
328
+ comp_xml.model @source_model if @source_model != ''
329
+ comp_xml.serial_no @source_serial_no if @source_serial_no != ''
330
+ comp_xml.year @source_year if @source_year != ''
331
+ comp_xml.url @source_url if @source_url != ''
332
+ }
333
+
334
+ unless @files.nil?
335
+ comp_xml.files {
336
+ @files.each do |file|
337
+ comp_xml.file {
338
+ comp_xml.version {
339
+ comp_xml.software_program file.version_software_program
340
+ comp_xml.identifier file.version_id
341
+ }
342
+
343
+ comp_xml.filename file.filename
344
+ comp_xml.filetype file.filetype
345
+ }
346
+ end
347
+ }
348
+ end
349
+
350
+ # check if we should write out costs, don't write if all values are 0 or nil
351
+ # DLM: schema always expects costs
352
+ write_costs = true
353
+ # if not @costs.nil?
354
+ # @costs.each do |cost|
355
+ # if (cost.value.nil?) && (not cost.value == 0)
356
+ # write_costs = true
357
+ # break
358
+ # end
359
+ # end
360
+ # end
361
+
362
+ if write_costs
363
+ comp_xml.costs {
364
+ @costs.each do |cost|
365
+ comp_xml.cost {
366
+ comp_xml.instance_name cost.cost_name
367
+ comp_xml.cost_type cost.cost_type
368
+ comp_xml.category cost.category
369
+ comp_xml.value cost.value
370
+ comp_xml.units cost.units if cost.units != ''
371
+ comp_xml.interval cost.interval if cost.interval != ''
372
+ comp_xml.interval_units cost.interval_units if cost.interval_units != ''
373
+ comp_xml.year cost.year if cost.year != ''
374
+ comp_xml.currency cost.currency if cost.currency != ''
375
+ comp_xml.source cost.source if cost.source != ''
376
+ comp_xml.reference_component_name cost.reference_component_name if cost.reference_component_name != ''
377
+ comp_xml.reference_component_id cost.reference_component_id if cost.reference_component_id != ''
378
+ }
379
+ end
380
+ }
381
+ end
382
+
383
+ }
384
+
385
+ xmlfile.close
386
+ end
387
+ end
388
+ end # module BCL