rdf 3.1.10 → 3.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -287,8 +287,17 @@ module RDF
287
287
  uri_str = [to_s, name.to_s].join('')
288
288
  URI.cache.delete(uri_str.to_sym) # Clear any previous entry
289
289
 
290
+ # Transform attribute keys that are PNames with a warning
291
+ # FIXME: add back later
292
+ #if !@is_deprecated && options.is_a?(Hash) &&
293
+ # options.keys.map(&:to_s).any? {|k| k.include?(':') && !k.match?(/^https?:/)}
294
+ #
295
+ # @is_deprecated = true
296
+ # warn "[DEPRECATION] Vocabulary #{to_uri} includes pname attribute keys, regenerate"
297
+ #end
298
+
290
299
  # Term attributes passed in a block for lazy evaluation. This helps to avoid load-time circular dependencies
291
- prop = Term.intern(uri_str, vocab: self, attributes: options)
300
+ prop = Term.intern(uri_str, vocab: self, attributes: options || {})
292
301
  props[name.to_sym] = prop
293
302
 
294
303
  # If name is empty, also treat it as the ontology
@@ -352,7 +361,7 @@ module RDF
352
361
  uri, options = args
353
362
  URI.cache.delete(uri.to_s.to_sym) # Clear any previous entry
354
363
  # Term attributes passed in a block for lazy evaluation. This helps to avoid load-time circular dependencies
355
- @ontology = Term.intern(uri.to_s, vocab: self, attributes: options)
364
+ @ontology = Term.intern(uri.to_s, vocab: self, attributes: options || {})
356
365
 
357
366
  # If the URI is the same as the vocabulary namespace, also define it as a term
358
367
  props[:""] ||= @ontology if self.to_s == uri.to_s
@@ -445,9 +454,7 @@ module RDF
445
454
  def imports
446
455
  return [] unless self.ontology
447
456
  @imports ||= begin
448
- Array(self.ontology.attributes[:"owl:imports"]).map do |pn|
449
- find(expand_pname(pn)) rescue nil
450
- end.compact
457
+ Array(self.ontology.properties[:"http://www.w3.org/2002/07/owl#imports"]).compact
451
458
  rescue KeyError
452
459
  []
453
460
  end
@@ -546,42 +553,8 @@ module RDF
546
553
  term = (embedded_defs[statement.subject] ||= {})
547
554
  end
548
555
 
549
- key = case statement.predicate
550
- when RDF.type then :type
551
- when RDF::RDFS.comment then :comment
552
- when RDF::RDFS.domain then :domain
553
- when RDF::RDFS.isDefinedBy then :isDefinedBy
554
- when RDF::RDFS.label then :label
555
- when RDF::RDFS.range then :range
556
- when RDF::RDFS.subClassOf then :subClassOf
557
- when RDF::RDFS.subPropertyOf then :subPropertyOf
558
- when RDF::URI("http://schema.org/domainIncludes") then :domainIncludes
559
- when RDF::URI("http://schema.org/rangeIncludes") then :rangeIncludes
560
- when RDF::URI("http://www.w3.org/2002/07/owl#allValuesFrom") then :allValuesFrom
561
- when RDF::URI("http://www.w3.org/2002/07/owl#cardinality") then :cardinality
562
- when RDF::URI("http://www.w3.org/2002/07/owl#equivalentClass") then :equivalentClass
563
- when RDF::URI("http://www.w3.org/2002/07/owl#equivalentProperty") then :equivalentProperty
564
- when RDF::URI("http://www.w3.org/2002/07/owl#intersectionOf") then :intersectionOf
565
- when RDF::URI("http://www.w3.org/2002/07/owl#inverseOf") then :inverseOf
566
- when RDF::URI("http://www.w3.org/2002/07/owl#maxCardinality") then :maxCardinality
567
- when RDF::URI("http://www.w3.org/2002/07/owl#minCardinality") then :minCardinality
568
- when RDF::URI("http://www.w3.org/2002/07/owl#onProperty") then :onProperty
569
- when RDF::URI("http://www.w3.org/2002/07/owl#someValuesFrom") then :someValuesFrom
570
- when RDF::URI("http://www.w3.org/2002/07/owl#unionOf") then :unionOf
571
- when RDF::URI("http://www.w3.org/2004/02/skos/core#altLabel") then :altLabel
572
- when RDF::URI("http://www.w3.org/2004/02/skos/core#broader") then :broader
573
- when RDF::URI("http://www.w3.org/2004/02/skos/core#definition") then :definition
574
- when RDF::URI("http://www.w3.org/2004/02/skos/core#editorialNote") then :editorialNote
575
- when RDF::URI("http://www.w3.org/2004/02/skos/core#exactMatch") then :exactMatch
576
- when RDF::URI("http://www.w3.org/2004/02/skos/core#hasTopConcept") then :hasTopConcept
577
- when RDF::URI("http://www.w3.org/2004/02/skos/core#inScheme") then :inScheme
578
- when RDF::URI("http://www.w3.org/2004/02/skos/core#member") then :member
579
- when RDF::URI("http://www.w3.org/2004/02/skos/core#narrower") then :narrower
580
- when RDF::URI("http://www.w3.org/2004/02/skos/core#notation") then :notation
581
- when RDF::URI("http://www.w3.org/2004/02/skos/core#note") then :note
582
- when RDF::URI("http://www.w3.org/2004/02/skos/core#prefLabel") then :prefLabel
583
- when RDF::URI("http://www.w3.org/2004/02/skos/core#related") then :related
584
- else statement.predicate.pname.to_sym
556
+ key = Term::URI_ATTRs.fetch(statement.predicate) do
557
+ statement.predicate.to_s.to_sym
585
558
  end
586
559
 
587
560
  # Skip literals other than plain or english
@@ -793,10 +766,59 @@ module RDF
793
766
 
794
767
  # A Vocabulary Term is a {RDF::Resource} that can also act as an {Enumerable} to generate the RDF definition of vocabulary terms as defined within the vocabulary definition.
795
768
  #
796
- # Terms include `attributes` where values a embedded resources, lists or other terms. This allows, for example, navigation of a concept heirarchy.
769
+ # Terms include {Term#attributes} where values a embedded resources, lists or other terms. This allows, for example, navigation of a concept heirarchy.
770
+ #
771
+ # Term attributes can also be accessed using {Term#properties} where the attribute values are transformed into different types of {RDF::Value}. Properties can be indexed by key, where a key is defined (See {Term::ATTR_URIs}), absolute URI, or PName, where the prefix is associated with a loaded vocabulary.
797
772
  module Term
798
773
  include RDF::Resource
799
774
 
775
+ ##
776
+ # Look up URIs for attribute symbols
777
+ #
778
+ # @return [Hash{Symbol => RDF::URI}]
779
+ ATTR_URIs = {
780
+ allValuesFrom: RDF::URI("http://www.w3.org/2002/07/owl#allValuesFrom"),
781
+ altLabel: RDF::URI("http://www.w3.org/2004/02/skos/core#altLabel"),
782
+ broader: RDF::URI("http://www.w3.org/2004/02/skos/core#broader"),
783
+ cardinality: RDF::URI("http://www.w3.org/2002/07/owl#cardinality"),
784
+ comment: RDF::URI("http://www.w3.org/2000/01/rdf-schema#comment"),
785
+ definition: RDF::URI("http://www.w3.org/2004/02/skos/core#definition"),
786
+ domain: RDF::URI("http://www.w3.org/2000/01/rdf-schema#domain"),
787
+ domainIncludes: RDF::URI("http://schema.org/domainIncludes"),
788
+ editorialNote: RDF::URI("http://www.w3.org/2004/02/skos/core#editorialNote"),
789
+ equivalentClass: RDF::URI("http://www.w3.org/2002/07/owl#equivalentClass"),
790
+ equivalentProperty: RDF::URI("http://www.w3.org/2002/07/owl#equivalentProperty"),
791
+ exactMatch: RDF::URI("http://www.w3.org/2004/02/skos/core#exactMatch"),
792
+ hasTopConcept: RDF::URI("http://www.w3.org/2004/02/skos/core#hasTopConcept"),
793
+ inScheme: RDF::URI("http://www.w3.org/2004/02/skos/core#inScheme"),
794
+ intersectionOf: RDF::URI("http://www.w3.org/2002/07/owl#intersectionOf"),
795
+ inverseOf: RDF::URI("http://www.w3.org/2002/07/owl#inverseOf"),
796
+ isDefinedBy: RDF::URI("http://www.w3.org/2000/01/rdf-schema#isDefinedBy"),
797
+ label: RDF::URI("http://www.w3.org/2000/01/rdf-schema#label"),
798
+ maxCardinality: RDF::URI("http://www.w3.org/2002/07/owl#maxCardinality"),
799
+ member: RDF::URI("http://www.w3.org/2004/02/skos/core#member"),
800
+ minCardinality: RDF::URI("http://www.w3.org/2002/07/owl#minCardinality"),
801
+ narrower: RDF::URI("http://www.w3.org/2004/02/skos/core#narrower"),
802
+ notation: RDF::URI("http://www.w3.org/2004/02/skos/core#notation"),
803
+ note: RDF::URI("http://www.w3.org/2004/02/skos/core#note"),
804
+ onProperty: RDF::URI("http://www.w3.org/2002/07/owl#onProperty"),
805
+ prefLabel: RDF::URI("http://www.w3.org/2004/02/skos/core#prefLabel"),
806
+ range: RDF::URI("http://www.w3.org/2000/01/rdf-schema#range"),
807
+ rangeIncludes: RDF::URI("http://schema.org/rangeIncludes"),
808
+ related: RDF::URI("http://www.w3.org/2004/02/skos/core#related"),
809
+ someValuesFrom: RDF::URI("http://www.w3.org/2002/07/owl#someValuesFrom"),
810
+ subClassOf: RDF::URI("http://www.w3.org/2000/01/rdf-schema#subClassOf"),
811
+ subPropertyOf: RDF::URI("http://www.w3.org/2000/01/rdf-schema#subPropertyOf"),
812
+ type: RDF::URI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
813
+ unionOf: RDF::URI("http://www.w3.org/2002/07/owl#unionOf"),
814
+ }.freeze
815
+
816
+ ##
817
+ # Look up attribute symbols from URIs
818
+ #
819
+ # @return [Hash{RDF::URI => Symbol}]
820
+ URI_ATTRs = ATTR_URIs.invert.freeze
821
+
800
822
  # @!attribute [r] comment
801
823
  # `rdfs:comment` accessor
802
824
  # @return [Literal, Array<Literal>]
@@ -910,6 +932,19 @@ module RDF
910
932
  attr_reader :vocab
911
933
 
912
934
  # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF.
935
+ #
936
+ # Attributes are indexed by symbol. Symbols directly interpreted by a term are the accessors defined for the {RDF::Vocabulary::Term} class, also in {Term::ATTR_URIs}. Other keys are interpreted as absolute URIs or PNames for properties defined on this term.
937
+ #
938
+ # Symbols which are accessors may also be looked up by their associated URI.
939
+ #
940
+ # @note lookup by PName is DEPRECATED and will be removed in a future version.
941
+ #
942
+ # @example looking up term label
943
+ # RDF::RDFS.Literal.attributes[:label] #=> "Literal"
944
+ # RDF::RDFS.Literal.attributes[:"rdfs:label"] #=> "Literal"
945
+ # RDF::RDFS.Literal.attributes[RDF::RDFS.label] #=> "Literal"
946
+ # RDF::RDFS.Literal.attributes["http://www.w3.org/2000/01/rdf-schema#label"] #=> "Literal"
947
+ # RDF::RDFS.Literal.attributes[:"http://www.w3.org/2000/01/rdf-schema#label"] #=> "Literal"
913
948
  # @return [Hash{Symbol,Resource => Term, #to_s}]
914
949
  attr_reader :attributes
915
950
 
@@ -917,16 +952,16 @@ module RDF
917
952
  # @overload new(uri, attributes:, **options)
918
953
  # @param [URI, String, #to_s] uri
919
954
  # @param [Vocabulary] vocab Vocabulary of this term.
920
- # @param [Hash{Symbol,Resource => Term, #to_s}] attributes
921
- # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF
955
+ # @param [Hash{Symbol => Symbol,Array<String,Term>}] attributes ({})
956
+ # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF. See {#attributes} and {#properties} for other ways to access.
922
957
  # @param [Hash{Symbol => Object}] options
923
958
  # Options from {URI#initialize}
924
959
  #
925
960
  # @overload new(attributes:, **options)
926
961
  # @param [Hash{Symbol => Object}] options
927
962
  # @param [Vocabulary] vocab Vocabulary of this term.
928
- # @param [Hash{Symbol => String,Array<String,Term>}] attributes
929
- # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF.
963
+ # @param [Hash{Symbol => Symbol,Array<String,Term>}] attributes ({})
964
+ # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF. See {#attributes} and {#properties} for other ways to access.
930
965
  # @param [Hash{Symbol => Object}] options
931
966
  # Options from {URI#initialize}
932
967
  def self.new(*args, vocab: nil, attributes: {}, **options)
@@ -940,6 +975,29 @@ module RDF
940
975
  RDF::Node
941
976
  else RDF::URI
942
977
  end
978
+
979
+ # Create default proc on attributes to allow lookup by different key types.
980
+ attributes = attributes.dup if attributes.frozen?
981
+ attributes.default_proc = -> (hash, key) do
982
+ sym = case key
983
+ when RDF::URI
984
+ URI_ATTRs.fetch(key, key.to_s.to_sym)
985
+ when String
986
+ URI_ATTRs.fetch(RDF::URI(key), key.to_s.to_sym)
987
+ when Symbol
988
+ case key.to_s
989
+ when /^https?:/
990
+ # Lookup by associated attribute, or pname
991
+ URI_ATTRs.fetch(RDF::URI(key.to_s), RDF::URI(key).pname.to_sym)
992
+ when /:/
993
+ uri = RDF::Vocabulary.expand_pname(key)
994
+ # Lookup by associated attribute or URI
995
+ URI_ATTRs.fetch(uri, uri.to_s.to_sym)
996
+ end
997
+ end
998
+ hash.fetch(sym, nil)
999
+ end
1000
+
943
1001
  term = klass.allocate.extend(Term)
944
1002
  term.send(:initialize, *args)
945
1003
  term.instance_variable_set(:@vocab, vocab)
@@ -1026,12 +1084,25 @@ module RDF
1026
1084
 
1027
1085
  ##
1028
1086
  # Enumerate attributes with values transformed into {RDF::Value} instances
1087
+ # Uses an empty hash with a default_proc which looks up values in attributes.
1088
+ #
1089
+ # Properties are indexed by symbol. Symbols directly interpreted by a term are the accessors defined for the {RDF::Vocabulary::Term} class, also in {Term::ATTR_URIs}. Other keys are interpreted as absolute URIs or PNames for properties defined on this term.
1090
+ #
1091
+ # Symbols which are accessors may also be looked up by their associated URI.
1092
+ #
1093
+ # @note lookup by PName is DEPRECATED and will be removed in a future version.
1094
+ #
1095
+ # @example looking up term label
1096
+ # RDF::RDFS.Literal.label #=> RDF::Literal("Literal")
1097
+ # RDF::RDFS.Literal.properties[:label] #=> RDF::Literal("Literal")
1098
+ # RDF::RDFS.Literal.properties[:"rdfs:label"] #=> RDF::Literal("Literal")
1099
+ # RDF::RDFS.Literal.properties[RDF::RDFS.label] #=> RDF::Literal("Literal")
1100
+ # RDF::RDFS.Literal.properties["http://www.w3.org/2000/01/rdf-schema#label"] #=> RDF::Literal("Literal")
1101
+ # RDF::RDFS.Literal.properties[:"http://www.w3.org/2000/01/rdf-schema#label"] #=> RDF::Literal("Literal")
1029
1102
  #
1030
1103
  # @return [Hash{Symbol => Array<RDF::Value>}]
1031
1104
  def properties
1032
- attributes.keys.inject({}) do |memo, p|
1033
- memo.merge(p => attribute_value(p))
1034
- end
1105
+ Hash.new {|hash, key| attribute_value(key)}
1035
1106
  end
1036
1107
 
1037
1108
  ##
@@ -1041,6 +1112,7 @@ module RDF
1041
1112
  # @return [RDF::Value, Array<RDF::Value>]
1042
1113
  def attribute_value(prop)
1043
1114
  values = attributes[prop]
1115
+ return nil if values.nil?
1044
1116
  values = [values].compact unless values.is_a?(Array)
1045
1117
  prop_values = values.map do |value|
1046
1118
  v = value.is_a?(Symbol) ? value.to_s : value
@@ -1079,37 +1151,15 @@ module RDF
1079
1151
  # @yieldparam [RDF::Statement]
1080
1152
  def each_statement
1081
1153
  attributes.keys.each do |p|
1154
+ prop = ATTR_URIs.fetch(p) { RDF::Vocabulary::expand_pname(p)}
1082
1155
  values = attribute_value(p)
1083
1156
  values = [values].compact unless values.is_a?(Array)
1084
1157
  values.each do |value|
1085
- begin
1086
- prop = case p
1087
- when :type
1088
- RDF::RDFV[p]
1089
- when :subClassOf, :subPropertyOf, :domain, :range, :isDefinedBy, :label, :comment
1090
- RDF::RDFS[p]
1091
- when :allValuesFrom, :cardinality, :equivalentClass, :equivalentProperty,
1092
- :intersectionOf, :inverseOf, :maxCardinality, :minCardinality,
1093
- :onProperty, :someValuesFrom, :unionOf
1094
- RDF::OWL[p]
1095
- when :domainIncludes, :rangeIncludes
1096
- RDF::Vocabulary.find_term("http://schema.org/#{p}")
1097
- when :broader, :definition, :exactMatch, :hasTopConcept, :inScheme,
1098
- :member, :narrower, :related, :altLabel, :editorialNote,
1099
- :notation, :note, :prefLabel
1100
- RDF::Vocabulary.find_term("http://www.w3.org/2004/02/skos/core##{p}")
1101
- else
1102
- RDF::Vocabulary.expand_pname(p)
1103
- end
1104
-
1105
- yield RDF::Statement(self, prop, value) if prop.is_a?(RDF::URI)
1158
+ yield RDF::Statement(self, prop, value) if prop.is_a?(RDF::URI)
1106
1159
 
1107
- # Enumerate over value statements, if enumerable
1108
- if value.is_a?(RDF::Enumerable) || (value.is_a?(Term) && value.node?)
1109
- value.each_statement {|s| yield s}
1110
- end
1111
- rescue KeyError
1112
- # Skip things eroneously defined in the vocabulary
1160
+ # Enumerate over value statements, if enumerable
1161
+ if value.is_a?(RDF::Enumerable) || (value.is_a?(Term) && value.node?)
1162
+ value.each_statement {|s| yield s}
1113
1163
  end
1114
1164
  end
1115
1165
  end
@@ -1184,18 +1234,16 @@ module RDF
1184
1234
  values = values.map do |value|
1185
1235
  if value.is_a?(Literal) && %w(: comment definition notation note editorialNote).include?(k.to_s)
1186
1236
  "%(#{value.to_s.gsub('(', '\(').gsub(')', '\)')}).freeze"
1187
- elsif value.is_a?(RDF::URI)
1188
- "#{value.pname.inspect}.freeze"
1189
- elsif value.is_a?(RDF::Vocabulary::Term)
1190
- value.to_ruby(indent: indent + " ")
1237
+ # elsif value.is_a?(RDF::Vocabulary::Term)
1238
+ # value.to_ruby(indent: indent + " ")
1191
1239
  elsif value.is_a?(RDF::Term)
1192
1240
  "#{value.to_s.inspect}.freeze"
1193
1241
  elsif value.is_a?(RDF::List)
1194
1242
  list_elements = value.map do |u|
1195
1243
  if u.uri?
1196
- "#{u.pname.inspect}.freeze"
1197
- elsif u.respond_to?(:to_ruby)
1198
- u.to_ruby(indent: indent + " ")
1244
+ "#{u.to_s.inspect}.freeze"
1245
+ # elsif u.respond_to?(:to_ruby)
1246
+ # u.to_ruby(indent: indent + " ")
1199
1247
  else
1200
1248
  "#{u.to_s.inspect}.freeze"
1201
1249
  end
@@ -1208,7 +1256,7 @@ module RDF
1208
1256
  "#{k.to_s.include?(':') ? k.to_s.inspect : k}: " +
1209
1257
  (values.length == 1 ? values.first : ('[' + values.join(',') + ']'))
1210
1258
  end.join(",\n#{indent} ") + "\n#{indent})"
1211
-
1259
+
1212
1260
  end
1213
1261
  protected
1214
1262
  # Implement accessor to symbol attributes
@@ -1225,7 +1273,7 @@ module RDF
1225
1273
  end
1226
1274
  when :type, :subClassOf, :subPropertyOf, :domain, :range, :isDefinedBy,
1227
1275
  :allValuesFrom, :cardinality, :equivalentClass, :equivalentProperty,
1228
- :intersectionOf, :inverseOf, :maxCardinality, :minCardinality,
1276
+ :imports, :intersectionOf, :inverseOf, :maxCardinality, :minCardinality,
1229
1277
  :onProperty, :someValuesFrom, :unionOf,
1230
1278
  :domainIncludes, :rangeIncludes,
1231
1279
  :broader, :exactMatch, :hasTopConcept, :inScheme, :member, :narrower, :related
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.10
4
+ version: 3.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-02-02 00:00:00.000000000 Z
13
+ date: 2021-02-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: link_header