Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2824 from 4Science/DS-4515_submit-external-source
DS-4515 - Start new submission via Search or ID Lookup (using Live Import)
- Loading branch information
Showing
24 changed files
with
870 additions
and
1,522 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
162 changes: 162 additions & 0 deletions
162
dspace-api/src/main/java/org/dspace/external/provider/impl/LiveImportDataProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/** | ||
* 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.external.provider.impl; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
import org.dspace.content.dto.MetadataValueDTO; | ||
import org.dspace.external.model.ExternalDataObject; | ||
import org.dspace.external.provider.ExternalDataProvider; | ||
import org.dspace.importer.external.datamodel.ImportRecord; | ||
import org.dspace.importer.external.exception.MetadataSourceException; | ||
import org.dspace.importer.external.metadatamapping.MetadatumDTO; | ||
import org.dspace.importer.external.service.components.QuerySource; | ||
|
||
/** | ||
* This class allows to configure a Live Import Provider as an External Data Provider | ||
* | ||
* @author Andrea Bollini (andrea.bollini at 4science.it) | ||
* | ||
*/ | ||
public class LiveImportDataProvider implements ExternalDataProvider { | ||
/** | ||
* The {@link QuerySource} live import provider | ||
*/ | ||
private QuerySource querySource; | ||
|
||
/** | ||
* An unique human readable identifier for this provider | ||
*/ | ||
private String sourceIdentifier; | ||
|
||
private String recordIdMetadata; | ||
|
||
private String displayMetadata = "dc.title"; | ||
|
||
@Override | ||
public String getSourceIdentifier() { | ||
return sourceIdentifier; | ||
} | ||
|
||
/** | ||
* This method set the SourceIdentifier for the ExternalDataProvider | ||
* @param sourceIdentifier The UNIQUE sourceIdentifier to be set on any LiveImport data provider | ||
*/ | ||
public void setSourceIdentifier(String sourceIdentifier) { | ||
this.sourceIdentifier = sourceIdentifier; | ||
} | ||
|
||
/** | ||
* This method set the MetadataSource for the ExternalDataProvider | ||
* @param metadataSource {@link org.dspace.importer.external.service.components.MetadataSource} implementation used to process the input data | ||
*/ | ||
public void setMetadataSource(QuerySource querySource) { | ||
this.querySource = querySource; | ||
} | ||
|
||
/** | ||
* This method set dublin core identifier to use as metadata id | ||
* @param recordIdMetadata dublin core identifier to use as metadata id | ||
*/ | ||
public void setRecordIdMetadata(String recordIdMetadata) { | ||
this.recordIdMetadata = recordIdMetadata; | ||
} | ||
|
||
/** | ||
* This method set the dublin core identifier to display the title | ||
* @param displayMetadata metadata to use as title | ||
*/ | ||
public void setDisplayMetadata(String displayMetadata) { | ||
this.displayMetadata = displayMetadata; | ||
} | ||
|
||
@Override | ||
public Optional<ExternalDataObject> getExternalDataObject(String id) { | ||
try { | ||
ExternalDataObject externalDataObject = getExternalDataObject(querySource.getRecord(id)); | ||
return Optional.of(externalDataObject); | ||
} catch (MetadataSourceException e) { | ||
throw new RuntimeException( | ||
"The live import provider " + querySource.getImportSource() + " throws an exception", e); | ||
} | ||
} | ||
|
||
@Override | ||
public List<ExternalDataObject> searchExternalDataObjects(String query, int start, int limit) { | ||
Collection<ImportRecord> records; | ||
try { | ||
records = querySource.getRecords(query, start, limit); | ||
return records.stream().map(r -> getExternalDataObject(r)).collect(Collectors.toList()); | ||
} catch (MetadataSourceException e) { | ||
throw new RuntimeException( | ||
"The live import provider " + querySource.getImportSource() + " throws an exception", e); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean supports(String source) { | ||
return StringUtils.equalsIgnoreCase(sourceIdentifier, source); | ||
} | ||
|
||
@Override | ||
public int getNumberOfResults(String query) { | ||
try { | ||
return querySource.getRecordsCount(query); | ||
} catch (MetadataSourceException e) { | ||
throw new RuntimeException( | ||
"The live import provider " + querySource.getImportSource() + " throws an exception", e); | ||
} | ||
} | ||
|
||
/** | ||
* Internal method to convert an ImportRecord to an ExternalDataObject | ||
* | ||
* FIXME it would be useful to remove ImportRecord at all in favor of the | ||
* ExternalDataObject | ||
* | ||
* @param record | ||
* @return | ||
*/ | ||
private ExternalDataObject getExternalDataObject(ImportRecord record) { | ||
//return 400 if no record were found | ||
if (record == null) { | ||
throw new IllegalArgumentException("No record found for query or id"); | ||
} | ||
ExternalDataObject externalDataObject = new ExternalDataObject(sourceIdentifier); | ||
String id = getFirstValue(record, recordIdMetadata); | ||
String display = getFirstValue(record, displayMetadata); | ||
externalDataObject.setId(id); | ||
externalDataObject.setDisplayValue(display); | ||
externalDataObject.setValue(display); | ||
for (MetadatumDTO dto : record.getValueList()) { | ||
// FIXME it would be useful to remove MetadatumDTO in favor of MetadataValueDTO | ||
MetadataValueDTO mvDTO = new MetadataValueDTO(); | ||
mvDTO.setSchema(dto.getSchema()); | ||
mvDTO.setElement(dto.getElement()); | ||
mvDTO.setQualifier(dto.getQualifier()); | ||
mvDTO.setValue(dto.getValue()); | ||
externalDataObject.addMetadata(mvDTO); | ||
} | ||
return externalDataObject; | ||
} | ||
|
||
private String getFirstValue(ImportRecord record, String metadata) { | ||
String id = null; | ||
String[] split = StringUtils.split(metadata, ".", 3); | ||
Collection<MetadatumDTO> values = record.getValue(split[0], split[1], split.length == 3 ? split[2] : null); | ||
if (!values.isEmpty()) { | ||
id = (values.iterator().next().getValue()); | ||
} | ||
return id; | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
...i/src/main/java/org/dspace/importer/external/arxiv/metadatamapping/ArXivFieldMapping.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* 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.importer.external.arxiv.metadatamapping; | ||
|
||
import java.util.Map; | ||
import javax.annotation.Resource; | ||
|
||
import org.dspace.importer.external.metadatamapping.AbstractMetadataFieldMapping; | ||
|
||
/** | ||
* An implementation of {@link AbstractMetadataFieldMapping} | ||
* Responsible for defining the mapping of the ArXiv metadatum fields on the DSpace metadatum fields | ||
* | ||
* @author Pasquale Cavallo (pasquale.cavallo at 4science dot it) | ||
*/ | ||
public class ArXivFieldMapping extends AbstractMetadataFieldMapping { | ||
|
||
/** | ||
* Defines which metadatum is mapped on which metadatum. Note that while the key must be unique it | ||
* only matters here for postprocessing of the value. The mapped MetadatumContributor has full control over | ||
* what metadatafield is generated. | ||
* | ||
* @param metadataFieldMap The map containing the link between retrieve metadata and metadata that will be set to | ||
* the item. | ||
*/ | ||
@Override | ||
@Resource(name = "arxivMetadataFieldMap") | ||
public void setMetadataFieldMap(Map metadataFieldMap) { | ||
super.setMetadataFieldMap(metadataFieldMap); | ||
} | ||
|
||
} |
60 changes: 60 additions & 0 deletions
60
...space/importer/external/arxiv/metadatamapping/contributor/ArXivIdMetadataContributor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
* 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.importer.external.arxiv.metadatamapping.contributor; | ||
|
||
import java.util.Collection; | ||
|
||
import org.apache.axiom.om.OMElement; | ||
import org.dspace.importer.external.metadatamapping.MetadatumDTO; | ||
import org.dspace.importer.external.metadatamapping.contributor.MetadataContributor; | ||
import org.dspace.importer.external.metadatamapping.contributor.SimpleXpathMetadatumContributor; | ||
|
||
/** | ||
* Arxiv specific implementation of {@link MetadataContributor} | ||
* Responsible for generating the ArXiv Id from the retrieved item. | ||
* | ||
* @author Pasquale Cavallo (pasquale.cavallo at 4science dot it) | ||
* | ||
*/ | ||
public class ArXivIdMetadataContributor extends SimpleXpathMetadatumContributor { | ||
|
||
/** | ||
* Retrieve the metadata associated with the given object. | ||
* Depending on the retrieved node (using the query), different types of values will be added to the MetadatumDTO | ||
* list | ||
* | ||
* @param t A class to retrieve metadata from. | ||
* @return a collection of import records. Only the identifier of the found records may be put in the record. | ||
*/ | ||
@Override | ||
public Collection<MetadatumDTO> contributeMetadata(OMElement t) { | ||
Collection<MetadatumDTO> values = super.contributeMetadata(t); | ||
parseValue(values); | ||
return values; | ||
} | ||
|
||
/** | ||
* ArXiv returns a full URL as in the <id> value, e.g. http://arxiv.org/abs/1911.11405v1. | ||
* This method parses out the identifier from the end of the URL, e.g. 1911.11405v1. | ||
* | ||
* @param dtos Metadata which contains the items uri | ||
*/ | ||
private void parseValue(Collection<MetadatumDTO> dtos) { | ||
if (dtos != null) { | ||
for (MetadatumDTO dto : dtos) { | ||
if (dto != null && dto.getValue() != null && dto.getValue().contains("/")) { | ||
int startIndex = dto.getValue().lastIndexOf('/') + 1; | ||
int endIndex = dto.getValue().length(); | ||
String id = dto.getValue().substring(startIndex, endIndex); | ||
dto.setValue(id); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.