Class MUES::Config
In: lib/mues/config/yamlloader.rb  (CVS)
lib/mues/config.rb  (CVS)
Parent: Object

A configuration file reader/writer object class. Given an IO object, a filename, or a String with configuration contents, this class parses the configuration and returns an instantiated configuration object that provides a method interface to the config values. MUES::Config objects can also dump the configuration back into a string for writing.

Methods

Included Modules

MUES::TypeCheckFunctions

Classes and Modules

Class MUES::Config::ConfigStruct
Class MUES::Config::Loader
Class MUES::Config::YamlLoader

Constants

SVNRev = %q$Rev: 1234 $   SVN Revision
SVNId = %q$Id: config.rb 1234 2004-08-21 22:47:00Z ged $   SVN Id
SVNURL = %q$URL: svn+ssh://deveiate.org/usr/local/svn/MUES/trunk/lib/mues/config.rb $   SVN URL
Defaults = { :general => { :serverName => "Experimental MUD", :serverDescription => "An experimental MUES server", :serverAdmin => "MUES ADMIN <muesadmin@localhost>", :rootDir => ".", :includePath => ["lib"], }, :engine => { :tickLength => 1.0, :exceptionStackSize => 10, :debugLevel => 0, :eventQueue => { :minWorkers => 5, :maxWorkers => 50, :threshold => 2, :safeLevel => 2, }, :privilegedEventQueue => { :minWorkers => 2, :maxWorkers => 5, :threshold => 1.5, :safeLevel => 1, }, :objectStore => { :name => 'engine', :backend => 'BerkeleyDB', :memorymanager => 'Null', :visitor => nil, :argHash => {}, }, :listeners => {}, }, :environments => { :envPath => ["server/environments"], :autoload => {}, }, :commandShell => { :commandPath => [], :shellClass => nil, :tableClass => nil, :parserClass => nil, :params => { :reloadInterval => 50, :defaultPrompt => 'mues> ', :commandPrefix => '/', }, }, :logging => { 'MUES' => { :level => :notice, :outputters => ""   Define the layout and defaults for the underlying structs

Attributes

createTime  [RW]  The time the configuration was loaded
defaultLoader  [RW] 
loader  [R]  The loader that will be used to save this config
loaders  [RW] 
name  [RW]  The name of the associated record stored on permanent storage for this configuration.
struct  [R]  The underlying config data structure

Public Class methods

Get the loader by the given name, creating a new one if one is not already instantiated.

[Source]

# File lib/mues/config.rb, line 145
        def self::getLoader( name=nil )
            name ||= self.defaultLoader
            self.loaders[name] ||= MUES::Config::Loader::create( name )
        end

Return a duplicate of the given hash with its keys transformed into symbols from whatever they were before.

[Source]

# File lib/mues/config.rb, line 196
        def self::internifyKeys( hash )
            unless hash.is_a?( Hash )
                raise TypeError, "invalid confighash: Expected Hash, not %s" %
                    hash.class.name
            end

            newhash = {}
            hash.each {|key,val|
                if val.is_a?( Hash )
                    newhash[ key.to_s.intern ] = internifyKeys( val )
                else
                    newhash[ key.to_s.intern ] = val
                end
            }

            return newhash
        end

Read and return an MUES::Config object from the given file or configuration source using the specified loader.

[Source]

# File lib/mues/config.rb, line 153
        def self::load( source, loaderObj=nil )
            loaderObj = self.getLoader( loaderObj ) unless
                loaderObj.is_a?( MUES::Config::Loader )
            confighash = loaderObj.load( source )

            obj = new( untaintValues(confighash) )
            obj.loader = loaderObj
            obj.name = source

            return obj
        end

Create a new MUES::Config object. Values passed in via the confighash will be used instead of the defaults.

[Source]

# File lib/mues/config.rb, line 238
        def initialize( confighash={} )
            checkType( confighash, Hash )
            ihash = self.class.internifyKeys( confighash )
            mergedhash = Defaults.merge( ihash, &MUES::HashMergeFunction )
            @struct = ConfigStruct::new( mergedhash )
            @createTime = Time::now
            @name = nil
            @loader = self.class.getLoader

            super()
        end

Return a version of the given hash with its keys transformed into Strings from whatever they were before.

[Source]

# File lib/mues/config.rb, line 217
        def self::stringifyKeys( hash )
            newhash = {}
            hash.each {|key,val|
                if val.is_a?( Hash )
                    newhash[ key.to_s ] = stringifyKeys( val )
                else
                    newhash[ key.to_s ] = val
                end
            }

            return newhash
        end

Return a copy of the specified hash with all of its values untainted.

[Source]

# File lib/mues/config.rb, line 168
        def self::untaintValues( hash )
            newhash = {}
            hash.each {|key,val|
                case val
                when Hash
                    newhash[ key ] = untaintValues( hash[key] )

                when NilClass, TrueClass, FalseClass, Numeric, Symbol
                    newhash[ key ] = val

                when Array
                    MUES::Logger[ self ].debug "Untainting array %p" % [val]
                    newval = val.collect {|v| v.dup.untaint}
                    newhash[ key ] = newval
                    
                else
                    MUES::Logger[ self ].debug "Untainting %p" % val
                    newval = val.dup
                    newval.untaint
                    newhash[ key ] = newval
                end
            }
            return newhash
        end

Public Instance methods

Returns true if the configuration has changed since it was last loaded, either by setting one of its members or changing the file from which it was loaded.

[Source]

# File lib/mues/config.rb, line 305
        def changed?
            return true if @struct.modified?
            return false unless self.name
            self.loader.isNewer?( self.name, self.createTime )
        end

Instantiate a new MUES::CommandShell::Factory from the configured values.

[Source]

# File lib/mues/config.rb, line 384
        def createCommandShellFactory
            cshell = self.commandShell
            MUES::CommandShell::Factory::new(
                cshell.commandPath,
                cshell.params.to_h,
                cshell.shellClass,
                cshell.tableClass,
                cshell.parserClass )
        end

Instantiate and return one or more MUES::Environment objects from the configuration.

[Source]

# File lib/mues/config.rb, line 397
        def createConfiguredEnvironments
            self.log.info "Autoloading %d environments from configuration" %
                self.environments.autoload.nitems
            MUES::Environment::derivativeDirs.unshift( *(self.environments.envPath) )

            return self.environments.autoload.collect {|name, env|
                self.log.debug "Loading a %s env as '%s'" %
                    [ env[:kind], name ]
                MUES::Environment::create(
                    env[:kind],
                    name.to_s,
                    env[:description],
                    env[:params] )
            }
        end

Instantiate and return one or more MUES::Listener objects from the configuration.

[Source]

# File lib/mues/config.rb, line 416
        def createConfiguredListeners
            self.log.info "Creating %d listener/s from configuration." %
                self.engine.listeners.nitems

            return self.engine.listeners.collect {|name, lconfig|
                self.log.info "Calling create for a '%s' listener named '%s': parameters: %s." %
                    [ lconfig[:kind], name, lconfig[:params].inspect ]

                MUES::Listener::create( lconfig[:kind], name, lconfig[:params] )
            }
        end

Instantiate the MUES::Engine‘s objectstore from the configured values.

[Source]

# File lib/mues/config.rb, line 332
        def createEngineObjectstore
            os = self.engine.objectStore

            # Turn the argument hash's keys back into Symbols
            args = {}
            os.argHash.to_h.each {|k,v|
                args[k.intern] = v
            } 

            # Make a Hash out of all the construction arguments
            configHash = {
                :name => os.name,
                :backend => os.backend,
                :memmgr => os.memorymanager,
                :config => args,
            }

            # Visitor element is optional, so don't add it if it's not defined.
            configHash[:visitor] = os.visitor if os.visitor

            return MUES::ObjectStore::create( configHash )
        end

Instantiate the primary event queue (a MUES::EventQueue object) from the config values.

[Source]

# File lib/mues/config.rb, line 358
        def createEventQueue
            qconfig = self.engine.eventQueue
            return MUES::EventQueue::new(
                qconfig.minWorkers,
                qconfig.maxWorkers,
                qconfig.threshold,
                qconfig.safeLevel,
                "Primary Event Queue" )
        end

Instantiate the privileged event queue (a MUES::EventQueue object) from the config values.

[Source]

# File lib/mues/config.rb, line 371
        def createPrivilegedEventQueue
            qconfig = self.engine.privilegedEventQueue
            return MUES::EventQueue::new(
                qconfig.minWorkers,
                qconfig.maxWorkers,
                qconfig.threshold,
                qconfig.safeLevel,
                "Privileged Event Queue" )
        end

Change the configuration object‘s loader. The newLoader argument can be either an MUES::Config::Loader object or the name of one suitable for passing to MUES::Config::Loader::create.

[Source]

# File lib/mues/config.rb, line 275
        def loader=( newLoader )
            if newLoader.is_a?( MUES::Config::Loader )
                @loader = newLoader
            else
                @loader = self.class.getLoader( newLoader )
            end
        end

Reload the configuration from the original source if it has changed. Returns true if it was reloaded and false otherwise.

[Source]

# File lib/mues/config.rb, line 314
        def reload
            return false unless @loader && @name
            confighash = @loader.load( @name )
            ihash = self.class.internifyKeys( self.class.untaintValues(confighash) )
            mergedhash = Defaults.merge( ihash, &MUES::HashMergeFunction )
            @struct = ConfigStruct::new( mergedhash )
        end

Returns true for methods which can be autoloaded

[Source]

# File lib/mues/config.rb, line 296
        def respond_to?( sym )
            return true if @struct.member?( sym.to_s.sub(/(=|\?)$/, '').intern )
            super
        end

Write the configuration object using the specified name and any additional args.

[Source]

# File lib/mues/config.rb, line 286
        def write( name=@name, *args )
            raise ArgumentError,
                "No name associated with this config." unless name
            lobj = self.loader
            strHash = self.class.stringifyKeys( @struct.to_h )
            self.loader.save( strHash, name, *args )
        end

Protected Instance methods

Handle calls to struct-members

[Source]

# File lib/mues/config.rb, line 434
        def method_missing( sym, *args )
            key = sym.to_s.sub( /(=|\?)$/, '' ).intern
            return super unless @struct.member?( key )

            self.log.debug( "Autoloading #{key} accessors." )

            self.class.class_eval %{
                def #{key}; @struct.#{key}; end
                def #{key}=(*args); @struct.#{key} = *args; end
                def #{key}?; @struct.#{key}?; end
            }

            @struct.send( sym, *args )
        end

[Validate]