/tools/Ruby/lib/ruby/gems/1.8/gems/configatron-2.8.2/lib/configatron/store.rb
http://github.com/agross/netopenspace · Ruby · 332 lines · 235 code · 31 blank · 66 comment · 29 complexity · c419ae9908884c0fee1b632c0d707eab MD5 · raw file
- class Configatron
- class Store
- if RUBY_VERSION.match(/^1\.9\.2/)
- require 'syck'
- ::YAML::ENGINE.yamler = 'syck'
- end
- alias_method :send!, :send
- # Takes an optional Hash of parameters
- def initialize(options = {}, name = nil, parent = nil)
- @_name = name
- @_parent = parent
- @_store = {}
- configure_from_hash(options)
- @_protected = []
- @_locked = false
- end
- # Returns a Hash representing the configurations
- def to_hash
- h = Hash.new
- @_store.each { |k,v|
- # Descend the tree and hashify each node
- h[k] = v.is_a?(Store) ? v.to_hash : v
- }
- h
- end
- def heirarchy
- path = [@_name]
- parent = @_parent
- until parent.nil?
- path << parent.instance_variable_get('@_name')
- parent = parent.instance_variable_get('@_parent')
- end
- path.compact!
- path.reverse!
- path.join('.')
- end
- def configatron_keys
- return @_store.keys.collect{|k| k.to_s}.sort
- end
- # Checks whether or not a parameter exists
- #
- # Examples:
- # configatron.i.am.alive = 'alive!'
- # configatron.i.am.exists?(:alive) # => true
- # configatron.i.am.exists?(:dead) # => false
- def exists?(name)
- @_store.has_key?(name.to_sym) || @_store.has_key?(name.to_s)
- end
- # respond_to to respond_to
- def respond_to?(name)
- exists?(name) || super
- end
- def inspect
- path = [@_name]
- parent = @_parent
- until parent.nil?
- path << parent.instance_variable_get('@_name')
- parent = parent.instance_variable_get('@_parent')
- end
- path << 'configatron'
- path.compact!
- path.reverse!
- f_out = []
- @_store.each do |k, v|
- if v.is_a?(Configatron::Store)
- v.inspect.each_line do |line|
- if line.match(/\n/)
- line.each_line do |l|
- l.strip!
- f_out << l
- end
- else
- line.strip!
- f_out << line
- end
- end
- else
- f_out << "#{path.join('.')}.#{k} = #{v.inspect}"
- end
- end
- f_out.compact.sort.join("\n")
- end
- # Allows for the configuration of the system via a Hash
- def configure_from_hash(options)
- parse_options(options)
- end
- # Allows for the configuration of the system from a YAML file.
- # Takes the path to the YAML file. Also takes an optional parameter,
- # <tt>:hash</tt>, that indicates a specific hash that should be
- # loaded from the file.
- def configure_from_yaml(path, opts = {})
- Configatron.log.warn "DEPRECATED! (configure_from_yaml) Please stop using YAML and use Ruby instead. This method will be removed in 2.9."
- begin
- yml = ::Yamler.load(path)
- yml = yml[opts[:hash]] unless opts[:hash].nil?
- configure_from_hash(yml)
- rescue Errno::ENOENT => e
- puts e.message
- end
- end
- # Returns true if there are no configuration parameters
- def nil?
- return @_store.empty?
- end
- def blank?
- value = retrieve(@_name)
- value.respond_to?(:empty?) ? value.empty? : !value
- end
- # Retrieves a certain parameter and if that parameter
- # doesn't exist it will return the default_value specified.
- def retrieve(name, default_value = nil)
- val = method_missing(name.to_sym)
- return val.is_a?(Configatron::Store) ? default_value : val
- end
- # Removes a parameter. In the case of a nested parameter
- # it will remove all below it.
- def remove(name)
- @_store.delete(name.to_sym)
- end
- # Sets a 'default' value. If there is already a value specified
- # it won't set the value.
- def set_default(name, default_value)
- unless @_store[name.to_sym]
- # @_store[name.to_sym] = parse_options(default_value)
- self.send("#{name}=", default_value)
- end
- end
- def method_missing(sym, *args) # :nodoc:
- if sym.to_s.match(/(.+)=$/)
- name = sym.to_s.gsub("=", '').to_sym
- raise Configatron::ProtectedParameter.new(name) if @_protected.include?(name) || methods_include?(name)
- raise Configatron::LockedNamespace.new(@_name) if @_locked && !@_store.has_key?(name)
- @_store[name] = parse_options(*args)
- elsif sym.to_s.match(/(.+)\?/)
- return !@_store[$1.to_sym].blank?
- elsif block_given?
- yield self.send(sym)
- elsif @_store.has_key?(sym)
- val = @_store[sym]
- if val.is_a?(Configatron::Proc)
- res = val.execute
- if val.finalize?
- @_store[sym] = res
- end
- return res
- end
- return val
- else
- store = Configatron::Store.new({}, sym, self)
- @_store[sym] = store
- return store
- end
- end
- def ==(other) # :nodoc:
- self.to_hash == other
- end
- # Prevents a parameter from being reassigned. If called on a 'namespace' then
- # all parameters below it will be protected as well.
- def protect(name)
- @_protected << name.to_sym
- end
- # Prevents all parameters from being reassigned.
- def protect_all!
- @_protected.clear
- @_store.keys.each do |k|
- val = self.send(k)
- val.protect_all! if val.class == Configatron::Store
- @_protected << k
- end
- end
- # Removes the protection of a parameter.
- def unprotect(name)
- @_protected.reject! { |e| e == name.to_sym }
- end
- def unprotect_all!
- @_protected.clear
- @_store.keys.each do |k|
- val = self.send(k)
- val.unprotect_all! if val.class == Configatron::Store
- end
- end
- # Prevents a namespace from having new parameters set. The lock is applied
- # recursively to any namespaces below it.
- def lock(name)
- namespace = @_store[name.to_sym]
- raise ArgumentError, "Namespace #{name.inspect} does not exist" if namespace.nil?
- namespace.lock!
- end
- def unlock(name)
- namespace = @_store[name.to_sym]
- raise ArgumentError, "Namespace #{name.inspect} does not exist" if namespace.nil?
- namespace.unlock!
- end
- # = DeepClone
- #
- # == Version
- # 1.2006.05.23 (change of the first number means Big Change)
- #
- # == Description
- # Adds deep_clone method to an object which produces deep copy of it. It means
- # if you clone a Hash, every nested items and their nested items will be cloned.
- # Moreover deep_clone checks if the object is already cloned to prevent endless recursion.
- #
- # == Usage
- #
- # (see examples directory under the ruby gems root directory)
- #
- # require 'rubygems'
- # require 'deep_clone'
- #
- # include DeepClone
- #
- # obj = []
- # a = [ true, false, obj ]
- # b = a.deep_clone
- # obj.push( 'foo' )
- # p obj # >> [ 'foo' ]
- # p b[2] # >> []
- #
- # == Source
- # http://simplypowerful.1984.cz/goodlibs/1.2006.05.23
- #
- # == Author
- # jan molic (/mig/at_sign/1984/dot/cz/)
- #
- # == Licence
- # You can redistribute it and/or modify it under the same terms of Ruby's license;
- # either the dual license version in 2003, or any later version.
- #
- def deep_clone( obj=self, cloned={} )
- if cloned.has_key?( obj.object_id )
- return cloned[obj.object_id]
- else
- begin
- cl = obj.clone
- rescue Exception
- # unclonnable (TrueClass, Fixnum, ...)
- cloned[obj.object_id] = obj
- return obj
- else
- cloned[obj.object_id] = cl
- cloned[cl.object_id] = cl
- if cl.is_a?( Hash )
- cl.clone.each { |k,v|
- cl[k] = deep_clone( v, cloned )
- }
- elsif cl.is_a?( Array )
- cl.collect! { |v|
- deep_clone( v, cloned )
- }
- end
- cl.instance_variables.each do |var|
- v = cl.instance_eval( var.to_s )
- v_cl = deep_clone( v, cloned )
- cl.instance_eval( "#{var} = v_cl" )
- end
- return cl
- end
- end
- end
- protected
- def lock!
- @_locked = true
- @_store.values.each { |store| store.lock! if store.is_a?(Configatron::Store) }
- end
- def unlock!
- @_locked = false
- @_store.values.each { |store| store.unlock! if store.is_a?(Configatron::Store) }
- end
- private
- def methods_include?(name)
- self.methods.include?(RUBY_VERSION > '1.9.0' ? name.to_sym : name.to_s)
- end
- def parse_options(options)
- if options.is_a?(Hash)
- options.each do |k,v|
- if v.is_a?(Hash)
- if v.keys.length == 1 && v.keys.first.is_a?(SYCK_CONSTANT)
- self.method_missing("#{k}=", v.values.first.flatten)
- else
- self.method_missing(k.to_sym).configure_from_hash(v)
- end
- else
- self.method_missing("#{k}=", v)
- end
- end
- else
- return options
- end
- end
- begin
- undef :test # :nodoc:
- rescue Exception => e
- end
-
- if RUBY_PLATFORM == 'java'
- SYCK_CONSTANT = YAML::Yecht::MergeKey
- else
- SYCK_CONSTANT = (RUBY_VERSION.match(/^1\.9/) ? Syck::MergeKey : YAML::Syck::MergeKey)
- end
- end # Store
- end # Configatron