diff --git a/AoU-Admin/src/main/java/ch/unige/aou/business/LicenseService.java b/AoU-Admin/src/main/java/ch/unige/aou/business/LicenseService.java index 1323dd83186b462e0d07a0058e9d8ab9913c8865..1e911c2cd102d1815a1079b6b1cdb5ccd4413f44 100644 --- a/AoU-Admin/src/main/java/ch/unige/aou/business/LicenseService.java +++ b/AoU-Admin/src/main/java/ch/unige/aou/business/LicenseService.java @@ -26,6 +26,7 @@ package ch.unige.aou.business; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.List; import java.util.Optional; import org.slf4j.Logger; @@ -77,10 +78,28 @@ public class LicenseService extends AouResourceService<License> { return ((LicenseRepository) this.itemRepository).findByTitle(title); } - public License findByUrl(URL url) { + public List<License> findByUrl(URL url) { return ((LicenseRepository) this.itemRepository).findByUrl(url); } + public License findMoreSpecificLicenseByUrl(String licenseUrl) { + try { + List<License> licenses = this.findByUrl(new URL(licenseUrl)); + if (licenses.size() == 1) { + return licenses.get(0); + } else { + for (License license : licenses) { + if (Boolean.TRUE.equals(license.getVisible()) && !StringTool.isNullOrEmpty(license.getVersion())) { + return license; + } + } + } + } catch (MalformedURLException e) { + log.warn("Error in creating License URL from value {} ", licenseUrl); + } + return null; + } + @Override public LicenseSpecification getSpecification(License resource) { return new LicenseSpecification(resource); diff --git a/AoU-Admin/src/main/java/ch/unige/aou/repository/LicenseRepository.java b/AoU-Admin/src/main/java/ch/unige/aou/repository/LicenseRepository.java index e96a2b3bfe8459e9735903e65a4895d4ea7ffdb4..ea77740745d2579cb36e0a81dfeb73dd95fb369c 100644 --- a/AoU-Admin/src/main/java/ch/unige/aou/repository/LicenseRepository.java +++ b/AoU-Admin/src/main/java/ch/unige/aou/repository/LicenseRepository.java @@ -9,12 +9,12 @@ * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. @@ -24,6 +24,7 @@ package ch.unige.aou.repository; import java.net.URL; +import java.util.List; import java.util.Optional; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -44,7 +45,7 @@ public interface LicenseRepository extends SolidifyRepository<License> { License findByTitle(String title); - License findByUrl(URL url); + List<License> findByUrl(URL url); @Query(value = "SELECT max(sortValue) FROM License") Optional<Integer> findMaxSortValue(); diff --git a/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/DoiCrossrefImportService.java b/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/DoiCrossrefImportService.java index 433e70157942654d39054bd07d6bbd3651d08eb7..57a3c656d504653c96fcc2bab28a3be4b0e8202e 100644 --- a/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/DoiCrossrefImportService.java +++ b/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/DoiCrossrefImportService.java @@ -24,10 +24,8 @@ package ch.unige.aou.service.metadata.imports; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -103,9 +101,11 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { private static final String XPATH_JOURNAL_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/journal"; private static final String XPATH_CONFERENCE_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/conference"; private static final String XPATH_CHAPTER_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/book/content_item[@component_type=\"chapter\"]"; - private static final String XPATH_BOOK_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/book[@book_type=\"edited_book\"]"; + private static final String XPATH_BOOK_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/book"; private static final String XPATH_DISSERTATION = DoiCrossrefImportService.XPATH_CROSSREF + "/dissertation"; private static final String XPATH_PREPRINT_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/posted_content[@type=\"preprint\"]"; + private static final String XPATH_REPORT_NODE = DoiCrossrefImportService.XPATH_CROSSREF + "/report-paper"; + private static final String XPATH_LICENSE_NODE = "/program/license_ref"; private static final String[] FILE_URLS_TO_IMPORT = { @@ -151,11 +151,7 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { String licenceValue = this.getLicenceValue(crossrefDoc); License license = null; if (!StringTool.isNullOrEmpty(licenceValue)) { - try { - license = this.licenseService.findByUrl(new URL(licenceValue)); - } catch (MalformedURLException e) { - log.warn("Error in creating License URL from DoiCrossref : {} ", licenceValue); - } + license = this.licenseService.findMoreSpecificLicenseByUrl(licenceValue); } // Fill file metadata this.fillFile(depositDoc, crossrefDoc, license); @@ -240,11 +236,12 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { Node bookNode = (Node) xpath.compile(DoiCrossrefImportService.XPATH_BOOK_NODE).evaluate(crossrefDoc, XPathConstants.NODE); Node dissertationNode = (Node) xpath.compile(DoiCrossrefImportService.XPATH_DISSERTATION).evaluate(crossrefDoc, XPathConstants.NODE); Node preprintNode = (Node) xpath.compile(DoiCrossrefImportService.XPATH_PREPRINT_NODE).evaluate(crossrefDoc, XPathConstants.NODE); + Node reportNode = (Node) xpath.compile(DoiCrossrefImportService.XPATH_REPORT_NODE).evaluate(crossrefDoc, XPathConstants.NODE); if (journalNode != null) { this.fillJournalDepositDoc(depositDoc, crossrefDoc); } else if (conferenceNode != null) { - this.fillConferenceDepositDoc(depositDoc, crossrefDoc); + this.fillConferenceDepositDoc(depositDoc, crossrefDoc, doi); } else if (chapterNode != null) { this.fillChapterDepositDoc(depositDoc, crossrefDoc); } else if (bookNode != null) { @@ -253,6 +250,8 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { this.fillDissertationDepositDoc(depositDoc, crossrefDoc); } else if (preprintNode != null) { this.fillPreprintDepositDoc(depositDoc, crossrefDoc); + } else if (reportNode != null) { + this.fillReportDepositDoc(depositDoc, crossrefDoc); } // if the DOI fetched from metadata is different from the one used to retrieve metadata, replace it @@ -331,12 +330,26 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { // @formatter:on } - private void fillConferenceDepositDoc(DepositDoc depositDoc, Document crossrefDoc) { + private void fillConferenceDepositDoc(DepositDoc depositDoc, Document crossrefDoc, String doi) throws XPathExpressionException { String xpathRoot = DoiCrossrefImportService.XPATH_CONFERENCE_NODE; + final XPath xpath = XMLTool.buildXPath(); + Node conferencePaperNode = (Node) xpath.compile(xpathRoot + "/conference_paper").evaluate(crossrefDoc, XPathConstants.NODE); + + // Depending on what metadata are present, it may be a "Conference proceedings", a "Conference presentation" (aka conference paper) + // or a "Proceedings chapter" + // More than one section may be present, but the DOI used to import the document may indicate which one it is + String subtype = AouConstants.DEPOSIT_SUBTYPE_ACTES_DE_CONFERENCE_NAME; + if (conferencePaperNode != null) { + String value = XMLTool.getFirstTextContent(crossrefDoc, xpathRoot + "/conference_paper/doi_data/doi"); + if (doi.equals(value)) { + subtype = AouConstants.DEPOSIT_SUBTYPE_CHAPITRE_D_ACTES_NAME; + } + } + // @formatter:off depositDoc.setType(AouConstants.DEPOSIT_TYPE_CONFERENCE_ID); - depositDoc.setSubtype(AouConstants.DEPOSIT_SUBTYPE_ACTES_DE_CONFERENCE_NAME); + depositDoc.setSubtype(subtype); this.fillTitle(depositDoc, crossrefDoc, xpathRoot + "/conference_paper/titles/title[1]"); this.fillDoi(depositDoc, crossrefDoc, xpathRoot + "/conference_paper/doi_data/doi"); this.fillContainerTitle(depositDoc, crossrefDoc, xpathRoot + "/event_metadata/conference_name"); @@ -399,51 +412,55 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { private void fillBookDepositDoc(DepositDoc depositDoc, Document crossrefDoc) throws XPathExpressionException { final XPath xpath = XMLTool.buildXPath(); - String xpathRoot = DoiCrossrefImportService.XPATH_BOOK_NODE; - String xpathBookMetadata; - //There are three top levels in case of books: book_metadata, book_set_metadata, book_series_metadata(this case is cover in chapters). - Node bookMetadataNode = (Node) xpath.compile(DoiCrossrefImportService.XPATH_BOOK_NODE + "/book_metadata") - .evaluate(crossrefDoc, XPathConstants.NODE); - if (bookMetadataNode != null) { - xpathBookMetadata = "/book_metadata"; - } else { - xpathBookMetadata = "/book_set_metadata"; - } - // @formatter:off - depositDoc.setType(AouConstants.DEPOSIT_TYPE_LIVRE_ID); - depositDoc.setSubtype(AouConstants.DEPOSIT_SUBTYPE_LIVRE_NAME); - this.fillTitleAndSubtitle(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/titles/title", xpathRoot + xpathBookMetadata + "/titles/subtitle"); - this.fillDoi(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/doi_data/doi"); - this.fillPublicationDate(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/publication_date/year", - xpathRoot + xpathBookMetadata +"/publication_date/month", - xpathRoot + xpathBookMetadata +"/publication_date/day"); + String bookXpath = this.getBookXpath(crossrefDoc); + Node bookMetadataNode = (Node) xpath.compile(bookXpath).evaluate(crossrefDoc, XPathConstants.NODE); - this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/contributors/*[@contributor_role=\"author\"]", AuthorRole.AUTHOR); - this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/contributors/person_name[@contributor_role=\"editor\"]", AuthorRole.EDITOR); - this.fillIsbn(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata +"/isbn"); + if (bookMetadataNode != null) { + depositDoc.setType(AouConstants.DEPOSIT_TYPE_LIVRE_ID); + depositDoc.setSubtype(AouConstants.DEPOSIT_SUBTYPE_LIVRE_NAME); + this.fillTitleAndSubtitle(depositDoc, crossrefDoc, bookXpath + "/titles/title", bookXpath + "/titles/subtitle"); + this.fillDoi(depositDoc, crossrefDoc, bookXpath + "/doi_data/doi"); + this.fillPublicationDate(depositDoc, crossrefDoc, + bookXpath + "/publication_date/year", + bookXpath + "/publication_date/month", + bookXpath + "/publication_date/day"); + + this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, bookXpath + "/contributors/*[@contributor_role=\"author\"]", + AuthorRole.AUTHOR); + this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, bookXpath + "/contributors/person_name[@contributor_role=\"editor\"]", + AuthorRole.EDITOR); + if (depositDoc.getContributors() == null || depositDoc.getContributors().getContributorOrCollaboration().isEmpty()) { + this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, + bookXpath + "/set_metadata/contributors/*[@contributor_role=\"author\"]", AuthorRole.AUTHOR); + this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, + bookXpath + "/set_metadata/contributors/person_name[@contributor_role=\"editor\"]", AuthorRole.EDITOR); + } - if (depositDoc.getIdentifiers() == null || StringTool.isNullOrEmpty(depositDoc.getIdentifiers().getIsbn())) { - this.fillIsbn(depositDoc, crossrefDoc, xpathRoot + "/isbn[@media_type=\"print\"]"); - } - this.fillEdition(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/edition_number"); - this.fillCommercialUrl(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata +"/doi_data/resource"); + this.fillIsbn(depositDoc, crossrefDoc, bookXpath + "/isbn"); + if (depositDoc.getIdentifiers() == null || StringTool.isNullOrEmpty(depositDoc.getIdentifiers().getIsbn())) { + String xpathRoot = DoiCrossrefImportService.XPATH_BOOK_NODE; + this.fillIsbn(depositDoc, crossrefDoc, xpathRoot + "/isbn[@media_type=\"print\"]"); + } + this.fillEdition(depositDoc, crossrefDoc, bookXpath + "/edition_number"); + this.fillCommercialUrl(depositDoc, crossrefDoc, bookXpath + "/doi_data/resource"); - this.fillFirstOnlineDate(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata +"/publication_date[@media_type=\"online\"]/year", - xpathRoot + xpathBookMetadata +"/publication_date[@media_type=\"online\"]/month", - xpathRoot + xpathBookMetadata +"/publication_date[@media_type=\"online\"]/day"); + this.fillFirstOnlineDate(depositDoc, crossrefDoc, + bookXpath + "/publication_date[@media_type=\"online\"]/year", + bookXpath + "/publication_date[@media_type=\"online\"]/month", + bookXpath + "/publication_date[@media_type=\"online\"]/day"); - this.fillPublisherName(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata + "/publisher/publisher_name"); - this.fillPublisherPlace(depositDoc, crossrefDoc, xpathRoot + xpathBookMetadata +"/publisher/publisher_place"); - this.fillLanguages(depositDoc, crossrefDoc, List.of(xpathRoot + xpathBookMetadata + "/@language")); - // @formatter:on + this.fillPublisherName(depositDoc, crossrefDoc, bookXpath + "/publisher/publisher_name"); + this.fillPublisherPlace(depositDoc, crossrefDoc, bookXpath + "/publisher/publisher_place"); + this.fillLanguages(depositDoc, crossrefDoc, List.of(bookXpath + "/@language")); + } } private void fillDissertationDepositDoc(DepositDoc depositDoc, Document crossrefDoc) { String xpathRoot = DoiCrossrefImportService.XPATH_DISSERTATION; // @formatter:off - depositDoc.setType(AouConstants.DEPOSIT_TYPE_RAPPORT_NAME); + depositDoc.setType(AouConstants.DEPOSIT_TYPE_RAPPORT_ID); depositDoc.setSubtype(AouConstants.DEPOSIT_SUBTYPE_RAPPORT_DE_RECHERCHE_NAME); this.fillTitle(depositDoc, crossrefDoc, xpathRoot + "/titles/title"); this.fillDoi(depositDoc, crossrefDoc, xpathRoot + "/doi_data/doi"); @@ -454,6 +471,39 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { // @formatter:on } + private void fillReportDepositDoc(DepositDoc depositDoc, Document crossrefDoc) throws XPathExpressionException { + String reportXpath = this.getReportXpath(crossrefDoc); + + if (!StringTool.isNullOrEmpty(reportXpath)) { + depositDoc.setType(AouConstants.DEPOSIT_TYPE_RAPPORT_ID); + depositDoc.setSubtype(AouConstants.DEPOSIT_SUBTYPE_RAPPORT_DE_RECHERCHE_NAME); + this.fillTitleAndSubtitle(depositDoc, crossrefDoc, reportXpath + "/titles/title", reportXpath + "/titles/subtitle"); + this.fillDoi(depositDoc, crossrefDoc, reportXpath + "/doi_data/doi"); + this.fillAbstracts(depositDoc, crossrefDoc, reportXpath + "/abstract", reportXpath + "/abstract/@lang"); + + this.fillPublicationDate(depositDoc, crossrefDoc, + reportXpath + "/publication_date/year", + reportXpath + "/publication_date/month", + reportXpath + "/publication_date/day"); + this.fillFirstOnlineDate(depositDoc, crossrefDoc, + reportXpath + "/publication_date[@media_type=\"online\"]/year", + reportXpath + "/publication_date[@media_type=\"online\"]/month", + reportXpath + "/publication_date[@media_type=\"online\"]/day"); + + this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, reportXpath + "/contributors/*[@contributor_role=\"author\"]", + AuthorRole.AUTHOR); + this.fillContributorsAndCollaborations(depositDoc, crossrefDoc, reportXpath + "/contributors/person_name[@contributor_role=\"editor\"]", + AuthorRole.EDITOR); + + this.fillEdition(depositDoc, crossrefDoc, reportXpath + "/edition_number"); + this.fillCommercialUrl(depositDoc, crossrefDoc, reportXpath + "/doi_data/resource"); + + this.fillPublisherName(depositDoc, crossrefDoc, reportXpath + "/publisher/publisher_name"); + this.fillPublisherPlace(depositDoc, crossrefDoc, reportXpath + "/publisher/publisher_place"); + this.fillLanguages(depositDoc, crossrefDoc, List.of(reportXpath + "/@language")); + } + } + /****************************************************************************************/ private void fillLanguages(DepositDoc depositDoc, Document crossrefDoc, List<String> xpathQueries) { @@ -745,7 +795,7 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { @SuppressWarnings("java:S2259") // fileUrl.lastIndexOf('/') cannot throw an NPE because fileUrl is checked by the method isNullOrEmpty - // this false positive should be remove when https://jira.sonarsource.com/browse/SONARJAVA-3502 will be solved + // this false positive should be removed when https://jira.sonarsource.com/browse/SONARJAVA-3502 will be solved private void fillFile(DepositDoc depositDoc, Document crossrefDoc, License license) { String fileUrl = this.getFileUrlByDocumentType(crossrefDoc); if (!StringTool.isNullOrEmpty(fileUrl)) { @@ -755,6 +805,16 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { // if not, REPORT->PREPRINT. if (this.isJournalRefPresent(crossrefDoc)) { file.setType(FileType.ARTICLE_PUBLISHED_VERSION); + } else if (depositDoc.getType().equals(AouConstants.DEPOSIT_TYPE_LIVRE_NAME)) { + file.setType(FileType.BOOK_PUBLISHED_VERSION); + } else if (depositDoc.getType().equals(AouConstants.DEPOSIT_TYPE_CONFERENCE_NAME)) { + if (depositDoc.getSubtype().equals(AouConstants.DEPOSIT_SUBTYPE_CHAPITRE_D_ACTES_NAME)) { + file.setType(FileType.PROCEEDINGS_CHAPTER_PUBLISHED_VERSION); + } else { + file.setType(FileType.PROCEEDINGS_ACCEPTED_VERSION); + } + } else if (depositDoc.getType().equals(AouConstants.DEPOSIT_TYPE_RAPPORT_NAME)) { + file.setType(FileType.REPORT); } else { file.setType(FileType.PREPRINT); } @@ -814,7 +874,10 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { } else if (chapterNode != null) { return "/book[@book_type=\"other\"]/content_item"; } else if (bookNode != null) { - return "/book[@book_type=\"edited_book\"]/book_metadata"; + String bookXpath = this.getBookXpath(crossrefDoc); + if (!StringTool.isNullOrEmpty(bookXpath)) { + return bookXpath.replace(DoiCrossrefImportService.XPATH_CROSSREF, ""); + } } else if (dissertationNode != null) { return "/dissertation"; } @@ -829,10 +892,26 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { return !StringTool.isNullOrEmpty(value); } - private Contributor createContributorFromNode(Node authors, AuthorRole role) { + private Contributor createContributorFromNode(Node authors, AuthorRole role) throws XPathExpressionException { String surname = XMLTool.getFirstTextContent(authors, "./surname"); String givenName = XMLTool.getFirstTextContent(authors, "./given_name"); - String institution = XMLTool.getFirstTextContent(authors, "./affiliation"); + String affiliation = XMLTool.getFirstTextContent(authors, "./affiliation"); + + // If affiliation name doesn't exist, look for eventual ROR ID + if (StringTool.isNullOrEmpty(affiliation)) { + // Try to find institution + XPath xpath = XMLTool.buildXPath(); + NodeList rorIdNodes = (NodeList) xpath.compile("./affiliations/institution/institution_id[@type='ror']") + .evaluate(authors, XPathConstants.NODESET); + for (int i = 0; i < rorIdNodes.getLength(); i++) { + Node rorIdNode = rorIdNodes.item(i); + if (AouConstants.UNIVERSITY_OF_GENEVA_ROR_ID.equals(rorIdNode.getTextContent())) { + affiliation = AouConstants.UNIVERSITY_OF_GENEVA_FR; + } else if (AouConstants.HUG_ROR_ID.equals(rorIdNode.getTextContent())) { + affiliation = AouConstants.HUG_FR; + } + } + } surname = this.getNameOrUndefinedValue(surname); givenName = this.getNameOrUndefinedValue(givenName); @@ -842,7 +921,7 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { Contributor contributor = new Contributor(); contributor.setLastname(CleanTool.capitalizeString(surname)); contributor.setFirstname(CleanTool.capitalizeString(givenName)); - contributor.setInstitution(institution); + contributor.setInstitution(affiliation); contributor.setRole(role); orcid = this.cleanOrcid(orcid); if (!StringTool.isNullOrEmpty(orcid)) { @@ -851,4 +930,37 @@ public class DoiCrossrefImportService extends MetadataAndFileImportService { return contributor; } + /** + * There are three possible top levels nodes in case of books: book_metadata, book_set_metadata, book_series_metadata. + * + * @param crossrefDoc + * @return + */ + private String getBookXpath(Document crossrefDoc) { + return this.getValidXpath(crossrefDoc, List.of( + DoiCrossrefImportService.XPATH_BOOK_NODE + "/book_metadata", + DoiCrossrefImportService.XPATH_BOOK_NODE + "/book_set_metadata", + DoiCrossrefImportService.XPATH_BOOK_NODE + "/book_series_metadata")); + } + + private String getReportXpath(Document crossrefDoc) { + return this.getValidXpath(crossrefDoc, List.of( + DoiCrossrefImportService.XPATH_REPORT_NODE + "/report-paper_metadata", + DoiCrossrefImportService.XPATH_REPORT_NODE + "/report-paper_series_metadata")); + } + + private String getValidXpath(Document crossrefDoc, List<String> xpathsToCheck) { + try { + final XPath xpath = XMLTool.buildXPath(); + for (String xpathToCheck : xpathsToCheck) { + Node bookMetadataNode = (Node) xpath.compile(xpathToCheck).evaluate(crossrefDoc, XPathConstants.NODE); + if (bookMetadataNode != null) { + return xpathToCheck; + } + } + return null; + } catch (XPathExpressionException e) { + return null; + } + } } diff --git a/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/InspireHepImportService.java b/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/InspireHepImportService.java index cf90479564e40da748ddd067fc03769fba697f8f..d2f737662ba1c8a4671f4410fa69c14adf294340 100644 --- a/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/InspireHepImportService.java +++ b/AoU-Admin/src/main/java/ch/unige/aou/service/metadata/imports/InspireHepImportService.java @@ -23,10 +23,8 @@ package ch.unige.aou.service.metadata.imports; -import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -297,7 +295,7 @@ public class InspireHepImportService extends MetadataAndFileImportService { this.ensureContributorsExist(depositDoc); for (int i = 0; i < jsonArray.length(); i++) { Collaboration collaboration = new Collaboration(); - collaboration.setName(this.getStringOrNull(jsonArray.getJSONObject(i),"value")); + collaboration.setName(this.getStringOrNull(jsonArray.getJSONObject(i), "value")); depositDoc.getContributors().getContributorOrCollaboration().add(collaboration); } } @@ -416,11 +414,7 @@ public class InspireHepImportService extends MetadataAndFileImportService { String licenceValue = this.getLicense(this.getArrayOrNull(metadata, "license")); License license = null; if (!StringTool.isNullOrEmpty(licenceValue)) { - try { - license = this.licenseService.findByUrl(new URL(licenceValue)); - } catch (MalformedURLException e) { - log.warn("Error in creating License URL from InspireHep : {} ", licenceValue); - } + license = this.licenseService.findMoreSpecificLicenseByUrl(licenceValue); } //Fill file metadata this.fillFile(depositDoc, this.getArrayOrNull(metadata, "urls"), fileType, license); diff --git a/AoU-Admin/src/test/java/ch/unige/aou/test/DoiCrossrefImportServiceTest.java b/AoU-Admin/src/test/java/ch/unige/aou/test/DoiCrossrefImportServiceTest.java index 3e213893b4cb0bc01b3230a55b30ba11a49a9b0c..9ffcdaecc9c744808a7b4f55d454826078732cb4 100644 --- a/AoU-Admin/src/test/java/ch/unige/aou/test/DoiCrossrefImportServiceTest.java +++ b/AoU-Admin/src/test/java/ch/unige/aou/test/DoiCrossrefImportServiceTest.java @@ -26,12 +26,12 @@ package ch.unige.aou.test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; import java.io.InputStream; - import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; @@ -58,6 +58,7 @@ import ch.unige.aou.business.DocumentFileService; import ch.unige.aou.business.DocumentFileTypeService; import ch.unige.aou.business.LicenseService; import ch.unige.aou.config.AouProperties; +import ch.unige.aou.model.xml.deposit.v2_4.AuthorRole; import ch.unige.aou.model.xml.deposit.v2_4.Contributor; import ch.unige.aou.model.xml.deposit.v2_4.DateTypes; import ch.unige.aou.model.xml.deposit.v2_4.DepositDoc; @@ -70,8 +71,14 @@ import ch.unige.aou.service.rest.OpenAireService; @ExtendWith(SpringExtension.class) class DoiCrossrefImportServiceTest { - private static final String CROSSREFF_XML_METADATA_FILE = "test-crossref-response.xml"; - private static final String TEST_DOI = "10.1126/science.1175088"; + private static final String CROSSREF_XML_ARTICLE_METADATA_FILE = "test-crossref-article-response.xml"; + private static final String ARTICLE_DOI = "10.1126/science.1175088"; + private static final String CROSSREF_XML_PROCEEDINGS_CHAPTER_METADATA_FILE = "test-crossref-proceedings-chapter-response.xml"; + private static final String PROCEEDINGS_CHAPTER_DOI = "10.1145/3552327.3552332"; + private static final String CROSSREF_XML_BOOK_METADATA_FILE = "test-crossref-book-response.xml"; + private static final String BOOK_DOI = "10.1007/978-3-030-94212-0"; + private static final String CROSSREF_XML_REPORT_METADATA_FILE = "test-crossref-report-response.xml"; + private static final String REPORT_DOI = "10.57071/948rpn"; private DoiCrossrefImportService doiCrossrefImportService; @@ -108,13 +115,15 @@ class DoiCrossrefImportServiceTest { } @Test - void fillDepositDocTest() { + void fillArticleDepositDocTest() { try { - Document crossrefDoc = XMLTool.parseXML(this.getCrossrefXmlMetadata()); + Document crossrefDoc = XMLTool.parseXML(this.getCrossrefXmlMetadata(CROSSREF_XML_ARTICLE_METADATA_FILE)); DepositDoc depositDoc = new DepositDoc(); - this.doiCrossrefImportService.fillDepositDoc(TEST_DOI, depositDoc, crossrefDoc); + this.doiCrossrefImportService.fillDepositDoc(ARTICLE_DOI, depositDoc, crossrefDoc); + assertEquals(AouConstants.DEPOSIT_TYPE_ARTICLE_ID, depositDoc.getType()); + assertEquals(AouConstants.DEPOSIT_SUBTYPE_ARTICLE_SCIENTIFIQUE_NAME, depositDoc.getSubtype()); assertEquals("An ER-Mitochondria Tethering Complex Revealed by a Synthetic Biology Screen", depositDoc.getTitle().getContent()); assertEquals(AouConstants.LANG_CODE_ENGLISH, depositDoc.getTitle().getLang()); assertEquals(AouConstants.LANG_CODE_ENGLISH, depositDoc.getLanguages().getLanguage().get(0)); @@ -133,7 +142,7 @@ class DoiCrossrefImportServiceTest { assertEquals("Benoît", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getFirstname()); assertTrue(depositDoc.getPages().getPagingOrOther().get(0).getName().toString().contains("paging")); assertEquals("477-481", depositDoc.getPages().getPagingOrOther().get(0).getValue()); - assertEquals(TEST_DOI, depositDoc.getIdentifiers().getDoi()); + assertEquals(ARTICLE_DOI, depositDoc.getIdentifiers().getDoi()); assertEquals("0036-8075", depositDoc.getIdentifiers().getIssn()); assertEquals("https://www.sciencemag.org/lookup/doi/10.1126/science.1175088", depositDoc.getPublisherVersionUrl()); assertEquals("Science", depositDoc.getContainer().getTitle()); @@ -141,15 +150,146 @@ class DoiCrossrefImportServiceTest { assertEquals("5939", depositDoc.getContainer().getIssue().toString()); } catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException e) { - throw new SolidifyRuntimeException("An error occurred when searching DOI '" + TEST_DOI + "' on Crossref", e); + throw new SolidifyRuntimeException("An error occurred when searching DOI '" + ARTICLE_DOI + "' on Crossref", e); + } + } + + @Test + void fillProceedingsChapterDepositDocTest() { + + try { + Document crossrefDoc = XMLTool.parseXML(this.getCrossrefXmlMetadata(CROSSREF_XML_PROCEEDINGS_CHAPTER_METADATA_FILE)); + DepositDoc depositDoc = new DepositDoc(); + this.doiCrossrefImportService.fillDepositDoc(PROCEEDINGS_CHAPTER_DOI, depositDoc, crossrefDoc); + + assertEquals(AouConstants.DEPOSIT_TYPE_CONFERENCE_ID, depositDoc.getType()); + assertEquals(AouConstants.DEPOSIT_SUBTYPE_CHAPITRE_D_ACTES_NAME, depositDoc.getSubtype()); + assertEquals("Analyzing the challenges of an assistive application’ integration", depositDoc.getTitle().getContent()); + assertEquals(AouConstants.LANG_CODE_ENGLISH, depositDoc.getTitle().getLang()); + assertEquals(AouConstants.LANG_CODE_ENGLISH, depositDoc.getLanguages().getLanguage().get(0)); + assertNotNull(depositDoc.getDates()); + assertNotNull(depositDoc.getDates().getDate()); + assertFalse(depositDoc.getDates().getDate().isEmpty()); + assertEquals("2022-10-04", depositDoc.getDates().getDate().get(0).getContent()); + assertEquals(DateTypes.FIRST_ONLINE, depositDoc.getDates().getDate().get(0).getType()); + assertEquals("2022-10-04", depositDoc.getDates().getDate().get(1).getContent()); + assertEquals(DateTypes.PUBLICATION, depositDoc.getDates().getDate().get(1).getType()); + + assertNotNull(depositDoc.getContributors()); + assertNotNull(depositDoc.getContributors().getContributorOrCollaboration()); + assertEquals(5, depositDoc.getContributors().getContributorOrCollaboration().size()); + assertTrue(depositDoc.getContributors().getContributorOrCollaboration().get(0) instanceof Contributor); + assertEquals("Larribau", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(3)).getLastname()); + assertEquals("Robert", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(3)).getFirstname()); + assertEquals(AuthorRole.AUTHOR, ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(3)).getRole()); + assertEquals("Hôpitaux Universitaires de Genève, Switzerland", + ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(3)).getInstitution()); + + assertEquals(PROCEEDINGS_CHAPTER_DOI, depositDoc.getIdentifiers().getDoi()); + assertEquals("https://dl.acm.org/doi/10.1145/3552327.3552332", depositDoc.getPublisherVersionUrl()); + assertEquals("ECCE 2022: 33rd European Conference on Cognitive Ergonomics", depositDoc.getContainer().getTitle()); + assertEquals(1, depositDoc.getPublisher().getNameOrPlace().size()); + assertEquals("ACM", depositDoc.getPublisher().getNameOrPlace().get(0).getValue()); + assertEquals("04 10 2022 07 10 2022", depositDoc.getContainer().getConferenceDate()); + assertEquals("Kaiserslautern Germany", depositDoc.getContainer().getConferencePlace()); + + } catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException e) { + throw new SolidifyRuntimeException("An error occurred when searching DOI '" + PROCEEDINGS_CHAPTER_DOI + "' on Crossref", e); + } + } + + @Test + void fillBookDepositDocTest() { + + try { + Document crossrefDoc = XMLTool.parseXML(this.getCrossrefXmlMetadata(CROSSREF_XML_BOOK_METADATA_FILE)); + DepositDoc depositDoc = new DepositDoc(); + this.doiCrossrefImportService.fillDepositDoc(BOOK_DOI, depositDoc, crossrefDoc); + + assertEquals(AouConstants.DEPOSIT_TYPE_LIVRE_ID, depositDoc.getType()); + assertEquals(AouConstants.DEPOSIT_SUBTYPE_LIVRE_NAME, depositDoc.getSubtype()); + + assertEquals("Quantifying Quality of Life: Incorporating Daily Life into Medicine", depositDoc.getTitle().getContent()); + assertEquals(AouConstants.LANG_CODE_ENGLISH, depositDoc.getTitle().getLang()); + assertEquals(AouConstants.LANG_CODE_ENGLISH, depositDoc.getLanguages().getLanguage().get(0)); + + assertNotNull(depositDoc.getDates()); + assertNotNull(depositDoc.getDates().getDate()); + assertFalse(depositDoc.getDates().getDate().isEmpty()); + assertEquals("2022", depositDoc.getDates().getDate().get(0).getContent()); + assertEquals(DateTypes.PUBLICATION, depositDoc.getDates().getDate().get(0).getType()); + + assertNotNull(depositDoc.getContributors()); + assertNotNull(depositDoc.getContributors().getContributorOrCollaboration()); + assertEquals(2, depositDoc.getContributors().getContributorOrCollaboration().size()); + assertTrue(depositDoc.getContributors().getContributorOrCollaboration().get(0) instanceof Contributor); + assertEquals("Wac", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getLastname()); + assertEquals("Katarzyna", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getFirstname()); + assertEquals(AuthorRole.EDITOR, ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getRole()); + + assertEquals(BOOK_DOI, depositDoc.getIdentifiers().getDoi()); + assertEquals("978-3-030-94211-3", depositDoc.getIdentifiers().getIsbn()); + assertEquals("https://link.springer.com/10.1007/978-3-030-94212-0", depositDoc.getPublisherVersionUrl()); + assertEquals(2, depositDoc.getPublisher().getNameOrPlace().size()); + assertEquals("Springer International Publishing", depositDoc.getPublisher().getNameOrPlace().get(0).getValue()); + assertEquals("Cham", depositDoc.getPublisher().getNameOrPlace().get(1).getValue()); + + } catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException e) { + throw new SolidifyRuntimeException("An error occurred when searching DOI '" + PROCEEDINGS_CHAPTER_DOI + "' on Crossref", e); + } + } + + @Test + void fillReportDepositDocTest() { + + try { + Document crossrefDoc = XMLTool.parseXML(this.getCrossrefXmlMetadata(CROSSREF_XML_REPORT_METADATA_FILE)); + DepositDoc depositDoc = new DepositDoc(); + this.doiCrossrefImportService.fillDepositDoc(REPORT_DOI, depositDoc, crossrefDoc); + + assertEquals(AouConstants.DEPOSIT_TYPE_RAPPORT_ID, depositDoc.getType()); + assertEquals(AouConstants.DEPOSIT_SUBTYPE_RAPPORT_DE_RECHERCHE_NAME, depositDoc.getSubtype()); + + assertEquals("Proactivité et réactivité: deux orientations pour concevoir des dispositifs visant le développement", + depositDoc.getTitle().getContent()); + assertNull(depositDoc.getTitle().getLang()); + assertNull(depositDoc.getLanguages()); + + assertNotNull(depositDoc.getDates()); + assertNotNull(depositDoc.getDates().getDate()); + assertFalse(depositDoc.getDates().getDate().isEmpty()); + assertEquals("2021-02-08", depositDoc.getDates().getDate().get(0).getContent()); + assertEquals(DateTypes.PUBLICATION, depositDoc.getDates().getDate().get(0).getType()); + + assertNotNull(depositDoc.getContributors()); + assertNotNull(depositDoc.getContributors().getContributorOrCollaboration()); + assertEquals(3, depositDoc.getContributors().getContributorOrCollaboration().size()); + assertTrue(depositDoc.getContributors().getContributorOrCollaboration().get(0) instanceof Contributor); + assertEquals("Flandin", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getLastname()); + assertEquals("Simon", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getFirstname()); + assertEquals(AuthorRole.AUTHOR, ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getRole()); + assertEquals("0000-0002-6332-1499", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(0)).getOrcid()); + assertEquals("Poizat", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(1)).getLastname()); + assertEquals("Germain", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(1)).getFirstname()); + assertEquals(AuthorRole.AUTHOR, ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(1)).getRole()); + assertEquals("0000-0002-6560-3342", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(1)).getOrcid()); + assertEquals("Université de Genève", ((Contributor) depositDoc.getContributors().getContributorOrCollaboration().get(1)).getInstitution()); + + assertEquals(REPORT_DOI, depositDoc.getIdentifiers().getDoi()); + assertEquals("https://www.foncsi.org/fr/publications/cahiers-securite-industrielle", depositDoc.getPublisherVersionUrl()); + assertEquals(1, depositDoc.getPublisher().getNameOrPlace().size()); + assertEquals("Fondation pour une culture de sécurité industrielle", depositDoc.getPublisher().getNameOrPlace().get(0).getValue()); + + } catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException e) { + throw new SolidifyRuntimeException("An error occurred when searching DOI '" + PROCEEDINGS_CHAPTER_DOI + "' on Crossref", e); } } - private String getCrossrefXmlMetadata() { - try (InputStream jsonStream = new ClassPathResource(CROSSREFF_XML_METADATA_FILE).getInputStream()) { + private String getCrossrefXmlMetadata(String fileName) { + try (InputStream jsonStream = new ClassPathResource(fileName).getInputStream()) { return FileTool.toString(jsonStream); } catch (IOException e) { - fail("Unable to read " + CROSSREFF_XML_METADATA_FILE + ": " + e.getMessage()); + fail("Unable to read " + CROSSREF_XML_ARTICLE_METADATA_FILE + ": " + e.getMessage()); return null; } } diff --git a/AoU-Admin/src/test/resources/test-crossref-response.xml b/AoU-Admin/src/test/resources/test-crossref-article-response.xml similarity index 100% rename from AoU-Admin/src/test/resources/test-crossref-response.xml rename to AoU-Admin/src/test/resources/test-crossref-article-response.xml diff --git a/AoU-Admin/src/test/resources/test-crossref-book-response.xml b/AoU-Admin/src/test/resources/test-crossref-book-response.xml new file mode 100644 index 0000000000000000000000000000000000000000..d21170adbe4d08a349e863a452a6d1181c9edf06 --- /dev/null +++ b/AoU-Admin/src/test/resources/test-crossref-book-response.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<doi_records> + <doi_record owner="10.1007" timestamp="2022-10-25 02:06:07"> + <crossref> + <book book_type="other"> + <book_series_metadata language="en"> + <series_metadata> + <titles> + <title>Health Informatics</title> + </titles> + <issn media_type="print">1431-1917</issn> + <issn media_type="electronic">2197-3741</issn> + </series_metadata> + <contributors> + <person_name contributor_role="editor" sequence="first"> + <given_name>Katarzyna</given_name> + <surname>Wac</surname> + </person_name> + <person_name contributor_role="editor" sequence="additional"> + <given_name>Sharon</given_name> + <surname>Wulfovich</surname> + </person_name> + </contributors> + <titles> + <title>Quantifying Quality of Life</title> + <subtitle>Incorporating Daily Life into Medicine</subtitle> + </titles> + <publication_date media_type="print"> + <year>2022</year> + </publication_date> + <isbn media_type="print">978-3-030-94211-3</isbn> + <isbn media_type="electronic">978-3-030-94212-0</isbn> + <publisher> + <publisher_name>Springer International Publishing</publisher_name> + <publisher_place>Cham</publisher_place> + </publisher> + <program name="AccessIndicators"> + <license_ref applies_to="tdm">https://creativecommons.org/licenses/by/4.0</license_ref> + <license_ref applies_to="vor" start_date="2022-04-14">https://creativecommons.org/licenses/by/4.0</license_ref> + </program> + <doi_data> + <doi>10.1007/978-3-030-94212-0</doi> + <resource>https://link.springer.com/10.1007/978-3-030-94212-0</resource> + <collection property="crawler-based"> + <item crawler="iParadigms"> + <resource>https://link.springer.com/content/pdf/10.1007/978-3-030-94212-0</resource> + </item> + </collection> + <collection property="text-mining"> + <item> + <resource mime_type="application/pdf">https://link.springer.com/content/pdf/10.1007/978-3-030-94212-0.pdf + </resource> + </item> + </collection> + </doi_data> + </book_series_metadata> + </book> + </crossref> + </doi_record> +</doi_records> \ No newline at end of file diff --git a/AoU-Admin/src/test/resources/test-crossref-proceedings-chapter-response.xml b/AoU-Admin/src/test/resources/test-crossref-proceedings-chapter-response.xml new file mode 100644 index 0000000000000000000000000000000000000000..f33091a38488164c20cbe5415cba5e5f7c1be10d --- /dev/null +++ b/AoU-Admin/src/test/resources/test-crossref-proceedings-chapter-response.xml @@ -0,0 +1,383 @@ +<?xml version="1.0" encoding="UTF-8"?> +<doi_records> + <doi_record owner="10.1145" timestamp="2023-11-30 16:41:19"> + <crossref> + <conference> + <contributors> + <person_name contributor_role="editor" sequence="first"> + <given_name>Achim</given_name> + <surname>Ebert</surname> + </person_name> + <person_name contributor_role="editor" sequence="additional"> + <given_name>Thomas</given_name> + <surname>Lachmann</surname> + </person_name> + <person_name contributor_role="editor" sequence="additional"> + <given_name>Klaus</given_name> + <surname>Dreßler</surname> + </person_name> + <person_name contributor_role="editor" sequence="additional"> + <given_name>Jessica</given_name> + <surname>Lindblom</surname> + </person_name> + <person_name contributor_role="editor" sequence="additional"> + <given_name>René</given_name> + <surname>Reinhard</surname> + </person_name> + </contributors> + <event_metadata> + <conference_name>ECCE 2022: 33rd European Conference on Cognitive Ergonomics</conference_name> + <conference_acronym>ECCE 2022</conference_acronym> + <conference_location>Kaiserslautern Germany</conference_location> + <conference_date>04 10 2022 07 10 2022</conference_date> + </event_metadata> + <proceedings_metadata language="en"> + <proceedings_title>Proceedings of the 33rd European Conference on Cognitive Ergonomics</proceedings_title> + <publisher> + <publisher_name>ACM</publisher_name> + <publisher_place>New York, NY, USA</publisher_place> + </publisher> + <publication_date media_type="print"> + <month>10</month> + <day>04</day> + <year>2022</year> + </publication_date> + <publication_date media_type="online"> + <month>10</month> + <day>04</day> + <year>2022</year> + </publication_date> + <isbn media_type="print">9781450398084</isbn> + <publisher_item> + <identifier id_type="doi">10.1145/3552327</identifier> + </publisher_item> + <doi_data> + <doi>10.1145/3552327</doi> + <timestamp>2023113018335800081</timestamp> + <resource>https://dl.acm.org/doi/proceedings/10.1145/3552327</resource> + <collection property="crawler-based"> + <item crawler="iParadigms"> + <resource>https://dl.acm.org/doi/pdf/10.1145/3552327</resource> + </item> + </collection> + </doi_data> + </proceedings_metadata> + <conference_paper publication_type="full_text" language="en"> + <contributors> + <person_name contributor_role="author" sequence="first"> + <given_name>OphéLie</given_name> + <surname>Morand</surname> + <affiliation>Télécom Paris, France</affiliation> + </person_name> + <person_name contributor_role="author" sequence="additional"> + <given_name>Stéphane</given_name> + <surname>Safin</surname> + <affiliation>Télécom Paris, France</affiliation> + </person_name> + <person_name contributor_role="author" sequence="additional"> + <given_name>Caroline</given_name> + <surname>Rizza</surname> + <affiliation>I3 (UMR 9217) CNRS. Telecom Paris. Institut Polytechnique de Paris, France</affiliation> + </person_name> + <person_name contributor_role="author" sequence="additional"> + <given_name>Robert</given_name> + <surname>Larribau</surname> + <affiliation>Hôpitaux Universitaires de Genève, Switzerland</affiliation> + </person_name> + <person_name contributor_role="author" sequence="additional"> + <given_name>Romain</given_name> + <surname>Pages</surname> + <affiliation>SARA 112, Reunion</affiliation> + </person_name> + </contributors> + <titles> + <title>Analyzing the challenges of an assistive application’ integration</title> + </titles> + <publication_date media_type="print"> + <month>10</month> + <day>04</day> + <year>2022</year> + </publication_date> + <publication_date media_type="online"> + <month>10</month> + <day>04</day> + <year>2022</year> + </publication_date> + <pages> + <first_page>1</first_page> + <last_page>9</last_page> + </pages> + <publisher_item> + <identifier id_type="doi">10.1145/3552327.3552332</identifier> + </publisher_item> + <crossmark> + <crossmark_version>2</crossmark_version> + <crossmark_policy>10.1145/crossmark-policy</crossmark_policy> + <crossmark_domains> + <crossmark_domain> + <domain>dl.acm.org</domain> + </crossmark_domain> + </crossmark_domains> + <crossmark_domain_exclusive>true</crossmark_domain_exclusive> + <custom_metadata> + <assertion group_label="Publication History" group_name="publication_history" label="Published" name="published" + order="2">2022-10-04 + </assertion> + </custom_metadata> + </crossmark> + <doi_data> + <doi>10.1145/3552327.3552332</doi> + <timestamp>2023113018335800081</timestamp> + <resource>https://dl.acm.org/doi/10.1145/3552327.3552332</resource> + <collection property="crawler-based"> + <item crawler="iParadigms"> + <resource>https://dl.acm.org/doi/pdf/10.1145/3552327.3552332</resource> + </item> + </collection> + </doi_data> + <citation_list> + <citation key="e_1_3_2_1_1_1"> + <doi>10.1186/s13054-020-2773-2</doi> + </citation> + <citation key="e_1_3_2_1_2_1"> + <doi>10.1016/j.resuscitation.2019.12.042</doi> + </citation> + <citation key="e_1_3_2_1_3_1"> + <doi>10.1161/CIR.0000000000000428</doi> + </citation> + <citation key="e_1_3_2_1_4_1"> + <doi>10.1016/j.resuscitation.2021.06.021</doi> + </citation> + <citation key="e_1_3_2_1_5_1"> + <doi>10.1016/j.resuscitation.2021.02.017</doi> + </citation> + <citation key="e_1_3_2_1_6_1"> + <doi>10.1016/j.resuscitation.2020.10.035</doi> + </citation> + <citation key="e_1_3_2_1_7_1"> + <doi>10.1161/CIR.0000000000000757</doi> + </citation> + <citation key="e_1_3_2_1_8_1"> + <doi>10.1016/j.resuscitation.2015.07.015</doi> + </citation> + <citation key="e_1_3_2_1_9_1"> + <doi provider="crossref">10.1016/j.cageo.2018.06.002</doi> + <unstructured_citation>Marc van den Homberg Robert Monné and Marco Spruit. 2018. Bridging the information gap of + disaster responders by optimizing data selection using cost and quality. Computers & geosciences 120 (2018) + 60–72. Marc van den Homberg Robert Monné and Marco Spruit. 2018. Bridging the information gap of disaster + responders by optimizing data selection using cost and quality. Computers & geosciences 120 (2018) 60–72. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_10_1"> + <doi>10.1007/s10796-009-9174-z</doi> + </citation> + <citation key="e_1_3_2_1_11_1"> + <volume_title>Large-scale coordination in emergency response</volume_title> + <author>Militello Laura G</author> + <unstructured_citation>Laura G Militello , Emily S Patterson , Robert Wears , and Jill A Ritter . 2005. Large-scale + coordination in emergency response . SAGE Publications Sage CA : Los Angeles, CA , 534–538. Laura G Militello, + Emily S Patterson, Robert Wears, and Jill A Ritter. 2005. Large-scale coordination in emergency response. SAGE + Publications Sage CA: Los Angeles, CA, 534–538. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_12_1"> + <journal_title>Interacting with Computers</journal_title> + <author>Sarcevic Aleksandra</author> + <first_page>203</first_page> + <volume>29</volume> + <cYear>2017</cYear> + <article_title>On the use of electronic documentation systems in fast-paced, time-critical medical settings + </article_title> + <unstructured_citation>Aleksandra Sarcevic and Nicole Ferraro . 2017 . On the use of electronic documentation systems + in fast-paced, time-critical medical settings . Interacting with Computers 29 , 2 (2017), 203 – 219 Aleksandra + Sarcevic and Nicole Ferraro. 2017. On the use of electronic documentation systems in fast-paced, time-critical + medical settings. Interacting with Computers 29, 2 (2017), 203–219 + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_13_1"> + <doi>10.1504/IJHTM.2005.007008</doi> + </citation> + <citation key="e_1_3_2_1_14_1"> + <doi provider="crossref">10.1518/001872095779049543</doi> + <unstructured_citation>Mica MR Endsley. 1995. Toward a theory of situation awareness in dynamic systems. human + factors 37 (1) 32-64. (1995). Mica MR Endsley. 1995. Toward a theory of situation awareness in dynamic systems. + human factors 37 (1) 32-64. (1995). + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_15_1"> + <doi>10.1177/1555343415572631</doi> + </citation> + <citation key="e_1_3_2_1_16_1"> + <unstructured_citation>Martha Bird Louise Hansen and Massimo Lanfranco. 2020. New ways of volunteering. Challenges + and opportunities. A working paper and toolbox for care and support for spontaneous unafilliated volunteers. + Martha Bird Louise Hansen and Massimo Lanfranco. 2020. New ways of volunteering. Challenges and opportunities. A + working paper and toolbox for care and support for spontaneous unafilliated volunteers. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_17_1"> + <volume_title>Dr Joshua Whittaker, and Professor John Handmer</volume_title> + <author>McLennan Blythe</author> + <cYear>2016</cYear> + <unstructured_citation>Blythe McLennan , Julie Molloy , Dr Joshua Whittaker, and Professor John Handmer . 2016 . + Centralised coordination of spontaneous emergency volunteers: the EV CREW model. 31, 1 (2016), 8. Blythe + McLennan, Julie Molloy, Dr Joshua Whittaker, and Professor John Handmer. 2016. Centralised coordination of + spontaneous emergency volunteers: the EV CREW model. 31, 1 (2016), 8. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_18_1"> + <doi>10.1016/j.ijhcs.2016.03.005</doi> + </citation> + <citation key="e_1_3_2_1_19_1"> + <doi>10.1016/j.resuscitation.2016.02.014</doi> + </citation> + <citation key="e_1_3_2_1_20_1"> + <journal_title>Nature Reviews Cardiology</journal_title> + <author>Berg David D</author> + <first_page>407</first_page> + <volume>16</volume> + <cYear>2019</cYear> + <article_title>Key components of a community response to out-of-hospital cardiac arrest</article_title> + <unstructured_citation>David D Berg , Bentley J Bobrow , and Robert A Berg . 2019 . Key components of a community + response to out-of-hospital cardiac arrest . Nature Reviews Cardiology 16 , 7 (2019), 407 – 416 . David D Berg, + Bentley J Bobrow, and Robert A Berg. 2019. Key components of a community response to out-of-hospital cardiac + arrest. Nature Reviews Cardiology 16, 7 (2019), 407–416. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_21_1"> + <doi>10.1080/10903127.2017.1308605</doi> + </citation> + <citation key="e_1_3_2_1_22_1"> + <doi>10.1016/j.resuscitation.2011.03.033</doi> + </citation> + <citation key="e_1_3_2_1_23_1"> + <doi>10.1111/acem.13987</doi> + </citation> + <citation key="e_1_3_2_1_24_1"> + <doi>10.1016/j.resuscitation.2019.12.004</doi> + </citation> + <citation key="e_1_3_2_1_25_1"> + <doi>10.1016/j.resuscitation.2017.12.010</doi> + </citation> + <citation key="e_1_3_2_1_26_1"> + <doi>10.1097/MEJ.0000000000000338</doi> + </citation> + <citation key="e_1_3_2_1_27_1"> + <volume_title>Culture and inference</volume_title> + <author>Hutchins Edwin</author> + <unstructured_citation>Edwin Hutchins . 2013. Culture and inference . Harvard University Press . Edwin Hutchins. + 2013. Culture and inference. Harvard University Press. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_28_1"> + <volume_title>Cognition in the Wild</volume_title> + <author>Hutchins Edwin</author> + <unstructured_citation>Edwin Hutchins . 1995. Cognition in the Wild . MIT press . Edwin Hutchins. 1995. Cognition in + the Wild. MIT press. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_29_1"> + <volume_title>Understanding micronesian navigation. Mental models</volume_title> + <author>Hutchins Edwin</author> + <cYear>1983</cYear> + <unstructured_citation>Edwin Hutchins . 1983. Understanding micronesian navigation. Mental models ( 1983 ), 191–225. + Edwin Hutchins. 1983. Understanding micronesian navigation. Mental models (1983), 191–225. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_30_1"> + <doi>10.1145/3479500</doi> + </citation> + <citation key="e_1_3_2_1_31_1"> + <doi>10.1145/353485.353487</doi> + </citation> + <citation key="e_1_3_2_1_32_1"> + <doi>10.1023/A:1015298005381</doi> + </citation> + <citation key="e_1_3_2_1_33_1"> + <volume_title>DiCoT: a methodology for applying distributed cognition to the design of teamworking systems + </volume_title> + <author>Blandford Ann</author> + <unstructured_citation>Ann Blandford and Dominic Furniss . 2005. DiCoT: a methodology for applying distributed + cognition to the design of teamworking systems . Springer , 26–38. Ann Blandford and Dominic Furniss. 2005. + DiCoT: a methodology for applying distributed cognition to the design of teamworking systems. Springer, 26–38. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_34_1"> + <doi provider="crossref">10.3389/fpsyg.2017.00075</doi> + <unstructured_citation>Ludovic Seifert Julien Lardy Jérôme Bourbousson David Adé Antoine Nordez Régis Thouvarecq and + Jacques Saury. 2017. Interpersonal coordination and individual organization combined with shared phenomenological + experience in rowing performance: two case studies. Frontiers in psychology 8 (2017) 75. Ludovic Seifert Julien + Lardy Jérôme Bourbousson David Adé Antoine Nordez Régis Thouvarecq and Jacques Saury. 2017. Interpersonal + coordination and individual organization combined with shared phenomenological experience in rowing performance: + two case studies. Frontiers in psychology 8 (2017) 75. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_35_1"> + <doi provider="crossref">10.1016/j.humov.2017.09.008</doi> + <unstructured_citation>Mehdi R'Kiouak Jacques Saury Marc Durand and Jérôme Bourbousson. 2018. Joint action in an + elite rowing pair crew after intensive team training: The reinforcement of extra-personal processes. Human + movement science 57 (2018) 303–313. Mehdi R'Kiouak Jacques Saury Marc Durand and Jérôme Bourbousson. 2018. Joint + action in an elite rowing pair crew after intensive team training: The reinforcement of extra-personal processes. + Human movement science 57 (2018) 303–313. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_36_1"> + <journal_title>Journal of Sports Science & Medicine</journal_title> + <author>Terrien Eric</author> + <first_page>298</first_page> + <volume>19</volume> + <cYear>2020</cYear> + <article_title>Coordination between crew members on flying multihulls: a case study on a Nacra 17</article_title> + <unstructured_citation>Eric Terrien , Benoît Huet , Paul Iachkine , and Jacques Saury . 2020 . Coordination between + crew members on flying multihulls: a case study on a Nacra 17 . Journal of Sports Science & Medicine 19 , 2 + (2020), 298 . Eric Terrien, Benoît Huet, Paul Iachkine, and Jacques Saury. 2020. Coordination between crew + members on flying multihulls: a case study on a Nacra 17. Journal of Sports Science & Medicine 19, 2 (2020), + 298. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_37_1"> + <volume_title>Usability of mobile computing in emergency response systems–Lessons learned and future directions + </volume_title> + <author>Leitner Gerhard</author> + <unstructured_citation>Gerhard Leitner , David Ahlström , and Martin Hitz . 2007. Usability of mobile computing in + emergency response systems–Lessons learned and future directions . Springer , 241–254. Gerhard Leitner, David + Ahlström, and Martin Hitz. 2007. Usability of mobile computing in emergency response systems–Lessons learned and + future directions. Springer, 241–254. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_38_1"> + <unstructured_citation>Lars Gerhold Roman Peperhove and Edda Brandes. 2020. Using Scenarios in a Living Lab for + improving Emergency Preparedness. (2020) 12. Lars Gerhold Roman Peperhove and Edda Brandes. 2020. Using Scenarios + in a Living Lab for improving Emergency Preparedness. (2020) 12. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_39_1"> + <doi>10.1007/978-3-319-68486-4_5</doi> + </citation> + <citation key="e_1_3_2_1_40_1"> + <unstructured_citation>P Vermersch. 1994. L'entretien d'explicitation [The explicitation interview]. P Vermersch. + 1994. L'entretien d'explicitation [The explicitation interview]. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_41_1"> + <doi>10.3917/th.793.0259</doi> + </citation> + <citation key="e_1_3_2_1_42_1"> + <volume_title>La pratique réflexive: un outil de développement des compétences infirmières</volume_title> + <author>Balas-Chanel Armelle</author> + <unstructured_citation>Armelle Balas-Chanel . 2013. La pratique réflexive: un outil de développement des compétences + infirmières . Elsevier Health Sciences . Armelle Balas-Chanel. 2013. La pratique réflexive: un outil de + développement des compétences infirmières. Elsevier Health Sciences. + </unstructured_citation> + </citation> + <citation key="e_1_3_2_1_43_1"> + <doi>10.1016/j.resuscitation.2021.08.048</doi> + </citation> + <citation key="e_1_3_2_1_44_1"> + <doi>10.1186/s13049-018-0584-0</doi> + </citation> + </citation_list> + </conference_paper> + </conference> + </crossref> + </doi_record> +</doi_records> \ No newline at end of file diff --git a/AoU-Admin/src/test/resources/test-crossref-report-response.xml b/AoU-Admin/src/test/resources/test-crossref-report-response.xml new file mode 100644 index 0000000000000000000000000000000000000000..07a72842cb2273e921801be448c330a6dd5c51db --- /dev/null +++ b/AoU-Admin/src/test/resources/test-crossref-report-response.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<doi_records> + <doi_record owner="10.57071" timestamp="2022-10-05 09:21:45"> + <crossref> + <report-paper> + <report-paper_metadata> + <contributors> + <person_name sequence="first" contributor_role="author"> + <given_name>Simon</given_name> + <surname>Flandin</surname> + <ORCID>https://orcid.org/0000-0002-6332-1499</ORCID> + </person_name> + <person_name sequence="additional" contributor_role="author"> + <given_name>Germain</given_name> + <surname>Poizat</surname> + <ORCID>https://orcid.org/0000-0002-6560-3342</ORCID> + <affiliations> + <institution> + <institution_id type="ror">https://ror.org/01swzsf04</institution_id> + </institution> + </affiliations> + </person_name> + <person_name sequence="additional" contributor_role="author"> + <given_name>Romuald</given_name> + <surname>Perinet</surname> + </person_name> + </contributors> + <titles> + <title>Proactivité et réactivité: deux orientations pour concevoir des dispositifs visant le développement</title> + </titles> + <abstract lang="en"> + <p>In a world exposed to uncertainty and upsets, the development of organizational resilience is often</p> + </abstract> + <publication_date media_type="online"> + <month>02</month> + <day>08</day> + <year>2021</year> + </publication_date> + <publisher> + <publisher_name>Fondation pour une culture de sécurité industrielle</publisher_name> + </publisher> + <institution> + <institution_name>Fondation pour une culture de sécurité industrielle</institution_name> + <institution_acronym>FonCSI</institution_acronym> + <institution_place>Toulouse, France</institution_place> + </institution> + <publisher_item> + <identifier id_type="report-number">2021-01</identifier> + </publisher_item> + <doi_data> + <doi>10.57071/948rpn</doi> + <resource>https://www.foncsi.org/fr/publications/cahiers-securite-industrielle</resource> + </doi_data> + </report-paper_metadata> + </report-paper> + </crossref> + </doi_record> +</doi_records> \ No newline at end of file diff --git "a/AoU-IntegrationTestsRunner/non-iso-8859-1-e\314\201\303\251.pdf" "b/AoU-IntegrationTestsRunner/non-iso-8859-1-e\314\201\303\251.pdf" deleted file mode 100644 index ac5d23335324e62cd89098cb29e15d24508643b2..0000000000000000000000000000000000000000 Binary files "a/AoU-IntegrationTestsRunner/non-iso-8859-1-e\314\201\303\251.pdf" and /dev/null differ diff --git a/AoU-Model/src/main/java/ch/unige/aou/AouConstants.java b/AoU-Model/src/main/java/ch/unige/aou/AouConstants.java index 280d9f8ffd4c88659d383c5864f1945e389b144e..46809d7991b0c98ad76b1ed8caa9e44c647a88d8 100644 --- a/AoU-Model/src/main/java/ch/unige/aou/AouConstants.java +++ b/AoU-Model/src/main/java/ch/unige/aou/AouConstants.java @@ -641,4 +641,7 @@ public class AouConstants { public static final String FILE_NAME_REPLACEMENT = "file"; public static final String UNIVERSITY_OF_GENEVA_FR = "Université de Genève"; + public static final String HUG_FR = "Hôpitaux universitaires de Genève"; + public static final String UNIVERSITY_OF_GENEVA_ROR_ID = "https://ror.org/01swzsf04"; + public static final String HUG_ROR_ID = "https://ror.org/01m1pv723"; }