Class: Properties

Inherits:
Object
  • Object
show all
Defined in:
lib/tungsten/properties.rb

Overview

Defines a properties object.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProperties

Initialize with some base values.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/tungsten/properties.rb', line 14

def initialize
  @props = {}
  
  # These hashes are used to prevent loops where the prompt handler needs
  # to get additional information from the configuration
  @in_prompt_handler = {}
  @in_template_value_prompt_handler = {}
  
  # The prompt handler provides a structuring for finding values
  # that do no exist in the props Hash. The prompt handler will calculate
  # default values or values based on parent defaults.
  @use_prompt_handler = false
  @prompt_handler = nil
  
  # This is used for translating the configuration from 1.3 deployments
  @force_json = true
end

Instance Attribute Details

#force_jsonObject

Returns the value of attribute force_json.



11
12
13
# File 'lib/tungsten/properties.rb', line 11

def force_json
  @force_json
end

#propsObject

Returns the value of attribute props.



11
12
13
# File 'lib/tungsten/properties.rb', line 11

def props
  @props
end

#use_prompt_handlerObject

Returns the value of attribute use_prompt_handler.



11
12
13
# File 'lib/tungsten/properties.rb', line 11

def use_prompt_handler
  @use_prompt_handler
end

Instance Method Details

#append(key, value = []) ⇒ Object



454
455
456
457
458
459
460
461
462
463
464
465
466
467
# File 'lib/tungsten/properties.rb', line 454

def append(key, value = [])
  if value == nil || value == ""
    value = []
  end
  
  if ! value.kind_of?(Array)
     value=Array(value) 
  end
  currentvalue=getNestedPropertyOr(key, [])
  if ! currentvalue.kind_of?(Array)
      currentvalue=Array(currentvalue)
  end
  setProperty(key, (currentvalue+value).uniq())
end

#empty?Boolean

Returns:

  • (Boolean)


434
435
436
# File 'lib/tungsten/properties.rb', line 434

def empty?
  (@props.size() == 0)
end

#force_outputObject



169
170
171
# File 'lib/tungsten/properties.rb', line 169

def force_output()
  TU.force_output(self.to_s)
end

#getNestedProperty(attrs) ⇒ Object

Fetch a nested hash value



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/tungsten/properties.rb', line 174

def getNestedProperty(attrs)
  if attrs.is_a?(String)
    attrs = attrs.split('.')
  end
  
  attr_count = attrs.size
  current_val = @props
  for i in 0..(attr_count-1)
    attr_name = attrs[i]
    return current_val[attr_name] if i == (attr_count-1)
    return nil if current_val[attr_name].nil?
    current_val = current_val[attr_name]
  end
  
  return nil
end

#getNestedPropertyOr(key, default = "") ⇒ Object



372
373
374
375
376
377
378
379
# File 'lib/tungsten/properties.rb', line 372

def getNestedPropertyOr(key, default = "")
  value = getNestedProperty(key)
  if value == nil
    default
  else
    value
  end
end

#getPromptHandlerObject



422
423
424
425
426
427
428
429
430
431
432
# File 'lib/tungsten/properties.rb', line 422

def getPromptHandler
  unless usePromptHandler()
    return nil
  end
  
  unless @prompt_handler
    @prompt_handler = ConfigurePromptHandler.new(self)
  end
  
  return @prompt_handler
end

#getProperty(key, allow_disabled = false) ⇒ Object

Get a property value.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/tungsten/properties.rb', line 220

def getProperty(key, allow_disabled = false)
  if key.is_a?(String)
    key_string = key
    key = key.split('.')
  else
    key_string = key.join('.')
  end
  
  value = getNestedProperty(key)
  if value != nil
    return value
  end
  
  if usePromptHandler()
    findProperty = lambda do |keys|
      if @in_prompt_handler[key_string] == true
        return nil
      end

      begin
        @in_prompt_handler[key_string] = true

        value = getPromptHandler().get_property(keys, allow_disabled)

        @in_prompt_handler[key_string] = false
      rescue IgnoreError
        @in_prompt_handler[key_string] = false
      rescue => e
        @in_prompt_handler[key_string] = false
        raise e
      end

      return value
    end
  
  
    value = findProperty.call(key)
  else
    findProperty = lambda do |keys|
      return getNestedProperty(keys)
    end
  end
  
  if value == nil && key.size == 1 && (host = getNestedProperty([DEPLOYMENT_HOST]))
    value = findProperty.call([HOSTS, host, key[0]])
    
    if value == nil && key.size == 1
      dataservice = getProperty(DEPLOYMENT_DATASERVICE)
      
      if dataservice
        value = findProperty.call([DATASERVICES, dataservice, key[0]])
      
        if value == nil
          value = findProperty.call([REPL_SERVICES, dataservice + "_" + host, key[0]])
        end
      
        if value == nil
          value = findProperty.call([MANAGERS, dataservice + "_" + host, key[0]])
        end
      end
    end
    
    if value == nil
      value = findProperty.call([CONNECTORS, host, key[0]])
    end
    
    if value == nil && key.size == 1 && (svc = getNestedProperty([DEPLOYMENT_SERVICE]))
      value = findProperty.call([REPL_SERVICES, svc, key[0]])
    end
  end
  
  value
end

#getPropertyOr(key, default = "") ⇒ Object

Get the property value or return the default if nil



363
364
365
366
367
368
369
370
# File 'lib/tungsten/properties.rb', line 363

def getPropertyOr(key, default = "")
  value = getProperty(key)
  if value == nil
    default
  else
    value
  end
end

#getTemplateValue(key) ⇒ Object

Get the config file value for a property.



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/tungsten/properties.rb', line 295

def getTemplateValue(key)
  if key.is_a?(String)
    key_string = key
    key = key.split('.')
  else
    key_string = key.join('.')
  end
  
  if usePromptHandler()
    findProperty = lambda do |keys|
      if @in_template_value_prompt_handler[key_string] == true
        return nil
      end

      begin
        @in_template_value_prompt_handler[key_string] = true

        value = getPromptHandler().find_template_value(keys)

        @in_template_value_prompt_handler[key_string] = false
      rescue IgnoreError
        @in_template_value_prompt_handler[key_string] = false
      rescue => e
        @in_template_value_prompt_handler[key_string] = false
        raise e
      end

      return value
    end
  
    value = findProperty.call(key)
  end
  
  if value == nil && key.size == 1 && (host = getNestedProperty([DEPLOYMENT_HOST]))
    value = findProperty.call([HOSTS, host, key[0]])
    
    if value == nil && key.size == 1
      dataservice = getNestedProperty([DEPLOYMENT_DATASERVICE])
      if dataservice == nil
        dataservice = getProperty(DEPLOYMENT_DATASERVICE)
      end
      
      if dataservice
        value = findProperty.call([DATASERVICES, dataservice, key[0]])
      
        if value == nil
          value = findProperty.call([REPL_SERVICES, dataservice + "_" + host, key[0]])
        end
      
        if value == nil
          value = findProperty.call([MANAGERS, dataservice + "_" + host, key[0]])
        end
      end
    end
    
    if value == nil
      value = findProperty.call([CONNECTORS, host, key[0]])
    end
  end
  
  if value == nil && key.size == 1 && (svc = getNestedProperty([DEPLOYMENT_SERVICE]))
    value = findProperty.call([REPL_SERVICES, svc, key[0]])
  end
  
  value
end

#hashObject

Get the underlying hash table.



414
415
416
# File 'lib/tungsten/properties.rb', line 414

def hash()
  @props
end

#import(properties_obj = {}) ⇒ Object



113
114
115
116
117
118
119
120
121
# File 'lib/tungsten/properties.rb', line 113

def import(properties_obj = {})
  if properties_obj.instance_of?(Hash)
    self.props = properties_obj
  elsif properties_obj.instance_of?(Properties)
    self.props = properties_obj.props
  else
    raise "You must pass in a Hash or Properties object to import"
  end
end

#include(key, value = {}) ⇒ Object



446
447
448
449
450
451
452
# File 'lib/tungsten/properties.rb', line 446

def include(key, value = {})
  if value == nil || value == ""
    value = {}
  end
  
  setProperty(key, value.merge(getNestedPropertyOr(key, {})))
end

#initialize_copy(source) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/tungsten/properties.rb', line 32

def initialize_copy(source)
  super(source)
  @props = Marshal::load(Marshal::dump(@props))
  @in_prompt_handler = {}
  @in_template_value_prompt_handler = {}
  @use_prompt_handler = source.use_prompt_handler
  @prompt_handler = nil
  @force_json = source.force_json
end

#load(properties_filename) ⇒ Object

Read properties from a file.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/tungsten/properties.rb', line 43

def load(properties_filename)
  file_contents = ""
  
  File.open(properties_filename, 'r') do |file|
    file.read.each_line do |line|
      line.strip!
      unless (line =~ /^#.*/)
        file_contents = file_contents + line
      end
    end
    
    begin
      parsed_contents = JSON.parse(file_contents)
    rescue Exception => e
      if file_contents == ""
        parsed_contents = {}
      elsif file_contents[0,1] == "{"
        raise "There was an error parsing the config file: #{e.message}"
      end
    end
    
    if parsed_contents && parsed_contents.instance_of?(Hash)
      @props = parsed_contents
    elsif @force_json == true
      raise "There was an error parsing the JSON config file: #{properties_filename}.  Try using the migration procedure if you have an old configuration file."
    else
      new_props = {}
      
      file.rewind()
      file.read.each_line do |line|
        line.strip!
        
        if (line =~ /^([\w\.]+)\[?([\w\.]+)?\]?\s*=\s*(\S.*)/)
          key = $1
          value = $3
      
          if $2
            new_props[key] = {} unless new_props[key]
            new_props[key][$2] = value
          else
            new_props[key] = value
          end
        elsif (line =~ /^([\w\.]+)\s*=/)
          key = $1
          value = ""
          new_props[key] = value
        end
      end
      
      @props = new_props
    end
    
    original_props = @props.dup
    
    if original_props != @props
      Configurator.instance.warning("Deprecated keys in the config file were updated")
    end
  end
end

#load_and_initialize(properties_filename, keys_module) ⇒ Object

Read properties from a file.



104
105
106
107
# File 'lib/tungsten/properties.rb', line 104

def load_and_initialize(properties_filename, keys_module)
  load(properties_filename)
  init(keys_module)
end

#outputObject



165
166
167
# File 'lib/tungsten/properties.rb', line 165

def output()
  TU.output(self.to_s)
end

#override(key, value = {}) ⇒ Object



438
439
440
441
442
443
444
# File 'lib/tungsten/properties.rb', line 438

def override(key, value = {})
  if value == nil || value == ""
    value = {}
  end
  
  setProperty(key, getNestedPropertyOr(key, {}).merge(value))
end

#resetObject



109
110
111
# File 'lib/tungsten/properties.rb', line 109

def reset
  self.props = {}
end

#setDefault(key, value) ⇒ Object

Set the property to a value only if it is currently unset.



391
392
393
394
395
396
397
398
399
# File 'lib/tungsten/properties.rb', line 391

def setDefault(key, value)
  if key.is_a?(String)
    key = key.split('.')
  end
  
  if getNestedProperty(key) == nil
    setNestedProperty(value, key)
  end
end

#setHashProperty(hash, key, value) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/tungsten/properties.rb', line 204

def setHashProperty(hash, key, value)
  if value == nil  || value == []
    return (hash.delete(key))
  else
    if value.is_a?(Hash)
      hash[key] ||= {}
      value.each{|sub_key,sub_value|
        setHashProperty(hash[key], sub_key, sub_value)
      }
    else
      return (hash[key] = value)
    end
  end
end

#setNestedProperty(new_val, attrs) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/tungsten/properties.rb', line 191

def setNestedProperty(new_val, attrs)
  attr_count = attrs.size
  current_val = @props
  for i in 0..(attr_count-1)
    attr_name = attrs[i]
    if i == (attr_count-1)
      return setHashProperty(current_val, attr_name, new_val)
    end
    current_val[attr_name] = {} if current_val[attr_name].nil?
    current_val = current_val[attr_name]
  end
end

#setPropertiesFromList(list, delimiter) ⇒ Object

Set multiple properties from a delimited string of key value pairs.



402
403
404
405
406
407
408
409
410
411
# File 'lib/tungsten/properties.rb', line 402

def setPropertiesFromList(list, delimiter)
  keyValuePairs = list.split(delimiter)
  keyValuePairs.each do |pair|
    if pair =~ /^(.*)=(.*)$/
      key = $1
      value = $2
      setProperty(key, value)
    end
  end
end

#setProperty(key, value) ⇒ Object

Set a property value.



382
383
384
385
386
387
388
# File 'lib/tungsten/properties.rb', line 382

def setProperty(key, value)
  if key.is_a?(String)
    key = key.split('.')
  end
  
  setNestedProperty(value, key)
end

#sizeObject

Return the size of the properties object.



157
158
159
# File 'lib/tungsten/properties.rb', line 157

def size()
  @props.size
end

#store(properties_filename, use_json = true) ⇒ Object

Write properties to a file. We use signal protection to avoid getting interrupted half-way through.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/tungsten/properties.rb', line 125

def store(properties_filename, use_json = true)
  # Protect I/O with trap for Ctrl-C. 
  interrupted = false
  old_trap = trap("INT") {
    interrupted = true;
  }
  
  # Write. 
  File.open(properties_filename, 'w') do |file|
    file.printf "# Tungsten configuration properties\n"
    file.printf "# Date: %s\n", DateTime.now
    
    if use_json == false
      @props.sort.each do | key, value |
        file.printf "%s=%s\n", key, value
      end
    else
      file.print self.to_s
    end
  end
  
  # Check for interrupt and restore handler. 
  if (interrupted) 
    puts
    puts ("Configuration interrupted") 
    exit 1;
  else
    trap("INT", old_trap);
  end
end

#to_sObject



161
162
163
# File 'lib/tungsten/properties.rb', line 161

def to_s
  JSON.pretty_generate(@props)
end

#usePromptHandlerObject



418
419
420
# File 'lib/tungsten/properties.rb', line 418

def usePromptHandler
  return @use_prompt_handler
end