Last active
August 29, 2015 13:57
-
-
Save no-reply/9519740 to your computer and use it in GitHub Desktop.
A Demo of ActiveFedora::Rdf in 7.x
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# RdfResource is a subclass of RDF::Graph with property configuration, accessors, and some other methods | |
# for managing "resources" as discrete subgraphs which can be managed by a Hydra datastream model. | |
bnode = ActiveFedora::Rdf::Resource.new | |
bnode.rdf_subject | |
# => #<RDF::Node:0x3f967a58c1b8(_:g69915530281400)> | |
bnode << RDF::Statement.new(bnode.rdf_subject, RDF::DC.title, RDF::Literal('A blank node')) | |
bnode << RDF::Statement.new(bnode.rdf_subject, RDF::DC.subject, RDF::Literal('RDF')) | |
bnode.dump :ntriples | |
# => "_:g69915530281400 <http://purl.org/dc/terms/title> \"A blank node\" .\n_:g69915530281400 <http://purl.org/dc/terms/subject> \"RDF\" .\n" | |
bnode.set_subject!(RDF::URI('http://example.org/1')) | |
bnode.rdf_subject | |
# => #<RDF::URI:0x3f967b832a9c URI:http://example.org/1> | |
bnode.dump :ntriples | |
# => "<http://example.org/1> <http://purl.org/dc/terms/title> \"A blank node\" .\n<http://example.org/1> <http://purl.org/dc/terms/subject> \"RDF\" .\n" | |
# Define subclasses of Resource to configure and register properties for types of resources | |
class License < ActiveFedora::Rdf::Resource | |
configure :base_uri => 'http://example.org/license', :type => RDF::DC.LicenseDocument | |
property :title, :predicate => RDF::DC.title do |index| | |
index.as :displayable, :facetable | |
end | |
end | |
cc = License.new('cc') | |
cc.rdf_subject | |
# => #<RDF::URI:0x3f967b9546b4 URI:http://example.org/license/cc> | |
# cc = License.new; cc.set_subject!('cc'); would accomplish the same thing | |
cc.title = "Creative Commons" | |
cc.dump :ntriples | |
# => "<http://example.org/license/cc> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/LicenseDocument> .\n<http://example.org/license/cc> <http://purl.org/dc/terms/title> \"Creative Commons\" .\n" | |
class Document < ActiveFedora::Rdf::Resource | |
configure :base_uri => 'http://example.org/document', :type => RDF::URI('http://purl.org/ontology/bibo/Document') | |
property :title, :predicate => RDF::DC.title do |index| | |
index.as :displayable, :facetable, :searchable | |
end | |
property :license, :predicate => RDF::DC.license, :class_name => License do |index| | |
index.as :displayable, :facetable | |
end | |
end | |
doc = Document.new('1') | |
doc.title = 'A Document' | |
doc.license = cc | |
doc.license | |
# => [#<License:0x47b22f4(default)>] | |
doc.license.first.title | |
# => ["Creative Commons"] | |
doc.dump :ntriples | |
# => "<http://example.org/document/1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Document> .\n<http://example.org/document/1> <http://purl.org/dc/terms/title> \"A Document\" .\n<http://example.org/document/1> <http://purl.org/dc/terms/license> <http://example.org/license/cc> .\n<http://example.org/license/cc> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/LicenseDocument> .\n<http://example.org/license/cc> <http://purl.org/dc/terms/title> \"Creative Commons\" .\n" | |
# Note that you can also manage the graph manually; but do so with care! | |
# It matters which statements are in the graph for the object being called. | |
doc2 = Document.new('2') | |
doc2 << RDF::Statement.new(doc2.rdf_subject, RDF::DC.license, cc.rdf_subject) | |
cc.title | |
# => ["Creative Commons"] | |
# We have added the statement specifying the license, but none of the License object's graph | |
doc2.license.first.rdf_subject | |
# => #<RDF::URI:0x3f967b9546b4 URI:http://example.org/license/cc> | |
doc2.license.first.dump :ntriples | |
# => "<http://example.org/license/cc> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/LicenseDocument> .\n" | |
doc2.license.first.title | |
# => [] | |
# If we add the Licenses' graph in full, all is well. | |
doc2 << cc | |
doc2.license.first.reload # rebuilds the cached License object from the manually edited graph | |
doc2.license.first.title | |
# => ["Creative Commons"] | |
# By default, resources persist to their 'parent' object. | |
doc2.license.first.title = "Creative Commons BY-SA" | |
doc2.license.first.title | |
# => ["Creative Commons BY-SA"] | |
cc.title | |
# => ["Creative Commons"] | |
# Persistence to any RDF::Repository is configurable. There are RDF::Repository implementations | |
# for all the major triplestores and a variety of RDBMS and NoSQL databases. | |
ActiveFedora::Rdf::Repositories.add_repository :repo, RDF::Repository.new | |
class CCLicense < ActiveFedora::Rdf::Resource | |
configure :base_uri => 'http://creativecommons.org/licenses/', :type => RDF::DC.LicenseDocument, :repository => :repo | |
property :title, :predicate => RDF::DC.title | |
end | |
by = CCLicense.new('by/4.0/') | |
by.title = 'By Attribution' | |
by.dump :ntriples | |
# =>"<http://creativecommons.org/licenses/by/4.0/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/LicenseDocument> .\n<http://creativecommons.org/licenses/by/4.0/> <http://purl.org/dc/terms/title> \"By Attribution\" .\n" | |
by.persist! | |
ActiveFedora::Rdf::Repositories.repositories[:repo].dump :ntriples | |
# =>"<http://creativecommons.org/licenses/by/4.0/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/LicenseDocument> .\n<http://creativecommons.org/licenses/by/4.0/> <http://purl.org/dc/terms/title> \"By Attribution\" .\n" | |
# The license is now in the repository, so any Resource initialized with that URI will load its data. | |
# Resources persisted to a repository can be shared across repository objects. | |
by2 = CCLicense.new('by/4.0/') | |
by2.title | |
# => ["By Attribution"] | |
# RDF Datastreams now implement the normal AF::Datastream interface as a wrapper around a Resource object. | |
# They will also pass down properties defined at the datastream level to the resource they wrap. | |
class GenericResourceDatastream < ActiveFedora::NtriplesRDFDatastream | |
property :title, :predicate => RDF::DC[:title] do |index| | |
index.as :searchable, :displayable | |
end | |
property :creator, :predicate => RDF::DC[:creator] do |index| | |
index.as :searchable, :displayable, :facetable | |
end | |
property :contributor, :predicate => RDF::DC[:contributor] do |index| | |
index.as :searchable, :displayable, :facetable | |
end | |
property :license, :predicate => RDF::DC[:license], :class_name => License do |index| | |
index.as :displayable | |
end | |
end | |
# The resource that powers the datastream is of class ObjectResource. | |
# This class has a default base_uri of 'info:fedora/' and implements a few tweaks | |
# to persistence to store its graph in the datastream. | |
GenericResourceDatastream.resource_class | |
# => ActiveFedora::Rdf::ObjectResource | |
# Until a resource has a PID, it will be a blank node | |
ds = GenericResourceDatastream.new | |
ds.resource.rdf_subject | |
# => #<RDF::Node:0x3f967bc3e08c(_:g69915554078860)> | |
class DummyAsset < ActiveFedora::Base | |
has_metadata 'descMetadata', type: GenericResourceDatastream | |
has_attributes :title, :license, datastream: 'descMetadata', :multiple => true | |
end | |
asset = DummyAsset.new | |
asset.title = "Comet in Moominland" | |
asset.license = cc | |
asset.save | |
asset.descMetadata.content | |
asset.descMetadata.content | |
# => "<info:fedora/changeme:1> <http://purl.org/dc/terms/title> \"Comet in Moominland\" .\n<info:fedora/changeme:1> <http://purl.org/dc/terms/license> <http://example.org/license/cc> .\n<http://example.org/license/cc> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/LicenseDocument> .\n" | |
# Objects that persist to an RDF::Repository will bypass the datastream. This avoids | |
# duplication of data across objects and issues with managing the same graph in many datastreams. | |
# Data in the RDF::Repository is only 'persisted' to the extent that underlying | |
# triplestore is trustworthy. | |
GenericResourceDatastream.property :license, :predicate => RDF::DC[:license], :class_name => CCLicense | |
asset = DummyAsset.new | |
asset.save | |
asset.license = by | |
asset.descMetadata.content | |
# => "<http://oregondigital.org/resource/changeme:66> <http://purl.org/dc/terms/license> <http://creativecommons.org/licenses/by/4.0/> .\n" | |
# Of course, the object still builds its graph. | |
asset.license.first.title | |
# => ["By Attribution"] | |
# Resources with URIs also respond to #fetch, which retrieves the data at their rdf_subject URI | |
# and loads it into the triplestore or parent. | |
by.fetch | |
by.title | |
# => ["By Attribution", "Attribution 4.0 International"] | |
# Resource responds to #rdf_label, which returns values from the first of the following | |
# predicates to respond non-empty: | |
# | |
# [RDF::SKOS.prefLabel, RDF::DC.title, RDF::RDFS.label, RDF::SKOS.altLabel, RDF::SKOS.hiddenLabel] | |
by.rdf_label | |
# => ["By Attribution", "Attribution 4.0 International"] | |
# #rdf_label is configurable on the class level. Configured labels are prepended to the default | |
# labels, and take priority. | |
CCLicense.configure :rdf_label => RDF::DC.title | |
# ActiveFedora::Rdf::Identifiable is a mixin module included in ActiveFedora::Base, allowing | |
# objects to be treated as deep nodes. This lets you create complex networks of relationships | |
# between objects in your repository. | |
class ChildAsset < ActiveFedora::Base | |
has_metadata 'descMetadata', type: GenericResourceDatastream | |
has_attributes :title, datastream: 'descMetadata', multiple: true | |
end | |
GenericResourceDatastream.property :related, :predicate => RDF::DC[:relation], :class_name => ChildAsset | |
class DummyAsset < ActiveFedora::Base | |
has_metadata 'descMetadata', type: GenericResourceDatastream | |
has_attributes :title, :license, :related, datastream: 'descMetadata', :multiple => true | |
end | |
child = ChildAsset.new | |
child.title = "Moomins the Movie" | |
child.save | |
asset = DummyAsset.new | |
asset.title = "Comet in Moominland" | |
asset.related = child | |
asset.related.first.title | |
# => ["Moomins the Movie"] | |
asset.descMetadata.content | |
# => "<info:fedora/changeme:11> <http://purl.org/dc/terms/title> \"Comet in Moominland\" .\n<info:fedora/changeme:11> <http://purl.org/dc/terms/relation> <info:fedora/changeme:10> .\n" | |
asset.related.first.descMetadata.content | |
# => "<info:fedora/changeme:10> <http://purl.org/dc/terms/title> \"Moomins the Movie\" .\n" | |
# The following methods have the same output: | |
# asset.related.first.dump :ntriples | |
# child.descMetadata.content | |
# child.dump :ntriples | |
# This also works with objects that do not have an RDFDatastream | |
class DummyOmAsset < ActiveFedora::Base | |
has_metadata 'descMetadata', type: ActiveFedora::OmDatastream | |
end | |
GenericResourceDatastream.property :related, :predicate => RDF::DC[:relation], :class_name => DummyOmAsset | |
child = DummyOmAsset.new | |
child.save | |
asset = DummyAsset.new | |
asset.title = "Comet in Moominland" | |
asset.related = child | |
asset.related | |
# => [#<DummyOmAsset pid: "changeme:4">] |
Thanks. I didn't know you could skip the 'name' parameter.
(also: bah! but I hate 1.9.3 hashes!)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'd suggest you declare your datastreams using 1.9.3 hashes and no "name" parameter