dnet-applications/apps/dnet-exporter-api/src/main/java/eu/dnetlib/openaire/dsm/dao/utils/DsmMappingUtils.java

313 lines
13 KiB
Java

package eu.dnetlib.openaire.dsm.dao.utils;
import static eu.dnetlib.openaire.common.ExporterConstants.ADMIN_INFO;
import static eu.dnetlib.openaire.common.ExporterConstants.ENGLISH_NAME;
import static eu.dnetlib.openaire.common.ExporterConstants.LATITUDE;
import static eu.dnetlib.openaire.common.ExporterConstants.LONGITUDE;
import static eu.dnetlib.openaire.common.ExporterConstants.OFFICIAL_NAME;
import static eu.dnetlib.openaire.common.ExporterConstants.PLATFORM;
import static eu.dnetlib.openaire.common.ExporterConstants.TIMEZONE;
import static eu.dnetlib.openaire.common.ExporterConstants.TYPOLOGY;
import static eu.dnetlib.openaire.common.ExporterConstants.WEBSITE_URL;
import java.sql.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.google.common.xml.XmlEscapers;
import eu.dnetlib.data.transform.xml.AbstractDNetXsltFunctions;
import eu.dnetlib.miscutils.datetime.DateUtils;
import eu.dnetlib.openaire.dsm.domain.ApiDetails;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetails;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailsUpdate;
import eu.dnetlib.openaire.dsm.domain.DatasourceSnippet;
import eu.dnetlib.openaire.dsm.domain.DatasourceSnippetExtended;
import eu.dnetlib.openaire.dsm.domain.OrganizationDetails;
import eu.dnetlib.openaire.dsm.domain.db.ApiDbEntry;
import eu.dnetlib.openaire.dsm.domain.db.DatasourceDbEntry;
import eu.dnetlib.openaire.dsm.domain.db.OrganizationDbEntry;
public class DsmMappingUtils {
public static final String DATE_FORMAT = "yyyy-MM-dd";
public static final String ID_SEPARATOR = "::";
public static final String ID_PREFIX = "api_________" + ID_SEPARATOR;
public static String createId(final ApiDetails api) {
return ID_PREFIX + api.getDatasource() + ID_SEPARATOR + RandomStringUtils.randomAlphanumeric(8);
}
public static DatasourceDetails asDetails(final DatasourceDbEntry d) {
final DatasourceDetails details = _convert(d, DatasourceDetails.class);
return details.setOpenaireId(asOpenaireId(details.getId()));
}
@Deprecated
public static DatasourceSnippet asSnippet(final DatasourceDbEntry d) {
final DatasourceSnippet ds = new DatasourceSnippet();
ds.setId(d.getId());
ds.setOfficialname(d.getOfficialname());
ds.setEnglishname(d.getEnglishname());
return ds;
}
public static DatasourceSnippetExtended asSnippetExtended(final DatasourceDbEntry d) {
final DatasourceSnippetExtended ds = new DatasourceSnippetExtended();
ds.setId(d.getId());
ds.setOfficialname(d.getOfficialname());
ds.setEnglishname(d.getEnglishname());
ds.setRegisteredby(d.getRegisteredby());
ds.setWebsiteurl(d.getWebsiteurl());
ds.setTypology(d.getTypology());
ds.setRegistrationdate(d.getRegistrationdate());
ds.setLogoUrl(d.getLogourl());
ds.setDescription(d.getDescription());
ds.setConsentTermsOfUse(d.getConsentTermsOfUse());
ds.setConsentTermsOfUseDate(d.getConsentTermsOfUseDate());
ds.setFullTextDownload(d.getFullTextDownload());
if (d.getOrganizations() != null) {
ds.setOrganizations(d.getOrganizations().stream().map(DsmMappingUtils::asOrganizationDetail).collect(Collectors.toSet()));
}
return ds;
}
private static OrganizationDetails asOrganizationDetail(final OrganizationDbEntry o) {
return new OrganizationDetails()
.setCountry(o.getCountry())
.setLegalname(o.getLegalname())
.setLegalshortname(o.getLegalshortname())
.setWebsiteurl(o.getWebsiteurl())
.setLogourl(o.getLogourl());
}
public static ApiDetails asDetails(final ApiDbEntry d) {
return _convert(d, ApiDetails.class);
}
public static ApiDbEntry asDbEntry(final ApiDetails d) {
final ApiDbEntry apiDbEntry = _convert(d, ApiDbEntry.class);
// Need to complete the references among objects, because you know, referential integrity ...
apiDbEntry.getApiParams().forEach(ap -> ap.getId().setApi(apiDbEntry));
return apiDbEntry;
}
public static DatasourceDbEntry asDbEntry(final DatasourceDetails d) {
final DatasourceDbEntry dbe = _convert(d, DatasourceDbEntry.class);
if (dbe.getOrganizations() != null) {
dbe.getOrganizations().forEach(o -> {
String prefix = StringUtils.isNotBlank(dbe.getNamespaceprefix()) ? dbe.getNamespaceprefix() : dbe.getId();
o.setId(prefix + ID_SEPARATOR + o.getLegalname());
if (o.getDateofcollection() == null) {
o.setDateofcollection(new Date(System.currentTimeMillis()));
}
o.setCollectedfrom(dbe.getCollectedfrom());
});
}
return dbe;
}
public static DatasourceDbEntry asDbEntry(final DatasourceDetailsUpdate d) {
return _convert(d, DatasourceDbEntry.class);
}
public static String asRepositoryProfile(final DatasourceDetails ds) {
final Element root = DocumentHelper.createElement("RESOURCE_PROFILE");
final Element header = root.addElement("HEADER");
header.addElement("RESOURCE_IDENTIFIER").addAttribute("value", "");
header.addElement("RESOURCE_TYPE").addAttribute("value", "RepositoryServiceResourceType");
header.addElement("RESOURCE_KIND").addAttribute("value", "RepositoryServiceResources");
header.addElement("RESOURCE_URI").addAttribute("value", "");
header.addElement("DATE_OF_CREATION").addAttribute("value", DateUtils.now_ISO8601());
header.addElement("PROTOCOL");
final Element body = root.addElement("BODY");
final Element conf = body.addElement("CONFIGURATION");
conf.addElement("DATASOURCE_TYPE").setText(ds.getTypology());
final Element origId = conf.addElement("DATASOURCE_ORIGINAL_ID");
origId.addAttribute("provenance", "D-NET");
origId.setText(ds.getId());
conf.addElement("DATASOURCE_AGGREGATED").setText("false");
conf.addElement("ENVIRONMENTS").addElement("ENVIRONMENT").setText("OPENAIRE");
conf.addElement("TYPOLOGY").setText("" + ds.getTypology());
conf.addElement("MAX_SIZE_OF_DATASTRUCTURE").setText("0");
conf.addElement("AVAILABLE_DISKSPACE").setText("0");
conf.addElement("MAX_NUMBER_OF_DATASTRUCTURE").setText("0");
final String officialName = ds.getOfficialname();
conf.addElement("OFFICIAL_NAME").setText(officialName);
final String englishName = ds.getEnglishname();
conf.addElement("ENGLISH_NAME").setText(StringUtils.isNotBlank(englishName) ? englishName : officialName);
conf.addElement("ICON_URI").setText("" + ds.getLogourl());
final OrganizationDetails org = getOrganization(ds);
conf.addElement("COUNTRY").setText(org != null ? org.getCountry() : "");
final Element location = conf.addElement("LOCATION");
location.addElement("LONGITUDE").setText("" + ds.getLongitude());
location.addElement("LATITUDE").setText("" + ds.getLatitude());
location.addElement("TIMEZONE").setText("" + ds.getTimezone());
conf.addElement("REPOSITORY_WEBPAGE").setText(ds.getWebsiteurl());
getOrganization(ds);
conf.addElement("REPOSITORY_INSTITUTION").setText(org != null ? org.getLegalname() : "");
conf.addElement("ADMIN_INFO").setText(ds.getContactemail());
conf.addElement("INTERFACES");
final Element extraFields = conf.addElement("EXTRA_FIELDS");
addExtraField(extraFields, "OpenAireDataSourceId", ds.getId());
addExtraField(extraFields, "ACTIVATION_ID", ds.getActivationId());
addExtraField(extraFields, "NamespacePrefix", ds.getNamespaceprefix());
addExtraField(extraFields, "aggregatorName", ds.getAggregator());
addExtraField(extraFields, "dateOfCollection", "" + ds.getDateofcollection());
addExtraField(extraFields, "dateOfValidation", "" + ds.getDateofvalidation());
conf.addElement("REGISTERED_BY").setText(ds.getRegisteredby());
final Element status = body.addElement("STATUS");
status.addElement("NUMBER_OF_OBJECTS").setText("0");
status.addElement("LAST_UPDATE").addAttribute("value", DateUtils.now_ISO8601());
final Element qos = body.addElement("QOS");
qos.addElement("AVAILABILITY").setText("0");
qos.addElement("CAPACITY");
qos.addElement("THROUGHPUT").setText("0");
body.addElement("SECURITY_PARAMETERS");
body.addElement("BLACKBOARD");
return root.asXML();
}
public static String asRepositoryInterfce(final ApiDetails api) {
final Element iface = DocumentHelper.createElement("INTERFACE");
iface.addAttribute("active", String.valueOf(api.getActive()))
.addAttribute("compliance", api.getCompatibility())
.addAttribute("contentDescription", api.getContentdescription())
.addAttribute("id", api.getId())
.addAttribute("label", String.format("%s (%s)", api.getTypology(), api.getCompatibility()))
.addAttribute("removable", String.valueOf(api.getRemovable()))
.addAttribute("typology", api.getTypology());
iface.addElement("ACCESS_PROTOCOL").setText(api.getProtocol());
if (api.getApiParams() != null) {
final Element accessProtocol = (Element) iface.selectSingleNode("./ACCESS_PROTOCOL");
api.getApiParams().forEach(ap -> {
accessProtocol.addAttribute(ap.getParam(), ap.getValue());
});
}
iface.addElement("BASE_URL").setText(api.getBaseurl());
iface.addElement("INTERFACE_EXTRA_FIELD").addAttribute("name", "last_collection_date");
iface.addElement("INTERFACE_EXTRA_FIELD").addAttribute("name", "last_collection_mdId");
iface.addElement("INTERFACE_EXTRA_FIELD").addAttribute("name", "last_collection_total");
iface.addElement("INTERFACE_EXTRA_FIELD").addAttribute("name", "last_aggregation_date");
iface.addElement("INTERFACE_EXTRA_FIELD").addAttribute("name", "last_aggregation_mdId");
iface.addElement("INTERFACE_EXTRA_FIELD").addAttribute("name", "last_aggregation_total");
final Element mdPathNode = iface.addElement("INTERFACE_EXTRA_FIELD");
mdPathNode.addAttribute("name", "metadata_identifier_path");
if (StringUtils.isNotBlank(api.getMetadataIdentifierPath())) {
mdPathNode.setText(api.getMetadataIdentifierPath());
}
return iface.asXML();
}
// HELPERS
private static <T> T _convert(final Object o, final Class<T> clazz) {
final ObjectMapper mapper = new ObjectMapper();
return mapper.convertValue(o, clazz);
}
private static OrganizationDetails getOrganization(final DatasourceDetails ds) {
if (ds.getOrganizations() != null && !ds.getOrganizations().isEmpty()) { return ds.getOrganizations().stream().findFirst().get(); }
return null;
}
private static void addExtraField(final Element extraFields, final String field, final String value) {
final Element f = extraFields.addElement("FIELD");
f.addElement("key").setText(field);
f.addElement("value").setText(value != null ? value : "");
}
private static String asOpenaireId(final String id) {
final String prefix = StringUtils.substringBefore(id, ID_SEPARATOR);
final String md5 = StringUtils.substringAfter(id, ID_SEPARATOR);
return prefix + ID_SEPARATOR + AbstractDNetXsltFunctions.md5(md5);
}
public static void copyNonNullProperties(final Object src, final Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
public static String[] getNullPropertyNames(final Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
final java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
final Set<String> emptyNames = new HashSet<>();
for (final java.beans.PropertyDescriptor pd : pds) {
final Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
final String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
public static Map<String, String> asMapOfChanges(final DatasourceDetailsUpdate d) {
final Map<String, String> changes = Maps.newHashMap();
if (d.getContactemail() != null) {
changes.put(ADMIN_INFO, XmlEscapers.xmlContentEscaper().escape(d.getContactemail()));
}
if (d.getEnglishname() != null) {
changes.put(ENGLISH_NAME, XmlEscapers.xmlContentEscaper().escape(d.getEnglishname()));
}
if (d.getOfficialname() != null) {
changes.put(OFFICIAL_NAME, XmlEscapers.xmlContentEscaper().escape(d.getOfficialname()));
}
if (d.getTimezone() != null) {
changes.put(TIMEZONE, XmlEscapers.xmlContentEscaper().escape(d.getTimezone()));
}
if (d.getLatitude() != null) {
changes.put(LATITUDE, XmlEscapers.xmlContentEscaper().escape(String.valueOf(d.getLatitude())));
}
if (d.getLongitude() != null) {
changes.put(LONGITUDE, XmlEscapers.xmlContentEscaper().escape(String.valueOf(d.getLongitude())));
}
if (d.getPlatform() != null) {
changes.put(PLATFORM, XmlEscapers.xmlContentEscaper().escape(d.getPlatform()));
}
if (d.getTypology() != null) {
changes.put(TYPOLOGY, XmlEscapers.xmlContentEscaper().escape(d.getTypology()));
}
if (d.getWebsiteurl() != null) {
changes.put(WEBSITE_URL, XmlEscapers.xmlContentEscaper().escape(d.getWebsiteurl()));
}
return changes;
}
}