diff --git a/build.gradle b/build.gradle index 8cf1869..4b02b7d 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { } group 'org.doremus' -version '1.3.5' +version '1.4.0' sourceCompatibility = 1.8 diff --git a/src/main/java/org/doremus/isnimatcher/ISNI.java b/src/main/java/org/doremus/isnimatcher/ISNI.java index 3f58978..70f1e1e 100644 --- a/src/main/java/org/doremus/isnimatcher/ISNI.java +++ b/src/main/java/org/doremus/isnimatcher/ISNI.java @@ -12,156 +12,158 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; public class ISNI { - private final static String ISNI_API = "http://isni.oclc.nl/sru/DB=1.2/"; - private final static String ISNI_BASE = "http://isni.org/isni/"; - private final static String START_TAG = ""; - private final static String END_TAG = ""; + private final static String ISNI_API = "http://isni.oclc.nl/sru/DB=1.2/"; + private final static String ISNI_BASE = "https://isni.org/isni/"; + private final static String START_TAG = ""; + private final static String END_TAG = ""; - private final static Pattern FLEX_DATE_PATTERN = Pattern.compile("[\\d?.]{0,4}"); + private final static Pattern FLEX_DATE_PATTERN = Pattern.compile("[\\d?.]{0,4}"); - private static boolean debug = false; - private static boolean bestViafBehavior = false; + private static boolean debug = false; + private static boolean bestViafBehavior = false; - public static ISNIRecord get(String id) throws IOException { - if (id.startsWith(ISNI_BASE)) - id = id.replace(ISNI_BASE, ""); - String query = "pica.isn = " + id; - List records = performQuery(query, 1); - if (records == null) return null; - return records.get(0); - } + public static ISNIRecord get(String id) throws IOException { + if (id.startsWith(ISNI_BASE)) + id = id.replace(ISNI_BASE, ""); - public static ISNIRecord search(String name) throws IOException { - return search(name, null); - } - - public static ISNIRecord search(String name, String date) throws IOException { - return search(null, name, date); - } - - public static ISNIRecord search(String forename, String surname, String date) throws IOException { - if (surname.isEmpty()) throw new RuntimeException("Empty surname for querying org.doremus.isnimatcher.ISNI"); - - String name = surname; - if (forename != null) name += ", " + forename; - if (name.isEmpty()) throw new RuntimeException("Empty name for querying org.doremus.isnimatcher.ISNI"); - - String query = "pica.nw = " + name.replaceAll("\\.", " "); - - int n = date == null ? 1 : 10; - - List records = performQuery(query, n); - if (records == null) return null; + String query = "pica.isn = \"" + id + "\""; + List records = performQuery(query, 1); + if (records == null) return null; + return records.get(0); + } - if (date == null) return records.get(0); - String _date = cleanDate(date); + public static ISNIRecord search(String name) throws IOException { + return search(name, null); + } - if (debug) { - System.out.println(records.size() + " records"); - for (ISNIRecord r : records) r.save("test/" + r.id + ".xml"); + public static ISNIRecord search(String name, String date) throws IOException { + return search(null, name, date); } - ISNIRecord match = records.stream() - .filter(r -> r.hasName(forename, surname, true)) - .filter(r -> dateMatch(_date, r.getBirthYear())) - .findFirst() - .orElse(null); + public static ISNIRecord search(String forename, String surname, String date) throws IOException { + if (surname.isEmpty()) throw new RuntimeException("Empty surname for querying org.doremus.isnimatcher.ISNI"); - if (bestViafBehavior) - return getBestViaf(match, records); + String name = surname; + if (forename != null) name += ", " + forename; - return match; - } + String query = "pica.nw = " + name.replaceAll("\\.", " "); - private static ISNIRecord getBestViaf(ISNIRecord base, List records) { - // Among the records with the same VIAF id, return the one with more links - if (base == null) return null; - String viaf = base.getViafURI(); - if (viaf == null) return base; + int n = 10; + List records = performQuery(query, n); + if (records == null) return null; - return records.stream() - .filter(r -> viaf.equals(r.getViafURI())) - .max(Comparator.comparingInt(ISNIRecord::getLinksNumber)) - .orElse(base); - } + if (debug) { + System.out.println(records.size() + " records"); + for (ISNIRecord r : records) r.save("test/" + r.id + ".xml"); + } - private static boolean dateMatch(String expected, String actual) { - if (actual == null || actual.isEmpty()) return false; - actual = cleanDate(actual); + Stream str = records.stream(); - return actual.matches(expected.replaceAll("\\?", ".")); - } + if (bestViafBehavior) + str = str.sorted(Comparator.comparingInt(ISNIRecord::getLinksNumber).reversed()); - private static String cleanDate(String date) { - // Examples: nach 1980, 1947?, 182? - Matcher m = FLEX_DATE_PATTERN.matcher(date); - if (!m.find()) return ""; - else return m.group().replaceAll("\\?", "."); - } + str = str.filter(r -> r.hasName(forename, surname, true)) + .filter(r -> dateMatch(cleanDate(date), r.getBirthYear())); - private static List performQuery(String query, int n) throws IOException { - if (n < 1) n = 1; - try { - HttpRequest request = Unirest.get(ISNI_API) - .queryString("query", query) - .queryString("operation", "searchRetrieve") - .queryString("recordSchema", "isni-b") - .queryString("maximumRecords", n); - if (debug) System.out.println(request.getUrl()); - HttpResponse response = request.asString(); + return str.findFirst() // tolerance for wrong name but not for wrong date + .orElse(date == null ? records.get(0) : null); + } - if (response.getStatus() != 200) - throw new IOException(response.getStatus() + " | " + response.getStatusText()); +// private static ISNIRecord getBestViaf(ISNIRecord base, List records) { +// // Among the records with the same VIAF id, return the one with more links +// if (base == null) return null; +// String viaf = base.getViafURI(); +// System.out.println(viaf); +// if (viaf == null) return base; +// +// return records.stream() +// .filter(r -> viaf.equals(r.getViafURI())) +// .max(Comparator.comparingInt(ISNIRecord::getLinksNumber)) +// .orElse(base); +// } + + private static boolean dateMatch(String expected, String actual) { + if (expected == null) return true; + if (actual == null || actual.isEmpty()) return false; + actual = cleanDate(actual); + return actual.matches(expected.replaceAll("\\?", ".")); + } + + private static String cleanDate(String date) { + if (date == null) return null; + // Examples: nach 1980, 1947?, 182? + Matcher m = FLEX_DATE_PATTERN.matcher(date); + if (!m.find()) return ""; + else return m.group().replaceAll("\\?", "."); + } - String body = response.getBody(); - List records = new ArrayList<>(); - for (String s : splitBody(body)) { + private static List performQuery(String query, int n) throws IOException { + if (n < 1) n = 1; try { - ISNIRecord isniRecord = ISNIRecord.fromString(s); - if (isniRecord != null) records.add(isniRecord); - } catch (JAXBException e) { - e.printStackTrace(); + HttpRequest request = Unirest.get(ISNI_API) + .queryString("query", query) + .queryString("operation", "searchRetrieve") + .queryString("recordSchema", "isni-b") + .queryString("maximumRecords", n); + + if (debug) System.out.println(request.getUrl()); + + HttpResponse response = request.asString(); + + if (response.getStatus() != 200) + throw new IOException(response.getStatus() + " | " + response.getStatusText()); + + String body = response.getBody(); + List records = new ArrayList<>(); + for (String s : splitBody(body)) { + ISNIRecord isniRecord = null; + try { + isniRecord = ISNIRecord.fromString(s); + } catch (JAXBException e) { + e.printStackTrace(); + } + if (isniRecord != null) records.add(isniRecord); + } + + if (records.size() == 0) return null; + return records; + } catch (UnirestException e) { + throw new IOException(e.getMessage()); } - } - - if (records.size() == 0) return null; - return records; - } catch (UnirestException e) { - throw new IOException(e.getMessage()); } - } - static List splitBody(String body) { - List records = new ArrayList<>(); - if (body.isEmpty()) return records; + static List splitBody(String body) { + List records = new ArrayList<>(); + if (body.isEmpty()) return records; - while (true) { - int start = body.indexOf(START_TAG); - int end = body.indexOf(END_TAG) + END_TAG.length(); + while (true) { + int start = body.indexOf(START_TAG); + int end = body.indexOf(END_TAG) + END_TAG.length(); - // no results - if (start == -1) break; + // no results + if (start == -1) break; - String record = body.substring(start, end); - records.add(record); - body = body.replace(record, ""); - } + String record = body.substring(start, end); + records.add(record); + body = body.replace(record, ""); + } - return records; - } + return records; + } - public static void setDebug(boolean debug) { - ISNI.debug = debug; - } + public static void setDebug(boolean debug) { + ISNI.debug = debug; + } - public static void setBestViafBehavior(boolean bestViafBehavior) { - ISNI.bestViafBehavior = bestViafBehavior; - } + public static void setBestViafBehavior(boolean bestViafBehavior) { + ISNI.bestViafBehavior = bestViafBehavior; + } } diff --git a/src/main/java/org/doremus/isnimatcher/ISNIRecord.java b/src/main/java/org/doremus/isnimatcher/ISNIRecord.java index 4d91434..052757d 100644 --- a/src/main/java/org/doremus/isnimatcher/ISNIRecord.java +++ b/src/main/java/org/doremus/isnimatcher/ISNIRecord.java @@ -215,8 +215,8 @@ public boolean hasName(String forename, String surname) { public boolean hasName(String forename, String surname, boolean _default) { if (surname == null) return false; if (forename == null) return _default; - for (PersonalName pn : personalNames) { + if (surname.equalsIgnoreCase(pn.surname) && forename.equalsIgnoreCase(pn.forename)) return true; diff --git a/src/test/java/ISNITest.java b/src/test/java/ISNITest.java index 9c256fe..9208634 100644 --- a/src/test/java/ISNITest.java +++ b/src/test/java/ISNITest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertNull; public class ISNITest { - private final static String MOZART_URI = "http://isni.org/isni/0000000121269154"; + private final static String MOZART_URI = "https://isni.org/isni/0000000121269154"; private final static String BEETHOVEN_ID = "0000000121268987"; @Before @@ -32,18 +32,21 @@ public void searchWithFullName() throws IOException { @Test public void getByISNIUri() throws IOException { ISNIRecord r = ISNI.get(MOZART_URI); + assert r != null; assertEquals("Mozart", r.personalNames.get(0).surname); } @Test public void getByISNICode() throws IOException { ISNIRecord r = ISNI.get(BEETHOVEN_ID); + assert r != null; assertEquals("Beethoven", r.personalNames.get(0).surname); } @Test public void getViaf() throws IOException { ISNIRecord r = ISNI.get("000000007368351X"); + assert r != null; assertEquals("https://viaf.org/viaf/19620875", r.getViafURI()); } @@ -73,8 +76,10 @@ public void differentIdentities() throws IOException { @Test public void searchWithNameSurname() throws IOException { - ISNIRecord r1 = ISNI.search("Martin", "Walter", "19.."); - ISNIRecord r2 = ISNI.search("Walter", "Martin", "19.."); + ISNIRecord r1 = ISNI.search("Martin", "Walter", null); + ISNIRecord r2 = ISNI.search("Walter", "Martin", null); + assert r1 != null; + assert r2 != null; assertNotEquals(r1.id, r2.id); } @@ -82,6 +87,7 @@ public void searchWithNameSurname() throws IOException { @Test public void beforeChrist() throws IOException { ISNIRecord r = ISNI.get("0000000123748095"); // Aristotle + assert r != null; assertEquals("-0384", r.getBirthYear()); assertEquals("-0322", r.getDeathYear()); } @@ -89,6 +95,7 @@ public void beforeChrist() throws IOException { @Test public void beforeAfterChrist() throws IOException { ISNIRecord r = ISNI.get("0000000120370699"); // Jesus Christ + assert r != null; assertEquals("-4", r.getBirthYear()); assertEquals("29", r.getDeathYear()); } @@ -136,6 +143,7 @@ public void unexistingPerson() throws IOException { public void writeAndLoad() throws IOException, JAXBException { ISNIRecord r = ISNI.get(MOZART_URI); String dst = "test/test.xml"; + assert r != null; r.save(dst); ISNIRecord s = ISNIRecord.fromFile(dst); assertEquals(r.uri, s.uri);