package eu.dnetlib.openaire.context; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Queue; import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; import com.google.common.base.Functions; import com.google.common.collect.Lists; import eu.dnetlib.openaire.exporter.model.context.Category; import eu.dnetlib.openaire.exporter.model.context.Concept; import eu.dnetlib.openaire.exporter.model.context.Context; import eu.dnetlib.openaire.exporter.model.context.Param; import eu.dnetlib.openaire.exporter.model.funders.FunderDetails; public class ContextMappingUtils { private static final List DATE_PATTERN = Lists.newArrayList("yyyy-MM-dd'T'hh:mm:ss", "yyyy-MM-dd'T'hh:mm:ssXXX", "yyyy-MM-dd'T'hh:mm:ss+00:00"); public static Context parseContext(final String s, final Queue errors) { try { final Document doc = DocumentHelper.parseText(s); final Element eContext = (Element) doc.selectSingleNode("/RESOURCE_PROFILE/BODY/CONFIGURATION/context"); final String creationDate = eContext.valueOf("./param[./@name='creationdate']/text()"); final Context c = new Context() .setId(eContext.attributeValue("id")) .setLabel(eContext.attributeValue("label")) .setType(eContext.attributeValue("type")) .setLastUpdateDate(asDate(doc.valueOf("/RESOURCE_PROFILE/HEADER/DATE_OF_CREATION/@value"))) .setParams(parseParams(eContext)) .setCategories(parseCategories(eContext)); // the creation date will be added in the param elements of the community profile. Funders may not have it, hence the check. if (StringUtils.isNotBlank(creationDate)) { c.setCreationDate(asDate(creationDate)); } return c; } catch (final DocumentException e) { errors.add(e); return new Context(); } } private static Date asDate(final String s) { for (final String pattern : DATE_PATTERN) { try { return DateUtils.parseDate(s, pattern); } catch (final ParseException e) {} } return null; } private static Map parseCategories(final Element eContext) { final List eCategory = eContext.selectNodes("//category"); return eCategory.stream() .map(n -> (Element) n) .map(eCat -> new Category() .setClaim(getClaim(eCat)) .setId(eCat.attributeValue("id")) .setLabel(eCat.attributeValue("label")) .setParams(parseParams(eCat)) .setConcepts(parseConcepts(eCat))) .collect(Collectors.toMap(Category::getId, Functions.identity())); } private static List parseConcepts(final Element eCategory) { final List eConcepts = eCategory.selectNodes("./concept"); return eConcepts.stream() .map(n -> (Element) n) .map(eCon -> new Concept() .setClaim(getClaim(eCon)) .setId(eCon.attributeValue("id")) .setLabel(eCon.attributeValue("label")) .setParams(parseParams(eCon)) .setConcepts(parseConcepts(eCon))) .collect(Collectors.toList()); } private static Boolean getClaim(final Element eCon) { final String claim = eCon.attributeValue("claim"); return BooleanUtils.toBooleanObject(StringUtils.isNotBlank(claim) ? claim : "false"); } private static Map> parseParams(final Element e) { final List params = e.selectNodes("./param"); return params.stream() .map(n -> (Element) n) .map(p -> new Param() .setName(p.attributeValue("name")) .setValue(p.getTextTrim())) .collect(Collectors.toMap(Param::getName, Lists::newArrayList, (p1, p2) -> { final List p = new ArrayList<>(p1); p.addAll(p2); return p; })); } public static FunderDetails asFunderDetails(final Context c) { return new FunderDetails() .setId(c.getId()) .setName(c.getLabel()) .setShortname(c.getId()); } }