rtm-ontopia 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rtm/ontopia.rb CHANGED
@@ -1,117 +1,176 @@
1
1
  # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
2
  # License: Apache License, Version 2.0
3
3
 
4
- begin
4
+ if Object.const_defined?("Gem") && rtmgem = Gem.loaded_specs["rtm-ontopia"]
5
5
  require 'rtm/javatmapi'
6
- rescue LoadError
6
+ else
7
7
  javatmapi_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../rtm-javatmapi/lib"))
8
8
  if File.directory?(javatmapi_path)
9
- $:.unshift javatmapi_path
9
+ $LOAD_PATH.unshift javatmapi_path
10
10
  require 'rtm/javatmapi'
11
11
  end
12
12
  end
13
13
 
14
14
  Dir[File.join(File.dirname(__FILE__), 'ontopia/javalibs/*.jar')].each {|file| require file }
15
- require (File.dirname(__FILE__) + '/ontopia/io/to_cxtm')
15
+ require File.join(File.dirname(__FILE__), '/ontopia/io/to_cxtm')
16
16
 
17
17
  module RTM
18
18
  class Ontopia < JavaTMAPI
19
+ require File.join(File.dirname(__FILE__), '/ontopia/rdbms/properties')
19
20
  identifier :ontopia
20
21
 
21
22
  def initialize(*args)
22
23
  super
23
- set_tmsf(Java::NetOntopiaTopicmapsImplTmapi2::TopicMapSystemFactory.new)
24
+ if @params[:store] == :rdbms
25
+ # enhance all ontopia properties from rails-style config
26
+ ontopia_properties = RTM::Ontopia::Rdbms::Properties.rails2ontopia(@params[:store_config])
27
+
28
+
29
+ # FIXME: this works only if properties was not specified as file
30
+ @params[:properties] ||= {}
31
+ ontopia_properties.each do |k,v|
32
+ @params[:properties][k] = v.to_s unless @params[:properties].key?(k)
33
+ end
34
+ end
35
+
36
+ tmsf = Java::NetOntopiaTopicmapsImplTmapi2::TopicMapSystemFactory.new
37
+ set_tmsf(tmsf)
24
38
  set_properties(@params[:properties])
25
39
  set_features(@params[:features])
26
40
  create_system
27
41
  end
42
+
43
+ # Migrate the Database to contain the Ontopia RDBMS schema. Uses the connection data provided with connect
44
+ def migrate_database
45
+ self.class.migrate_database(@params[:store_config])
46
+ end
47
+
48
+ # Drops the Ontopia schema from the database. This corresponds to migrating the database down.
49
+ def migrate_database_down
50
+ self.class.migrate_database_down(@params[:store_config])
51
+ end
52
+
53
+ # Migrate the Database to contain the Ontopia RDBMS schema.
54
+ # Uses a Rails-style database configuration hash to connect to the database.
55
+ #
56
+ # Additional hash-keys to override the defaults:
57
+ # :connection => an existing connection to be used instead of creating using given parameters
58
+ # :schema_sql => directly supply sql to execute instead of :schema_file or autodetect
59
+ # :schema_file => directly supply sql file to execute instead of autodetect
60
+ # :adapter_schema_name => directly supply the schema name (generic, h2, mysql, oracle8, oracle9i, oracle10g, postresql, sqlserver)
61
+ # :direction => :up|:down create or drop schema (defaults to :up)
62
+ #
63
+ def self.migrate_database(config)
64
+ require 'active_record' unless defined?(ActiveRecord)
65
+ require 'jdbc_adapter' unless defined?(ActiveRecord::ConnectionAdapters::Jdbc)
66
+
67
+ # create a new anonymous class extending ActiveRecord::Base for a separate connection
68
+ anonymous_active_record_base = Class.new(ActiveRecord::Base)
69
+
70
+ # use a supplied connection or create one using the config
71
+ connection = config[:connection]
72
+ unless connection
73
+ # connect to backend using the anonymous base class
74
+ anonymous_active_record_base.establish_connection(config)
75
+ connection = anonymous_active_record_base.connection
76
+ end
77
+
78
+ # see if we were provided with a schema directly or get it from file
79
+ schema_sql = config[:schema_sql]
80
+ unless schema_sql
81
+ # should we migrate up or down?
82
+ direction = config[:direction] || :up
83
+ create_or_drop = direction.to_s == "up" ? "create" : "drop"
84
+
85
+ # get the adapter name for ontopia from the config
86
+ adapter_schema_name = config[:adapter_schema_name] || config[:adapter].sub(/^jdbc/, '')
87
+
88
+ # check if it is one of the available adapters
89
+ available_schemas = %w[generic h2 mysql oracle8 oracle9i oracle10g postresql sqlserver]
90
+ adapter_schema_name = "generic" unless available_schemas.include?(adapter_schema_name)
91
+
92
+ # find the corresponding schema file
93
+ schema_file = config[:schema_file] || File.join(File.dirname(__FILE__), "/../../res/rdbms/setup/#{adapter_schema_name}.#{create_or_drop}.sql")
94
+ raise "Could not find schema definition file #{File.expand_path(schema_file)}." unless File.exist?(schema_file)
95
+
96
+ # read the schema
97
+ schema_sql = File.read(schema_file)
98
+ end
99
+
100
+ # execute the schema
101
+ connection.execute(schema_sql)
102
+ end
103
+
104
+ # Drops the Ontopia schema from the database. This corresponds to migrating the database down.
105
+ def self.migrate_database_down(params={})
106
+ migrate_database(params.merge(:direction => :down))
107
+ end
28
108
  end
29
109
  end
30
110
 
31
- module Java::OrgTmapiCore::TopicMap
32
- include RTM::TopicMap
33
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl)
34
- superize
35
- end
111
+
112
+ Java::OrgTmapiCore::TopicMap.register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl
36
113
 
37
114
  module Java::OrgTmapiCore::Topic
38
- include RTM::Topic
39
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.TopicImpl)
40
- superize
115
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicImpl
41
116
  end
42
117
 
43
118
  module Java::OrgTmapiCore::Association
44
- include RTM::Association
45
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.AssociationImpl)
46
- superize
119
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl
47
120
  end
48
121
 
49
122
  module Java::OrgTmapiCore::Name
50
- include RTM::Name
51
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.NameImpl)
52
- superize
123
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl
53
124
  end
54
125
 
55
- # there is nothing superized in occurrence
56
- # module Java::OrgTmapiCore::Occurrence
57
- # include RTM::Occurrence
58
- # JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl)
59
- # superize
60
- # end
126
+ module Java::OrgTmapiCore::Occurrence
127
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl
128
+ end
61
129
 
62
- # ther is nothing superized in variant
63
- # module Java::OrgTmapiCore::Variant
64
- # include RTM::Variant
65
- # JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.VariantImpl)
66
- # superize
67
- # end
130
+ module Java::OrgTmapiCore::Variant
131
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl
132
+ end
68
133
 
69
134
  module Java::OrgTmapiCore::Role
70
- include RTM::Role
71
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.RoleImpl)
72
- superize
135
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.RoleImpl
73
136
  end
74
137
 
75
138
  module Java::OrgTmapiCore::Scoped
76
- include RTM::Scoped
77
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.ScopedImpl)
78
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.AssociationImpl)
79
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.NameImpl)
80
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl)
81
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.VariantImpl)
82
- superize
139
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.ScopedImpl
140
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl
141
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl
142
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl
143
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl
83
144
  end
84
145
 
85
146
  module Java::OrgTmapiCore::Typed
86
- include RTM::Typed
87
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.AssociationImpl)
88
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.NameImpl)
89
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl)
90
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.RoleImpl)
91
- superize
147
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl
148
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl
149
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl
150
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.RoleImpl
92
151
  end
93
152
 
94
153
  module Java::OrgTmapiCore::Construct
95
- include RTM::Construct
96
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.ConstructImpl)
97
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl)
98
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.TopicImpl)
99
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.AssociationImpl)
100
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.NameImpl)
101
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl)
102
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.VariantImpl)
103
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.RoleImpl)
104
- superize
154
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.ConstructImpl
155
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl
156
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicImpl
157
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl
158
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl
159
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl
160
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl
161
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.RoleImpl
105
162
  end
106
163
 
107
164
  module Java::OrgTmapiCore::Reifiable
108
- include RTM::Reifiable
109
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.ReifiableImpl)
110
- superize
165
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.ReifiableImpl
111
166
  end
112
167
 
113
168
  module Java::OrgTmapiCore::Locator
114
- include RTM::Locator
115
- JavaImplementations.add(self,net.ontopia.topicmaps.impl.tmapi2.LocatorImpl)
116
- superize
169
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.LocatorImpl
170
+ end
171
+
172
+ module Java::OrgTmapiCore::DatatypeAware
173
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.DatatypeAwareImpl
174
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl
175
+ register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl
117
176
  end
@@ -10,13 +10,28 @@ module RTM::IO
10
10
 
11
11
  module Ontopia
12
12
  module TopicMap
13
- def to_cxtm(filename, base_iri = nil)
13
+ def to_cxtm(file=nil)
14
14
  raise("Only supported for Ontopia.") unless self.kind_of?(net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl)
15
- out_file = java.io.FileOutputStream.new(filename)
16
- writer = net.ontopia.topicmaps.xml.CanonicalXTMWriter.new(out_file)
15
+ if file
16
+ if file.is_a?(java.io.OutputStream)
17
+ out_stream = file
18
+ else
19
+ out_stream = java.io.BufferedOutputStream.new(java.io.FileOutputStream.new(file))
20
+ end
21
+ else
22
+ # if no file was given we want to return a string which will be written into a stream by the writer
23
+ out_stream = java.io.ByteArrayOutputStream.new
24
+ end
25
+
26
+ writer = net.ontopia.topicmaps.xml.CanonicalXTMWriter.new(out_stream)
17
27
  writer.write(self.wrapped)
18
- out_file.flush
19
- out_file.close
28
+ out_stream.flush
29
+
30
+ # close the file unless we were provided with a stream
31
+ out_stream.close unless file && file.is_a?(java.io.OutputStream)
32
+
33
+ # if there was no file, we have a ByteArrayOutputStream. Get the String out of it (and return it)
34
+ out_stream.to_s unless file
20
35
  end
21
36
  end
22
37
 
@@ -0,0 +1,148 @@
1
+ module RTM::Ontopia::Rdbms
2
+
3
+ module Properties
4
+ def self.rails2ontopia(config)
5
+ ontopia_properties = {}
6
+ ontopia_prefix = "net.ontopia.topicmaps."
7
+ ontopia_properties["#{ontopia_prefix}store"] = config[:store] || "rdbms"
8
+ ontopia_rdbms_prefix = "#{ontopia_prefix}impl.rdbms."
9
+
10
+ adapter = config[:adapter].sub(/^jdbc/, '')
11
+
12
+ adapter_config = "#{adapter}_config".to_s
13
+ config = DatabaseDefaults.send(adapter_config, config) if DatabaseDefaults.respond_to?(adapter_config)
14
+
15
+ ontopia_properties["#{ontopia_rdbms_prefix}Database"] = adapter
16
+ ontopia_properties["#{ontopia_rdbms_prefix}DriverClass"] = config[:driver]
17
+ ontopia_properties["#{ontopia_rdbms_prefix}ConnectionString"] = config[:url]
18
+ ontopia_properties["#{ontopia_rdbms_prefix}UserName"] = config[:username] || "sa"
19
+ ontopia_properties["#{ontopia_rdbms_prefix}Password"] = config[:password] || ""
20
+ ontopia_properties["#{ontopia_rdbms_prefix}ConnectionPool"] = true
21
+ ontopia_properties["#{ontopia_rdbms_prefix}BatchUpdates"] = true
22
+ ontopia_properties["#{ontopia_rdbms_prefix}StorePool.MinimumSize"] = 2
23
+
24
+ ontopia_properties
25
+ end
26
+
27
+ # The defaults for database connections here were extracted from the *_connection methods from
28
+ # activerecord-jdbc-adapter-0.9.2.
29
+ # They had to be copied here because we don't want to establish connections here.
30
+ # The definitions where slightly extended, e.g. the host is optional and defaults to localhost.
31
+ module DatabaseDefaults
32
+ # enhances a config hash using the defaults for cachedb
33
+ def cachedb_config(config)
34
+ config[:host] ||= "localhost"
35
+ config[:port] ||= 1972
36
+ config[:url] ||= "jdbc:Cache://#{config[:host]}:#{config[:port]}/#{config[:database]}"
37
+ config[:driver] ||= "com.intersys.jdbc.CacheDriver"
38
+ config
39
+ end
40
+
41
+ # enhances a config hash using the defaults for db2
42
+ def db2_config(config)
43
+ config[:adapter] ||= "jdbc"
44
+ config[:driver] ||= "com.ibm.db2.jcc.DB2Driver"
45
+ config[:url] ||= "jdbc:db2:#{config[:database]}"
46
+ config
47
+ end
48
+
49
+ # enhances a config hash using the defaults for derby
50
+ def derby_config(config)
51
+ config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
52
+ config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
53
+ config
54
+ end
55
+
56
+ # enhances a config hash using the defaults for hsqldb
57
+ def hsqldb_config(config)
58
+ config[:url] ||= "jdbc:hsqldb:#{config[:database]}" # Ontopia adds ";MVCC=true"
59
+ config[:driver] ||= "org.hsqldb.jdbcDriver"
60
+ config
61
+ end
62
+
63
+ # enhances a config hash using the defaults for h2
64
+ def h2_config(config)
65
+ config[:url] ||= "jdbc:h2:#{config[:database]}"
66
+ config[:url] << config[:h2_params] if config[:h2_params]
67
+ config[:driver] ||= "org.h2.Driver"
68
+ config
69
+ end
70
+
71
+ # enhances a config hash using the defaults for informix
72
+ def informix_config(config)
73
+ config[:host] ||= "localhost"
74
+ config[:servername] ||= config[:host]
75
+ config[:port] ||= 9088
76
+ config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
77
+ config[:driver] = 'com.informix.jdbc.IfxDriver'
78
+ config
79
+ end
80
+
81
+ # enhances a config hash using the defaults for mysql
82
+ def mssql_config(config)
83
+ config[:host] ||= "localhost"
84
+ config[:adapter] ||= "jdbc" # Ontopia example: sqlserver
85
+ config[:url] ||= "jdbc:jtds:sqlserver://localhost:1433/weblog_development" # Ontopia example: jdbcspy:jdbc:sqlserver://127.0.0.1\\ONTOPIA;databaseName=topicmaps;lockTimeout=60000
86
+ config[:driver] ||= 'net.sourceforge.jtds.jdbc.Driver' # Ontopia example: com.microsoft.sqlserver.jdbc.SQLServerDriver
87
+ config
88
+ end
89
+ alias :sqlserver_config :mssql_config
90
+
91
+ # enhances a config hash using the defaults for mysql
92
+ def mysql_config(config)
93
+ config[:host] ||= "localhost"
94
+ config[:port] ||= 3306
95
+ config[:encoding] ||= 'utf8'
96
+ url_options = "zeroDateTimeBehavior=convertToNull&jdbcCompliantTruncation=false&useUnicode=true&characterEncoding=#{config[:encoding]}"
97
+ if config[:url]
98
+ config[:url] = config[:url]['?'] ? "#{config[:url]}&#{url_options}" : "#{config[:url]}?#{url_options}"
99
+ else
100
+ config[:url] = "jdbc:mysql://#{config[:host]}:#{config[:port]}/#{config[:database]}?#{url_options}"
101
+ end
102
+ config[:driver] = "com.mysql.jdbc.Driver"
103
+ config
104
+ end
105
+
106
+ # enhances a config hash using the defaults for oracle
107
+ def oracle_config(config)
108
+ config[:host] ||= "localhost"
109
+ config[:port] ||= 1521
110
+ config[:url] ||= "jdbc:oracle:thin:@#{config[:host]}:#{config[:port]}:#{config[:database]}"
111
+ config[:driver] ||= "oracle.jdbc.driver.OracleDriver"
112
+ config
113
+ end
114
+ alias :oracle8_config :oracle_config
115
+ alias :oracle9i_config :oracle_config
116
+ alias :oracle10g_config :oracle_config
117
+
118
+ # enhances a config hash using the defaults for postgresql
119
+ def postgresql_config(config)
120
+ config[:host] ||= "localhost"
121
+ config[:port] ||= 5432
122
+ config[:url] ||= "jdbc:postgresql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
123
+ config[:url] << config[:pg_params] if config[:pg_params]
124
+ config[:driver] ||= "org.postgresql.Driver"
125
+ config
126
+ end
127
+
128
+ # enhances a config hash using the defaults for sqlite3
129
+ def sqlite3_config(config)
130
+ config[:database] ||= config[:dbfile]
131
+
132
+ # Allow database path relative to RAILS_ROOT, but only if
133
+ # the database path is not the special path that tells
134
+ # Sqlite to build a database only in memory.
135
+ if Object.const_defined?(:RAILS_ROOT) && ':memory:' != config[:database]
136
+ config[:database] = File.expand_path(config[:database], RAILS_ROOT)
137
+ end
138
+
139
+ config[:url] ||= "jdbc:sqlite:#{config[:database]}"
140
+ config[:driver] ||= "org.sqlite.JDBC"
141
+ config
142
+ end
143
+
144
+ # Make all instance methods also available as module methods
145
+ extend self
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,8 @@
1
+ net.ontopia.topicmaps.impl.rdbms.Database=h2
2
+ net.ontopia.topicmaps.impl.rdbms.ConnectionString=jdbc:h2:/tmp/test2;MVCC=true
3
+ net.ontopia.topicmaps.impl.rdbms.DriverClass=org.h2.Driver
4
+
5
+ net.ontopia.topicmaps.impl.rdbms.UserName=sa
6
+ net.ontopia.topicmaps.impl.rdbms.Password=
7
+
8
+ net.ontopia.topicmaps.impl.rdbms.ConnectionPool=true
@@ -0,0 +1,8 @@
1
+ net.ontopia.topicmaps.impl.rdbms.Database=mysql
2
+ net.ontopia.topicmaps.impl.rdbms.ConnectionString=jdbc:mysql://localhost/topicmaps?useUnicode=yes&characterEncoding=utf8&relaxAutoCommit=true
3
+ net.ontopia.topicmaps.impl.rdbms.DriverClass=com.mysql.jdbc.Driver
4
+
5
+ net.ontopia.topicmaps.impl.rdbms.UserName=foo
6
+ net.ontopia.topicmaps.impl.rdbms.Password=bar
7
+
8
+ net.ontopia.topicmaps.impl.rdbms.ConnectionPool=true
@@ -0,0 +1,8 @@
1
+ net.ontopia.topicmaps.impl.rdbms.Database=oracle8
2
+ net.ontopia.topicmaps.impl.rdbms.ConnectionString=jdbc:oracle:thin:@127.0.0.1:1521:TOPICMAPS
3
+ net.ontopia.topicmaps.impl.rdbms.DriverClass=oracle.jdbc.driver.OracleDriver
4
+
5
+ net.ontopia.topicmaps.impl.rdbms.UserName=foo
6
+ net.ontopia.topicmaps.impl.rdbms.Password=bar
7
+
8
+ net.ontopia.topicmaps.impl.rdbms.ConnectionPool=true