module RTM class Engine include RTM::TopicMapSystem def self.abstract? self == Engine end def self.inherited(subclass) Engine.add(subclass) # this MUST be Engine and not self! Otherwise every intermediate class in the inheritance chain will have it's own list end def self.add(engine) @engines ||= [] @engines << engine end def self.identifier(i=nil) if i # setter / declaration @identifier = i else # getter @identifier end end def self.all @engines ||= [] @engines.reject!{|e| e.abstract?} # this needs to be done here because in the inherited hook the method is not yet available. @engines end def self.list all.map{|e| e.identifier} end def self.[](identifier) all.find {|e| e.identifier == identifier} end def self.load(engine_name) engine_gem_name = engine_name engine_gem_name = engine_name.to_s.split("_").first if engine_gem_name.to_s =~ /_/ unless Object.const_defined?("Gem") && rtmgem = Gem.loaded_specs["rtm"] engine_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../rtm-#{engine_gem_name}/lib")) $LOAD_PATH.unshift engine_path if File.directory?(engine_path) end require "rtm/#{engine_gem_name}" self[engine_name] end def self.load!(engine_name=nil) engine_name = self.detect unless engine_name unless list.include?(engine_name) warn("Requested engine '#{engine_name}' not loaded. Trying to autoload it.") engine = load(engine_name) if list.include?(engine_name) warn("Autoloading '#{engine_name}' was successful") else raise "Autoloading '#{engine_name}' failed. Make sure rtm-#{engine_name} exists and is installed or require it manually." end end engine || load(engine_name) end def self.detect(preferred=nil) if preferred # return the users preference, if given implementation = preferred elsif engine_name = ENV['RTM_BACKEND'] || ENV['RTM_IMPLEMENTATION'] || ENV['RTM_ENGINE'] # inspect system environment (several alternatives) implementation = engine_name.to_sym elsif implementation = self.list.first # check if one is already loaded warn("No engine implementation was specified for RTM.connect. Using the first already loaded engine (#{implementation.inspect}).") else implementation = self.default # use hardcoded default warn("No engine implementation was specified for RTM.connect. Choosing default (#{implementation.inspect}).") implementation end implementation end def self.default if RUBY_PLATFORM =~ /java/ :ontopia else :activerecord end end def self.connect(*args) self.new(*args) end attr_reader :connections def initialize(params={}) @params = params end # returns an identifier of the engine, e.g. :ontopia or :ontopia_rdbms def identifier self.class.identifier end # Check if everything is set up. This should be overwritten by backends # which need special setup, like a database schema migration. def check true end end end