# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig. # License: Apache License, Version 2.0 begin require 'java' rescue Exception => e raise "TMAPI Implementations are supported for JRuby only" end if Object.const_defined?("Gem") && rtmgem = Gem.loaded_specs["rtm-javatmapi"] require 'rtm' else rtm_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../rtm/lib")) if File.directory?(rtm_path) $LOAD_PATH.unshift rtm_path require 'rtm' end end Dir[File.join(File.dirname(__FILE__), 'javatmapi/javalibs/*.jar')].each {|file| require file } # provide easy access to java classes in a net.* package def net Java::Net end # provide easy access to java classes in a de.* package def de Java::De end import org.tmapi.core.TopicMapSystemFactory require "rtm/javatmapi/superiseable" require "rtm/javatmapi/ext" require "rtm/javatmapi/core" require "rtm/javatmapi/aliases" module RTM class JavaTMAPI < Engine def self.abstract? self == JavaTMAPI end extend Superiseable include org.tmapi.core.TopicMapSystem attr_reader :tmsf attr_reader :tms def set_properties(properties) if properties.is_a?(Hash) properties.each do |key, value| @tmsf.setProperty(key, value) end elsif properties.is_a?(String) && File.exists?(properties) in_file = java.io.FileInputStream.new(properties) props = java.util.Properties.new props.load(in_file) if @tmsf.respond_to?(:setProperties) # This is not part of the TMAPI interfaces but e.g. Ontopia supports it @tmsf.setProperties(props) else # Try to read a java properties file. This ignores file continuations with backslash and may be incomplete in other respects in_file = File.read_lines(features) in_file.each do |line| line.strip! # strip whitespaces at begin and end next if line.blank? # skip empty lines next if line =~ /^[#!]/ # skip comments key, value = line.split(/\s*[=:\s]\s*/, 2) # split at "=", ":" or any whitespace surrounded by any number of whitespace next if key.blank? # the value may be the empty string @tmsf.setFeature(key, value) end end end end def set_tmsf(tmsf) @tmsf = tmsf end def set_features(features) if features.is_a?(Hash) features.each do |key, value| @tmsf.setFeature(key, value) end elsif features.is_a?(String) && File.exists?(features) # in contrast to properties, features values are always boolean in_file = File.read_lines(features) in_file.each do |line| key, value = line.strip.split(/\s*[=:]\s*/, 2) next if key.blank? or value.blank? @tmsf.setFeature(key, %w[true 1 on enabled ja wahr da oui jo].include?(value)) # multi cultural feature files :) end end end def create_system @tms = @tmsf.newTopicMapSystem end def refresh RTM.included_modules.each {|im| self.extend(im)} RTM.included_modules.each {|im| self.class.class_eval("include #{im}")} end # Returns a Locator instance representing the specified IRI reference. # The specified IRI reference is assumed to be absolute. # # :call-seq: # create_locator(reference) -> Locator # def create_locator(reference) @tms.create_locator(reference) end alias :createLocator :create_locator # Creates and returns a new topic map given a base_locator. # The base locator may be a String or a Locator. # # :call-seq: # create(base_locator) -> Topic Map # def create(base_locator, *args) base_locator = @tms.create_locator(base_locator) if base_locator.is_a?(String) raise("base_locator must be a String or Locator") unless base_locator.is_a?(Locator) if (@tms.getLocators.include?(base_locator)) tm = @tms.getTopicMap(base_locator) else tm = @tms.createTopicMap(base_locator) end tm.base_iri ||= base_locator.reference #safe as String tm.engine = self tm.prefixes = {} return tm #end end alias :create_topic_map :create alias :createTopicMap :create # Retrieves a topic map managed by this connection # with the specified storage address iri. # The iri may be a String or Locator. # # If no topic map is stored at the specified iri, nil is returned. def topic_map(iri) raise("The iri must be a String or Locator") unless iri.is_a?(Locator) || iri.is_a?(String) return @tms.getTopicMap(iri) end alias :getTopicMap :topic_map alias :get_topic_map :topic_map # Returns all storage addresses of TopicMap instances known by this # connection. The return value may be empty but is never null. # # :call-seq: # locators -> Array of Strings # def locators() @tms.getLocators.map {|l| l.reference} end alias :get_locators :locators # Returns all storage addresses of TopicMap instances known by this # connection. The return value may be empty but is never null. # # :call-seq: # locators -> Array of Locators # def getLocators @tms.getLocators end # Returns the value of the feature specified by feature_name # for the TopicMapSystem instance stored by this connection: # * true, if the named feature is enabled # * false if the named feature is disabled def getFeature(feature_name) @tms.getFeature(feature_name) end # Returns a property in the underlying implementation of TopicMapSystem. def property(property_name) @tmsf.getProperty(property_name) end alias :get_property :property alias :getProperty :property # Returns topic maps stored in this connection. # The optional arguments may specify the iri the topic maps are stored at. # # The iris may be Strings and/or Locators. # The result may be empty. # # :call-seq: # [] -> Array of TopicMaps # [iri1, iri2, ...] -> Array of TopicMaps # def [](*args) if args.empty? return @tms.getLocators.map {|l| @tms.getTopicMap(l)} end return args.map{|l| @tms.getTopicMap(l)} end # Applications SHOULD call this method when the topic map is no longer required def close if defined?(@tms) && @tms.nil? @tms.close @tms = nil end end end end