/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.core.manager.impl; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.annotation.Resource; import org.orcid.core.exception.OrcidSearchException; import org.orcid.core.manager.OrcidProfileCacheManager; import org.orcid.core.manager.OrcidSearchManager; import org.orcid.core.manager.read_only.RecordManagerReadOnly; import org.orcid.jaxb.model.message.Funding; import org.orcid.jaxb.model.message.FundingList; import org.orcid.jaxb.model.message.OrcidMessage; import org.orcid.jaxb.model.message.OrcidProfile; import org.orcid.jaxb.model.message.OrcidSearchResult; import org.orcid.jaxb.model.message.OrcidSearchResults; import org.orcid.jaxb.model.message.OrcidWork; import org.orcid.jaxb.model.message.OrcidWorks; import org.orcid.jaxb.model.message.RelevancyScore; import org.orcid.jaxb.model.search_v2.Result; import org.orcid.jaxb.model.search_v2.Search; import org.orcid.persistence.dao.SolrDao; import org.orcid.utils.solr.entities.OrcidSolrResult; import org.orcid.utils.solr.entities.OrcidSolrResults; import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.NonTransientDataAccessResourceException; public class OrcidSearchManagerImpl implements OrcidSearchManager { @Value("${org.orcid.core.public_caching_source:SOLR}") private String cachingSource; @Resource private SolrDao solrDao; @Resource private RecordManagerReadOnly recordManagerReadOnly; private static String SOLR = "SOLR"; private static String DB = "DB"; private OrcidProfileCacheManager orcidProfileCacheManager; public SolrDao getSolrDao() { return solrDao; } public void setSolrDao(SolrDao solrDao) { this.solrDao = solrDao; } @Required public void setOrcidProfileCacheManager(OrcidProfileCacheManager orcidProfileCacheManager) { this.orcidProfileCacheManager = orcidProfileCacheManager; } @Override public OrcidMessage findOrcidSearchResultsById(String orcid) { OrcidMessage orcidMessage = new OrcidMessage(); OrcidSearchResults searchResults = new OrcidSearchResults(); OrcidSolrResult indexedOrcid = solrDao.findByOrcid(orcid); if (indexedOrcid != null) { List<OrcidSearchResult> orcidSearchResults = buildSearchResultsFromPublicProfile(Arrays.asList(indexedOrcid)); searchResults.getOrcidSearchResult().addAll(orcidSearchResults); } orcidMessage.setOrcidSearchResults(searchResults); searchResults.setNumFound(1); return orcidMessage; } private List<OrcidSearchResult> buildSearchResultsFromPublicProfile(List<OrcidSolrResult> solrResults) { List<OrcidSearchResult> orcidSearchResults = new ArrayList<OrcidSearchResult>(); for (OrcidSolrResult solrResult : solrResults) { OrcidMessage orcidMessage = null; String orcid = solrResult.getOrcid(); if (cachingSource.equals(SOLR)) { try (Reader reader = solrDao.findByOrcidAsReader(orcid)) { if (reader != null) { BufferedReader br = new BufferedReader(reader); orcidMessage = OrcidMessage.unmarshall(br); } } catch (IOException e) { throw new OrcidSearchException("Error closing record stream from solr search results for orcid: " + orcid, e); } } OrcidProfile orcidProfile = null; if (orcidMessage == null) { // Fall back to DB orcidProfile = orcidProfileCacheManager.retrievePublicBio(orcid); } else { orcidProfile = orcidMessage.getOrcidProfile(); } if (orcidProfile != null) { OrcidSearchResult orcidSearchResult = new OrcidSearchResult(); RelevancyScore relevancyScore = new RelevancyScore(); relevancyScore.setValue(solrResult.getRelevancyScore()); orcidSearchResult.setRelevancyScore(relevancyScore); OrcidWorks orcidWorksTitlesOnly = new OrcidWorks(); OrcidWorks fullOrcidWorks = orcidProfile.retrieveOrcidWorks(); if (fullOrcidWorks != null && !fullOrcidWorks.getOrcidWork().isEmpty()) { for (OrcidWork fullOrcidWork : fullOrcidWorks.getOrcidWork()) { OrcidWork orcidWorkSubset = new OrcidWork(); orcidWorkSubset.setVisibility(fullOrcidWork.getVisibility()); orcidWorkSubset.setWorkTitle(fullOrcidWork.getWorkTitle()); orcidWorkSubset.setWorkExternalIdentifiers(fullOrcidWork.getWorkExternalIdentifiers()); orcidWorksTitlesOnly.getOrcidWork().add(orcidWorkSubset); } } FundingList reducedFundings = new FundingList(); FundingList fullOrcidFundings = orcidProfile.retrieveFundings(); if (fullOrcidFundings != null && !fullOrcidFundings.getFundings().isEmpty()) { for (Funding fullOrcidFunding : fullOrcidFundings.getFundings()) { Funding reducedFunding = new Funding(); reducedFunding.setVisibility(fullOrcidFunding.getVisibility()); reducedFunding.setDescription(fullOrcidFunding.getDescription()); reducedFunding.setTitle(fullOrcidFunding.getTitle()); reducedFundings.getFundings().add(reducedFunding); } } orcidProfile.setOrcidWorks(orcidWorksTitlesOnly); orcidProfile.setFundings(reducedFundings); orcidSearchResult.setOrcidProfile(orcidProfile); orcidSearchResults.add(orcidSearchResult); } } return orcidSearchResults; } @Override public OrcidMessage findPublicProfileById(String orcid) { OrcidMessage om = null; try { if (cachingSource.equals(DB)) { OrcidProfile orcidProfile = orcidProfileCacheManager.retrievePublic(orcid); orcidProfile.setOrcidInternal(null); om = new OrcidMessage(orcidProfile); } else { try (Reader reader = solrDao.findByOrcidAsReader(orcid)) { if (reader != null) { BufferedReader br = new BufferedReader(reader); om = OrcidMessage.unmarshall(br); } } } } catch (NonTransientDataAccessResourceException e) { throw new OrcidSearchException("Error searching by id: " + orcid, e); } catch (IOException e) { throw new OrcidSearchException("Error closing stream for id: " + orcid, e); } if (om == null) throw new OrcidSearchException("Result is null"); return om; } @Override public OrcidMessage findOrcidsByQuery(String query) { return findOrcidsByQuery(query, null, null); } @Override public OrcidMessage findOrcidsByQuery(String query, Integer start, Integer rows) { OrcidMessage orcidMessage = new OrcidMessage(); OrcidSearchResults searchResults = new OrcidSearchResults(); OrcidSolrResults orcidSolrResults = solrDao.findByDocumentCriteria(query, start, rows); searchResults.setNumFound(orcidSolrResults.getNumFound()); List<OrcidSolrResult> indexedOrcids = orcidSolrResults.getResults(); if (indexedOrcids != null && !indexedOrcids.isEmpty()) { List<OrcidSearchResult> orcidSearchResults = buildSearchResultsFromPublicProfile(indexedOrcids); searchResults.getOrcidSearchResult().addAll(orcidSearchResults); } orcidMessage.setOrcidSearchResults(searchResults); return orcidMessage; } @Override public OrcidMessage findOrcidsByQuery(Map<String, List<String>> query) { OrcidMessage orcidMessage = new OrcidMessage(); OrcidSearchResults searchResults = new OrcidSearchResults(); OrcidSolrResults orcidSolrResults = solrDao.findByDocumentCriteria(query); searchResults.setNumFound(orcidSolrResults.getNumFound()); List<OrcidSolrResult> indexedOrcids = orcidSolrResults.getResults(); if (indexedOrcids != null && !indexedOrcids.isEmpty()) { List<OrcidSearchResult> orcidSearchResults = buildSearchResultsFromPublicProfile(indexedOrcids); searchResults.getOrcidSearchResult().addAll(orcidSearchResults); } orcidMessage.setOrcidSearchResults(searchResults); return orcidMessage; } @Override public Search findOrcidIds(Map<String, List<String>> queryParameters) { Search search = new Search(); OrcidSolrResults orcidSolrResults = solrDao.findByDocumentCriteria(queryParameters); if (orcidSolrResults != null && orcidSolrResults.getResults() != null) { List<Result> orcidIdList = orcidSolrResults.getResults().stream().map(r -> { Result result = new Result(); result.setOrcidIdentifier(recordManagerReadOnly.getOrcidIdentifier(r.getOrcid())); return result; }).collect(Collectors.toList()); search.getResults().addAll(orcidIdList); search.setNumFound(orcidSolrResults.getNumFound()); } else { search.setNumFound(0L); } return search; } }