Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This guide is designed to describe the details of both LDP and PCDM in the context of F4 by walking through a simple example of a single collection, consisting of a single book that implements page ordering.

Note: Note0: Although the following example uses specifically named resources, such as "poe" and "raven", production scenarios will likely use opaque identifiers/URLs by allowing them to be auto-generated by F4.
Note1: An easy way to stand-up an environment for executing the following REST requests is to use fcrepo4-vagrant

Panel
titleBGColorgray
title0: Final State - Complete
borderStylesolid

This diagram depicts the logical structure of resources and relationships of a collection ("poe") that consists of a book ("raven") that consists of three pages that are ordered.

The following steps will walk through the process of creating this structure from the ground up.
The different types of LDP containers and sources will be detailed, as well as the PCDM types and relationships in the steps below. 

Panel
titleBGColorgray
title1: Final State - Book
The ldp:BasicContainers are simply containers of other resources. BasicContainers can contain both other containers as well as ldp:NonRdfSources (or "binaries").
There are three PCDM types here:
  • pcdm:Object
  • pcdm:Collection
  • pcdm:File

Additionally, there are two PCDM relationships that indicate resource membership and file membership:

  • pcdm:hasMember
  • pcdm:hasFile

The descriptions of these resource types and relationships may be found in the detailed Portland Common Data Model page.

Expand
titleBook Creation Details...
Panel
titleBGColorgray
titleBook - Create DirectContainer

Here we will begin to walk through the mechanics of creating the structures that will facilitate creation of the book and its pages.

Image Modified
First, create the top-level "objects/" pcdm:Object, which is also an ldp:BasicContainer.

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @pcdm-object.ttl localhost:8080/rest/objects/

Where "pcdm-object.ttl" follows:

Code Block
titlepcdm-object.ttl
@prefix pcdm: <http://pcdm.org/models#>
 
<> a pcdm:Object .

Second, create the nested "raven/" pcdm:Object, which is also another ldp:BasicContainer.

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @pcdm-object.ttl localhost:8080/rest/objects/raven/

Lastly, create an ldp:DirectContainer, "pages/" that will facilitate the establishment of relationships between "raven/" and its constituent pages.

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @ldp-direct.ttl localhost:8080/rest/objects/raven/pages/

Where "ldp-direct.ttl" follows:

Code Block
titleldp-direct.ttl
@prefix ldp: <http://www.w3.org/ns/ldp#>
@prefix pcdm: <http://pcdm.org/models#>

<> a ldp:DirectContainer, pcdm:Object ;
  ldp:membershipResource </rest/objects/raven/> ;
  ldp:hasMemberRelation pcdm:hasMember .

An ldp:DirectContaner is an LDP construct that activates the creation of certain RDF triples when a new resource is added as a child of this container.
Specifically, when an new resources is added inside of the "pages/" DirectContainer, a new triple on the ldp:membershipResource ("raven/") will be created with the predicate defined by the ldp:hasMemberRelation property ("pcdm:hasMember") and a subject that is a reference to the new resource.

We will see this in action next!

Panel
titleBGColorgray
titleBook - Create cover

Create a new pcdm:Object, "cover/", that is also an ldp:BasicContainer within the "pages/" DirectContainer.
Image Modified 

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @pcdm-object.ttl localhost:8080/rest/objects/raven/pages/cover/

Where "pcdm-object.ttl" follows:

Code Block
titlepcdm-object.ttl
@prefix pcdm: <http://pcdm.org/models#>

<> a pcdm:Object .

As described in the previous step, the addition of "cover/" automatically creates the following new triple on "raven/"

No Format
<http://localhost:8080/rest/objects/raven/> pcdm:hasMember <http://localhost:8080/rest/objects/raven/pages/cover/>

Restating from the previous step,

  • the subject of the triple comes from the "ldp:membershipResource" defined on "pages/"
  • the predicate of the triple comes from the "ldp:hasMemberRelation" defined on "pages/", and
  • the object of the triple is the new resource ("cover/") that was added to the ldp:DirectContainer ("pages/")
Panel
titleBGColorgray
titleBook - Create Page0

 In the same fashion as the previous step, adding "page0/" to the DirectContainer, "pages/" results in a new auto-generated triple on "raven/" of the form:

No Format
<http://localhost:8080/rest/objects/raven/> pcdm:hasMember <http://localhost:8080/rest/objects/raven/pages/page0/>

Image Modified

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @pcdm-object.ttl localhost:8080/rest/objects/raven/pages/page0/
Panel
titleBGColorgray
titleBook - Create Page1

This step in creating the final page, "page1/", follows the same pattern shown in the previous two steps. 

Image Modified

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @pcdm-object.ttl localhost:8080/rest/objects/raven/pages/page1/
Panel
titleBGColorgray
titleCover - Create DirectContainer

In the same way that we used an ldp:DirectContainer to facilitate the auto-generation of triples linking "raven/" to each of the pages, now use the same pattern to auto-generate the creation of triples that link each page pcdm:Object to their various file representations.

Image Modified
To begin with, create an ldp:DirectContainer, "files/", which is also a pcdm:Object, as a child of "cover/" as follows:

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @ldp-cover-direct.ttl localhost:8080/rest/objects/raven/pages/cover/files/

Where "ldp-cover-direct.ttl" follows:

Code Block
titleldp-cover-direct.ttl
@prefix ldp: <http://www.w3.org/ns/ldp#>
@prefix pcdm: <http://pcdm.org/models#>

<> a ldp:DirectContainer, pcdm:Object ;
  ldp:membershipResource </rest/objects/raven/pages/cover/> ;
  ldp:hasMemberRelation pcdm:hasFile .

Now, any new resource that is added as a child of the DirectContainer "files/" will cause the auto-generation of a new triple on "cover/" that has a predicate of pcdm:hasFile and an object of the new resource.

Panel
titleBGColorgray
titleCover - Create Files

Once again, we demonstrate the use of LDP in creating PCDM relationships simply as a result of repository interactions.

Image Modified
Add two pcdm:File resources to the DirectContainer, "files/" as follows:

Code Block
curl -i -XPUT -H"Content-Type: image/jpeg" --data-binary @cover.jpg localhost:8080/rest/objects/raven/pages/cover/files/cover.jpg

Where "cover.jpg" is attached.

If you perform a subsequent HTTP HEAD on this new resource, you will see there is a "Link" header of rel="describedby". Update the RDF metadata of the ldp:NonRdfSource to specify that the resource is a pcdm:File, as follows:

Code Block
curl -i -XPATCH -H"Content-Type: application/sparql-update" --data-binary @pcdm-file.ru localhost:8080/rest/objects/raven/pages/cover/files/cover.jpg/fcr:metadata

Where "pcdm-file.ru" follows:

Code Block
titlepcdm-file.ru
 PREFIX pcdm: <http://pcdm.org/models#>
INSERT {
  <> a pcdm:File
} WHERE {
}

Repeat for the attached TIFF, cover.tif

Code Block
curl -i -XPUT -H"Content-Type: image/tiff" --data-binary @cover.tif localhost:8080/rest/objects/raven/pages/cover/files/cover.tif
curl -i -XPATCH -H"Content-Type: application/sparql-update" --data-binary @pcdm-file.ru localhost:8080/rest/objects/raven/pages/cover/files/cover.tif/fcr:metadata

After creating the two "cover" resources, an HTTP GET on "cover/" will include the two new triples:

No Format
<http://localhost:8080/rest/objects/raven/pages/cover/> pcdm:hasFile <http://localhost:8080/rest/objects/raven/pages/cover/files/cover.jpg> 
<http://localhost:8080/rest/objects/raven/pages/cover/> pcdm:hasFile <http://localhost:8080/rest/objects/raven/pages/cover/files/cover.tif>

Once again,

  • the subject of the triple comes from the "ldp:membershipResource" defined on "files/"
  • the predicate of the triple comes from the "ldp:hasMemberRelation" defined on "files/", and
  • the object of the triple is the new resource ("cover.jpg" or "cover.tif") that was added to the ldp:DirectContainer ("files/")
Panel
titleBGColorgray
titlePage0 - Create DirectContainer

Here we repeat the exact steps as for the "cover/" above, but for "page0/".

Image Modified

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @ldp-page0-direct.ttl localhost:8080/rest/objects/raven/pages/page0/files/

Where "ldp-page0-direct.ttl" follows:

Code Block
titleldp-page0-direct.ttl
@prefix ldp: <http://www.w3.org/ns/ldp#>
@prefix pcdm: <http://pcdm.org/models#>

<> a ldp:DirectContainer, pcdm:Object ;
  ldp:membershipResource </rest/objects/raven/pages/page0/> ;
  ldp:hasMemberRelation pcdm:hasFile .
Panel
titleBGColorgray
titlePage0 - Create Files

Here we add the attached page0 files (page0.jpg and page0.tif) to the newly created DirectContainer. 

Image Modified

Code Block
curl -i -XPUT -H"Content-Type: image/jpeg" --data-binary @page0.jpg localhost:8080/rest/objects/raven/pages/page0/files/page0.jpg
curl -i -XPUT -H"Content-Type: image/tiff" --data-binary @page0.tif localhost:8080/rest/objects/raven/pages/page0/files/page0.tif

Followed by assigning the type of pcdm:File to the respective RDF Sources found in the "Link; rel=describedby" header of each of the ldp:NonRdfSources.

Code Block
curl -i -XPATCH -H"Content-Type: application/sparql-update" --data-binary @pcdm-file.ru localhost:8080/rest/objects/raven/pages/page0/files/page0.jpg/fcr:metadata
curl -i -XPATCH -H"Content-Type: application/sparql-update" --data-binary @pcdm-file.ru localhost:8080/rest/objects/raven/pages/page0/files/page0.tif/fcr:metadata

Where "pcdm-file.ru" follows:

Code Block
titlepcdm-file.ru
PREFIX pcdm: <http://pcdm.org/models#>
INSERT {
  <> a pcdm:File
} WHERE {
}
Panel
titleBGColorgray
titlePage1 - Create DirectContainer

Here we repeat the exact steps as for the "page0/" above, but for "page1/".

Image Modified

Code Block
curl -i -XPUT -H"Content-Type: text/turtle" --data-binary @ldp-page1-direct.ttl localhost:8080/rest/objects/raven/pages/page1/files/

Where "ldp-page1-direct.ttl" follows:

Code Block
titleldp-page0-direct.ttl
@prefix ldp: <http://www.w3.org/ns/ldp#>
@prefix pcdm: <http://pcdm.org/models#>

<> a ldp:DirectContainer, pcdm:Object ;
  ldp:membershipResource </rest/objects/raven/pages/page1/> ;
  ldp:hasMemberRelation pcdm:hasFile .
Panel
titleBGColorgray
titlePage1 - Create Files

Finally, we add the attached page1 files (page1.jpg and page1.tif) to the newly created DirectContainer. 

Image Modified

Code Block
curl -i -XPUT -H"Content-Type: image/jpeg" --data-binary @page1.jpg localhost:8080/rest/objects/raven/pages/page1/files/page1.jpg
curl -i -XPUT -H"Content-Type: image/tiff" --data-binary @page1.tif localhost:8080/rest/objects/raven/pages/page1/files/page1.tif

Followed by assigning the type of pcdm:File to the respective RDF Sources found in the "Link; rel=describedby" header of each of the ldp:NonRdfSources.

Code Block
curl -i -XPATCH -H"Content-Type: application/sparql-update" --data-binary @pcdm-file.ru localhost:8080/rest/objects/raven/pages/page1/files/page0.jpg/fcr:metadata
curl -i -XPATCH -H"Content-Type: application/sparql-update" --data-binary @pcdm-file.ru localhost:8080/rest/objects/raven/pages/page1/files/page0.tif/fcr:metadata

Where "pcdm-file.ru" follows:

Code Block
titlepcdm-file.ru
PREFIX pcdm: <http://pcdm.org/models#>
INSERT {
  <> a pcdm:File
} WHERE {
}

Conclusion: Using LDP in conjunction with PCDM terms, we have created a book, "raven/", with its constituent pages and their file representations.

Panel
titleBGColorgray
title2: Final State - Collection

 

...