mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 15:33:09 +00:00
Draft: Multi remote DSpace Repositories plugin for handle storage
This commit is contained in:

committed by
Pascal-Nicolas Becker

parent
5e4aec7464
commit
f2ee5454ee
@@ -0,0 +1,468 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.handle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.handle.hdllib.Encoder;
|
||||
import net.handle.hdllib.HandleException;
|
||||
import net.handle.hdllib.HandleStorage;
|
||||
import net.handle.hdllib.HandleValue;
|
||||
import net.handle.hdllib.ScanCallback;
|
||||
import net.handle.hdllib.Util;
|
||||
import net.handle.util.StreamTable;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* Extension to the CNRI Handle Server that translates requests to resolve
|
||||
* handles into remote calls to the mini-DSpace Handle resolver JSON API. This
|
||||
* only provides some of the functionality (namely, the resolving of handles to
|
||||
* URLs) of the CNRI HandleStorage interface.
|
||||
*
|
||||
* <p>
|
||||
* This class is intended to be embedded in the CNRI Handle Server. It conforms
|
||||
* to the HandleStorage interface that was delivered with Handle Server version
|
||||
* 6.2.0.
|
||||
* </p>
|
||||
*
|
||||
* @author Andrea Bollini
|
||||
*/
|
||||
public class MultiRemoteDSpaceRepositoryHandlePlugin implements HandleStorage
|
||||
{
|
||||
/** log4j category */
|
||||
private static Logger log = Logger
|
||||
.getLogger(MultiRemoteDSpaceRepositoryHandlePlugin.class);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public MultiRemoteDSpaceRepositoryHandlePlugin()
|
||||
{
|
||||
}
|
||||
|
||||
// //////////////////////////////////////
|
||||
// Non-Resolving methods -- unimplemented
|
||||
// //////////////////////////////////////
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void init(StreamTable st) throws Exception
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called init (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void setHaveNA(byte[] theHandle, boolean haveit)
|
||||
throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called setHaveNA (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void createHandle(byte[] theHandle, HandleValue[] values)
|
||||
throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called createHandle (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public boolean deleteHandle(byte[] theHandle) throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called deleteHandle (not implemented)");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void updateValue(byte[] theHandle, HandleValue[] values)
|
||||
throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called updateValue (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void deleteAllRecords() throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called deleteAllRecords (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void checkpointDatabase() throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called checkpointDatabase (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void shutdown()
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called shutdown (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void scanHandles(ScanCallback callback) throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called scanHandles (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HandleStorage interface method - not implemented.
|
||||
*/
|
||||
public void scanNAs(ScanCallback callback) throws HandleException
|
||||
{
|
||||
// Not implemented
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called scanNAs (not implemented)");
|
||||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////
|
||||
// Resolving methods
|
||||
// //////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Return the raw values for this handle. This implementation returns a
|
||||
* single URL value.
|
||||
*
|
||||
* @param theHandle
|
||||
* byte array representation of handle
|
||||
* @param indexList
|
||||
* ignored
|
||||
* @param typeList
|
||||
* ignored
|
||||
* @return A byte array with the raw data for this handle. Currently, this
|
||||
* consists of a single URL value.
|
||||
* @exception HandleException
|
||||
* If an error occurs while calling the Handle API.
|
||||
*/
|
||||
public byte[][] getRawHandleValues(byte[] theHandle, int[] indexList,
|
||||
byte[][] typeList) throws HandleException
|
||||
{
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called getRawHandleValues");
|
||||
}
|
||||
|
||||
if (theHandle == null)
|
||||
{
|
||||
throw new HandleException(HandleException.INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
String handle = Util.decodeString(theHandle);
|
||||
String url = getRemoteDSpaceURL(handle);
|
||||
HandleValue value = new HandleValue();
|
||||
|
||||
value.setIndex(100);
|
||||
value.setType(Util.encodeString("URL"));
|
||||
value.setData(Util.encodeString(url));
|
||||
value.setTTLType((byte) 0);
|
||||
value.setTTL(100);
|
||||
value.setTimestamp(100);
|
||||
value.setReferences(null);
|
||||
value.setAdminCanRead(true);
|
||||
value.setAdminCanWrite(false);
|
||||
value.setAnyoneCanRead(true);
|
||||
value.setAnyoneCanWrite(false);
|
||||
|
||||
List<HandleValue> values = new LinkedList<HandleValue>();
|
||||
|
||||
values.add(value);
|
||||
|
||||
byte[][] rawValues = new byte[values.size()][];
|
||||
|
||||
for (int i = 0; i < values.size(); i++)
|
||||
{
|
||||
HandleValue hvalue = values.get(i);
|
||||
|
||||
rawValues[i] = new byte[Encoder.calcStorageSize(hvalue)];
|
||||
Encoder.encodeHandleValue(rawValues[i], 0, hvalue);
|
||||
}
|
||||
|
||||
return rawValues;
|
||||
|
||||
}
|
||||
|
||||
private String getRemoteDSpaceURL(String handle) throws HandleException
|
||||
{
|
||||
InputStreamReader jsonStreamReader = null;
|
||||
String url = null;
|
||||
try
|
||||
{
|
||||
String prefix = handle.split("/")[0];
|
||||
String endpoint = ConfigurationManager
|
||||
.getProperty("handle-resolver.prefix." + prefix);
|
||||
|
||||
String jsonurl = endpoint + "/resolve/" + handle;
|
||||
jsonStreamReader = new InputStreamReader(
|
||||
new URL(jsonurl).openStream(), "UTF-8");
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement jsonElement = parser.parse(jsonStreamReader);
|
||||
|
||||
if (jsonElement == null || jsonElement.isJsonNull()
|
||||
|| jsonElement.getAsJsonArray().size() == 0)
|
||||
{
|
||||
throw new HandleException(HandleException.HANDLE_DOES_NOT_EXIST);
|
||||
}
|
||||
|
||||
url = jsonElement.getAsJsonArray().get(0).getAsString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Exception in getRawHandleValues", e);
|
||||
}
|
||||
|
||||
// Stack loss as exception does not support cause
|
||||
throw new HandleException(HandleException.INTERNAL_ERROR);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (jsonStreamReader != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
jsonStreamReader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we have this handle in storage.
|
||||
*
|
||||
* @param theHandle
|
||||
* byte array representation of handle
|
||||
* @return True if we have this handle in storage
|
||||
* @exception HandleException
|
||||
* If an error occurs while calling the Handle API.
|
||||
*/
|
||||
public boolean haveNA(byte[] theHandle) throws HandleException
|
||||
{
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called haveNA");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all handles in local storage which start with the naming authority
|
||||
* handle.
|
||||
*
|
||||
* @param theNAHandle
|
||||
* byte array representation of naming authority handle
|
||||
* @return All handles in local storage which start with the naming
|
||||
* authority handle.
|
||||
* @exception HandleException
|
||||
* If an error occurs while calling the Handle API.
|
||||
*/
|
||||
public Enumeration getHandlesForNA(byte[] theNAHandle)
|
||||
throws HandleException
|
||||
{
|
||||
String naHandle = Util.decodeString(theNAHandle);
|
||||
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info("Called getHandlesForNA for NA " + naHandle);
|
||||
}
|
||||
|
||||
List<String> handles = getRemoteDSpaceHandles(naHandle);
|
||||
List<byte[]> results = new LinkedList<byte[]>();
|
||||
|
||||
for (String handle : handles)
|
||||
{
|
||||
// Transforms to byte array
|
||||
results.add(Util.encodeString(handle));
|
||||
}
|
||||
|
||||
return Collections.enumeration(results);
|
||||
|
||||
}
|
||||
|
||||
private List<String> getRemoteDSpaceHandles(String naHandle)
|
||||
throws HandleException
|
||||
{
|
||||
List<String> handles = new ArrayList<String>();
|
||||
|
||||
String endpoint = ConfigurationManager
|
||||
.getProperty("handle-resolver.prefix." + naHandle);
|
||||
|
||||
InputStreamReader jsonStreamReader = null;
|
||||
try
|
||||
{
|
||||
String jsonurl = endpoint + "/listhandles/" + naHandle;
|
||||
jsonStreamReader = new InputStreamReader(
|
||||
new URL(jsonurl).openStream(), "UTF-8");
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement jsonElement = parser.parse(jsonStreamReader);
|
||||
|
||||
if (jsonElement != null && jsonElement.getAsJsonArray().size() != 0)
|
||||
{
|
||||
for (int i = 0; i < jsonElement.getAsJsonArray().size(); i++)
|
||||
{
|
||||
handles.add(jsonElement.getAsJsonArray().get(i)
|
||||
.getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Exception in getHandlesForNA", e);
|
||||
}
|
||||
|
||||
// Stack loss as exception does not support cause
|
||||
throw new HandleException(HandleException.INTERNAL_ERROR);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (jsonStreamReader != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
jsonStreamReader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return handles;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
MultiRemoteDSpaceRepositoryHandlePlugin multi = new MultiRemoteDSpaceRepositoryHandlePlugin();
|
||||
try
|
||||
{
|
||||
System.out.println(StringUtils.join(
|
||||
multi.getRemoteDSpaceHandles("123456789"), ","));
|
||||
}
|
||||
catch (HandleException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
try
|
||||
{
|
||||
System.out.println(StringUtils.join(
|
||||
multi.getRemoteDSpaceHandles("123456780"), ","));
|
||||
}
|
||||
catch (HandleException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
try
|
||||
{
|
||||
System.out.println(multi.getRemoteDSpaceURL("123456789/1"));
|
||||
}
|
||||
catch (HandleException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
try
|
||||
{
|
||||
System.out.println(multi.getRemoteDSpaceURL("123456789/1111111"));
|
||||
}
|
||||
catch (HandleException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
try
|
||||
{
|
||||
System.out.println(multi.getRemoteDSpaceURL("123456780/1"));
|
||||
}
|
||||
catch (HandleException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
try
|
||||
{
|
||||
System.out.println(multi.getRemoteDSpaceURL("123456780/1111111"));
|
||||
}
|
||||
catch (HandleException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user