Project

General

Profile

1
package eu.dnetlib.openaire.directindex.objects;
2

    
3
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
4
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
5
import eu.dnetlib.miscutils.datetime.DateUtils;
6
import eu.dnetlib.miscutils.functional.hash.Hashing;
7
import eu.dnetlib.miscutils.functional.string.EscapeXml;
8
import eu.dnetlib.openaire.directindex.api.DirecIndexApiException;
9
import eu.dnetlib.openaire.directindex.api.OpenAIRESubmitterUtils;
10
import org.apache.commons.lang.StringUtils;
11
import org.apache.commons.logging.Log;
12
import org.apache.commons.logging.LogFactory;
13
import org.apache.velocity.app.VelocityEngine;
14
import org.springframework.ui.velocity.VelocityEngineUtils;
15

    
16
import java.text.SimpleDateFormat;
17
import java.util.Date;
18
import java.util.HashMap;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.concurrent.TimeUnit;
22

    
23
public class ResultEntryToOaf {
24

    
25
    private static final Log log = LogFactory.getLog(ResultEntryToOaf.class);
26

    
27
    private static long last_cache_update = 0;
28
    private static final Map<String, Map<String, String>> cached_vocabularies = new HashMap<>();
29
    private static final Map<String, DatasourceEntry> cached_datasources = new HashMap<>();
30
    private static final Map<String, String> cached_contexts = new HashMap<>();
31

    
32
    private OpenAIRESubmitterUtils utils;
33

    
34
    public String asOafRecord(final ResultEntry entry, final VelocityEngine ve,
35
                              final ISLookUpService lookupService,
36
                              final String oafSchemaLocation,
37
                              final String community_api) throws Exception {
38

    
39
        if (StringUtils.isBlank(entry.getOriginalId())
40
                && StringUtils
41
                .isBlank(entry.getOpenaireId())) { throw new DirecIndexApiException("One of the following fields is required: originalId or openaireId"); }
42
        if (StringUtils.isBlank(entry.getTitle())) { throw new DirecIndexApiException("A required field is missing: title"); }
43
        if (StringUtils.isBlank(entry.getUrl())) { throw new DirecIndexApiException("A required field is missing: url"); }
44
        if (StringUtils.isBlank(entry.getLicenseCode()) && StringUtils.isBlank(entry.getAccessRightCode())) { throw new DirecIndexApiException("A required field is missing: accessRightCode"); }
45
        if (StringUtils.isBlank(entry.getResourceType())) { throw new DirecIndexApiException("A required field is missing: resourceType"); }
46
        if (StringUtils.isBlank(entry.getCollectedFromId())) { throw new DirecIndexApiException("A required field is missing: collectedFromId"); }
47
        if (StringUtils.isBlank(entry.getType())) { throw new DirecIndexApiException("A required field is missing: type"); }
48

    
49
        final DatasourceEntry collectedFromEntry = getDatasourceInfo(entry.getCollectedFromId(), lookupService);
50
        final DatasourceEntry hostedByEntry = getDatasourceInfo(entry.getHostedById(), lookupService);
51

    
52
        if (StringUtils.isBlank(entry.getOpenaireId())) {
53
            entry.setOpenaireId(calculateOpenaireId(entry.getOriginalId(), collectedFromEntry));
54
        }
55

    
56
        if (!entry.getOpenaireId()
57
                .matches("^\\w{12}::\\w{32}$")) { throw new DirecIndexApiException(
58
                "Invalid openaireId: " + entry.getOpenaireId() + " - regex ^\\w{12}::\\w{32}$ not matched"); }
59

    
60

    
61
        final List<OpenAIRESubmitterUtils.ContextInfo> contextInfos = utils.processContexts(entry.getContexts(), getContexts(lookupService));
62

    
63
        final Map<String, Object> model = new HashMap<>();
64
        model.put("esc", new EscapeXml());
65
        model.put("util",utils);
66
        model.put("pub", this);
67
        model.put("objIdentifier", entry.getOpenaireId());
68
        model.put("oafSchemaLocation", oafSchemaLocation);
69
        model.put("resultTypes", getVocabulary("dnet:result_typologies", lookupService));
70
        model.put("rights", getVocabulary("dnet:access_modes", lookupService));
71
        model.put("resourceTypes", getVocabulary("dnet:publication_resource", lookupService));
72
        model.put("pidTypes", getVocabulary("dnet:pid_types", lookupService));
73
        model.put("languages", getVocabulary("dnet:languages", lookupService));
74
        model.put("contexts", getContexts(lookupService));
75
        model.put("contextInfo",contextInfos);
76
        model.put("dateOfCollection", new SimpleDateFormat("yyyy-MM-dd\'T\'hh:mm:ss\'Z\'").format(new Date()));
77
        model.put("collectedFrom", collectedFromEntry);
78
        model.put("hostedBy", hostedByEntry);
79

    
80
        return VelocityEngineUtils.mergeTemplateIntoString(ve, "/eu/dnetlib/openaire/directindex/indexRecord.xml.vm", "UTF-8", model);
81
    }
82

    
83
    private synchronized static DatasourceEntry getDatasourceInfo(final String dsId, final ISLookUpService lookupService) throws ISLookUpException {
84
        if (StringUtils
85
                .isBlank(dsId)) { return new DatasourceEntry("openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18", "Unknown Repository", "unknown_____"); }
86

    
87
        if (!cached_datasources.containsKey(dsId)) {
88
            final String query =
89
                    "collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')//CONFIGURATION[./DATASOURCE_ORIGINAL_ID='" + dsId
90
                            + "']/concat(./OFFICIAL_NAME, ' @@@ ', .//FIELD/value[../key='NamespacePrefix'])";
91
            final String s = lookupService.getResourceProfileByQuery(query);
92
            final String[] arr = s.split("@@@");
93

    
94
            final DatasourceEntry ds = new DatasourceEntry(dsId, arr[0].trim(), arr[1].trim());
95

    
96
            if (StringUtils.isBlank(ds.getName()) || StringUtils.isBlank(ds.getPrefix())) {
97
                log.error("Invalid datasource id: " + dsId);
98
                throw new ISLookUpException("Invalid datasource id: " + dsId);
99
            } else {
100
                cached_datasources.put(dsId, ds);
101
            }
102
        }
103

    
104
        return cached_datasources.get(dsId);
105

    
106
    }
107

    
108
    private synchronized static Map<String, String> getVocabulary(final String voc, final ISLookUpService lookupService) throws ISLookUpException {
109

    
110
        if (DateUtils.now() - last_cache_update < TimeUnit.MINUTES.toMillis(15) && cached_vocabularies.containsKey(voc)) {
111
            return cached_vocabularies.get(voc);
112
        } else {
113
            final String query = "collection('/db/DRIVER/VocabularyDSResources/VocabularyDSResourceType')[.//VOCABULARY_NAME/@code='" + voc
114
                    + "']//TERM/concat(@code, ' @@@ ', @english_name)";
115

    
116
            final Map<String, String> map = new HashMap<>();
117
            for (final String s : lookupService.quickSearchProfile(query)) {
118
                final String[] arr = s.split("@@@");
119
                map.put(arr[0].trim(), arr[1].trim());
120
            }
121

    
122
            cached_vocabularies.put(voc, map);
123

    
124
            last_cache_update = DateUtils.now();
125

    
126
            return map;
127
        }
128
    }
129

    
130
    private synchronized static Map<String, String> getContexts(final ISLookUpService lookupService) throws ISLookUpException {
131
        if (DateUtils.now() - last_cache_update > TimeUnit.MINUTES.toMillis(15) || cached_contexts.isEmpty()) {
132
            final String query =
133
                    "collection('/db/DRIVER/ContextDSResources/ContextDSResourceType')[.//context/@type='community' or .//context/@type='ri']//*[name()='context' or name()='category' or name()='concept']/concat(@id, ' @@@ ', @label)";
134

    
135
            cached_contexts.clear();
136
            for (final String s : lookupService.quickSearchProfile(query)) {
137
                final String[] arr = s.split("@@@");
138
                cached_contexts.put(arr[0].trim(), arr[1].trim());
139
            }
140
            last_cache_update = DateUtils.now();
141
        }
142
        return cached_contexts;
143
    }
144

    
145
    private static String calculateOpenaireId(final String originalId, final DatasourceEntry collectedFromEntry) {
146
        return collectedFromEntry.getPrefix() + "::" + Hashing.md5(originalId);
147
    }
148

    
149
    public static String calculateOpenaireId(final String originalId, final String collectedFromId, final ISLookUpService lookupService)
150
            throws ISLookUpException {
151
        return calculateOpenaireId(originalId, getDatasourceInfo(collectedFromId, lookupService));
152
    }
153
    public OpenAIRESubmitterUtils getUtils() {
154
        return utils;
155
    }
156

    
157
    public void setUtils(OpenAIRESubmitterUtils utils) {
158
        this.utils = utils;
159
    }
160
}
(4-4/5)