Revision 61341
Added by Alessia Bardi almost 3 years ago
ResultEntry.java | ||
---|---|---|
56 | 56 |
// info:eu-repo/grantAgreement/Funder/FundingProgram/ProjectID/[Jurisdiction]/[ProjectName]/[ProjectAcronym] |
57 | 57 |
private List<String> linksToProjects = new ArrayList<>(); |
58 | 58 |
|
59 |
private static long last_cache_update = 0; |
|
60 |
private static final Map<String, Map<String, String>> cached_vocabularies = new HashMap<>(); |
|
61 |
private static final Map<String, DatasourceEntry> cached_datasources = new HashMap<>(); |
|
62 |
private static final Map<String, String> cached_contexts = new HashMap<>(); |
|
63 |
|
|
64 | 59 |
private static final Log log = LogFactory.getLog(ResultEntry.class); |
65 | 60 |
|
66 | 61 |
public ResultEntry() {} |
... | ... | |
198 | 193 |
this.contexts = contexts; |
199 | 194 |
} |
200 | 195 |
|
201 |
|
|
202 |
|
|
203 | 196 |
@ApiModelProperty(value = "E.g. info:eu-repo/grantAgreement/EC/FP7/283595/EU//OpenAIREplus") |
204 | 197 |
public List<String> getLinksToProjects() { |
205 | 198 |
return linksToProjects; |
... | ... | |
226 | 219 |
this.embargoEndDate = embargoEndDate; |
227 | 220 |
} |
228 | 221 |
|
229 |
public String asOafRecord(final VelocityEngine ve, |
|
230 |
final ISLookUpService lookupService, |
|
231 |
final String oafSchemaLocation, |
|
232 |
final String community_api) throws Exception { |
|
233 |
|
|
234 |
if (StringUtils.isBlank(getOriginalId()) |
|
235 |
&& StringUtils |
|
236 |
.isBlank(getOpenaireId())) { throw new DirecIndexApiException("One of the following fields is required: originalId or openaireId"); } |
|
237 |
if (StringUtils.isBlank(getTitle())) { throw new DirecIndexApiException("A required field is missing: title"); } |
|
238 |
if (StringUtils.isBlank(getUrl())) { throw new DirecIndexApiException("A required field is missing: url"); } |
|
239 |
if (StringUtils.isBlank(getLicenseCode()) && StringUtils.isBlank(getAccessRightCode())) { throw new DirecIndexApiException("A required field is missing: accessRightCode"); } |
|
240 |
if (StringUtils.isBlank(getResourceType())) { throw new DirecIndexApiException("A required field is missing: resourceType"); } |
|
241 |
if (StringUtils.isBlank(getCollectedFromId())) { throw new DirecIndexApiException("A required field is missing: collectedFromId"); } |
|
242 |
if (StringUtils.isBlank(getType())) { throw new DirecIndexApiException("A required field is missing: type"); } |
|
243 |
|
|
244 |
final DatasourceEntry collectedFromEntry = getDatasourceInfo(collectedFromId, lookupService); |
|
245 |
final DatasourceEntry hostedByEntry = getDatasourceInfo(hostedById, lookupService); |
|
246 |
|
|
247 |
if (StringUtils.isBlank(openaireId)) { |
|
248 |
setOpenaireId(calculateOpenaireId(originalId, collectedFromEntry)); |
|
249 |
} |
|
250 |
|
|
251 |
if (!openaireId |
|
252 |
.matches("^\\w{12}::\\w{32}$")) { throw new DirecIndexApiException( |
|
253 |
"Invalid openaireId: " + openaireId + " - regex ^\\w{12}::\\w{32}$ not matched"); } |
|
254 |
|
|
255 |
final Map<String, Object> model = new HashMap<>(); |
|
256 |
model.put("esc", new EscapeXml()); |
|
257 |
model.put("util", new OpenAIRESubmitterUtils(community_api)); |
|
258 |
model.put("pub", this); |
|
259 |
model.put("objIdentifier", getOpenaireId()); |
|
260 |
model.put("oafSchemaLocation", oafSchemaLocation); |
|
261 |
model.put("resultTypes", getVocabulary("dnet:result_typologies", lookupService)); |
|
262 |
model.put("rights", getVocabulary("dnet:access_modes", lookupService)); |
|
263 |
model.put("resourceTypes", getVocabulary("dnet:publication_resource", lookupService)); |
|
264 |
model.put("pidTypes", getVocabulary("dnet:pid_types", lookupService)); |
|
265 |
model.put("languages", getVocabulary("dnet:languages", lookupService)); |
|
266 |
model.put("contexts", getContexts(lookupService)); |
|
267 |
model.put("dateOfCollection", new SimpleDateFormat("yyyy-MM-dd\'T\'hh:mm:ss\'Z\'").format(new Date())); |
|
268 |
model.put("collectedFrom", collectedFromEntry); |
|
269 |
model.put("hostedBy", hostedByEntry); |
|
270 |
|
|
271 |
return VelocityEngineUtils.mergeTemplateIntoString(ve, "/eu/dnetlib/openaire/directindex/indexRecord.xml.vm", "UTF-8", model); |
|
272 |
} |
|
273 |
|
|
274 |
private static String calculateOpenaireId(final String originalId, final DatasourceEntry collectedFromEntry) { |
|
275 |
return collectedFromEntry.getPrefix() + "::" + Hashing.md5(originalId); |
|
276 |
} |
|
277 |
|
|
278 |
public static String calculateOpenaireId(final String originalId, final String collectedFromId, final ISLookUpService lookupService) |
|
279 |
throws ISLookUpException { |
|
280 |
return calculateOpenaireId(originalId, getDatasourceInfo(collectedFromId, lookupService)); |
|
281 |
} |
|
282 |
|
|
283 |
private synchronized static DatasourceEntry getDatasourceInfo(final String dsId, final ISLookUpService lookupService) throws ISLookUpException { |
|
284 |
if (StringUtils |
|
285 |
.isBlank(dsId)) { return new DatasourceEntry("openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18", "Unknown Repository", "unknown_____"); } |
|
286 |
|
|
287 |
if (!cached_datasources.containsKey(dsId)) { |
|
288 |
final String query = |
|
289 |
"collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')//CONFIGURATION[./DATASOURCE_ORIGINAL_ID='" + dsId |
|
290 |
+ "']/concat(./OFFICIAL_NAME, ' @@@ ', .//FIELD/value[../key='NamespacePrefix'])"; |
|
291 |
final String s = lookupService.getResourceProfileByQuery(query); |
|
292 |
final String[] arr = s.split("@@@"); |
|
293 |
|
|
294 |
final DatasourceEntry ds = new DatasourceEntry(dsId, arr[0].trim(), arr[1].trim()); |
|
295 |
|
|
296 |
if (StringUtils.isBlank(ds.getName()) || StringUtils.isBlank(ds.getPrefix())) { |
|
297 |
log.error("Invalid datasource id: " + dsId); |
|
298 |
throw new ISLookUpException("Invalid datasource id: " + dsId); |
|
299 |
} else { |
|
300 |
cached_datasources.put(dsId, ds); |
|
301 |
} |
|
302 |
} |
|
303 |
|
|
304 |
return cached_datasources.get(dsId); |
|
305 |
|
|
306 |
} |
|
307 |
|
|
308 |
private synchronized static Map<String, String> getVocabulary(final String voc, final ISLookUpService lookupService) throws ISLookUpException { |
|
309 |
|
|
310 |
if (DateUtils.now() - last_cache_update < TimeUnit.MINUTES.toMillis(15) && cached_vocabularies.containsKey(voc)) { |
|
311 |
return cached_vocabularies.get(voc); |
|
312 |
} else { |
|
313 |
final String query = "collection('/db/DRIVER/VocabularyDSResources/VocabularyDSResourceType')[.//VOCABULARY_NAME/@code='" + voc |
|
314 |
+ "']//TERM/concat(@code, ' @@@ ', @english_name)"; |
|
315 |
|
|
316 |
final Map<String, String> map = new HashMap<>(); |
|
317 |
for (final String s : lookupService.quickSearchProfile(query)) { |
|
318 |
final String[] arr = s.split("@@@"); |
|
319 |
map.put(arr[0].trim(), arr[1].trim()); |
|
320 |
} |
|
321 |
|
|
322 |
cached_vocabularies.put(voc, map); |
|
323 |
|
|
324 |
last_cache_update = DateUtils.now(); |
|
325 |
|
|
326 |
return map; |
|
327 |
} |
|
328 |
} |
|
329 |
|
|
330 |
private synchronized static Map<String, String> getContexts(final ISLookUpService lookupService) throws ISLookUpException { |
|
331 |
if (DateUtils.now() - last_cache_update > TimeUnit.MINUTES.toMillis(15) || cached_contexts.isEmpty()) { |
|
332 |
final String query = |
|
333 |
"collection('/db/DRIVER/ContextDSResources/ContextDSResourceType')[.//context/@type='community' or .//context/@type='ri']//*[name()='context' or name()='category' or name()='concept']/concat(@id, ' @@@ ', @label)"; |
|
334 |
|
|
335 |
cached_contexts.clear(); |
|
336 |
for (final String s : lookupService.quickSearchProfile(query)) { |
|
337 |
final String[] arr = s.split("@@@"); |
|
338 |
cached_contexts.put(arr[0].trim(), arr[1].trim()); |
|
339 |
} |
|
340 |
last_cache_update = DateUtils.now(); |
|
341 |
} |
|
342 |
return cached_contexts; |
|
343 |
} |
|
344 |
|
|
345 | 222 |
@Override |
346 | 223 |
public String toString() { |
347 | 224 |
return new Gson().toJson(this); |
Also available in: Unified diff
When the label of the context cannot be resolved, the context tag is not added.
To ensure tests do not make any external calls, the code has been refactored so that the proper mock could be defined.