activerubic 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,170 @@
1
+ # Manages namespace abbreviations and expansions. Extends the ActiveRDF namespace by self.protocol, self.prefix and self.ancestors. Forked from ActiveRDF-1.6.6, patch offered upstream, but rejected.
2
+ class Namespace
3
+ @@namespaces = Hash.new
4
+ @@inverted_namespaces = Hash.new
5
+ # occurrence of # or / (heuristical namespace delimitor)
6
+ @@delimitor = /#|\//
7
+
8
+ # registers a namespace prefix and its associated expansion (full URI)
9
+ # e.g. :rdf and 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
10
+ def self.register(prefix, fullURI)
11
+ raise ActiveRdfError, 'prefix nor uri can be empty' if (prefix.to_s.empty? or fullURI.to_s.empty?)
12
+ raise ActiveRdfError, "namespace uri should end with # or /" unless /\/|#/ =~ fullURI.to_s[-1..-1]
13
+ $activerdflog.info "Namespace: registering #{fullURI} to #{prefix}"
14
+ @@namespaces[prefix.to_sym] = fullURI.to_s
15
+ @@inverted_namespaces[fullURI.to_s] = prefix.to_sym
16
+
17
+ # enable namespace lookups through FOAF::name
18
+ # if FOAF defined, add to it
19
+ if Object.const_defined?(prefix.to_s.upcase)
20
+ ns = Object.const_get(prefix.to_s.upcase)
21
+ else
22
+ # otherwise create a new module for it
23
+ ns = Module.new
24
+ Object.const_set(prefix.to_s.upcase, ns)
25
+ end
26
+
27
+ # catch FOAF::name or all other lookups
28
+ class << ns
29
+ def method_missing(method, *args)
30
+ Namespace.lookup(self.to_s.downcase.to_sym, method)
31
+ end
32
+
33
+ def const_missing(klass)
34
+ Namespace.lookup(self.to_s.downcase.to_sym, klass)
35
+ end
36
+
37
+ # make some builtin methods private because lookup doesn't work otherwise
38
+ # on e.g. RDF::type and FOAF::name
39
+ [:type, :name, :id].each {|m| private(m) }
40
+ end
41
+
42
+ # return the namespace proxy object
43
+ ns
44
+ end
45
+
46
+ # returns a resource whose URI is formed by concatenation of prefix and localname
47
+ def self.lookup(prefix, localname)
48
+ full_resource = expand(prefix, localname)
49
+ RDFS::Resource.new(expand(prefix, localname))
50
+ end
51
+
52
+ # returns URI (string) formed by concatenation of prefix and localname
53
+ def self.expand(prefix, localname)
54
+ # do not die with nil.to_sym
55
+ if prefix
56
+ @@namespaces[prefix.to_sym].to_s + localname.to_s
57
+ else
58
+ return nil
59
+ end
60
+ end
61
+
62
+ # returns the protocol part of the URI
63
+ def self.protocol(resource)
64
+ # get string representation of resource uri
65
+ uri = case resource
66
+ when RDFS::Resource: resource.uri
67
+ else resource.to_s
68
+ end
69
+
70
+ ( /^.*:\/\//.match uri ).to_s # do not return MatchData, but a String
71
+ # uri.scan( /^.*:\/\// ).to_s # alternative method
72
+ end
73
+
74
+ # returns prefix (if known) for the non-local part of the URI,
75
+ # or nil if the prefix is not registered.
76
+ # finds the longest match in registered URIs, so the namespace can have
77
+ # several URIs that have the same beginning but vary later in the path
78
+ def self.prefix(resource)
79
+ # get string representation of resource uri
80
+ uri = case resource
81
+ when RDFS::Resource: resource.uri
82
+ # uri.to_s gives us the uri of the resource (if resource given)
83
+ else resource.to_s
84
+ end
85
+ # STDERR.puts resource
86
+
87
+ # get the protocol to a variable since it is used later
88
+ protocol = self.protocol( uri )
89
+
90
+ # strip the protocol and localname from the URI,
91
+ # so the resource_prefix can be scanned without them interfering
92
+ stripped_uri = uri.gsub( protocol, '' ).gsub( self.localname(uri), '' )
93
+
94
+ # scan the number of path elements in the procol-less uri
95
+ elements = stripped_uri.scan( @@delimitor ).size
96
+
97
+ # for each possible prefix path (number of elements) until match,
98
+ # check @@inverted_namespaces
99
+ # start with one, since it is the index count for match()
100
+ nominees = Array.new
101
+
102
+ # reverse the Range, as Ruby does not handle ( 3 .. 1 ).each properly
103
+ range = Array.new
104
+ ( 1 .. elements ).each { |index| range << index }
105
+ range.reverse.each do |index|
106
+ # allow the regexp to pass #{index} times before matching
107
+ # TODO: use @@delimitor, keep it DRY
108
+ nominees << stripped_uri.match( /([^#|\/]*(#|\/)){#{index}}/ ).to_s
109
+ end
110
+
111
+ # if nominee matches an entry in @@inverted_namespaces, return match
112
+ nominees.each do |partial_prefix|
113
+ possible_match = protocol + partial_prefix
114
+ # STDERR.puts "comparing #{possible_match}"
115
+ match = @@inverted_namespaces[ possible_match ]
116
+ # STDERR.puts match
117
+ return match if match
118
+ # else descend one level in the path..
119
+ end
120
+
121
+ # ..until hit rock bottom (no matching keys in @@inverted_namespaces)
122
+ return nil
123
+ end
124
+
125
+ # return the portion in the URI between the prefix and localname as string.
126
+ # this function returns an Array of Strings when there is something
127
+ # between matching prefix and the last delimitor, after which is the localname.
128
+ # TODO: return the OWL::Class(es) as [ RDFS::Resource(s) ]
129
+ def self.ancestors(resource)
130
+ # get string representation of resource uri
131
+ uri = case resource
132
+ when RDFS::Resource: resource.uri
133
+ # uri.to_s gives us the uri of the resource (if resource given)
134
+ else resource.to_s
135
+ end
136
+
137
+ prefix = self.expand(self.prefix(uri),nil)
138
+ localname = self.localname(uri)
139
+
140
+ # remove the prefix and localname
141
+ if prefix and localname
142
+ klasses = uri.gsub( prefix, '' ).gsub( localname, '' )
143
+ return klasses.split( @@delimitor )
144
+ else
145
+ return nil
146
+ end
147
+ end
148
+
149
+ # returns local-part of URI
150
+ def self.localname(resource)
151
+ # get string representation of resource uri
152
+ uri = case resource
153
+ when RDFS::Resource: resource.uri
154
+ else resource.to_s
155
+ end
156
+
157
+ delimiter = uri.rindex(/#|\//)
158
+ if delimiter.nil? or delimiter == uri.size-1
159
+ uri
160
+ else
161
+ uri[delimiter+1..-1]
162
+ end
163
+ end
164
+
165
+ # returns currently registered namespace abbreviations (e.g. :foaf, :rdf)
166
+ def self.abbreviations
167
+ @@namespaces.keys
168
+ end
169
+ end
170
+
@@ -0,0 +1,150 @@
1
+ # Introduces OWL into the namespace.
2
+ #
3
+ # See also: RDFS
4
+ module OWL
5
+ # Resembles a class in OWL context.
6
+ class OWL::Class < RDFS::Resource
7
+
8
+ # adding accessor to the class uri:
9
+ # the uri of the rdf resource being represented by this class
10
+ class << self
11
+ attr_accessor :class_uri
12
+ end
13
+
14
+ # uri of the resource (for instances of this class: rdf resources)
15
+ attr_reader :uri
16
+
17
+ # Creates a new OWL::Class.
18
+ #
19
+ # parameters:
20
+ # 1 resource ( RDFS::Resource or URI )
21
+ # 2 options ( Hash; )
22
+ def initialize( resource, options={} )
23
+ @@log.deep "Formulating new OWL::Class #{resource} from #{resource.class}"
24
+ @uri = case resource
25
+ when OWL::Class
26
+ @@log.warn "Redundant new OWL::Class, resource already was one."
27
+ resource.uri
28
+ when RDFS::Resource
29
+ resource.uri
30
+ when String
31
+ resource
32
+ else
33
+ raise ActiveRdfError, "Resource #{resource} (#{resource.class}) is improperly formulated"
34
+ return nil
35
+ end
36
+
37
+ # @data_stores = options[ :from ] || RUBIC_DATASTORES
38
+ # @predicates = Hash.new
39
+ end
40
+
41
+ # setting our own class uri to owl:class
42
+ # (has to be done after defining our OWL::Class.new
43
+ # because it cannot be found in Namespace.lookup otherwise)
44
+ self.class_uri = Namespace.lookup(:owl, :Class)
45
+
46
+ def self.uri; class_uri.uri; end
47
+ def self.==(other)
48
+ other.respond_to?(:uri) ? other.uri == self.uri : false
49
+ end
50
+
51
+ ##### ######
52
+ ##### start of instance-level code
53
+ ##### ######
54
+
55
+
56
+ ##############################################################
57
+ ## Tree model operations
58
+ ##############################################################
59
+
60
+ # find the child classes
61
+ def children
62
+ begin
63
+ # the class variable is set if this query has been executed already
64
+ if @children.nil? then
65
+ @children = ActiveRubic::Base.find( :children, :class => self )
66
+ end
67
+ return @children
68
+ rescue
69
+ return Array.new
70
+ end
71
+ end
72
+
73
+ # find the descendant classes
74
+ def descendants
75
+ begin
76
+ # the class variable is set if this query has been executed already
77
+ if @descendants.nil? then
78
+ @descendants = ActiveRubic::Base.find( :descendants, :class => self )
79
+ end
80
+ return @descendants
81
+ rescue
82
+ return Array.new
83
+ end
84
+ end
85
+
86
+ def instances
87
+ begin
88
+ # the class variable is set if this query has been executed already
89
+ if @instances.nil? then
90
+ @instances = ActiveRubic::Base.find( :instances_of, :class => self )
91
+ end
92
+ return @instances
93
+ rescue
94
+ return Array.new
95
+ end
96
+ end
97
+
98
+ ##############################################################
99
+
100
+ # returns the instances of this class that have latitude and longitude
101
+ def markers( options={} )
102
+ limit = options[ :limit ] || nil
103
+ begin
104
+ if @markers.nil? then
105
+ @markers = ActiveRubic::Base.find( :markers, :class => self, :limit => limit )
106
+
107
+ # sort alphabetically by label
108
+ # @markers = @markers.sort_by { |i| i.labelize }
109
+
110
+ @@log.debug "#{@markers.size} markers found"
111
+
112
+ end
113
+ return @markers
114
+ rescue
115
+ @@log.error $!
116
+ return Array.new
117
+ end
118
+ end
119
+ alias :geopoints :markers
120
+
121
+ # Examines all instances of this class, breaks when first mappable resource is found, and returns true. If no mappable instances are found, returns false.
122
+ def is_mappable?
123
+ begin
124
+ # STDERR.puts "studying #{self}"
125
+ if @is_mappable.nil?
126
+ self.instances.each do |resource|
127
+ # STDERR.puts "examinining #{resource}"
128
+ if resource.is_mappable?
129
+ # STDERR.puts "yes"
130
+ @is_mappable = true
131
+ break;
132
+ else
133
+ # STDERR.puts "no"
134
+ @is_mappable = false
135
+ break;
136
+ end
137
+ end
138
+ end
139
+ # STDERR.puts "fine"
140
+ return @is_mappable
141
+ rescue
142
+ @@log.error $!
143
+ return false
144
+ end
145
+ end
146
+ alias :has_markers? :is_mappable? # :nodoc:
147
+ alias :has_coordinates? :is_mappable? # :nodoc:
148
+
149
+ end # OWL::Class
150
+ end # module
@@ -0,0 +1,89 @@
1
+ module OWL
2
+ # Resembles a property in OWL context.
3
+ class OWL::ObjectProperty < RDFS::Resource
4
+
5
+ # adding accessor to the class uri:
6
+ # the uri of the rdf resource being represented by this class
7
+ class << self
8
+ attr_accessor :class_uri
9
+ end
10
+
11
+ # uri of the resource (for instances of this class: rdf resources)
12
+ attr_reader :uri
13
+
14
+ # Creates a new OWL::Class.
15
+ #
16
+ # parameters:
17
+ # 1 resource ( RDFS::Resource or URI )
18
+ # 2 options ( Hash; )
19
+ def initialize( resource, options={} )
20
+ @@log.deep "Formulating new OWL::ObjectProperty #{resource} from #{resource.class}"
21
+ @uri = case resource
22
+ when OWL::ObjectProperty
23
+ @@log.warn "Redundant new OWL::ObjectProperty, resource already was one."
24
+ resource.uri
25
+ when RDFS::Resource
26
+ resource.uri
27
+ when String
28
+ resource
29
+ else
30
+ raise ActiveRdfError, "Resource #{resource} (#{resource.class}) is improperly formulated"
31
+ return nil
32
+ end
33
+
34
+ # @data_stores = options[ :from ] || RUBIC_DATASTORES
35
+ # @predicates = Hash.new
36
+ end
37
+
38
+ # setting our own class uri to owl:ObjectProperty
39
+ # (has to be done after defining our OWL::ObjectProperty.new
40
+ # because it cannot be found in Namespace.lookup otherwise)
41
+ self.class_uri = Namespace.lookup(:owl, :ObjectProperty)
42
+
43
+ def self.uri; class_uri.uri; end
44
+ def self.==(other)
45
+ other.respond_to?(:uri) ? other.uri == self.uri : false
46
+ end
47
+
48
+ ##### ######
49
+ ##### start of instance-level code
50
+ ##### ######
51
+
52
+ # returns the inverse of the given bidirectional ObjectProperty
53
+ def inverse
54
+ if @inverse.nil?
55
+ # ActiveRubic always returns values in an Array, but a property
56
+ # can have only one inverse values.
57
+ @inverse = ActiveRubic::Base.find( :inverse, :property => self ).first
58
+ end
59
+ return @inverse
60
+ end
61
+ alias :inverse_of :inverse
62
+
63
+ # returns the resources that are a domain for the given ObjectProperty
64
+ def domain
65
+ begin
66
+ if @domain.nil?
67
+ @domain = ActiveRubic::Base.query(
68
+ Query.new.distinct( :domain ).where( :domain, self, :any ) )
69
+ end
70
+ return @domain
71
+ rescue
72
+ @@log.error $!
73
+ end
74
+ end
75
+
76
+ # returns the resources that are in the range of the given ObjectProperty
77
+ def range
78
+ begin
79
+ if @range.nil?
80
+ @range = ActiveRubic::Base.find( :within_range, :property => self )
81
+ end
82
+ return @range
83
+ rescue
84
+ @@log.error $!
85
+ end
86
+ end
87
+
88
+ end # class
89
+ end # module
@@ -0,0 +1,78 @@
1
+ # Introduces OWL into the namespace.
2
+ #
3
+ # See also: RDFS
4
+ module OWL
5
+ # Resembles the ontology root.
6
+ class OWL::Thing < RDFS::Resource
7
+
8
+ # adding accessor to the class uri:
9
+ # the uri of the rdf resource being represented by this class
10
+ class << self
11
+ attr_accessor :class_uri
12
+ end
13
+
14
+ # uri of the resource (for instances of this class: rdf resources)
15
+ attr_reader :uri
16
+
17
+ # Creates a new OWL::Thing.
18
+ #
19
+ # parameters:
20
+ # 1 resource ( RDFS::Resource or URI String )
21
+ def initialize( resource, options={} )
22
+ @@log.deep "Formulating new Owl::Thing #{resource} from #{resource.class}"
23
+ @uri = case resource
24
+ when OWL::Thing
25
+ @@log.warn "Redundant new OWL::Thing, resource already was one."
26
+ resource.uri
27
+ when RDFS::Resource
28
+ resource.uri
29
+ when String
30
+ resource
31
+ else
32
+ raise ActiveRdfError, "Resource #{resource} (#{resource.class}) is improperly formulated"
33
+ return nil
34
+ end
35
+
36
+ # @data_stores = options[ :from ] || RUBIC_DATASTORES
37
+ # @predicates = Hash.new
38
+ end
39
+
40
+ # setting our own class uri to owl:class
41
+ # (has to be done after defining our OWL::Class.new
42
+ # because it cannot be found in Namespace.lookup otherwise)
43
+ self.class_uri = Namespace.lookup(:owl, :Thing)
44
+
45
+ def self.uri; class_uri.uri; end
46
+ def self.==(other)
47
+ other.respond_to?(:uri) ? other.uri == self.uri : false
48
+ end
49
+
50
+ ##### ######
51
+ ##### start of instance-level code
52
+ ##### ######
53
+
54
+ # return the localname as label
55
+ def label
56
+ @label = Namespace.localname( self.uri ).capitalize
57
+ return @label
58
+ end
59
+ alias :labelize :label
60
+
61
+ # the roots of the ontology (only available from Jena)
62
+ def roots
63
+ begin
64
+ if @roots.nil? then
65
+ @roots = Array.new
66
+ ActiveRubic::Base.find( :roots, :ontology => self.uri ).each do |root|
67
+ @roots << OwlClass.new( root )
68
+ end
69
+ end
70
+ return @roots
71
+
72
+ rescue
73
+ return Array.new
74
+ end
75
+ end
76
+
77
+ end
78
+ end