Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Warning
titleRemoved in DSpace 6.0 (and above)

As of DSpace 6.0, the Lightweight Network Interface (LNI) is no longer provided with DSpace out-of-the-box.  However, the codebase is still available (in an unmaintained state) at https://github.com/DSpace/dspace-lni

If LNI is of importance to you or your institution, please get it touch, and we can work to provide you the "keys" to this old codebase.

Warning

NOTE: This page was copied from the old MoinMoin wiki and contains many markup artifacts and incorrect translations. Consult the the original page preserved here if you need precise answers about URI syntax, identifiers, etc.

...

Info
titleAbout the "prefix"

Prefix is the initial URL path at which the LNI service is "mounted" on its Web server. Since the LNI is intended
to be run out of a Java Servlet container such as Tomcat, possibly the same one running other DSpace services (e.g. the Web UI), it will probably be mounted under a separate initial path to distinguish its requests from those bound for other servlets. For example, on a server host "library.uni.edu", if the LNI is mounted at /dspace/dav, the complete prefix is http://library.uni.edu/dspace/davImage Removed.

The absolute path of the URI for each type of content object is composed as follows:

DSpace Site

/[prefix]/

Lookup handle

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0363e80d-ddaf-4602-a6f1-599ebb7040f8"><ac:plain-text-body><![CDATA[

DSpace Site

/[prefix]/

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a0ea83a9-77a4-457e-822f-4295c5d45828"><ac:plain-text-body><![CDATA[

Lookup handle

/[prefix]/lookup/handle/[handle] , /[prefix]/lookup/bitstream-handle/[sequence]/[handle]_

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a352bfcf-180a-438c-a5fc-3158b8c2daa0"><ac:plain-text-body><![CDATA[

Community, Collection, Item (DSpace Objects)

/[prefix]/dso_[persistent-identifier]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="665996c5-94f4-4a50-afb0-10996c58d78c"><ac:plain-text-body><![CDATA[

Bitstream

/[prefix]/dso_[persistent-identifier]/bitstream_[pid]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="fd5a5880-5a0e-4e43-99c9-158be9511746"><ac:plain-text-body><![CDATA[

Workspace Items list

/[prefix]/workspace

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8ade2235-9235-4259-8ee7-19fb5bb7a1bc"><ac:plain-text-body><![CDATA[

Workspace Item

/[prefix]/workspace/wsi_db_[id]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c20bdb44-0db8-4f93-bf3d-c418dcd4c78f"><ac:plain-text-body><![CDATA[

Workflow Items list

/[prefix]/workflow_ownlookup/ , handle/[prefix]/workflow_pool/

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="235d8df4-547f-4340-b5ff-1a0c3fae978d"><ac:plain-text-body><![CDATA[

handle] , /[prefix]/lookup/bitstream-handle/[sequence]/[handle]_

Community, Collection, Item (DSpace Objects) Workflow Item

/[prefix]/workflow_own/wfi_db_[id]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="fde82abd-5a86-412c-af5b-46750880dc96"><ac:plain-text-body><![CDATA[

dso_[persistent-identifier]

Bitstream

/[prefix]/dso_[persistent-identifier]/bitstream_[pid]

Workspace Items list

/[prefix]/workspace

Workspace Item EPerson list

/[prefix]/eperson/ workspace/wsi_db_[id]

Workflow Items list

/[prefix]/workflow_own/ , /[prefix]/workflow_pool/

Workflow Item

/[prefix]/workflow_own/wfi_db_[id]

EPerson list

/[prefix]/eperson/

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="bf916754-f9f9-42c1-836a-46060a91236b"><ac:plain-text-body><![CDATA[

EPerson

/[prefix]/eperson/ep_db_[id]

]]></ac:plain-text-body></ac:structured-macro>

Key:

  • Wiki Markup\[prefix\] was covered above.
  • Wiki Markup\[persistent-identifier\] is a specially-encoded version of the DSpace object's persistent identifier (such as a Handle). (See discussion of {{/lookup}} below for details).
  • Wiki Markup\[handle\] is the Handle or other persistent identifier. It may only be used with the {{lookup}} service.
  • Wiki Markup\[pid\] in the bitstream URI is a _persistent bitstream identifier_.unmigrated-wiki-markup
  • \[id\] is the numeric identifier of row in the database, used to identify e.g. an in-progress Item, such as a workflow or workspace item.

About Identifiers

DSpace assigns "persistent identifiers", such as Handles, to all of its first-class content objects. The LNI's resource URIs do not contain literal DSpace identifiers, however, because some identifier formats contain characters (e.g. '/') which cause problems with existing WebDAV software, even when properly "escaped". To work around this problem and to prevent similar trouble with any new persistent identifier schemes adopted in the future, the LNI transforms an identifier by its own proprietary process before putting it into a resource URI. The exact transformation is not published so it can be changed without affecting clients.

...

Some example URIs:

Code Block

    Site          http://uni.edu/dspace/dav

    Lookup        http://uni.edu/dspace/dav/lookup/handle/1721.1/46
                  http://uni.edu/dspace/dav/lookup/handle/1721.1%2F46
                  http://uni.edu/dspace/dav/lookup/bitstream-handle/13/1721.1%2F46

    Community     http://uni.edu/dspace/dav/dso_1721.1$46

    Collection    http://uni.edu/dspace/dav/dso_1721.1$3549

    Item          http://uni.edu/dspace/dav/dso_1721.1$5543
                  http://uni.edu/dspace/dav/dso_1721.1$3549/dso_1721.1$5543

    Bitstream     http://uni.edu/dspace/dav/dso_1721.1$5543/bitstream_13
    Bitstream     http://uni.edu/dspace/dav/dso_1721.1$5543/bitstream_13.pdf

...

The body of the request is an XML

Code Block
<nowiki>propfind</nowiki>

propfind element constraining the query.
It may contain either a single

Code Block
<nowiki>propname</nowiki>

propname element (meaning just return
the names of all available properties),
a

Code Block
<nowiki>prop</nowiki>

a prop element containing a sequence of

Code Block
<nowiki>propname</nowiki>

propname}}s for which
to return values,
or an

Code Block
<nowiki>allprop</nowiki>

{{allprop element meaning "return all available properties and values."

Finally, the `Depth` header
determines how deeply the query descends the hierarchy
of resources. A depth of

Code Block
<nowiki>0</nowiki>

depth of 0 means just return properties on the resource
itself;

Code Block
<nowiki>1</nowiki>

1 includes only the direct descendents (i.e. Items in a
Collection or Bitstreams in an Item). The special constant

Code Block
<nowiki>INFINITY</nowiki>

INFINITY `(-1 in the SOAP call)` means return the chosen
properties on all descendents.

...

There is one other twist in the LNI's implementation of `PROPFIND`: you
can select which types of DSpace Objects to visit, in order to limit
a traversal to the "upper layers" (i.e. Communities and Collections) of
the object hierarchy.

Add the query argument `type` to the resource URI to invoke this
feature. The value must be the name the type of DSpace Object to which
you want the query restricted, one of: `COMMUNITY, COLLECTION, ITEM, BITSTREAM.`
The name is case-insensitive.
To choose more than one type, add another `type` query arg to the URL.

The request's URI is always visited, regardless of
any `type` limitation.

For example, the first URI visits all
of the collections and communities in the whole Site, while the
second only shows Collections under a given Community (avoiding
sub-Communities):

Code Block
<nowiki>
  http://uni.edu/dspace/dav/?type=COMMUNITY&type=COLLECTION

  http://uni.edu/dspace/dav/dso_1721.1$3549?type=collection
</nowiki>

More on PROPFIND

See the propfind_xml description of the `propfind` XML element and
the WebDAV protocol specifcation
specification for complete details on the use of

Code Block
<nowiki>propfind</nowiki>

and

Code Block
<nowiki>multistatus</nowiki>

propfind and multistatus.

You can map the hierarchy of resources under a specific URI
by calling

Code Block
<nowiki>propfind</nowiki>

with
propfind with an empty list of properties, so it just returns the structure of resources
without any property data.

The #properties properties supported by the DSpace LNI are described below.
Each kind of DSpace Object (e.g. Collection, Item, etc) has its own
set of supported properties, and there are a few common ones.

`PROPFIND`
returns the results in a

Code Block
<nowiki>multistatus</nowiki>

multistatus element that contains
a

Code Block
<nowiki>propstat</nowiki>

a propstat element for each property found.
See the WebDAV protocol specifcation
specification for
more details.

PROPPATCH

The `PROPPATCH` method modifies and/or deletes properties on a single resource.
In the HTTP request, the URI identifies the resource to
be modified.

The body of the request
is an XML

Code Block
<nowiki>propertyupdate</nowiki>

propertyupdate element describing the properties to
be changed or removed. It contains a series of

Code Block
<nowiki>set</nowiki>

and

Code Block
<nowiki>remove</nowiki>

set and remove elements, each has
a

Code Block
<nowiki>prop</nowiki>

a prop element child describing the property to be set or deleted.

`PROPPATCH` reurns a

Code Block
<nowiki>multistatus</nowiki>

multistatus element similar to the one returnd by

Code Block
<nowiki>propfind</nowiki>

propfind, with a separate status for each property that was changed.

The #properties properties supported by the DSpace LNI are described below.
Each kind of DSpace Object (e.g. Collection, Item, etc) has its own
set of supported properties, and there are a few common ones.
Not all properties may be modified. Some are inherently read-only,
some are derived from e.g. the descriptive metadata which administrators
may not want to be modified through the LNI.

See the propfind_xml description of the `proppatch` XML element and http://www.webdav.org/specs/rfc2518.html the WebDAV protocol specifcation]
specification for complete details on the use of

Code Block
<nowiki>propfind</nowiki>

and

Code Block
<nowiki>multistatus</nowiki>

propfind and multistatus.

COPY

The `COPY` method
creates what appears to be a copy of a resource at a new location.
It actually just
establishes a link, or reference, to the resource at the destination
location, but
we use the `COPY` method because
of all the core WebDAV methods,
it comes
closest to having the right semantics.

Although it would arguably be more correct to implement the
WebDAV BIND protocol instead,
that protocol
is not yet mature and established enough to become part of the LNI.
Also, not much client support is available.

`COPY` is in the LNI mainly so an Item
can be installed into multiple Collections. This is sometimes
required when ingesting content packages. The LNI does not (yet?) support
the operations to modify the resource namespace in a general way.

...

The type of the destination resource must meet the limits imposed by the
source:

...

...

Source is:

...

Destination must be:

...

<:> `Bitstream`

Bitstream

...

<:> `Collection`

...

not allowed

...

<:> `Item`

...

<:> `Collection`

...

<:> `Workspace Item`

...

<:> `Collection`

...

<:> `Workflow Item`

...

<:> `Collection`

Item

Collection

Workspace Item

Collection

Workflow Item

Collection

Collection

Community

...

(not implemented yet)

...

<:> `Community`

Community

Community, Site

(not implemented yet)

Upon success, the source URI will be a member of the destination
collective object.

HTTP GET

The `GET` method returns the contents of a resource, which must be either
an Item or a Bitstream.

  • `GET` on an Item goes through the Packager Plugins PackagerPlugins to return the contents of the item as a Dissemination Information Package (DIP). This can actually be anything that a packager wants to generate, i.e. a Zip file stream, just the manifest, or an archive of only some of the content.
  • `GET` on a Bitstream returns the contents of the bitstream, just as an HTTP server would return the contents of a file resource.

The general format of a GET URI is:

<nowiki>/<

/

nowiki>

* prefix *

<nowiki>

/

</nowiki>

* resource_path *

<nowiki>

?package=

</nowiki>

* package-format *&other-packager-parameters
GET URI for Bitstream:: *

<nowiki>

/

</nowiki>

* prefix *

<nowiki>/<

/

nowiki>

\* _resource_path_ _\[ .optional-extension \ ]_

Panel

GET URI for Item:: *

Code Block
Code Block
Code Block
Code Block
Code Block
Wiki Markup

Where prefix and the URI path are as described in the section above
on Resource URIs.

The `package` query argument and Package-format is required for
Item resources; package-format selects the
Packager Plugins PackagerPlugins module that creates the package.

Any other query arguments are forwarded to the Packager Plugins PackagerPlugins plugin, so
the client has a direct channel of communicaton with the packager.
These parameters typically control the kind of package created and
what content is included.

When the resource is a bitstream, the package query arg is omitted, since the
bitstream is always sent unpackaged. You can always add an extension to
the bitstream URI, since this helps some HTTP clients handle the content
correctly.

Code Block
<nowiki>GET</nowiki>

GET is not implemented for Communities and Collections. `PROPFIND` can
fetch all of the significant information about those types of objects, namely
their administrative metadata and their member objects.

Some examples of GET requests:

Code Block
<nowiki>
    GET /dspace/dav/dso_1721.1$5543?package=METS&dmd=MODS

    GET /dspace/dav/dso_1721.1$5543/bitstream_13

    GET /dspace/dav/dso_1721.1$5543/bitstream_13.pdf
</nowiki>

GET Headers

The GET request also responds to HTTP request headers to modify the
request:

  • Range:: Only send specified byte range of the resource. Syntax of the header value is described in RFC 2068.

If the client does not want to transfer a large object (e.g. multi-gigabyte
video clip) in one transaction, it can use the

Code Block
<nowiki>Range</nowiki>

Range header to
break up the transfer into multiple requests. If one of those fails,
it is faster (and perhaps safer) to retry it than to redo a large transfer.

...

In WebDAV, the `PUT` method creates a new resource at the given URI (if there
wasn't already anything there) or replaces the contents of an existing
resource. In the DSpace LNI, `PUT` can only create a new resource under an existing "collection" (in the WebDAV sense of "collection") resource.
It cannot create a new resource at a specified URI because DSpace must
determine the persistent identifier, and thus the URI, after the object
is created. The DSpace LNI `PUT` can also replace the contents of an
existing resource, if this is allowed and implemented.

The LNI does not provide any means to install more than one Item
in a single request, or to install an entire populated DSpace Collection.

...

The most obvious and common application of WebDAV is to create a new
resource by supplying the exact URI at which it will reside.
This conflicts with the way DSpace names new objects, since a DSpace
URI is based on a Handle (or other persistent identifier), and that is only available after the resource is created, – not at the
time the client is sending its `PUT` request.

To work around this, we take advantage of the fact that a DSpace Collection
is also a "collection" in the WebDAV sense of the word, that is, a
grouping of resources. To create a new Item, just
do `PUT` on a DSpace Collection resource,
which creates a new Item within that Collection.

The HTTP response from such a `PUT` includes a

Code Block
<nowiki>Location</nowiki>

Location header with
the URI of the new Item, so the client can find out the URI (and thus
the persistent identifier, if available) of the Item it created.

N.B. The URI returned by `Location` is a LNI resource URI.
It will be one of these types of object:

...

If you need a persistent identifier, use `PROPFIND` on the returned
resource URI to retrieve its `dspace:type` and `dspace:handle`
properties. (If a handle is not available, the type will help explain why.)

...

For example, to add a new item to the Collection at handle

...

1721.1/

...

3549, we observe the following request and response:

Code Block
<nowiki>
Request:    PUT /dspace/dav/dso_1721.1$3549?package=OCW-IMSCP
             ....package contents in body...

Response:   HTTP/1.1 201 OK
            Location: http://uni.edu/dspace/dav/dso_1721.1$F5549
             ....other headers....
</nowiki>

PUT Semantics: Adding an Item to Multiple Collections

To add an item to more than one Collection, first create it
under its parent Collection and then use the `COPY` method to map
it into the other Collections.

...

Applying the `PUT` method to a DSpace Item resource replaces or updates
that Item with the contents of the package supplied in the body of the `PUT`.
The exact semantics depend on the individual packager plugin; some of them
may not implement this operation so the result would be an exception.

...

In a `PUT`, the resource URI naming a Collection or Item must include a `package` query argument, which
names the packager plugin to be called to import the data sent with the `PUT`.

Other query arguments are passed along to the packager plugin as parameters,
allowing the client a direct channel of communication with the packager.

...

  • Content-Length:: The number of bytes in the content block following the request and entity headers.
  • Content-MD5:: An MD5 checksum of the content. This is optional but encouraged. The checksum applies only to the bytes sent, in the case of a subset defined by a
    Code Block
    <nowiki>Content-Range</nowiki>
    Content-Range header.
  • Content-Range:: This request only includes part of the entity. In this network interface, ranges MUST be consecutive and MUST be sent in their natural order.

NOTE: The range header allows large objects to be transferred in
segments, with checksum and/or length validation on each segment. This
minimizes the risk of failure when sending extremely large packages over
unreliable networks.

PROPFIND and PROPPATCH XML elements

The LNI makes most administrative and technical metadata of DSpace
objects available through the
WebDAV concept of ''resource
properties''.
WebDAV properties are an extensible metadata framework which
works as well as anything we could custom-design for this purpose.
Please see the WebDAV protocol specification for
more details about the property mechanism.

The client makes inquiries about properties with the `PROPFIND` method,
and the query itself is defined by the `propfind` XML element supplied
in the request body.
For
example, this query gets the `displayname` WebDAV property,
`dspace:type` (DSpace object type),
and `getlastmodified` (the WebDAV last-modified time):

Code Block
<nowiki>
<propfind xmlns="DAV:">
  <prop xmlns:dspace="http://www.dspace.org/xmlns/dspace">
    <displayname/>
    <getlastmodified/>
    <dspace:type/>
  </prop>
</propfind>
</nowiki>

The result of a `PROPFIND` is a

Code Block
<nowiki>multistatus</nowiki>

multistatus}}element, which contains the status (success/failure) of the query of
each property on each resource, and the property values in `propstat` elements.
This example returns successfully for the

...

{{"displayname"

...

and `dspace:type` properties, and fails
to access the

...

"getlastmodified"

...

property:

Code Block
<nowiki>
<multistatus xmlns="DAV:">
  <response>
    <href>/dspace/dav/dso_1721.1$5543</href>
    <propstat xmlns:dspace="http://www.dspace.org/xmlns/dspace">
      <prop>
        <displayname>Zen and the Art of Java Maintenance</displayname>
        <dspace:type>
          <dspace:item/>
        </dspace:type>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
    <propstat>
      <prop>
        <getlastmodified/>
      </prop>
      <status>HTTP/1.1 403 Forbidden<status>
      <responsedescription>
      You do not have the right to read getlastmodified.
      </responsedescription>
    </propstat>
  </response>
</multistatus>
</nowiki>

The client modifies and deletes properties with the `PROPPATCH` method,
and the instructions on what to do are encoded in a
`propertyupdate` element
in the request body.

The `PROPPATCH` request returns a response with a `multistatus` element
much like the response for `PROPFIND`.

Here is an example that changes (or adds) the `displayname` property and
removes `dspace:license`:

Code Block
<nowiki>
<propertyupdate  xmlns="DAV:" xmlns:dspace="http://www.dspace.org/xmlns/dspace">
  <set>
    <prop>
      <displayname>Zen and the Art of Java Maintenance</displayname>
    </prop>
  </set>
  <remove>
    <prop>
      <dspace:license>
    </prop>
  </remove>
</propertyupdate>
</nowiki>

DSpace-specific Properties

Anchor(properties)These WebDAV property elements are defined in the DSpace XML namespace
(see Xml Namespaces XmlNamespaces). The namespace URI is `"http://www.dspace.org/xmlns/dspace"`, shown here as the
prefix `dspace:`, but of course it could be anything.

DSpace resources also support the required Web D A VWebDAV properties, and some
optional ones. They are prefixed with

Code Block
<nowiki>DAV:</nowiki>

DAV: to represent the namespace
URI, which is also `DAV:`.

ALL DSpace Resources::

  • Code Block
    <nowiki>dspace:type</nowiki>
    dspace:type – DSpace Object type, the value is an element whose name is the type in lowercase, e.g. one of Code Block<nowiki><dspace<dspace:bitstream>, <dspace:item>, <dspace:collection>, <dspace:community>, <dspace:site></nowiki>site>, etc.
  • Code Block
    <nowiki>DAV:resourcetype</nowiki>
    DAV:resourcetype – WebDAV resource type, value is either Code Block<nowiki><DAV<DAV:collection/></nowiki>> for a collection or empty for an "atom".
  • Code Block
    <nowiki>DAV:displayname</nowiki>
    DAV:displayname – Label for a human-readable display of this resource, typically title or filename.
  • Code Block<nowiki>DAVDAV:current-user-privilege-set</nowiki>set – The permissions the current user has to access this resource, in the format specified by the WebDAV Access Control Protocol RFC3744. Note that we do not (yet) implement any more of RFC3744.

Site (root of URI hierarchy)::

  • Code Block<nowiki>dspacedspace:news_top</nowiki>top – News (string) to be displayed in the top area of the DSpace home page. Code Block<nowiki>dspace
  • dspace:news_side</nowiki>side – News (string) to be displayed in the sidebar of the DSpace home page. Code Block<nowiki>dspace
  • dspace:default_license</nowiki>license – Site-wide default license text applying to new items. Read-only.

Community objects::

  • Code Block
    <nowiki>dspace:logo</nowiki>
    dspace:logo – actual image content of the logo image, in a `<bitstream>` tag bitstream_xml (see below). Code Block
  • <nowiki>dspacedspace:short_description</nowiki>description – short description. Code Block<nowiki>dspace
  • dspace:introductory_text</nowiki>text – short introductory text.
  • Code Block<nowiki>dspacedspace:side_bar_text</nowiki>text – sidebar text (news) to show on community page. Code Block<nowiki>dspace
  • dspace:copyright_text</nowiki>text – copyright statement to show on community page.
  • Code Block
    <nowiki>dspace:handle</nowiki>
    dspace:handle – the persistent identifier of this resource in URN format, e.g. `hdl:123.45/6789`.

Collection objects::

  • Code Block
    <nowiki>dspace:logo</nowiki>
    dspace:logo – actual image content of the logo image, in a `<bitstream>` tag bitstream_xml (see below). Code Block
  • <nowiki>dspacedspace:short_description</nowiki>description – short description. Code Block<nowiki>dspace
  • dspace:introductory_text</nowiki>text – short introductory text.
  • Code Block<nowiki>dspacedspace:side_bar_text</nowiki>text – sidebar text (news) to show on collection page. Code Block<nowiki>dspace
  • dspace:copyright_text</nowiki>text – copyright statement to show on collection page.
  • Code Block<nowiki>dspacedspace:default_license</nowiki>license – default license text applying to new items. Code Block<nowiki>dspace
  • dspace:provenance_description</nowiki>description – the `"provenance_description"` metadata for collection, whatever that is.
  • Code Block
    <nowiki>dspace:handle</nowiki>
    dspace:handle – the persistent identifier of this resource in URN format, e.g. `hdl:123.45/6789`.

Item objects::

  • Code Block
    <nowiki>dspace:submitter</nowiki>
    dspace:submitter – ePerson resource of original submitter of this item. Code Block<nowiki>dspace
  • dspace:owning_collection</nowiki>collection – persistent identifier (handle) of Collection that owns this item.
  • Code Block
    <nowiki>dspace:license</nowiki>
    dspace:license – contents of license bitstream for this item, in a `<bitstream>` tag bitstream_xml (see below). Code Block
  • <nowiki>dspacedspace:cc_license_text</nowiki>text – text of Creative Commons license bitstream for this item, in a `<bitstream>` tag bitstream_xml (see below). Code Block<nowiki>dspace
  • dspace:cc_license_rdf</nowiki>rdf – RDF of Creative Commons license bitstream for this item, in a `<bitstream>` tag bitstream_xml (see below).
  • Code Block<nowiki>dspacedspace:cc_license_url</nowiki>url – URL of Creative Commons license for this item.
  • Code Block
    <nowiki>DAV:getlastmodified</nowiki>
    DAV:getlastmodified – This DAV property is assigned the DSpace last-modified date.
  • dspace:handle
    Code Block
    <nowiki>dspace:handle</nowiki>
    – the persistent identifier of this resource in URN format, e.g. `hdl:123.45/6789`.
  • Code Block
    <nowiki>dspace:withdrawn</nowiki>
    dspace:withdrawn – `true` or `false`, indicating whether the Item has been withdrawn. This is the only property most users will have permission to read on a withdrawn Item.

Bitstream objects::

  • Code Block
    <nowiki>DAV:getcontentlength</nowiki>
    DAV:getcontentlength – value returned by bitstream's
    Code Block
    <nowiki>[[get Size]]</nowiki>
    . getSize().
  • DAV:getcontenttype
    Code Block
    <nowiki>DAV:getcontenttype</nowiki>
    – mimetype from bistream's format.
  • NOTE: the DSpace object model _ has no notion of `getcontentlength` for Bitstreams, so we cannot offer it._
  • Code Block
    <nowiki>dspace:source</nowiki>
    dspace:source – bitstream's
    Code Block
    <nowiki>source</nowiki>
    source attribute.
    Code Block
    <nowiki>dspace:description</nowiki>
  • dspace:description – bitstream's
    Code Block
    <nowiki>description</nowiki>
    description attribute.
  • Code Block
    <nowiki>dspace:format</nowiki>
    dspace:format – bitstream's Code Block<nowiki>[[get Format]]getFormat().getID()</nowiki>. Code Block<nowiki>dspace
  • dspace:format_description</nowiki>description – bitstream's
    Code Block
    <nowiki>[[get User Format Description]]</nowiki>
    .
    Code Block
    <nowiki>dspace:checksum</nowiki>
    getUserFormatDescription().
  • dspace:checksum – bitstream's Code Block<nowiki>[[get Checksum]]getChecksum()</nowiki>.
  • Code Block<nowiki>dspacedspace:checksum_algorithm</nowiki>algorithm – bitstream's Code Block<nowiki>[[get Checksum Algorithm]]getChecksumAlgorithm()</nowiki>. Code Block<nowiki>dspace
  • dspace:sequence_id</nowiki>id – returned by bitstream's
    Code Block
    <nowiki>[[get Sequence I D]]</nowiki>
    . getSequenceID().
  • dspace:bundle
    Code Block
    <nowiki>dspace:bundle</nowiki>
    – name of bundle in which bitstream was created.
  • Code Block
    <nowiki>dspace:handle</nowiki>
    dspace:handle – the persistent identifier of this resource in URN format, e.g. `hdl:123.45/6789` (but usually not available for bitstreams (yet?))

In-progress Item::

  • Code Block
    <nowiki>dspace:submitter</nowiki>
    dspace:submitter – EPerson resource of original submitter of this item.
  • Code Block
    <nowiki>dspace:collection</nowiki>
    dspace:collection – persistent identifier (handle) of Collection to which this item is being submitted.
  • Code Block<nowiki>dspacedspace:has_multiple_files</nowiki>files – value of `has Multiple FileshasMultipleFiles()` Code Block<nowiki>dspace
  • dspace:has_multiple_titles</nowiki>titles – value of `has Multiple TitleshasMultipleTitles()`
  • Code Block<nowiki>dspacedspace:is_published_before</nowiki>before – value returned by `is Published BeforeisPublishedBefore()`
  • Every in-progress item also has one child resource which is a DSpace Item.

...

  • all properties of the In-progress Item, and:
  • Code Block<nowiki>dspacedspace:stage_reached</nowiki>reached – Symbolic name of the last stage reached in the submission process.
  • *
    Code Block
    <nowiki>dspace:state</nowiki>
    --dspace:stateWrite-Only: Change this to the keyword `start` or `start_without_notify` to enter a workspace item into its collection's workflow.

...

  • all properties of the In-progress Item, and:
  • Code Block
    <nowiki>dspace:owner</nowiki>
    dspace:owner – EPerson resource of owner of this workflow item.
  • dspace:state
    *
    Code Block
    <nowiki>dspace:state</nowiki>
    – When read, returns the symbolic name of the current workflow step, e.g. `STEP1_POOL`. You can also *set* this property to one of the following keywords to manipulate its place in the workflow: (See API doc for `orgorg.dspace.workflow.Workflow Manager` WorkflowManager for details)
  • `abort` – Aborts workflow, returning item to its submitter's workspace.
  • `reject` – Reject an item at `STEP1`, send mail to submitter, otherwise the same as `abort`.
  • `advance` – Move an item to the pool for the next step, or archive it if it was on the last step. You must have previously claimed the workflow item.
  • `claim` – Take responsibility for a workflow item that was in the pool of unclaimed items.
  • `unclaim` – Return an item you have claimed to the pool.

...

  • `dspace:email` – email address.
  • `dspace:first_name` – first, or given name.
  • `dspace:last_name` – last, or family name.
  • `dspace:require_certificate` – if true, this eperson can only login with an X.509 client certificate.
  • `dspace:self_registered` – eperson record created by selfsame user.
  • `dspace:can_login` – if true, user is allowed to login.
  • Code Block
    <nowiki>dspace:handle</nowiki>
    dspace:handle – the persistent identifier of this resource in URN format, e.g. `hdl:123.45/6789` (but not available for epersons yet?))

Bitstream in XML Element

Anchor(bitstream_xml)The `logo` attribute's value is a bitstream of an image. It is represented
by the `dspace:bitstream` XML element, which gives the choice of encoding
the bitstream as either a link (to an external resource) or inline base64-encoded data.
The inline encoding should only be used for small (a few Kb) images.
This example shows both alternatives:

Code Block
<nowiki>
   <!-- link to external resource -->
   <dspace:bitstream>
     <dspace:link href="http://dspace.myuniv.edu/dspace/dav/retrieve_54321" />
   </dspace:bitstream>

   <!-- inline encoding -->
   <dspace:bitstream>
     <dspace:content contenttype="image/gif" contentlength="299" contentencoding="base64">
       ...text of base64-encoded data...
     </dspace:content>
   </dspace:bitstream>
</nowiki>

SOAP API Calls

This Java class outline shows the LNI's SOAP RPC interface, which
is accessed through the `orgorg.dspace.app.dav.client.L N I Soap Servlet` LNISoapServlet class.
The utility class `orgorg.dspace.app.dav.client.L N I Client Utils` also
LNIClientUtils also has some methods of use to client writers.

SOAP clients must still use HTTP `GET` and `PUT` to disseminate and submit
packages and bitstream data, however, since standard SOAP is not effective
for bulk data transfers.

NOTE: The SOAP servlet accepts WebDAV `GET` and `PUT` requests as well
as SOAP messages, which simplifies the switching of modes in your
client code. Typically, you will start with a SOAP endpoint URL that looks
something like `http://uni.edu/dspace/lni/DSpaceLNI`. The final pathname
element, `DSpaceLNI` DSpaceLNI, names a SOAP application within the servlet, so
the servlet path is actually everything up to `/dspace/lni/`. To construct
a WebDAV URL, simply use that servlet path as your WebDAV prefix, so
e.g. a resource URL would become:
`http://uni.edu/dspace/lni/dso_1721.1$5543`. There is a convenience
method in the Java class `L N I Client Utils` LNIClientUtils to help manage this, but you will
have to implement it yourself for SOAP clients in other languages.'''NOTE:

Note

Every feature of the LNI is available

...

through WebDAV (HTTP); this API is provided for callers

...

who prefer to use SOAP RPCs where possible.

...

Code Block
<nowiki>
public class org.dspace.app.dav.client.[[L N I Soap Servlet]] LNISoapServlet {

  /**
  *** Returns Resource URI for the DSpace Object whose persistent
  *** identifier (i.e. Handle) is  "handle".  Optionally add Persistent ID
  *** (sequence ID) of a bitstream under the Item, if a URI to a bitstream
  *** is desired, otherwise bitstreamPID should be null.
  *** This does the same thing as the /lookup URI.
  ***/
  public String lookup(String handle, String bitstreamPID)
    throws java.rmi.[[Remote Exception]].rmi.RemoteException, org.dspace.app.dav.client.[[L N I Remote Exception]]LNIRemoteException

  /**
  *** Same as PROPFIND WebDAV method.  "uri" may be relative to DSpace LNI
  *** prefix, or absolute; "propfind" is the propfind element, and depth is
  *** the content of the "Depth:" header.  Depth should be 0, 1, or the
  *** constant org.dspace.app.dav.client.[[L N I Client Utils]]LNIClientUtils.INFINITY (-1).
  *** Types is a comma-separated list of DSpace item types to which to
  *** restrict the query (see "type" option of PROPFIND method). May be null.
  *** Returns the multistatus document from the method's response.
  ***/
  public String propfind(String uri, Document propfind, int depth, String types)
    throws java.rmi.[[Remote Exception]]RemoteException, org.dspace.app.dav.client.[[L N I Remote Exception]]LNIRemoteException

  /**
  *** Same as PROPPATCH WebDAV method.  "uri" may be relative to DSpace
  *** LNI prefix, or absolute; "propertyupdate" is the propertyupdate
  *** element.  Returns the multistatus document from the method's response.
  ***/
  public String proppatch(String uri, String propertyupdate)
    throws java.rmi.[[Remote Exception]]RemoteException, org.dspace.app.dav.client.[[L N I Remote Exception]]LNIRemoteException

  /**
  *** Executes COPY method; "uri" and "destination_uri" may be relative
  *** to DSpace LNI prefix, or absolute.
  *** The depth and [[keep Properties]]'keepProperties' parameters correspond to
  *** parameters on the actual COPY WebDAV method, but DSpace ignores them
  *** at this time.
  *** The overwrite option will allow the copy to overwrite an existing
  *** resource if necessary.
  ***
  *** Returns the HTTP status code.
  ***/
  public int copy(String uri, String destination_uri, int depth,
                  boolean overwrite, boolean [[keep Properties]]keepProperties)
    throws java.rmi.[[Remote Exception]]RemoteException, org.dspace.app.dav.client.[[L N I Remote Exception]]LNIRemoteException
  }

  public class org.dspace.app.dav.client.[[L N I Client Utils]] LNIClientUtils {

  /** Depth of infinity in SOAP propfind() */
  public final static int INFINITY = -1;

  /**
  *** Make up a URL to access a WebDAV resource, given the SOAP "endpoint" URL
  *** and a relative URI such as is returned by lookup().  Clients should
  *** use this to obtain URLs to make HTTP GET and PUT requests.
  *** Packager may be null for a resource such as a Bitstream that does
  *** not require a packager.
  ***/
  public static URL makeDAVURL(String endpoint, String davURI, String packager);
    throws MalformedURLException

  /** alternate version that does not require packager. */
  public static URL makeDAVURL(String endpoint, String davURI);
    throws MalformedURLException

  /**
  *** Translates a WebDAV URL, such as would be returned by the PUT
  *** method, into a resource URI relative to the DAV root which can
  *** be passed to the SOAP methods.  Inverse of makeDAVURL.
  ***/
  public static String makeLNIURI(String endpoint, String davURL)
    throws MalformedURLException
  }
</nowiki>

Security Considerations

The LNI's approach to security has two layers: First, authentication and authorization , to let DSpace administrators control access
to the resources in the archive. Second is confidentiality , which
protects the contents of LNI transactions and the archive content itself
from being copied as they are transmitted over the Internet.

...

The LNI relies on DSpace's "business logic" layer API for authentication
and authorization. It calls on the Stackable Authentication Methods
StackableAuthenticationMethods to authenticate the user using the same authentication methods as are
implemented for the Web UI. The only difference is that methods calling
for a username and password get those data from the
HTTP Basic Authentication
protocol instead of an interactive Web page.

Both the SOAP and pure WebDAV modes of the LNI use the same authentication
protocol.

By default, the LNI only allows access by authenticated users.
There is no compelling reason not to allow anonymous access via the LNI,
except that badly-behaved clients can put a misproportionate load on the
server by issuing extensive recursive PROPFIND requests. It just seemed
like a reasonably cautious default. To change it, see the
#toc12 Configuration #Configuration section; the property is `dav.access.anonymous`.

If you allow anonymous access, the anonymous users won't be allowed to do
anything more than they would under the WebUI; i.e. mostly examine
resources with PROPFIND and retrieve Items and Bitstreams with GET.

Authorization is implemented in the DSpace object model, so, as the LNI
is at the application layer, it is subject to the same authorization
constraints as other applications like the Web UI. All of the authorization
policies imposed by DSpace administrators apply to LNI clients just as
they do to other application clients.

...

If you are letting users make authenticated LNI transactions on a server
that is on the public Internet, I strongly recommend requiring
all authenticated transactions to be encrypted (e.g. by SSL) to protect
the user's credentials, as well as the material being transferred.

Wiki MarkupBoth the SOAP and WebDAV modes of the LNI work perfectly well over HTTPS, which is HTTP over SSL. All you need to do is configure your web servlet container (e.g. \[Apache Jakarta Tomcat 5.0\|http://tomcat.apache.org/tomcat-5.0-doc/setup.html\]) for SSL .0) for SSL connections.

You can also add a `security-constraint` tag to the `web.xml`
configuration file in the DSpace web application, to require
SSL connections on LNI transactions. There will be notes
about this in the `dspace-web.xml` file in the source distribution.

...

Here is an example of how a client would create a session and issue
a `propfind` call with the LNI. It assumes the SOAP interface is built
upon Apache's Axis SOAP implementation.

Code Block
<nowiki>
  // DSpace credentials are either user/password in the URL, or X.509
  // client cert supplied with https: connection.
  String endpoint = "http://user:password@dspace.uni.edu/dspace/lni/DSpaceLNI";

  // get Axis locator
  [[Lni Soap Servlet Service Locator]]LniSoapServletServiceLocator locator = new [[Lni Soap Servlet Service Locator]]LniSoapServletServiceLocator();

  // create client endpoint
  [[Lni Soap Servlet]LniSoapServle] lni = locator.getDSpaceLNI(new java.net.URL(endpoint));

  // get resource URI for known handle:
  String handle = "1234.56/789";
  String [[resource Uri]]resourceUri = lni.lookup(handle, null);

  // get its properties..
  String result = lni.propfind([[resource Uri]]resourceUri,
        "<propfind xmlns=\"DAV:\"><allprop /></propfind>", 1);

  // ..now parse and display the XML in "result"..
</nowiki>

B. Submit a new Item to multiple collections

Start with the item in an acceptable package format, for example, an
IMSCP content package in a Zip file. The goal is to install it in
two collections (handles

Code Block
<nowiki>123456789/11</nowiki>

and

Code Block
<nowiki>123456789/22</nowiki>

).
123456789/11 and 123456789/22). Here are the HTTP WebDAV requests you would make:

  1. Do a `GET` on `/dspace/dav/lookup/handle/123456789/11` to get the LNI resource URI for the first collection, which will be `/dspace/dav/dso_123456789$11`.
  2. Submit the item with a
    Code Block
    <nowiki>PUT</nowiki>
    PUT request to Code Block<nowiki>/dspace/dav/dso_123456789$11?format=IMSCP</nowiki>IMSCP
  3. The response to the
    Code Block
    <nowiki>PUT</nowiki>
    PUT includes a `Location:` header giving the URI of the item it created, e.g. `Location: /dspace/dav/workflow/wfi_db_23`
  4. To add it to the second collection, start with a `GET` on `/dspace/dav/lookup/handle/123456789/22` to get the LNI resource URI for the second collection, which will be `/dspace/dav/dso_123456789$22`.
  5. Issue the request Code Block<nowiki>COPY COPY /dspace/dav/workflow/23</nowiki>23 with the header, `Destination: /dspace/dav/dso_123456789$22` to add the workflow item to the second collection. When the Item gets through workflow and is archived, it will appear in both collections.

...

Note

If there is no workflow and the item gets archived immediately,

...

Code Block
<nowiki>Location:</nowiki>

you would get back a regular Item URI in the

...

Location: header of

...

Code Block
<nowiki>PUT</nowiki>

the response to the

...

PUT and would copy that into the new collection.

C. Disseminating an Item

This example gets a dissemination of the item at handle

Code Block
<nowiki>123456789/33</nowiki>

123456789/33 in the default format, which is (probably)
a DSpace METS-based
package very much like the internal AIP format, used e.g. for exchange
between DSpace instances.

If the item is readable to the

Code Block
<nowiki>Anonymous</nowiki>

Anonymous group, we do not need to
authenticate.

  1. Do a `GET` on `/dspace/dav/lookup/handle/123456789/33` to get the LNI resource URI for that handle.
  2. The client sends a
    Code Block
    <nowiki>GET</nowiki>
    GET request to the URI Code Block<nowiki>/dspace/dav/dso_123456789$33?package=METS</nowiki>METS
  3. The response from the server is status 200 (success) followed by entity headers Code Block<nowiki>ContentContent-Type: application/zip</nowiki>zip, any other relevant headers, and finally the Zip file data.

...

Get a list of all the collections to which the authenticated user can
submit new Items. This would be a typical operation in a user interface
for submitting Items.

Note that getting the list of all communities and collections on
the DSpace Site may be slow if there are very many of them, so this should be
narrowed down to a single Community (or repeated for several communities
of interest) if it needs to be faster.

  1. Call
    Code Block
    <nowiki>propfind</nowiki>
    propfind on the URI `"/dspace/dav/?type=COMMUNITY&type=COLLECTION"`, depth=`INFINITY` and the
    Code Block
    <nowiki>propfind</nowiki>
    propfind request document shown below, which lists the relevant authorization properties.
  2. Examine the
    Code Block
    <nowiki>multistatus</nowiki>
    multistatus document returned by `propfind`, looking for resources whose Code Block<nowiki>DAVwhose DAV:current_user_privilege_set</nowiki>set properties include the element `DAV:bind` (or `DAV:all`). These are the Collections into which you can submit.

Here is the document to send with the

Code Block
<nowiki>propfind</nowiki>

propfind request:

Code Block
<nowiki>
   <propfind xmlns="DAV:">
     <prop xmlns:dspace="http://www.dspace.org/xmlns/dspace">
       <DAV:current_user_privilege_set />
     </prop>
   </propfind>
</nowiki>

Extending the Network Interface

This initial design is undoubtedly full of gaps and shortcomings.
Since it was mainly driven by the needs of the CWSpace project and
few other users were forthcoming about requirements,
it was designed to be easily extensible.

...

To add a new new kind of Resource URI, you have to modify the
WebDAV server to respond to that URI. It must have a unique prefix
so the dispatcher can tell it apart from, e.g. a request for an Item
starting with `"dso_"`.

Next, you need to determine the mapping of URIs to DSpace objects. It's
a good idea to reflect whatever hierarchical structure exists in the
objects, but do not add any artificial hierarchy. As we will see in one
example below, there is sometimes a reason to group resources into a
collection so they can all be enumerated. If the target object is
usually referenced by random access than by descending a hierarchy,
perhaps it makes more sense to keep it at the top level (like DSpace
Objects).

These are the points to consider when designing an LNI resource:

...

Model the Bitstream Format registry as one resource of the "collection"
type. That top-level resource is just a container for the format
records, so they can all be listed (e.g. by `PROPFIND`). The formats
themselves are child resources of the Registry, named by the string
returned by `get Short DescriptiongetShortDescription()` on the format.

  • The Registry URI is _/prefix_ Code Block<nowiki>/format/</nowiki>
  • Each Bitstream Format's URI is _/prefix__ Code Block<nowiki>/format/</nowiki>_short-description
  • `GET` is not implemented on any of these resources.
  • `PUT` of a new Bitstream Format URI creates it. The request body must be empty.
  • Bitstream Format resources have the following properties. They are all settable unless marked read-only.
    • `DAV:displayname` – same as description
    • `DAV:resourcetype` – empty. (`/format/` is a collection).
    • `dspace:type` – `<bitstream-format/>`
    *
    • `description` – Full description of the bitstream format.
    *
    • `extensions` – Comma-separated list of filename extensions associated with this format.
    *
    • `ID` – READ-ONLY; internal database ID of this format.
    *
    • `MIMEType` – Internet format type, aka MIME type, associated with this format. May not be unique amongst formats.
    *
    • `support Level` – Support level, one of `UNKNOWN`, `KNOWN`, `SUPPORTED`.
    *
    • `is Internal` – Is this format useed to store internal system information, rather than content? One of `TRUE`, `FALSE`.

Since the format resources are named by the "short description", it is
a simple matter to find a format if you know the short description – just
compose the URI and make a `PROPFIND` request. Otherwise list all
formats with a `PROPFIND` request
of depth 1 on the parent collection, `/format/`.

It might be helpful to add query args to the `/format/` resource to
search out formats, e.g. by filename extension. For example, the URI
`/format?[find By Extension]=pdf` pdf would return a `Location:` header redirecting
to the format URI that has `pdf` among its extensions.

...

The LNI can also be extended by adding support for all of the core WebDAV
operations, according to these guidelines.
The missing operations are:

  • PUT Method:: Implement `PUT` on a Bitstream resource to replace its contents, and on an Item to replace it with the contents of a new package. This is waiting for policy decisions and possibly a versioning mechanism.
  • DELETE Method:: DSpace objects are usually never deleted, although the object API supports it. Perhaps `DELETE` is worth implementing only for some types of resources.
  • MKCOL Method:: Create a new collection, i.e. DSpace Collection or Community. Have it create an empty/blank object and then set properties with
    Code Block
    <nowiki>proppatch</nowiki>
    proppatch.
  • MOVE Method:: Possibly useful for rearranging the namespace, i.e. moving children of Collections and Communities around.
  • LOCK Method:: Not implemented, and not strictly required by WebDAV. Recommended that this be left out until DSpace has versioning.
  • Versioning:: Not implemented, and not strictly required by WebDAV. Recommended that this be left out until DSpace has versioning.

See Also

LightweightNetworkInterface - DownloadsAndClients for a sample implementation (unstable) and a pre-built test client.

...

9 pp. PDF showing schematic description of LNI Submit from MIT OpenCourseWare to MIT DSpace.

...

Complete PPT from which 9 pages above are extracted

  • http://dsug2006.uib.no/archive/reilly.ppt
    "Technical Introduction To and Initial Use Of the Lightweight Network Interface (LNI) (---to DSpace!)"
    It's rather difficult to post external link on this page.
    DSpace User Group Meeting, Bergen, Norway, April 2006

...

Wreilly 15:42, 12 June 2009 (EDT)</html>