Warning | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
Prefix is the initial URL path at which the LNI service is "mounted" on its Web server. Since the LNI is intended |
The absolute path of the URI for each type of content object is composed as follows:
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="12f97be8-49a1-4fcd-9eef-429190faf5ff"><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="2cf82056-a8a9-4f6f-ab85-74fa5a9c1c09"><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="4c68b885-5464-41d4-8995-acba218e9754"><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="635d19d2-3b4d-42a5-ba40-8ebfbb49d55c"><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="dceb34f9-0734-4307-9b30-199534df6ed0"><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="9290af05-da6f-4d30-8249-21fa8921ffd3"><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="ef26d471-9e15-4a53-b3b1-16974030c519"><ac:plain-text-body><![CDATA[ | Workflow Items list | /[prefix]/workflow_own/ , /[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="0c962354-273d-4277-9a12-c0afb8f896df"><ac:plain-text-body><![CDATA[ | 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="2482757f-6a74-45d1-b12a-1e6b8b88cc78"><ac:plain-text-body><![CDATA[ | 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="f63622ed-2c60-4795-a0dd-b8d4093e0064"><ac:plain-text-body><![CDATA[ | EPerson | /[prefix]/eperson/ep_db_[id] | ]]></ac:plain-text-body></ac:structured-macro> |
Key:
DSpace Site | /[prefix]/ |
Lookup handle | /[prefix]/lookup/handle/[handle] , /[prefix]/lookup/bitstream-handle/[sequence]/[handle]_ |
Community, Collection, Item (DSpace Objects) | /[prefix]/dso_[persistent-identifier] |
Bitstream | /[prefix]/dso_[persistent-identifier]/bitstream_[pid] |
Workspace Items list | /[prefix]/workspace |
Workspace Item | /[prefix]/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/ |
EPerson | /[prefix]/eperson/ep_db_[id] |
Key:
- [prefix] was covered above.
- [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). - [handle] is the Handle or other persistent identifier. It may only be used with the
lookup
service. - [pid] in the bitstream URI is a persistent bitstream identifier.
- [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
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_.
\[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.Wiki Markup
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
|
...
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 |
---|
http://uni.edu/dspace/dav/?type=COMMUNITY&type=COLLECTION
http://uni.edu/dspace/dav/dso_1721.1$3549?type=collection
|
...
The general format of a GET URI is:
Panel | |
---|---|
|
Where prefix and the URI path are as described in the section above on Resource URIs.
...
Some examples of GET requests:
Code Block |
---|
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
|
...
For example, to add a new item to the Collection at handle 1721.1/3549
, we observe the following request and response:
Code Block |
---|
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....
|
...
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 |
---|
<propfind xmlns="DAV:">
<prop xmlns:dspace="http://www.dspace.org/xmlns/dspace">
<displayname/>
<getlastmodified/>
<dspace:type/>
</prop>
</propfind>
|
The result of a `PROPFIND` is a 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 |
---|
<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>
|
...
Here is an example that changes (or adds) the `displayname` property and removes `dspace:license`:
Code Block |
---|
<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>
|
...
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 |
---|
<!-- 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>
|
...
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
, 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 LNIClientUtils
to help manage this, but you will
have to implement it yourself for SOAP clients in other languages.
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 |
---|
public class org.dspace.app.dav.client.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.RemoteException, org.dspace.app.dav.client.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.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.RemoteException, org.dspace.app.dav.client.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.RemoteException, org.dspace.app.dav.client.LNIRemoteException
/**
*** Executes COPY method; "uri" and "destination_uri" may be relative
*** to DSpace LNI prefix, or absolute.
*** The depth and '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 keepProperties)
throws java.rmi.RemoteException, org.dspace.app.dav.client.LNIRemoteException
}
public class org.dspace.app.dav.client.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
}
|
...
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 |
---|
// 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
LniSoapServletServiceLocator locator = new LniSoapServletServiceLocator();
// create client endpoint
LniSoapServle] lni = locator.getDSpaceLNI(new java.net.URL(endpoint));
// get resource URI for known handle:
String handle = "1234.56/789";
String resourceUri = lni.lookup(handle, null);
// get its properties..
String result = lni.propfind(resourceUri,
"<propfind xmlns=\"DAV:\"><allprop /></propfind>", 1);
// ..now parse and display the XML in "result"..
|
...
Here is the document to send with the propfind
request:
Code Block |
---|
<propfind xmlns="DAV:">
<prop xmlns:dspace="http://www.dspace.org/xmlns/dspace">
<DAV:current_user_privilege_set />
</prop>
</propfind>
|
...
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/`.unmigrated-wiki-markup
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
}} would return a `Location:` header redirecting to the format URI that has `pdf` among its extensions.
Other good Candidates for New Resource Types
...