/** * 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.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.dspace.identifier.doi.DOIIdentifierException; /** * DOI identifiers. * * @author Pascal-Nicolas Becker */ public class DOI implements Identifier { public static final String SCHEME = "doi:"; public static final String RESOLVER = "http://dx.doi.org"; /** * This method helps to convert a DOI into a URL. It takes DOIs in one of * the following formats and returns it as URL (f.e. * http://dx.doi.org/10.123/456). Allowed formats are: * <ul> * <li>doi:10.123/456</li> * <li>10.123/456</li> * <li>http://dx.doi.org/10.123/456</li> * </ul> * * @param identifier A DOI that should be returned in external form. * @return A String containing a URL to the official DOI resolver. * @throws IllegalArgumentException If identifier is null or an empty String. * @throws IdentifierException If identifier could not be recognized as valid DOI. */ public static String DOIToExternalForm(String identifier) throws IdentifierException { if (null == identifier) throw new IllegalArgumentException("Identifier is null.", new NullPointerException()); if (identifier.isEmpty()) throw new IllegalArgumentException("Cannot format an empty identifier."); if (identifier.startsWith(SCHEME)) return RESOLVER + "/" + identifier.substring(SCHEME.length()); if (identifier.startsWith("10.") && identifier.contains("/")) return RESOLVER + "/" + identifier; if (identifier.startsWith(RESOLVER + "/10.")) return identifier; throw new IdentifierException(identifier + "does not seem to be a DOI."); } public static String DOIFromExternalFormat(String identifier) throws DOIIdentifierException { Pattern pattern = Pattern.compile("^" + RESOLVER + "/+(10\\..*)$"); Matcher matcher = pattern.matcher(identifier); if (matcher.find()) { return SCHEME + matcher.group(1); } throw new DOIIdentifierException("Cannot recognize DOI!", DOIIdentifierException.UNRECOGNIZED); } /** * Recognize format of DOI and return it with leading doi-Scheme. * @param identifier Identifier to format, following format are accepted: * f.e. 10.123/456, doi:10.123/456, http://dx.doi.org/10.123/456. * @return Given Identifier with DOI-Scheme, f.e. doi:10.123/456. * @throws IllegalArgumentException If identifier is empty or null. * @throws DOIIdentifierException If DOI could not be recognized. */ public static String formatIdentifier(String identifier) throws DOIIdentifierException { if (null == identifier) { throw new IllegalArgumentException("Identifier is null.", new NullPointerException()); } if (identifier.startsWith(DOI.SCHEME)) { return identifier; } if (identifier.isEmpty()) { throw new IllegalArgumentException("Cannot format an empty identifier."); } if (identifier.startsWith("10.") && identifier.contains("/")) { return DOI.SCHEME + identifier; } if (identifier.startsWith(RESOLVER + "/10.")) { return DOI.SCHEME + identifier.substring(18); } throw new DOIIdentifierException(identifier + "does not seem to be a DOI.", DOIIdentifierException.UNRECOGNIZED); } }