Skip to content

Lesson: Use RDF to Represent Flat Metadata like Dublin Core (AF7)

metaweidner edited this page Dec 9, 2014 · 13 revisions

This lesson is known to work with active-fedora version 7.0.

Please update this wiki to reflect any other versions that have been tested.

Goals

  • Define a Ruby Class whose instances Create/Manipulate RDF Resources with RDF assertions in them

Explanation

The real awesomeness of RDF comes when you start building heterogeneous graphs/networks of linked nodes. However, as you will see, even with a homogeneous network where all of the resources are the same RDF Type, you can build rich networks of linked data. For this example, we will create resources with Dublin Core metadata assertions in them.

Steps

Step: Define an "RdfResource" Class for Resources that use Dublin Core RDF metadata

Note: Within a code base, we prefer to put the RdfResource definitions into a directory called rdf_types that lives either in the lib directory or in app/models.

Create a directory called rdf_types and

mkdir lib
mkdir lib/rdf_types

Then create a file called lib/rdf_types/dublin_core_asset.rb and put the following code into it

class DublinCoreAsset < ActiveFedora::Rdf::Resource 
  property :title, predicate: RDF::DC.title
  property :creator, predicate: RDF::DC.creator
  property :contributor, predicate: RDF::DC.contributor
  property :date, predicate: RDF::DC.date
  property :subject, predicate: RDF::DC.subject
  property :relation, predicate: RDF::DC.relation
end

Step: In console Create a Resource and inspect its graph

On the command line, run bundle console

Within the console, require the class you've just defined.

require "./lib/rdf_types/dublin_core_asset"
 => true 

Now create a new DublinCoreAsset resource and inspect its graph.

subject = RDF::URI('http://example.com/1234')
# => #<RDF::URI:0x234f8a8 URI:http://example.com/1234> 
asset = DublinCoreAsset.new(subject)
# => #<DublinCoreAsset:0x3f8748eb229c(default)>
asset.dump(:ntriples)
# => ""

We haven't added any assertions into the graph yet, so we got an empty string when we dumped it. Now let's add some assertions.

Step: Assert association with a literal as the Subject -- Put String values into your Graph

Add an assertion that the title of your asset is "My title"

asset.title
# => [] 
asset.title = "My title"
# => "My title" 
asset.title
# => ["My title"] 

Now look at the graph again

asset.dump(:ntriples)
# => "<http://example.com/1234> <http://purl.org/dc/terms/title> \"My title\" .\n"  

Now there's an assertion that our resource (identified by <http://example.com/1234> in this example) has a dc:title that is the String literal "My title".

Add some more assertions and then look at the graph again.

asset.creator = "Sally Creator"
# => "Sally Creator" 
asset.contributor = "Billy Contributor"
# => "Billy Contributor" 
asset.contributor << "Sgt Labdirector"
# => nil 
# but
asset.contributor
# => ["Billy Contributor", "Sgt Labdirector"] 
asset.subject = ["repositories", "small data"]
# => ["repositories", "small data"] 
puts asset.dump(:ntriples)
# <http://example.com/1234> <http://purl.org/dc/terms/title> "My title" .
# <http://example.com/1234> <http://purl.org/dc/terms/creator> "Sally Creator" .
# <http://example.com/1234> <http://purl.org/dc/terms/contributor> "Billy Contributor" .
# <http://example.com/1234> <http://purl.org/dc/terms/contributor> "Sgt Labdirector" .
# <http://example.com/1234> <http://purl.org/dc/terms/subject> "repositories" .
# <http://example.com/1234> <http://purl.org/dc/terms/subject> "small data" .
# => nil 

Step: Assert association with a Resource as the Subject -- Create a Relationship between two Resource

asset2 = DublinCoreAsset.new
# => #<DublinCoreAsset:0x007fbc128c3248 @graph=#<RDF::Graph:0x3fde09461b54(default)>, @rdf_subject=#<RDF::Node:0x3fde09461910(_:g70222870878480)>>
asset.relation = asset2
# => #<DublinCoreAsset:0x007fc494fcd130 @graph=#<RDF::Graph:0x3fe24a7e6960(default)>, @rdf_subject=#<RDF::Node:0x3fe24a7e6884(_:g70222870878480)>> 
asset2.rdf_subject.id
# => "g70222870878480" 
puts asset.dump :ntriples
# <http://example.com/1234> <http://purl.org/dc/terms/title> "My title" .
# <http://example.com/1234> <http://purl.org/dc/terms/creator> "Sally Creator" .
# <http://example.com/1234> <http://purl.org/dc/terms/contributor> "Billy Contributor" .
# <http://example.com/1234> <http://purl.org/dc/terms/contributor> "Sgt Labdirector" .
# <http://example.com/1234> <http://purl.org/dc/terms/subject> "repositories" .
# <http://example.com/1234> <http://purl.org/dc/terms/subject> "small data" .
# <http://example.com/1234> <http://purl.org/dc/terms/relation> _:g69850278268800 .
# => nil 
asset.relation.first == asset2
# => true

Step: Configure RDF type and base URI in your resources

Classes of resources often share common features like a URI prefix or an RDF type assertion. For example, you might want your DublinCoreAssets to share the base URI info:fedora/ and to assert that they are objects of type 'http://www.mydomain.mn/metadata/ontologies/foo#SpecialAsset'. For convenience, it is possible to set these on the class level with the configure method:

require "active-fedora"

class DublinCoreAsset < ActiveFedora::Rdf::Resource
  configure type: RDF::URI('http://www.mydomain.mn/metadata/ontologies/foo#SpecialAsset'), base_uri: 'info:fedora'
  property :title, predicate: RDF::DC.title
  property :creator, predicate: RDF::DC.creator
  property :contributor, predicate: RDF::DC.contributor
  property :date, predicate: RDF::DC.date
  property :subject, predicate: RDF::DC.subject
  property :relation, predicate: RDF::DC.relation
end

Now restart the console and create an asset

require "./lib/rdf_types/dublin_core_asset"
asset = DublinCoreAsset.new('1')
# => #<DublinCoreAsset:0x007faa3ba06580(default)>> 
asset.dump :ntriples
# => "<info:fedora/1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.mydomain.mn/metadata/ontologies/foo#SpecialAsset> .\n"

As you can see, even before we add any assertions our node has an rdf:type assertion pointing to the URI we specified.

Step: Use an RDF Datastream and create a Fedora asset

Resources can be associated with a Fedora object through an RDFDatastream. Create a new datastream in app/models/datastreams/dublin_core_datastream.rb:

mkdir -p app/models/datastreams
require 'active-fedora'
class DublinCoreDatastream < ActiveFedora::RDFDatastream
  property :title, predicate: RDF::DC.title
  property :creator, predicate: RDF::DC.creator
  property :contributor, predicate: RDF::DC.contributor
  property :date, predicate: RDF::DC.date
  property :subject, predicate: RDF::DC.subject
  property :relation, predicate: RDF::DC.relation
end

Restart the console, require your class, and create a datastream:

require "./app/models/datastreams/dublin_core_datastream"
# => true 
ds = DublinCoreDatastream.new
# => #<DublinCoreDatastream @pid="" @dsid="" @controlGroup="M" changed="false" @mimeType="" >

RDFDatastreams have an underlying Resource of a special class ActiveFedora::Rdf::ObjectResource which saves its contents to the datastream.

ds.resource
# => #<ActiveFedora::Rdf::ObjectResource:0x3fc9ca1dbb58(default)>
ds.title = "Comet in Moominland"
# => "Comet in Moominland"
ds.title
# => ["Comet in Moominland"]
ds.resource.title
# => ["Comet in Moominland"]

TODO: Add asset stuff here

Next Step

Go on to Lesson: Define a custom Vocabulary (AF7) or return to the Tame your RDF Metadata with ActiveFedora landing page.

Clone this wiki locally