Begin debugging recent changes.

Conflicts:
	dspace-api/src/main/java/org/dspace/identifier/ezid/EZIDResponse.java
This commit is contained in:
Mark H. Wood
2012-11-07 08:54:44 -05:00
committed by Pascal-Nicolas Becker
parent ab684edfc0
commit 98ee2d7e43
6 changed files with 300 additions and 73 deletions

View File

@@ -9,7 +9,6 @@
package org.dspace.identifier;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.sql.SQLException;
import java.util.HashMap;
@@ -93,6 +92,8 @@ public class DataCiteIdentifierProvider
public String register(Context context, DSpaceObject dso)
throws IdentifierException
{
log.debug("register {}", dso);
Item item;
if (dso instanceof Item)
@@ -107,12 +108,29 @@ public class DataCiteIdentifierProvider
id = mint(context, item);
item.addMetadata(MD_SCHEMA_DSPACE, DSPACE_DOI_ELEMENT, DSPACE_DOI_QUALIFIER, null, id);
try {
item.update();
} catch (SQLException ex) {
throw new IdentifierException("New identifier not stored", ex);
} catch (AuthorizeException ex) {
throw new IdentifierException("New identifier not stored", ex);
}
log.info("Registered {}", id);
return id;
}
@Override
public void register(Context context, DSpaceObject object, String identifier)
{
log.debug("register {} as {}", object, identifier);
if (!(object instanceof Item))
{
// TODO throw new IdentifierException("Unsupported object type " + object.getTypeText());
log.error("Unsupported object type " + object.getTypeText());
return;
}
EZIDResponse response;
String doi = "unknown"; // In case we can't even build a name
try {
@@ -136,6 +154,16 @@ public class DataCiteIdentifierProvider
Item item = (Item)object;
item.addMetadata(MD_SCHEMA_DSPACE, DSPACE_DOI_ELEMENT,
DSPACE_DOI_QUALIFIER, null, identifier);
try {
item.update();
log.info("registered {}", identifier);
} catch (SQLException ex) {
// TODO throw new IdentifierException("New identifier not stored", ex);
log.error("New identifier not stored", ex);
} catch (AuthorizeException ex) {
// TODO throw new IdentifierException("New identifier not stored", ex);
log.error("New identifier not stored", ex);
}
}
else
{
@@ -148,6 +176,8 @@ public class DataCiteIdentifierProvider
public void reserve(Context context, DSpaceObject dso, String identifier)
throws IdentifierException
{
log.debug("reserve {}", identifier);
EZIDResponse response;
String doi = "unknown"; // In case we can't even build a name
try {
@@ -157,9 +187,6 @@ public class DataCiteIdentifierProvider
Map<String, String> metadata = crosswalkMetadata(dso);
metadata.put("_status", "reserved");
response = request.create(metadata);
} catch (IdentifierException e) {
log.error("doi:{} not registered: {}", doi, e.getMessage());
return;
} catch (IOException e) {
log.error("doi:{} not registered: {}", doi, e.getMessage());
return;
@@ -173,6 +200,14 @@ public class DataCiteIdentifierProvider
Item item = (Item)dso;
item.addMetadata(MD_SCHEMA_DSPACE, DSPACE_DOI_ELEMENT,
DSPACE_DOI_QUALIFIER, null, identifier);
try {
item.update();
log.info("reserved {}", identifier);
} catch (SQLException ex) {
throw new IdentifierException("New identifier not stored", ex);
} catch (AuthorizeException ex) {
throw new IdentifierException("New identifier not stored", ex);
}
}
else
{
@@ -185,8 +220,52 @@ public class DataCiteIdentifierProvider
public String mint(Context context, DSpaceObject dso)
throws IdentifierException
{
String doi = request(crosswalkMetadata(dso));
return doi;
log.debug("mint for {}", dso);
// Compose the request
EZIDRequest request;
try {
request = requestFactory.getInstance(getShoulder(), getUser(), getPassword());
} catch (URISyntaxException ex) {
log.error(ex.getMessage());
throw new IdentifierException("DOI request not sent: " + ex.getMessage());
}
// Send the request
EZIDResponse response;
try
{
response = request.mint(crosswalkMetadata(dso));
} catch (IOException ex)
{
log.error("Failed to send EZID request: {}", ex.getMessage());
throw new IdentifierException("DOI request not sent: " + ex.getMessage());
}
// Good response?
if (HttpURLConnection.HTTP_CREATED != response.getHttpStatusCode())
{
log.error("EZID server responded: {} {}", response.getHttpStatusCode(),
response.getHttpReasonPhrase());
throw new IdentifierException("DOI not created: " + response.getHttpReasonPhrase());
}
// Extract the DOI from the content blob
if (response.isSuccess())
{
String value = response.getEZIDStatusValue();
int end = value.indexOf('|'); // Following pipe is "shadow ARK"
if (end < 0)
end = value.length();
String doi = value.substring(0, end).trim();
log.info("Created {}", doi);
return doi;
}
else
{
log.error("EZID responded: {}", response.getEZIDStatusValue());
throw new IdentifierException("No DOI returned");
}
}
@Override
@@ -194,6 +273,8 @@ public class DataCiteIdentifierProvider
String... attributes)
throws IdentifierNotFoundException, IdentifierNotResolvableException
{
log.debug("resolve {}", identifier);
try
{
ItemIterator found = Item.findByMetadataField(context, MD_SCHEMA_DSPACE, DSPACE_DOI_ELEMENT, DSPACE_DOI_QUALIFIER,
@@ -203,6 +284,7 @@ public class DataCiteIdentifierProvider
Item found1 = found.next();
if (found.hasNext())
log.error("DOI {} multiply bound!", identifier);
log.debug("Resolved to {}", found1);
return found1;
} catch (SQLException ex)
{
@@ -223,6 +305,8 @@ public class DataCiteIdentifierProvider
public String lookup(Context context, DSpaceObject object)
throws IdentifierNotFoundException, IdentifierNotResolvableException
{
log.debug("lookup {}", object);
Item item;
if (!(object instanceof Item))
throw new IllegalArgumentException("Unsupported type " + object.getTypeText());
@@ -230,7 +314,10 @@ public class DataCiteIdentifierProvider
item = (Item)object;
DCValue[] metadata = item.getMetadata(MD_SCHEMA_DSPACE, DSPACE_DOI_ELEMENT, DSPACE_DOI_QUALIFIER, null);
if (metadata.length > 0)
{
log.debug("Found {}", metadata[0].value);
return metadata[0].value;
}
else
throw new IdentifierNotFoundException(object.getTypeText() + " "
+ object.getID() + " has no DOI");
@@ -240,6 +327,8 @@ public class DataCiteIdentifierProvider
public void delete(Context context, DSpaceObject dso)
throws IdentifierException
{
log.debug("delete {}", dso);
if (!(dso instanceof Item))
throw new IllegalArgumentException("Unsupported type " + dso.getTypeText());
@@ -277,6 +366,8 @@ public class DataCiteIdentifierProvider
public void delete(Context context, DSpaceObject dso, String identifier)
throws IdentifierException
{
log.debug("delete {} from {}", identifier, dso);
throw new UnsupportedOperationException("Not supported yet."); // TODO implement delete(specific)
// TODO find metadata value == identifier
// TODO delete from EZID
@@ -313,55 +404,6 @@ public class DataCiteIdentifierProvider
else
throw new IdentifierException("Unconfigured: define " + CFG_SHOULDER);
}
/**
* Submit some object details and request identifiers for the object.
*
* @param postBody the details, formatted for EZID.
*/
private String request(Map<String, String> metadata)
throws IdentifierException
{
// Compose the request
EZIDRequest ezrequest;
try {
ezrequest = requestFactory.getInstance(getShoulder(), getUser(), getPassword());
} catch (URISyntaxException ex) {
log.error(ex.getMessage());
throw new IdentifierException("DOI request not sent: " + ex.getMessage());
}
// Send the request
EZIDResponse response;
try
{
response = ezrequest.create(metadata);
} catch (IOException ex)
{
log.error("Failed to send EZID request: {}", ex.getMessage());
throw new IdentifierException("DOI request not sent: " + ex.getMessage());
}
// Good response?
if (HttpURLConnection.HTTP_CREATED != response.getHttpStatusCode())
{
log.error("EZID responded: {} {}", response.getHttpStatusCode(),
response.getHttpReasonPhrase());
throw new IdentifierException("DOI not created: " + response.getHttpReasonPhrase());
}
// Extract the DOI from the content blob
if (response.isSuccess())
{
String value = response.getEZIDStatusValue();
int end = value.indexOf('|'); // Following pipe is "shadow ARK"
if (end < 0)
end = value.length();
return value.substring(0, end).trim();
}
else
throw new IdentifierException("No DOI returned");
}
/**
* Map selected DSpace metadata to fields recognized by DataCite.

View File

@@ -1,7 +1,9 @@
/*
* Copyright 2012 Indiana University. All rights reserved.
/**
* 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
*
* Mark H. Wood, IUPUI University Library, Nov 1, 2012
* http://www.dspace.org/license/
*/
package org.dspace.identifier.ezid;
@@ -51,6 +53,7 @@ public class EZIDRequest
EZIDRequest(URI url, String username, String password)
throws URISyntaxException
{
this.url = url;
client = new DefaultHttpClient();
if (null != username)
client.getCredentialsProvider().setCredentials(

View File

@@ -1,12 +1,9 @@
/*
* Copyright 2012 Indiana University. All rights reserved.
/**
* 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
*
* Mark H. Wood, IUPUI University Library, Nov 6, 2012
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
* http://www.dspace.org/license/
*/
package org.dspace.identifier.ezid;
@@ -49,9 +46,27 @@ public class EZIDRequestFactory
throws URISyntaxException
{
URIBuilder uri = new URIBuilder();
uri.setScheme(EZID_SCHEME);
uri.setHost(EZID_HOST);
uri.setPath(EZID_PATH + '/' + requestPath);
String head, tail;
if (EZID_PATH.endsWith("/"))
head = EZID_PATH.substring(0, EZID_PATH.length() - 1);
else
head = EZID_PATH;
if (requestPath.startsWith("/"))
tail = requestPath.substring( 0, requestPath.length() - 1);
else
tail = requestPath;
StringBuilder path = new StringBuilder();
path.append(head);
path.append('/');
path.append(tail);
uri.setPath(path.toString());
return new EZIDRequest(uri.build(), username, password);
}

View File

@@ -0,0 +1,171 @@
/**
* 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.identifier.ezid;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.util.EntityUtils;
import org.dspace.identifier.IdentifierException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Decoded response data evoked by a request made to EZID.
*/
public class EZIDResponse
{
private static final Logger log = LoggerFactory.getLogger(EZIDResponse.class);
private final String status;
private final String statusValue;
private final Map<String, String> attributes = new HashMap<String, String>();
private final HttpResponse response;
public EZIDResponse(HttpResponse response)
throws IdentifierException
{
this.response = response;
HttpEntity responseBody = response.getEntity();
// Collect the content of the percent-encoded response.
String body;
try
{
body = EntityUtils.toString(responseBody, "UTF-8");
} catch (IOException ex)
{
log.error(ex.getMessage());
throw new IdentifierException("EZID response not understood: "
+ ex.getMessage());
} catch (ParseException ex)
{
log.error(ex.getMessage());
throw new IdentifierException("EZID response not understood: "
+ ex.getMessage());
}
String[] parts;
String[] lines = body.split("[\\n\\r]");
// First line is request status and message or value
parts = lines[0].split(":", 2);
status = parts[0].trim();
if (parts.length > 1)
{
statusValue = parts[1].trim();
}
else
{
statusValue = null;
}
// Remaining lines are key: value pairs
for (int i = 1; i < lines.length; i++)
{
parts = lines[i].split(":", 2);
String key = null, value = null;
try {
key = URLDecoder.decode(parts[0], "UTF-8").trim();
if (parts.length > 1)
{
value = URLDecoder.decode(parts[1], "UTF-8").trim();
}
else
{
value = null;
}
} catch (UnsupportedEncodingException e) {
// XXX SNH, we always use UTF-8 which is required by the Java spec.
}
attributes.put(key, value);
}
}
/**
* Did the EZID request succeed?
*
* @return returned status was success.
*/
public boolean isSuccess()
{
return status.equalsIgnoreCase("success");
}
/**
* Get the EZID request status.
*
* @return should be "success" or "error".
*/
public String getEZIDStatus()
{
return status;
}
/**
* Value associated with the EZID status (identifier, error text, etc.)
*/
public String getEZIDStatusValue()
{
return statusValue;
}
/**
* Expose the available keys.
*
* @return all keys found in the response.
*/
public List<String> getKeys()
{
List<String> keys = new ArrayList<String>();
for (String key : attributes.keySet())
{
keys.add(key);
}
return keys;
}
/**
* Look up the value of a given response datum.
*
* @param key the datum to look up.
* @return the value of {@code key}, or null if {@code key} is undefined.
*/
public String get(String key)
{
return attributes.get(key);
}
/**
* @return status of the HTTP request.
*/
public int getHttpStatusCode()
{
return response.getStatusLine().getStatusCode();
}
/**
* @return reason for status of the HTTP request.
*/
public String getHttpReasonPhrase()
{
return response.getStatusLine().getReasonPhrase();
}
}

View File

@@ -19,8 +19,7 @@
<property name="configurationService"
ref="org.dspace.services.ConfigurationService"/>
<property name='requestFactory'>
<bean id='org.dspace.identifier.ezid.EZIDRequestFactory'
class='org.dspace.identifier.ezid.EZIDRequestFactory'>
<bean class='org.dspace.identifier.ezid.EZIDRequestFactory'>
<property name='EZID_SCHEME' value='https'/>
<property name='EZID_HOST' value='n2t.net'/>
<property name='EZID_PATH' value='/ezid/shoulder/'/>

View File

@@ -5,10 +5,7 @@
*
* http://www.dspace.org/license/
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.dspace.identifier;
import java.util.List;