Difference between revisions of "API:EPrints/Storage"

From EPrints Documentation
Jump to: navigation, search
 
(9 intermediate revisions by 2 users not shown)
Line 4: Line 4:
  
  
<!-- Pod2Wiki=_private_ -->{{API:Unstable}}<!-- Pod2Wiki=head_name -->
+
<!-- Pod2Wiki=_private_ -->{{API:Unstable}}
 +
 
 +
<!-- Pod2Wiki=head_name -->
 
==NAME==
 
==NAME==
'''EPrints::Storage''' - store and retrieve objects in the storage engine
+
EPrints::Storage - manage data streams in storage devices (storage layer)
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
 
 
<!-- Pod2Wiki=head_synopsis -->
 
<!-- Pod2Wiki=head_synopsis -->
 
==SYNOPSIS==
 
==SYNOPSIS==
  my $store = $repository-&gt;storage();
+
<source lang="perl">my $store = $repository->storage();
 
+
 
  $store-&gt;store(
+
$str = "Hello, World!";
    $fileobj,   # file object
+
open(my $fh, "<", \$str);
    "diddle.pdf", # filename
+
$f = sub {
    $fh        # file handle
+
read($fh, my $buffer, 6); # just to demonstrate!
  );
+
return $buffer;
 
+
};
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
+
$store->store(
<span style='display:none'>User Comments</span>
+
$fileobj, # file object
 +
$f, # callback
 +
1024, # offset
 +
);</source>
 +
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
 
 
<!-- Pod2Wiki=head_description -->
 
<!-- Pod2Wiki=head_description -->
 
==DESCRIPTION==
 
==DESCRIPTION==
 +
Unless you are directly manipulating how data streams are stored you should use the methods for retrieving and writing data available from [[API:EPrints/DataObj/File|EPrints::DataObj::File]].
 +
 
This module is the storage control layer which uses [[API:EPrints/Plugin/Storage|EPrints::Plugin::Storage]] plugins to support various storage back-ends. It enables the storage, retrieval and deletion of data streams. The maximum size of a stream is dependent on the back-end storage mechanism.
 
This module is the storage control layer which uses [[API:EPrints/Plugin/Storage|EPrints::Plugin::Storage]] plugins to support various storage back-ends. It enables the storage, retrieval and deletion of data streams. The maximum size of a stream is dependent on the back-end storage mechanism.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
+
Storage works on [[API:EPrints/DataObj/File|EPrints::DataObj::File]] objects, which record the size of the data stream and where it has been stored. Unless a specific storage back-end is used, where a file is stored depends on the storage policy which is located in ''lib/storage/default.xml'':
<span style='display:none'>User Comments</span>
+
 
 +
<source lang="xml"><store xmlns="http://eprints.org/ep3/storage" xmlns:epc="http://eprints.org/ep3/control">
 +
<epc:choose>
 +
<epc:when test="datasetid = 'document'">
 +
<plugin name="Local"/>
 +
</epc:when>
 +
<epc:otherwise>
 +
<plugin name="Local"/>
 +
</epc:otherwise>
 +
</epc:choose>
 +
</store></source>
 +
 
 +
The storage policy is a EP-script file that resolves to a list of one or more "plugin" elements. When storing, all matching plugins will be given the data stream to store (i.e. multiple copies). When retrieving, the first plugin to be successfully opened for reading will be used. The item context used when the storage policy is evaluated is the [[API:EPrints/DataObj/File|EPrints::DataObj::File]].
 +
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_callbacks -->
<!-- Pod2Wiki=head_methods -->
+
===Callbacks===
==METHODS==
+
Writing to and retrieving from data streams makes use of callback functions. This allows data to be streamed (to avoid memory overheads) and for flexibility in where data is going.
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
+
 
<span style='display:none'>User Comments</span>
+
For details on the callback API see [[API:EPrints/DataObj/File#get_file|EPrints::DataObj::File/get_file]] and [[API:EPrints/DataObj/File#set_file|EPrints::DataObj::File/set_file]] for retrieving and writing respectively.
 +
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_methods -->
<!-- Pod2Wiki=item_new -->
+
==METHODS==
 +
<!-- Pod2Wiki=head_new -->
 
===new===
 
===new===
  
$store = EPrints::Storage-&gt;new( $repository )
+
<source lang="perl">$store = EPrints::Storage->new( $repository )
 +
 
 +
</source>
 
Create a new storage object for $repository. Should not be used directly, see [[API:EPrints/Session|EPrints::Session]].
 
Create a new storage object for $repository. Should not be used directly, see [[API:EPrints/Session|EPrints::Session]].
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_store -->
<!-- Pod2Wiki=item_store -->
 
 
===store===
 
===store===
  
$len = $store-&gt;store( $fileobj, CODEREF )
+
<source lang="perl">$len = $store->store( $fileobj, CODEREF [, $offset ] )
Read from and store all data from CODEREF for $fileobj. The '''filesize''' field in $fileobj must be set at the expected number of bytes to read from CODEREF.
 
  
Returns undef if the file couldn't be stored, otherwise the number of bytes read.
+
</source>
 +
Read from and store all data from CODEREF for $fileobj. If $offset is given starts writing from that point onwards.
 +
 
 +
Behaviour is undefined if an attempt is made to write beyond $fileobj's '''filesize'''.
 +
 
 +
Returns the number of bytes written or undef if an error occurred.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
 
+
The combination of methods open_write, write, and close_write can be used as an alternative to this method.
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_retrieve -->
<!-- Pod2Wiki=item_retrieve -->
 
 
===retrieve===
 
===retrieve===
  
$success = $store-&gt;retrieve( $fileobj, $offset, $n, CALLBACK )
+
<source lang="perl">$success = $store->retrieve( $fileobj, $offset, $n, CALLBACK )
 +
 
 +
</source>
 
Retrieve the contents of the $fileobj starting at $offset for $n bytes.
 
Retrieve the contents of the $fileobj starting at $offset for $n bytes.
  
 
CALLBACK = $rc = &amp;f( BUFFER )
 
CALLBACK = $rc = &amp;f( BUFFER )
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_delete -->
<!-- Pod2Wiki=item_delete -->
 
 
===delete===
 
===delete===
  
$success = $store-&gt;delete( $fileobj )
+
<source lang="perl">$success = $store->delete( $fileobj )
 +
 
 +
</source>
 
Delete all object copies stored for $fileobj.
 
Delete all object copies stored for $fileobj.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_delete_copy -->
<!-- Pod2Wiki=item_delete_copy -->
 
 
===delete_copy===
 
===delete_copy===
  
$ok = $store-&gt;delete_copy( $plugin, $fileobj )
+
<source lang="perl">$ok = $store->delete_copy( $plugin, $fileobj )
Delete the copy of this file stored in $plugin.
+
 
 +
</source>
 +
Delete the copy of this file stored in the storage layer [[API:EPrints/Plugin/Storage|$plugin]].
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_get_local_copy -->
<!-- Pod2Wiki=item_get_local_copy -->
 
 
===get_local_copy===
 
===get_local_copy===
  
$filename = $store-&gt;get_local_copy( $fileobj )
+
<source lang="perl">$fh = $store->get_local_copy( $fileobj )
Return the name of a local copy of the file.
 
  
Will retrieve and cache the remote object using {{API:PodLink|file=File/Temp|package_name=File::Temp|section=|text=File::Temp}} if necessary.
+
</source>
 +
Return a local copy of the file. Potentially expensive if the file has to be retrieved.
 +
 
 +
Stringifying $fh will give the full path to the local file, which may be useful for calling external tools (see {{API:PodLink|file=File/Temp|package_name=File::Temp|section=|text=File::Temp}}).
  
 
Returns undef if retrieval failed.
 
Returns undef if retrieval failed.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_get_remote_copy -->
<!-- Pod2Wiki=item_get_remote_copy -->
 
 
===get_remote_copy===
 
===get_remote_copy===
  
$url = $store-&gt;get_remote_copy( $fileobj )
+
<source lang="perl">$url = $store->get_remote_copy( $fileobj )
 +
 
 +
</source>
 +
Some storage back-ends may provide direct Web access to the data stream (e.g. Amazon S3). If the back-end supports this, a user can be redirected to the storage back-end rather than downloading the file from EPrints. Internally, EPrints will always use the [[API:EPrints/Storage#retrieve|retrieve]] method.
 +
 
 
Returns a URL from which this file can be accessed.
 
Returns a URL from which this file can be accessed.
  
 
Returns undef if this file is not available via another service.
 
Returns undef if this file is not available via another service.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_get_plugins -->
<!-- Pod2Wiki=item_get_plugins -->
 
 
===get_plugins===
 
===get_plugins===
  
@plugins = $store-&gt;get_plugins( $fileobj )
+
<source lang="perl">@plugins = $store->get_plugins( $fileobj )
Returns the [[API:EPrints/Plugin/Storage|EPrints::Plugin::Storage]] plugin(s) to use for $fileobj. If more than one plugin is returned they should be used in turn until one succeeds.
+
 
 +
</source>
 +
Returns the [[API:EPrints/Plugin/Storage|EPrints::Plugin::Storage]] plugin(s) available to use for $fileobj, based on the storage policy. If more than one plugin is returned they should be used in turn until one succeeds.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_copy -->
<!-- Pod2Wiki=item_copy -->
 
 
===copy===
 
===copy===
  
$ok = $store-&gt;copy( $plugin, $fileobj )
+
<source lang="perl">$ok = $store->copy( $plugin, $fileobj )
Copy the contents of $fileobj into another storage $plugin.
+
 
 +
</source>
 +
Copy the contents of $fileobj into another storage $plugin. This uses [[API:EPrints/Storage#retrieve|retrieve]] and [[API:EPrints/Storage#store|store]].
  
 
Returns 1 on success, 0 on failure and -1 if a copy already exists in $plugin.
 
Returns 1 on success, 0 on failure and -1 if a copy already exists in $plugin.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_open_write -->
<!-- Pod2Wiki=item_open_write -->
 
 
===open_write===
 
===open_write===
  
$ok = $storage-&gt;open_write( $fileobj )
+
<source lang="perl">$ok = $storage->open_write( $fileobj [, $offset ] )
Start a write session for $fileobj. $fileobj must have at least the "filesize" property set (which is the number of bytes that will be written).
+
 
 +
</source>
 +
Start a write session for $fileobj. $fileobj must have at least the "filesize" property set (which is the total number of bytes that will be written).
 +
 
 +
Don't forget to [[API:EPrints/Storage#close_write|close_write]] otherwise the handle to the write will be left open.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
 
+
This, along with write and close_write, is an alternative to the store method.
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_write -->
<!-- Pod2Wiki=item_write -->
 
 
===write===
 
===write===
  
$ok = $storage-&gt;write( $fileobj, $buffer )
+
<source lang="perl">$ok = $storage->write( $fileobj, $buffer )
Write $buffer to the storage plugin(s).
+
 
 +
</source>
 +
Write $buffer to the storage plugin(s), starting from the previously written data.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
 
+
This, along with open_write and close_write, is an alternative to the store method.
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=head_close_write -->
<!-- Pod2Wiki=item_close_write -->
 
 
===close_write===
 
===close_write===
  
$ok = $storage-&gt;close_write( $fileobj );
+
<source lang="perl">$ok = $storage->close_write( $fileobj );
 +
 
 +
</source>
 
Finish writing to the storage plugin(s) for $fileobj.
 
Finish writing to the storage plugin(s) for $fileobj.
  
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #cce;  padding: 0em 1em 0em 1em; font-size: 80%; '>
 
<span style='display:none'>User Comments</span>
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
 
 
<!-- Pod2Wiki=head_copyright -->
 
<!-- Pod2Wiki=head_copyright -->
 
==COPYRIGHT==
 
==COPYRIGHT==
<div style='background-color: #e8e8f; margin: 0.5em 0em 1em 0em; border: solid 1px #ccepadding: 0em 1em 0em 1em; font-size: 80%; '>
+
Copyright 2000-2011 University of Southampton.
<span style='display:none'>User Comments</span>
+
 
 +
This file is part of EPrints http://www.eprints.org/.
 +
 
 +
EPrints is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 +
 
 +
EPrints is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 +
 
 +
You should have received a copy of the GNU Lesser General Public License along with EPrints.  If not, see http://www.gnu.org/licenses/.
 +
 
 
<!-- Edit below this comment -->
 
<!-- Edit below this comment -->
  
  
 
<!-- Pod2Wiki= -->
 
<!-- Pod2Wiki= -->
</div>
+
<!-- Pod2Wiki=_postamble_ -->
<!-- Pod2Wiki=_postamble_ --><!-- Edit below this comment -->
+
<!-- Edit below this comment -->

Latest revision as of 13:34, 25 July 2013

EPrints 3 Reference: Directory Structure - Metadata Fields - Repository Configuration - XML Config Files - XML Export Format - EPrints data structure - Core API - Data Objects


API: Core API

Latest Source Code (3.4, 3.3) | Revision Log | Before editing this page please read Pod2Wiki


Warning The interface for this module has not been finalised and may change in the future.

NAME

EPrints::Storage - manage data streams in storage devices (storage layer)


SYNOPSIS

my $store = $repository->storage();

$str = "Hello, World!";
open(my $fh, "<", \$str);
$f = sub {
	read($fh, my $buffer, 6); # just to demonstrate!
	return $buffer;
};
$store->store(
	$fileobj,		# file object
	$f,				# callback
	1024,			# offset
);


DESCRIPTION

Unless you are directly manipulating how data streams are stored you should use the methods for retrieving and writing data available from EPrints::DataObj::File.

This module is the storage control layer which uses EPrints::Plugin::Storage plugins to support various storage back-ends. It enables the storage, retrieval and deletion of data streams. The maximum size of a stream is dependent on the back-end storage mechanism.

Storage works on EPrints::DataObj::File objects, which record the size of the data stream and where it has been stored. Unless a specific storage back-end is used, where a file is stored depends on the storage policy which is located in lib/storage/default.xml:

<store xmlns="http://eprints.org/ep3/storage" xmlns:epc="http://eprints.org/ep3/control">
<epc:choose>
	<epc:when test="datasetid = 'document'">
		<plugin name="Local"/>
	</epc:when>
	<epc:otherwise>
		<plugin name="Local"/>
	</epc:otherwise>
</epc:choose>
</store>

The storage policy is a EP-script file that resolves to a list of one or more "plugin" elements. When storing, all matching plugins will be given the data stream to store (i.e. multiple copies). When retrieving, the first plugin to be successfully opened for reading will be used. The item context used when the storage policy is evaluated is the EPrints::DataObj::File.


Callbacks

Writing to and retrieving from data streams makes use of callback functions. This allows data to be streamed (to avoid memory overheads) and for flexibility in where data is going.

For details on the callback API see EPrints::DataObj::File/get_file and EPrints::DataObj::File/set_file for retrieving and writing respectively.


METHODS

new

$store = EPrints::Storage->new( $repository )

Create a new storage object for $repository. Should not be used directly, see EPrints::Session.


store

$len = $store->store( $fileobj, CODEREF [, $offset ] )

Read from and store all data from CODEREF for $fileobj. If $offset is given starts writing from that point onwards.

Behaviour is undefined if an attempt is made to write beyond $fileobj's filesize.

Returns the number of bytes written or undef if an error occurred.


The combination of methods open_write, write, and close_write can be used as an alternative to this method.

retrieve

$success = $store->retrieve( $fileobj, $offset, $n, CALLBACK )

Retrieve the contents of the $fileobj starting at $offset for $n bytes.

CALLBACK = $rc = &f( BUFFER )


delete

$success = $store->delete( $fileobj )

Delete all object copies stored for $fileobj.


delete_copy

$ok = $store->delete_copy( $plugin, $fileobj )

Delete the copy of this file stored in the storage layer $plugin.


get_local_copy

$fh = $store->get_local_copy( $fileobj )

Return a local copy of the file. Potentially expensive if the file has to be retrieved.

Stringifying $fh will give the full path to the local file, which may be useful for calling external tools (see File::Temp).

Returns undef if retrieval failed.


get_remote_copy

$url = $store->get_remote_copy( $fileobj )

Some storage back-ends may provide direct Web access to the data stream (e.g. Amazon S3). If the back-end supports this, a user can be redirected to the storage back-end rather than downloading the file from EPrints. Internally, EPrints will always use the retrieve method.

Returns a URL from which this file can be accessed.

Returns undef if this file is not available via another service.


get_plugins

@plugins = $store->get_plugins( $fileobj )

Returns the EPrints::Plugin::Storage plugin(s) available to use for $fileobj, based on the storage policy. If more than one plugin is returned they should be used in turn until one succeeds.


copy

$ok = $store->copy( $plugin, $fileobj )

Copy the contents of $fileobj into another storage $plugin. This uses retrieve and store.

Returns 1 on success, 0 on failure and -1 if a copy already exists in $plugin.


open_write

$ok = $storage->open_write( $fileobj [, $offset ] )

Start a write session for $fileobj. $fileobj must have at least the "filesize" property set (which is the total number of bytes that will be written).

Don't forget to close_write otherwise the handle to the write will be left open.


This, along with write and close_write, is an alternative to the store method.

write

$ok = $storage->write( $fileobj, $buffer )

Write $buffer to the storage plugin(s), starting from the previously written data.


This, along with open_write and close_write, is an alternative to the store method.

close_write

$ok = $storage->close_write( $fileobj );

Finish writing to the storage plugin(s) for $fileobj.


COPYRIGHT

Copyright 2000-2011 University of Southampton.

This file is part of EPrints http://www.eprints.org/.

EPrints is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

EPrints is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with EPrints. If not, see http://www.gnu.org/licenses/.