diff --git a/Gemfile b/Gemfile index 424729c..ae706fa 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ source 'https://rubygems.org' gemspec -# GETTING FROM GEMFILE UNTIL MintLocalName CODE IS PUSHED INTO MASTER, THEN MOVE THIS BACK TO *.gemspec FILE -# Use active-triple for handling of triple persistence -gem "active-triples", :git => 'git@github.com:no-reply/ActiveTriples.git', :branch => 'generate_id' +# GETTING FROM GEMFILE UNTIL ActiveTriples master CODE IS RELEASED (>0.4.0), THEN MOVE THIS BACK TO *.gemspec FILE +# Use active-triples for handling of triple persistence +gem 'active-triples', :git => 'git@github.com:ActiveTriples/ActiveTriples.git', :branch => 'master' + diff --git a/README.md b/README.md index 4e76f3c..91a6a9a 100644 --- a/README.md +++ b/README.md @@ -2,68 +2,128 @@ LD4L FOAF RDF provides tools for modeling person triples based on the FOAF ontology and persisting to a triplestore. + ## Installation +Temporary get the gem from github until the gem is released publicly. + Add this line to your application's Gemfile: - gem 'ld4l-foaf_rdf' + + gem 'ld4l-foaf_rdf', '~> 0.0.3', :git => 'git@github.com:ld4l/foaf_rdf.git' + And then execute: $ bundle install + + ## Usage **Caveat:** This gem is part of the LD4L Project and is being used in that context. There is no guarantee that the code will work in a usable way outside of its use in LD4L Use Cases. -### Models +### Examples -The LD4L::FoafRDF gem provides model definitions using the -[ActiveTriples](https://github.com/no-reply/ActiveTriples) framework extension of -[ruby-rdf/rdf](https://github.com/ruby-rdf/rdf). The following models are provided: +Setup required for all examples. +``` +require 'ld4l/foaf_rdf' -1. LD4L::FoafRDF::Person - Implements the Person class in the FOAF ontology. +# create an in-memory repository +ActiveTriples::Repositories.add_repository :default, RDF::Repository.new +``` -### Ontologies +Example creating a person. +``` +p = LD4L::FoafRDF::Person.new('p4') -The listed ontologies are used to represent the primary metadata about the person. -Other ontologies may also be used that aren't listed. - -* [FOAF](http://xmlns.com/foaf/spec/) -* [RDF](http://www.w3.org/TR/rdf-syntax-grammar/) +puts p.dump :ttl +``` + +Example triples created for a person. +``` + a . +``` -### Creating a Person +### Configurations -Start console in a terminal. +* base_uri - base URI used when new resources are created (default="http://localhost/") +* localname_minter - minter function to use for creating unique local names (default=nil which uses default minter in active_triples-local_name gem) + +*Setup for all examples.* + +* Restart your interactive session (e.g. irb, pry). +* Use the Setup for all examples in main Examples section above. + +*Example usage using configured base_uri and default localname_minter.* ``` -bundle console +LD4L::FoafRDF.configure do |config| + config.base_uri = "http://example.org/" +end + +p = LD4L::FoafRDF::Person.new(ActiveTriples::LocalName::Minter.generate_local_name( + LD4L::FoafRDF::Person, 10, {:prefix=>'p'} )) + +puts p.dump :ttl ``` +NOTE: If base_uri is not used, you need to restart your interactive environment (e.g. irb, pry). Once the + Person class is instantiated the first time, the base_uri for the class is set. If you ran + through the main Examples, the base_uri was set to the default base_uri. -In console, you can test creating a person. + +*Example triples created for a person with configured base_uri and default minter.* +``` + a . ``` -# Create an in-memory repository -ActiveTriples::Repositories.add_repository :default, RDF::Repository.new -# Configure a base_uri for all person objects +*Example usage using configured base_uri and configured localname_minter.* +``` LD4L::FoafRDF.configure do |config| - config.base_uri = "http://example.org/individual/" + config.base_uri = "http://example.org/" + config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid } end -# Create a person -p = LD4L::FoafRDF::Person.new('1') -p.rdf_subject -# => http://example.org/individual/pr1 +p = LD4L::FoafRDF::Person.new(ActiveTriples::LocalName::Minter.generate_local_name( + LD4L::FoafRDF::Person, 10, 'p', + &LD4L::FoafRDF.configuration.localname_minter )) -# View triples as tutle puts p.dump :ttl -# => a . ``` +NOTE: If base_uri is not used, you need to restart your interactive environment (e.g. irb, pry). Once the + Person class is instantiated the first time, the base_uri for the class is set. If you ran + through the main Examples, the base_uri was set to the default base_uri. + + +*Example triples created for a person with configured base_uri and configured minter.* +``` + a . +``` + + +### Models + +The LD4L::FoafRDF gem provides model definitions using the +[ActiveTriples](https://github.com/ActiveTriples/ActiveTriples) framework extension of +[ruby-rdf/rdf](https://github.com/ruby-rdf/rdf). The following models are provided: + +1. LD4L::FoafRDF::Person - Implements the Person class in the FOAF ontology. (extremely simple for holding rdf_subject only) + + +### Ontologies + +The listed ontologies are used to represent the primary metadata about the person. +Other ontologies may also be used that aren't listed. + +* [FOAF](http://xmlns.com/foaf/spec/) +* [RDF](http://www.w3.org/TR/rdf-syntax-grammar/) + ## Contributing diff --git a/ld4l-foaf_rdf.gemspec b/ld4l-foaf_rdf.gemspec index 658af8e..bb8af5b 100644 --- a/ld4l-foaf_rdf.gemspec +++ b/ld4l-foaf_rdf.gemspec @@ -26,6 +26,9 @@ Gem::Specification.new do |spec| # GETTING FROM GEMFILE UNTIL MintLocalName CODE IS PUSHED INTO MASTER # spec.add_dependency('active-triples', '~> 0.2') + spec.add_dependency('active_triples-local_name', '~> 0.1') + + spec.add_development_dependency('pry') spec.add_development_dependency('rdoc') spec.add_development_dependency('rspec') spec.add_development_dependency('guard-rspec') diff --git a/lib/ld4l/foaf_rdf.rb b/lib/ld4l/foaf_rdf.rb index cebd71f..bc48976 100644 --- a/lib/ld4l/foaf_rdf.rb +++ b/lib/ld4l/foaf_rdf.rb @@ -1,8 +1,10 @@ require 'rdf' require 'active_triples' +require 'active_triples/local_name' require 'linkeddata' require 'ld4l/foaf_rdf/version' + module LD4L module FoafRDF diff --git a/lib/ld4l/foaf_rdf/configuration.rb b/lib/ld4l/foaf_rdf/configuration.rb index 1dfa80d..f9b4657 100644 --- a/lib/ld4l/foaf_rdf/configuration.rb +++ b/lib/ld4l/foaf_rdf/configuration.rb @@ -3,14 +3,22 @@ module FoafRDF class Configuration attr_reader :base_uri + attr_reader :localname_minter def self.default_base_uri @default_base_uri = "http://localhost/".freeze end private_class_method :default_base_uri + def self.default_localname_minter + # by setting to nil, it will use the default minter in the minter gem + @default_localname_minter = nil + end + private_class_method :default_localname_minter + def initialize - @base_uri = self.class.send(:default_base_uri) + @base_uri = self.class.send(:default_base_uri) + @localname_minter = self.class.send(:default_localname_minter) end def base_uri=(new_base_uri) @@ -20,6 +28,14 @@ def base_uri=(new_base_uri) def reset_base_uri @base_uri = self.class.send(:default_base_uri) end + + def localname_minter=(new_minter) + @localname_minter = new_minter + end + + def reset_localname_minter + @localname_minter = self.class.send(:default_localname_minter) + end end end end diff --git a/lib/ld4l/foaf_rdf/person.rb b/lib/ld4l/foaf_rdf/person.rb index 82edb3e..f398b51 100644 --- a/lib/ld4l/foaf_rdf/person.rb +++ b/lib/ld4l/foaf_rdf/person.rb @@ -4,7 +4,8 @@ module LD4L module FoafRDF class Person < ActiveTriples::Resource - @local_name_prefix="p" + class << self; attr_reader :localname_prefix end + @localname_prefix="p" configure :type => RDF::FOAF.Person, :base_uri => LD4L::FoafRDF.configuration.base_uri, :repository => :default end diff --git a/spec/ld4l/foaf_rdf/configuration_spec.rb b/spec/ld4l/foaf_rdf/configuration_spec.rb index 20b049d..04b71df 100644 --- a/spec/ld4l/foaf_rdf/configuration_spec.rb +++ b/spec/ld4l/foaf_rdf/configuration_spec.rb @@ -81,6 +81,52 @@ class DummyPerson < LD4L::FoafRDF::Person expect(LD4L::FoafRDF.configuration.base_uri).to eq "http://localhost/" end end + + describe "localname_minter" do + context "when minter is nil" do + before do + class DummyPerson < LD4L::FoafRDF::Person + configure :type => RDF::FOAF.Person, :base_uri => LD4L::FoafRDF.configuration.base_uri, :repository => :default + end + end + after do + Object.send(:remove_const, "DummyPerson") if Object + end + it "should use default minter in minter gem" do + localname = ActiveTriples::LocalName::Minter.generate_local_name( + LD4L::FoafRDF::Person, 10, {:prefix=>'default_'}, + LD4L::FoafRDF.configuration.localname_minter ) + expect(localname).to be_kind_of String + expect(localname.size).to eq 44 + expect(localname).to match /default_[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/ + end + end + + context "when minter is configured" do + before do + LD4L::FoafRDF.configure do |config| + config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid } + end + class DummyPerson < LD4L::FoafRDF::Person + configure :type => RDF::FOAF.Person, :base_uri => LD4L::FoafRDF.configuration.base_uri, :repository => :default + end + end + after do + Object.send(:remove_const, "DummyPerson") if Object + LD4L::FoafRDF.reset + end + + it "should generate an Person URI using the configured localname_minter" do + localname = ActiveTriples::LocalName::Minter.generate_local_name( + LD4L::FoafRDF::Person, 10, + LD4L::FoafRDF::Person.localname_prefix, + &LD4L::FoafRDF.configuration.localname_minter ) + expect(localname).to be_kind_of String + expect(localname.size).to eq 49 + expect(localname).to match /p_configured_[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/ + end + end + end end @@ -104,5 +150,25 @@ class DummyPerson < LD4L::FoafRDF::Person expect(config.base_uri).to eq "http://localhost/" end end + + describe "#localname_minter" do + it "should default to nil" do + expect(LD4L::FoafRDF::Configuration.new.localname_minter).to eq nil + end + + it "should be settable" do + config = LD4L::FoafRDF::Configuration.new + config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid } + expect(config.localname_minter).to be_kind_of Proc + end + + it "should be re-settable" do + config = LD4L::FoafRDF::Configuration.new + config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid } + expect(config.localname_minter).to be_kind_of Proc + config.reset_localname_minter + expect(config.localname_minter).to eq nil + end + end end end diff --git a/spec/ld4l/foaf_rdf/person_rdf_spec.rb b/spec/ld4l/foaf_rdf/person_rdf_spec.rb index cbee26a..ee7697d 100644 --- a/spec/ld4l/foaf_rdf/person_rdf_spec.rb +++ b/spec/ld4l/foaf_rdf/person_rdf_spec.rb @@ -63,6 +63,13 @@ end end + describe '#localname_prefix' do + it "should return default prefix" do + prefix = LD4L::FoafRDF::Person.localname_prefix + expect(prefix).to eq "p" + end + end + # ----------------------------------------------- # END -- Test attributes specific to this model # ----------------------------------------------- @@ -185,7 +192,7 @@ before do class DummyPerson < ActiveTriples::Resource configure :type => RDF::URI('http://example.org/Person') - property :name, :predicate => RDF::FOAF.name + property :foafname, :predicate => RDF::FOAF.name property :publications, :predicate => RDF::FOAF.publications, :class_name => 'DummyDocument' property :knows, :predicate => RDF::FOAF.knows, :class_name => DummyPerson end @@ -215,13 +222,13 @@ class DummyDocument < ActiveTriples::Resource let (:person1) do p = DummyPerson.new - p.name = 'Alice' + p.foafname = 'Alice' p end let (:person2) do p = DummyPerson.new - p.name = 'Bob' + p.foafname = 'Bob' p end @@ -250,7 +257,7 @@ class DummyDocument < ActiveTriples::Resource document2.creator = person1 person1.knows = person2 subject.item = [document1] - expect(subject.item.first.creator.first.knows.first.name).to eq ['Bob'] + expect(subject.item.first.creator.first.knows.first.foafname).to eq ['Bob'] end end end diff --git a/spec/ld4l/foaf_rdf_spec.rb b/spec/ld4l/foaf_rdf_spec.rb index e2c79a0..7f01420 100644 --- a/spec/ld4l/foaf_rdf_spec.rb +++ b/spec/ld4l/foaf_rdf_spec.rb @@ -6,6 +6,7 @@ before do LD4L::FoafRDF.configure do |config| config.base_uri = "http://localhost/test/" + config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid } end class DummyPerson < LD4L::FoafRDF::Person configure :type => RDF::FOAF.Person, :base_uri => LD4L::FoafRDF.configuration.base_uri, :repository => :default @@ -19,11 +20,18 @@ class DummyPerson < LD4L::FoafRDF::Person it "should return configured value" do config = LD4L::FoafRDF.configuration expect(config.base_uri).to eq "http://localhost/test/" + expect(config.localname_minter).to be_kind_of Proc end it "should use configured value in Person sub-class" do p = DummyPerson.new('1') expect(p.rdf_subject.to_s).to eq "http://localhost/test/1" + + p = DummyPerson.new(ActiveTriples::LocalName::Minter.generate_local_name( + LD4L::FoafRDF::Person, 10, 'foo', + &LD4L::FoafRDF.configuration.localname_minter )) + expect(p.rdf_subject.to_s.size).to eq 73 + expect(p.rdf_subject.to_s).to match /http:\/\/localhost\/test\/foo_configured_[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/ end end @@ -31,6 +39,7 @@ class DummyPerson < LD4L::FoafRDF::Person before :each do LD4L::FoafRDF.configure do |config| config.base_uri = "http://localhost/test/" + config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid } end end @@ -38,6 +47,7 @@ class DummyPerson < LD4L::FoafRDF::Person LD4L::FoafRDF.reset config = LD4L::FoafRDF.configuration expect(config.base_uri).to eq "http://localhost/" + expect(config.localname_minter).to eq nil end end end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9c4e130..5238146 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,8 @@ require 'bundler/setup' Bundler.setup -require 'active_triples' require 'ld4l/foaf_rdf' +require 'pry' Dir['./spec/support/**/*.rb'].each { |f| require f }