mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Add initial code
This commit is contained in:

committed by
Pascal-Nicolas Becker

parent
4ebe7217d9
commit
e5d53f8f43
12
dspace-api/src/main/java/org/dspace/identifier/DOI.java
Normal file
12
dspace-api/src/main/java/org/dspace/identifier/DOI.java
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
package org.dspace.identifier;
|
||||
|
||||
/**
|
||||
* DOI identifiers.
|
||||
*
|
||||
* @author mwood
|
||||
*/
|
||||
public class DOI
|
||||
implements Identifier
|
||||
{
|
||||
}
|
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.httpclient.StatusLine;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ParseException;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.AbstractHttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* Provide service for DOIs through DataCite.
|
||||
*
|
||||
* @author mwood
|
||||
*/
|
||||
public class DataCiteIdentifierProvider
|
||||
extends IdentifierProvider
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(DataCiteIdentifierProvider.class);
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<? extends Identifier> identifier)
|
||||
{
|
||||
return DOI.class.isAssignableFrom(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(String identifier)
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String register(Context context, DSpaceObject item)
|
||||
throws IdentifierException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mint(Context context, DSpaceObject dso)
|
||||
throws IdentifierException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DSpaceObject resolve(Context context, String identifier,
|
||||
String... attributes)
|
||||
throws IdentifierNotFoundException, IdentifierNotResolvableException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookup(Context context, DSpaceObject object)
|
||||
throws IdentifierNotFoundException, IdentifierNotResolvableException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Context context, DSpaceObject dso)
|
||||
throws IdentifierException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Context context, DSpaceObject dso, String identifier)
|
||||
throws IdentifierException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reserve(Context context, DSpaceObject dso, String identifier)
|
||||
throws IdentifierException
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Context context, DSpaceObject object, String identifier)
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
private static String EZID_SCHEME; // = "https";
|
||||
private static String EZID_HOST; // = "n2t.net";
|
||||
private static String EZID_PATH; // = "/ezid/shoulder/";
|
||||
|
||||
/** Map DataCite metadata into local metadata */
|
||||
private static Map<String, String> crosswalk = new HashMap<String, String>();
|
||||
/* default mapping */
|
||||
/*
|
||||
static
|
||||
{
|
||||
crosswalk.put("datacite.creator", "dc.creator.author");
|
||||
crosswalk.put("datacite.title", "dc.title");
|
||||
crosswalk.put("datacite.publisher", "dc.publisher");
|
||||
crosswalk.put("datacite.publicationyear", "dc.date.published");
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param aEZID_SCHEME the EZID URL scheme to set
|
||||
*/
|
||||
@Autowired
|
||||
@Required
|
||||
public static void setEZID_SCHEME(String aEZID_SCHEME)
|
||||
{
|
||||
EZID_SCHEME = aEZID_SCHEME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aEZID_HOST the EZID host to set
|
||||
*/
|
||||
@Autowired
|
||||
@Required
|
||||
public static void setEZID_HOST(String aEZID_HOST)
|
||||
{
|
||||
EZID_HOST = aEZID_HOST;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aEZID_PATH the EZID path to set
|
||||
*/
|
||||
@Autowired
|
||||
@Required
|
||||
public static void setEZID_PATH(String aEZID_PATH)
|
||||
{
|
||||
EZID_PATH = aEZID_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aCrosswalk the crosswalk to set
|
||||
*/
|
||||
@Autowired
|
||||
public static void setCrosswalk(Map<String, String> aCrosswalk)
|
||||
{
|
||||
crosswalk = aCrosswalk;
|
||||
}
|
||||
|
||||
private static final Pattern DOIpattern = Pattern.compile("doi:[\\S]+");
|
||||
private static final Pattern ARKpattern = Pattern.compile("ark:[\\S]+");
|
||||
private static final ContentType CONTENT_UTF8_TEXT = ContentType.create("text/plain", "UTF-8");
|
||||
|
||||
private String doi = null;
|
||||
private String ark = null;
|
||||
|
||||
/**
|
||||
* Submit some object details and request identifiers for the object.
|
||||
*
|
||||
* @param postBody the details, formatted for EZID.
|
||||
*/
|
||||
public void request(String postBody)
|
||||
throws IdentifierException
|
||||
{
|
||||
// Address the service
|
||||
URIBuilder mintURL = new URIBuilder();
|
||||
mintURL.setScheme(EZID_SCHEME)
|
||||
.setHost(EZID_HOST)
|
||||
.setPath(EZID_PATH + configurationService.getProperty("identifier.doi.ezid.shoulder"));
|
||||
|
||||
// Compose the request
|
||||
HttpPost request;
|
||||
try {
|
||||
request = new HttpPost(mintURL.build());
|
||||
} catch (URISyntaxException ex) {
|
||||
log.error(ex.getMessage());
|
||||
throw new IdentifierException("DOI request not sent: " + ex.getMessage());
|
||||
}
|
||||
request.setEntity(new StringEntity(postBody, CONTENT_UTF8_TEXT));
|
||||
|
||||
AbstractHttpClient mint = new DefaultHttpClient();
|
||||
mint.getCredentialsProvider().setCredentials(
|
||||
new AuthScope(mintURL.getHost(), mintURL.getPort()),
|
||||
new UsernamePasswordCredentials(
|
||||
configurationService.getProperty("identifier.doi.ezid.user"),
|
||||
configurationService.getProperty("identifier.doi.ezid.password")));
|
||||
|
||||
// Send the request
|
||||
HttpResponse response;
|
||||
try
|
||||
{
|
||||
response = mint.execute(request);
|
||||
} catch (IOException ex)
|
||||
{
|
||||
log.error("Failed to send EZID request: {}", ex.getMessage());
|
||||
throw new IdentifierException("DOI request not sent: " + ex.getMessage());
|
||||
}
|
||||
|
||||
// Good response?
|
||||
StatusLine status = (StatusLine) response.getStatusLine();
|
||||
if (HttpURLConnection.HTTP_CREATED != status.getStatusCode())
|
||||
{
|
||||
log.error("EZID responded: {} {}", status.getStatusCode(),
|
||||
status.getReasonPhrase());
|
||||
throw new IdentifierException("DOI not created: " + status.getReasonPhrase());
|
||||
}
|
||||
|
||||
HttpEntity responseBody = response.getEntity();
|
||||
|
||||
// Collect the content of the response
|
||||
String content;
|
||||
try {
|
||||
content = 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());
|
||||
}
|
||||
|
||||
// Extract the identifiers from the content blob
|
||||
|
||||
Matcher matcher;
|
||||
|
||||
// DOI
|
||||
matcher = DOIpattern.matcher(content);
|
||||
if (matcher.find())
|
||||
doi = matcher.group();
|
||||
|
||||
// ARK
|
||||
matcher = ARKpattern.matcher(content);
|
||||
if (matcher.find())
|
||||
ark = matcher.group();
|
||||
}
|
||||
|
||||
public String getDoi() { return doi; }
|
||||
|
||||
public String getArk() { return ark; }
|
||||
|
||||
/**
|
||||
* Assemble the identifier request document, one field per line.
|
||||
*
|
||||
* @param dso the object we want to identify.
|
||||
*/
|
||||
static public String generatePostBody(DSpaceObject dso)
|
||||
{
|
||||
if ((null == dso) || !(dso instanceof Item))
|
||||
throw new IllegalArgumentException("Must be an Item");
|
||||
Item item = (Item) dso; // TODO generalize to DSO when all DSOs have metadata.
|
||||
|
||||
StringBuilder bupher = new StringBuilder();
|
||||
|
||||
for (Map.Entry<String, String> datum : crosswalk.entrySet())
|
||||
{
|
||||
DCValue[] values = item.getMetadata(datum.getValue());
|
||||
if (null != values)
|
||||
{
|
||||
for (DCValue value : values)
|
||||
{
|
||||
bupher.append(datum.getKey())
|
||||
.append(": ")
|
||||
.append(value.value)
|
||||
.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bupher.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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/
|
||||
*/
|
||||
/**
|
||||
* Providers of durable unique identifiers (Handles, DOIs, etc.).
|
||||
* Generally, subclasses of {@link org.dspace.identifier.IdentifierProvider}
|
||||
* offer methods to create, delete, and resolve subclasses of
|
||||
* {@link org.dspace.identifier.Identifier}. Classes outside this package
|
||||
* should rely on {@link org.dspace.identifier.IdentifierService} to perform
|
||||
* these operations using the most appropriate provider.
|
||||
*/
|
||||
|
||||
package org.dspace.identifier;
|
Reference in New Issue
Block a user