/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package edu.harvard.iq.dataverse; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.net.MalformedURLException; import java.util.logging.Level; import java.util.logging.Logger; import java.net.URL; import javax.ejb.EJB; /** * * @author skraffmiller */ public class GlobalId implements java.io.Serializable { public static final String DOI_PROTOCOL = "doi"; public static final String HDL_PROTOCOL = "hdl"; @EJB SettingsServiceBean settingsService; // I'm marking this constructor as "deprecated" because it's not reliable; // it uses the parser (below) that makes incorrect assumptions about // handles and dois. (see comments there) @Deprecated public GlobalId(String identifier) { // set the protocol, authority, and identifier via parsePersistentId if (!this.parsePersistentId(identifier)){ throw new IllegalArgumentException("Failed to parse identifier: " + identifier); } } public GlobalId(String protocol, String authority, String identifier) { this.protocol = protocol; this.authority = authority; this.identifier = identifier; } public GlobalId(Dataset dataset){ this.authority = dataset.getAuthority(); this.protocol = dataset.getProtocol(); this.identifier = dataset.getIdentifier(); } private String protocol; private String authority; private String identifier; public String getProtocol() { return protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } public String getAuthority() { return authority; } public void setAuthority(String authority) { this.authority = authority; } public String getIdentifier() { return identifier; } public void setIdentifier(String identifier) { this.identifier = identifier; } public String toString() { return protocol + ":" + authority + "/" + identifier; } public URL toURL() { URL url = null; try { if (protocol.equals(DOI_PROTOCOL)){ url = new URL("http://dx.doi.org/" + authority + "/" + identifier); } else if (protocol.equals(HDL_PROTOCOL)){ url = new URL("http://hdl.handle.net/" + authority + "/" + identifier); } } catch (MalformedURLException ex) { Logger.getLogger(GlobalId.class.getName()).log(Level.SEVERE, null, ex); } return url; } /** * Parse a Persistent Id and set the protocol, authority, and identifier * * Example 1: doi:10.5072/FK2/BYM3IW * protocol: doi * authority: 10.5072/FK2 * identifier: BYM3IW * * Example 2: hdl:1902.1/111012 * protocol: hdl * authority: 1902.1 * identifier: 111012 * * @param persistentId * */ // This parser makes an incorrect assumption, that a handle has to be made of 2 // "/"-separated parts, and a doi - of 3. ICPSR's DOIs are an example of a DOI // that has 2 parts only: doi:10.3886/ICPSR24006.v2 // We already have working global id parsers elsewhere in the app: // for ex., parseStudyIdDOI() and parseStudyIdHandle() in importDDIServiceBean; // We should probably copy that code here, than change the app so that all // the pieces are using this class, instead of replicating the functionality // in multiple places. @Deprecated private boolean parsePersistentId(String persistentId){ if (persistentId==null){ return false; } String doiSeparator = "/";//settingsService.getValueForKey(SettingsServiceBean.Key.DoiSeparator, "/"); // Looking for this split // doi:10.5072/FK2/BYM3IW => (doi) (10.5072/FK2/BYM3IW) // // or this one: (hdl) (1902.1/xxxxx) // String[] items = persistentId.split(":"); if (items.length != 2){ return false; } String protocolPiece = items[0].toLowerCase(); String[] pieces = items[1].split(doiSeparator); // ----------------------------- // Is this a handle? // ----------------------------- if ( pieces.length == 2 && protocolPiece.equals(HDL_PROTOCOL)){ // example: hdl:1902.1/111012 this.protocol = protocolPiece; // hdl this.authority = formatIdentifierString(pieces[0]); // 1902.1 this.identifier = formatIdentifierString(pieces[1]); // 111012 return true; }else if (pieces.length == 3 && protocolPiece.equals(DOI_PROTOCOL)){ // ----------------------------- // Is this a DOI? // ----------------------------- // example: doi:10.5072/FK2/BYM3IW this.protocol = protocolPiece; // doi String doiAuthority = formatIdentifierString(pieces[0]) + doiSeparator + formatIdentifierString(pieces[1]); // "10.5072/FK2" if (this.checkDOIAuthority(doiAuthority)){ this.authority = doiAuthority; } else { return false; } this.identifier = formatIdentifierString(pieces[2]); // "BYM3IW" return true; } return false; } private String formatIdentifierString(String str){ if (str == null){ return null; } // remove whitespace, single quotes, and semicolons return str.replaceAll("\\s+|'|;",""); /* < (%3C) > (%3E) { (%7B) } (%7D) ^ (%5E) [ (%5B) ] (%5D) ` (%60) | (%7C) \ (%5C) + */ // http://www.doi.org/doi_handbook/2_Numbering.html } private boolean checkDOIAuthority(String doiAuthority){ if (doiAuthority==null){ return false; } if (!(doiAuthority.startsWith("10."))){ return false; } return true; } }