Project

General

Profile

1
package eu.dnetlib.parthenos.registry;
2

    
3
import java.io.IOException;
4
import java.io.StringWriter;
5
import java.util.Map;
6
import java.util.Set;
7
import java.util.UUID;
8
import javax.annotation.PostConstruct;
9

    
10
import com.fasterxml.jackson.core.JsonFactory;
11
import com.fasterxml.jackson.core.JsonGenerator;
12
import com.google.common.collect.Maps;
13
import com.google.common.collect.Sets;
14
import eu.dnetlib.parthenos.CRM;
15
import eu.dnetlib.parthenos.CRMdig;
16
import eu.dnetlib.parthenos.CRMpe;
17
import eu.dnetlib.parthenos.publisher.ParthenosPublisherException;
18
import org.apache.commons.io.IOUtils;
19
import org.apache.commons.lang3.StringUtils;
20
import org.apache.commons.logging.Log;
21
import org.apache.commons.logging.LogFactory;
22
import org.apache.jena.assembler.AssemblerHelp;
23
import org.apache.jena.ontology.OntModel;
24
import org.apache.jena.ontology.OntModelSpec;
25
import org.apache.jena.rdf.model.*;
26
import org.apache.jena.vocabulary.RDF;
27
import org.gcube.common.authorization.client.Constants;
28
import org.gcube.common.authorization.library.AuthorizationEntry;
29
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
30
import org.gcube.common.scope.api.ScopeProvider;
31
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
32
import org.gcube.informationsystem.resourceregistry.client.ParthenosRegistryClientSetter;
33
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
34
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
35
import org.gcube.informationsystem.resourceregistry.publisher.ParthenosRegistryPublisherSetter;
36
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher;
37
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory;
38
import org.springframework.beans.factory.annotation.Autowired;
39
import org.springframework.beans.factory.annotation.Value;
40
import org.springframework.stereotype.Component;
41

    
42
/**
43
 * Created by Alessia Bardi on 26/09/2017.
44
 *
45
 * @author Alessia Bardi
46
 */
47
@Component
48
public class GCubeResourceRegistrator {
49

    
50
	private static final Log log = LogFactory.getLog(GCubeResourceRegistrator.class);
51

    
52
	@Value("${gcube.registry.baseurl}")
53
	private String registryBaseURL;
54
	@Value("${gcube.registry.application.token}")
55
	private String applicationToken;
56

    
57
	@Autowired
58
	private FacetWriter facetWriter;
59
	@Autowired
60
	private RelWriter relWriter;
61

    
62
	private ResourceRegistryPublisher resourceRegistryPublisher;
63
	private ResourceRegistryClient resourceRegistryClient;
64

    
65
	private OntModel baseModel;
66

    
67
	@PostConstruct
68
	public void init() throws Exception {
69
		ParthenosRegistryClientSetter.forceToURL(getRegistryBaseURL());
70
		ParthenosRegistryPublisherSetter.forceToURL(getRegistryBaseURL());
71
		log.info("Registry URL forced to " + getRegistryBaseURL());
72
		if (StringUtils.isNotBlank(getApplicationToken())) {
73
			GCubeResourceRegistrator.setContext(getApplicationToken());
74
			log.info("GCube Context set");
75
		} else {
76
			log.fatal("GCube context cannot be configured without a value in gcube.registry.application.token");
77
		}
78
		this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
79
		this.resourceRegistryClient = ResourceRegistryClientFactory.create();
80
		baseModel = ModelFactory.createOntologyModel(OntModelSpec.RDFS_MEM_TRANS_INF);
81
		baseModel.read(CRMpe.RDFS_URL);
82
		baseModel.read(CRM.RDFS_URL);
83
		baseModel.read(CRMdig.RDFS_URL);
84
	}
85

    
86
	protected static String getCurrentScope(String token) throws Exception {
87
		AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token);
88
		String context = authorizationEntry.getContext();
89
		log.info("Context of token " + token + " is: " + context);
90
		return context;
91
	}
92

    
93
	protected static void setContext(String token) throws Exception {
94
		SecurityTokenProvider.instance.set(token);
95
		ScopeProvider.instance.set(getCurrentScope(token));
96
	}
97

    
98
	public int unregister(final String datasourceApi) {
99
		//TODO: implement me
100
		return -1;
101
	}
102

    
103
	/**
104
	 * Registers resources and relationships into the Parthenos Registry
105
	 *
106
	 * @param rdfRecord RDF record in RDF/XML PLAIN format
107
	 */
108
	public void register(final String rdfRecord, final String objIdentifier) throws ParthenosPublisherException, IOException {
109
		log.info("Processing record " + objIdentifier + " for registration on JRR");
110
		if (StringUtils.isBlank(rdfRecord)) {
111
			log.warn("Got empty record " + objIdentifier);
112
		} else {
113
			InfModel model = loadBaseModel();
114
			model.read(IOUtils.toInputStream(rdfRecord, "UTF-8"), CRMpe.NS);
115

    
116
			JsonFactory jsonFactory = new JsonFactory();
117
			Set<String> uriProcessed = Sets.newHashSet();
118
			/* Maps URI to ParthenosRegistryResource (with uuids) */
119
			Map<String, ParthenosRegistryResource> idMap = Maps.newHashMap();
120
			try {
121
			/* Resource */
122
				int registeredServices = processServices(model, uriProcessed, jsonFactory, idMap);
123
				int registeredDigitalObjects = processDigitalObjects(model, uriProcessed, jsonFactory, idMap);
124
				int registeredActors = processActors(model, uriProcessed, jsonFactory, idMap);
125
				int registeredProjects = processProjects(model, uriProcessed, jsonFactory, idMap);
126
				int registeredTypes = processTypes(model, uriProcessed, jsonFactory, idMap);
127

    
128
				int total = registeredActors + registeredDigitalObjects + registeredProjects + registeredServices+registeredTypes;
129
				log.info(String.format("Registered %d resources from record with objIdentifier %s", total, objIdentifier));
130

    
131
			/* Relationships */
132
				int relTotal = 0;
133
				for (String uri : uriProcessed) {
134
					relTotal += processRelationships(model, uri, idMap);
135
				}
136
				log.info(String.format("Registered %d relationships from record with objIdentifier %s", relTotal, objIdentifier));
137
			} catch (Throwable e) {
138
				String msg = "Registration of " + objIdentifier + " could not be completed correctly";
139
				log.error(msg, e);
140
				throw new ParthenosPublisherException(msg, e);
141
			}
142
		}
143
	}
144

    
145
	private int processRelationships(final InfModel model, final String uri, final Map<String, ParthenosRegistryResource> idMap)
146
			throws IOException, ResourceRegistryException, ParthenosPublisherException {
147
		Resource subject = model.getResource(uri);
148
		String uuid = idMap.get(uri).getUuid();
149
		JsonFactory jsonFactory = new JsonFactory();
150
		int relCount = 0;
151

    
152
		if (subject.hasProperty(RDF.type, CRMpe.PE1_Service)) {
153
			StmtIterator itOfferedBy = subject.listProperties(CRMpe.PP1i_is_currently_offered_by);
154
			while (itOfferedBy.hasNext()) {
155
				Resource project = itOfferedBy.nextStatement().getResource();
156
				ParthenosRegistryResource source = idMap.get(uri);
157
				ParthenosRegistryResource projectRes = idMap.get(project.getURI());
158
				String relJson = relWriter
159
						.writeRelationship(jsonFactory, "PP1_currently_offers", projectRes.getUuid(), projectRes.getRegistryType(), source.getUuid(),
160
								source.getRegistryType());
161
				this.resourceRegistryPublisher.createIsRelatedTo("PP1_currently_offers", relJson);
162
				relCount++;
163
			}
164
			StmtIterator itProvidedBy = subject.listProperties(CRMpe.PP2_provided_by);
165
			while (itProvidedBy.hasNext()) {
166
				Resource provider = itProvidedBy.nextStatement().getResource();
167
				ParthenosRegistryResource prr = idMap.get(uri);
168
				ParthenosRegistryResource providerRes = idMap.get(provider.getURI());
169
				String relJson = relWriter.writeRelationship(jsonFactory, "PP2_provided_by", prr.getUuid(), prr.getRegistryType(), providerRes.getUuid(),
170
						providerRes.getRegistryType());
171
				this.resourceRegistryPublisher.createIsRelatedTo("PP2_provided_by", relJson);
172
				relCount++;
173
				//TODO: IsRelatedTo the contact person of the provider. Interpret '"Follow path of service ‘Provided by’ and switch E39 for E21: E21- >p76->E51""
174
			}
175
			relCount += registerRelationship(CRMpe.PP45_has_competency, subject, idMap, jsonFactory);
176
			relCount += registerRelationship(CRMpe.PP4_hosts_object, subject, idMap, jsonFactory);
177
			relCount += registerRelationship(CRMpe.PP31_uses_curation_plan, subject, idMap, jsonFactory);
178
			relCount += registerRelationship(CRMpe.PP32_curates, subject, idMap, jsonFactory);
179
			relCount += registerRelationship(CRMpe.PP6_hosts_digital_object, subject, idMap, jsonFactory);
180
			relCount += registerRelationship(CRMpe.PP7_hosts_software_object, subject, idMap, jsonFactory);
181
			relCount += registerRelationship(CRMpe.PP8_hosts_dataset, subject, idMap, jsonFactory);
182
			relCount += registerRelationship(CRMpe.PP29_uses_access_protocol, subject, idMap, jsonFactory);
183
			relCount += registerRelationship(CRMpe.PP47_has_protocol_type, subject, idMap, jsonFactory);
184
			relCount += registerRelationship(CRMpe.PP48_uses_protocol_parameter, subject, idMap, jsonFactory);
185
			relCount += registerRelationship(CRMpe.PP46_brokers_access_to, subject, idMap, jsonFactory);
186
			relCount += registerRelationship(CRMpe.PP11_curates_volatile_digital_object, subject, idMap, jsonFactory);
187
			relCount += registerRelationship(CRMpe.PP12_curates_volatile_software, subject, idMap, jsonFactory);
188
			relCount += registerRelationship(CRMpe.PP13_curates_volatile_dataset, subject, idMap, jsonFactory);
189
			relCount += registerRelationship(CRMpe.PP15_delivers_on_request, subject, idMap, jsonFactory);
190
			relCount += registerRelationship(CRMpe.PP46_brokers_access_to, subject, idMap, jsonFactory);
191
		}
192
		if (subject.hasProperty(RDF.type, CRMpe.PE18_Dataset)) {
193
			StmtIterator itPartOf = subject.listProperties(CRMpe.PP23i_is_dataset_part_of);
194
			while (itPartOf.hasNext()) {
195
				Resource obj = itPartOf.nextStatement().getResource();
196
				ParthenosRegistryResource prr = idMap.get(uri);
197
				ParthenosRegistryResource objres = idMap.get(obj.getURI());
198
				String relJson = relWriter.writeRelationship(jsonFactory, "PP23_has_dataset_part", objres.getUuid(), objres.getRegistryType(), prr.getUuid(),
199
						prr.getRegistryType());
200
				this.resourceRegistryPublisher.createIsRelatedTo("PP23_has_dataset_part", relJson);
201
				relCount++;
202
			}
203
			//TODO: this is in the registry model but I am not sure what's going to happen...
204
			StmtIterator itIsAbout = subject.listProperties(CRM.P129_is_about);
205
			while (itIsAbout.hasNext()) {
206
				Resource obj = itIsAbout.nextStatement().getResource();
207
				if (obj.hasProperty(RDF.type, CRM.E55_Type)) {
208
					ParthenosRegistryResource prr = idMap.get(uri);
209
					ParthenosRegistryResource objres = idMap.get(obj.getURI());
210
					String relJson = relWriter
211
							.writeRelationship(jsonFactory, "P129_is_about", prr.getUuid(), prr.getRegistryType(), objres.getUuid(), objres.getRegistryType());
212
					this.resourceRegistryPublisher.createIsRelatedTo("P129_is_about", relJson);
213
					relCount++;
214
				}
215
			}
216
		}
217
		if (subject.hasProperty(RDF.type, CRMpe.PE19_Persistent_Digital_Object)) {
218
			relCount += registerRelationship(CRMpe.PP16_has_persistent_digital_object_part, subject, idMap, jsonFactory);
219
		}
220
		if (subject.hasProperty(RDF.type, CRMpe.PE20_Volatile_Digital_Object)) {
221
			relCount += registerRelationship(CRMpe.PP17_has_snapshot, subject, idMap, jsonFactory);
222
			relCount += registerRelationship(CRMpe.PP18_has_digital_object_part, subject, idMap, jsonFactory);
223
		}
224
		if (subject.hasProperty(RDF.type, CRMpe.PE21_Persistent_Software)) {
225
			relCount += registerRelationship(CRMpe.PP19_has_persistent_software_part, subject, idMap, jsonFactory);
226
		}
227
		if (subject.hasProperty(RDF.type, CRMpe.PE22_Persistent_Dataset)) {
228
			relCount += registerRelationship(CRMpe.PP20_has_persistent_dataset_part, subject, idMap, jsonFactory);
229
			relCount += registerRelationship(CRMpe.PP39_is_metadata_for, subject, idMap, jsonFactory);
230
		}
231
		if (subject.hasProperty(RDF.type, CRMpe.PE23_Volatile_Software)) {
232
			relCount += registerRelationship(CRMpe.PP21_has_software_part, subject, idMap, jsonFactory);
233
			relCount += registerRelationship(CRMpe.PP22_has_release, subject, idMap, jsonFactory);
234
		}
235
		if (subject.hasProperty(RDF.type, CRMpe.PE24_Volatile_Dataset)) {
236
			relCount += registerRelationship(CRMpe.PP23_has_dataset_part, subject, idMap, jsonFactory);
237
			relCount += registerRelationship(CRMpe.PP24_has_dataset_snapshot, subject, idMap, jsonFactory);
238
			relCount += registerRelationship(CRMpe.PP41_is_index_of, subject, idMap, jsonFactory);
239
		}
240
		if (subject.hasProperty(RDF.type, CRMpe.PE26_RI_Project)) {
241
			relCount += registerRelationship(CRMpe.PP25_has_maintaining_RI, subject, idMap, jsonFactory);
242
		}
243
		if (subject.hasProperty(RDF.type, CRMpe.PE35_Project)) {
244
			relCount += registerRelationship(CRMpe.PP43_supported_project_activity, subject, idMap, jsonFactory);
245
			relCount += registerRelationship(CRMpe.PP44_has_maintaining_team, subject, idMap, jsonFactory);
246
		}
247
		log.debug(String.format("Registered %d relationships for uri %s, uuid %s", relCount, uri, uuid));
248
		return relCount;
249
	}
250

    
251
	protected int registerRelationship(final Property rel,
252
			final Resource subject,
253
			final Map<String, ParthenosRegistryResource> idMap,
254
			final JsonFactory jsonFactory)
255
			throws IOException, ResourceRegistryException, ParthenosPublisherException {
256
		int relCount = 0;
257
		StmtIterator it = subject.listProperties(rel);
258
		while (it.hasNext()) {
259
			Resource obj = it.nextStatement().getResource();
260
			if (obj == null) throw new ParthenosPublisherException(String.format("No target resource available for %s --> %s", subject.getURI(), rel.getURI()));
261
			ParthenosRegistryResource source = idMap.get(subject.getURI());
262
			ParthenosRegistryResource target = idMap.get(obj.getURI());
263
			String relJson = relWriter
264
					.writeRelationship(jsonFactory, rel.getLocalName(), source.getUuid(), source.getRegistryType(), target.getUuid(), target.getRegistryType());
265
			this.resourceRegistryPublisher.createIsRelatedTo(rel.getLocalName(), relJson);
266
			relCount++;
267
		}
268
		return relCount;
269
	}
270

    
271
	protected InfModel loadBaseModel() {
272
		return ModelFactory.createRDFSModel(baseModel);
273
	}
274

    
275
	protected int processServices(final InfModel model,
276
			final Set<String> uriProcessed,
277
			final JsonFactory jsonFactory,
278
			final Map<String, ParthenosRegistryResource> idMap)
279
			throws IOException, ResourceRegistryException {
280
		log.debug("Processing services");
281
		int count = 0;
282
		int total = 0;
283
		ResIterator iter = model.listResourcesWithProperty(RDF.type, CRMpe.PE1_Service);
284
		while (iter.hasNext()) {
285
			total++;
286
			Resource res = iter.nextResource();
287
			String resourceURI = res.getURI();
288
			if (!uriProcessed.contains(resourceURI)) {
289
				ParthenosRegistryResource prr = processService(res, jsonFactory, idMap);
290
				//TODO: if something goes wrong we stop the registration but we are not rolling back the one that may have succeeded before.
291
				//Let's decide if this is ok or if we must be smarter than this
292
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
293
				uriProcessed.add(resourceURI);
294
				idMap.put(resourceURI, prr);
295
				count++;
296
			} else {
297
				log.debug(resourceURI + " already processed, now skipping it");
298
			}
299
		}
300
		log.debug(String.format("Registered %d/%d services", count, total));
301
		return count;
302

    
303
	}
304

    
305
	private ParthenosRegistryResource processService(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
306
			throws IOException {
307
		log.debug("Processing " + res.getURI());
308

    
309
		StringWriter sw = new StringWriter();
310
		JsonGenerator jg = jsonFactory.createGenerator(sw);
311
		jg.writeStartObject();
312
		String specificType = findSpecificType(res, CRMpe.PE1_Service).getLocalName();
313
		String uuid = writeCommon(res, specificType, jg, idMap);
314
		//******THE FACETS *******//
315
		jg.writeArrayFieldStart("consistsOf");
316
		//list of facets
317
		writeCommonFacets(res, jg);
318
		facetWriter.writeEventFacet(jg);
319
		facetWriter.writeRightsFacet(jg, res);
320
		if (res.hasProperty(CRMpe.PP2_provided_by)) {
321
			//TODO: shouldn't this be a rel to an actor?
322
			Resource provider = res.getPropertyResourceValue(CRMpe.PP2_provided_by);
323
			facetWriter.writeContactReferenceFacet(jg, provider);
324
		}
325
		facetWriter.writeDesignatedAccessPointFacet(jg, res);
326
		jg.writeEndArray();
327
		jg.writeEndObject();
328
		jg.close();
329
		String json = sw.toString();
330
		log.debug(json);
331
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
332
	}
333

    
334
	protected int processTypes(final InfModel model,
335
			final Set<String> uriProcessed,
336
			final JsonFactory jsonFactory,
337
			final Map<String, ParthenosRegistryResource> idMap)
338
			throws IOException, ResourceRegistryException {
339
		log.debug("Processing types");
340
		int count = 0;
341
		int total = 0;
342
		ResIterator iter = model.listResourcesWithProperty(RDF.type, CRM.E55_Type);
343
		while (iter.hasNext()) {
344
			total++;
345
			Resource res = iter.nextResource();
346
			String resourceURI = res.getURI();
347
			if (!uriProcessed.contains(resourceURI)) {
348
				ParthenosRegistryResource prr = processType(res, jsonFactory, idMap);
349
				//TODO: if something goes wrong we stop the registration but we are not rolling back the one that may have succeeded before.
350
				//Let's decide if this is ok or if we must be smarter than this
351
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
352
				uriProcessed.add(resourceURI);
353
				idMap.put(resourceURI, prr);
354
				count++;
355
			} else {
356
				log.debug(resourceURI + " already processed, now skipping it");
357
			}
358
		}
359
		log.debug(String.format("Registered %d/%d types", count, total));
360
		return count;
361

    
362
	}
363

    
364
	private ParthenosRegistryResource processType(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
365
			throws IOException {
366
		log.debug("Processing " + res.getURI());
367

    
368
		StringWriter sw = new StringWriter();
369
		JsonGenerator jg = jsonFactory.createGenerator(sw);
370
		jg.writeStartObject();
371
		String specificType = findSpecificType(res, CRM.E55_Type).getLocalName();
372
		String uuid = writeCommon(res, specificType, jg, idMap);
373
		//******THE FACETS *******//
374
		jg.writeArrayFieldStart("consistsOf");
375
		writeCommonFacets(res, jg);
376
		jg.writeEndArray();
377
		jg.writeEndObject();
378
		jg.close();
379
		String json = sw.toString();
380
		log.debug(json);
381
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
382
	}
383

    
384

    
385
	/**
386
	 * Write the common properties: header, class for all resources
387
	 *
388
	 * @param resource  input Resource.
389
	 * @param className name of the class for the registry
390
	 * @param jg        JsonGenerator to write with.
391
	 * @param idMap     map of the already assigned UUID
392
	 * @return the uuid of the resource
393
	 */
394
	protected String writeCommon(final Resource resource, final String className, final JsonGenerator jg, final Map<String, ParthenosRegistryResource> idMap)
395
			throws IOException {
396
		String uuid;
397
		if (idMap.containsKey(resource.getURI())) {
398
			uuid = idMap.get(resource.getURI()).getUuid();
399
		} else {
400
			uuid = UUID.randomUUID().toString();
401
			idMap.put(resource.getURI(), new ParthenosRegistryResource().setUuid(uuid));
402
		}
403
		jg.writeObjectFieldStart("header");
404
		jg.writeStringField("uuid", uuid);
405
		jg.writeEndObject();
406
		jg.writeStringField("@class", StringUtils.remove(className, '-'));
407
		return uuid;
408
	}
409

    
410
	/**
411
	 * Write the common facets: identifier and info facets
412
	 *
413
	 * @param res
414
	 * @param jg
415
	 */
416
	protected void writeCommonFacets(final Resource res, final JsonGenerator jg) throws IOException {
417
		facetWriter.writeIdentifierFacet(jg, res.getURI());
418
		facetWriter.writeP1Facets(jg, res);
419
		facetWriter.writeInfoFacet(jg, res);
420
	}
421

    
422
	protected int processDigitalObjects(final InfModel model,
423
			final Set<String> uriProcessed,
424
			final JsonFactory jsonFactory,
425
			final Map<String, ParthenosRegistryResource> idMap)
426
			throws IOException, ResourceRegistryException {
427
		log.debug("Processing digital objects (include dataset and software)");
428
		int count = 0;
429
		int total = 0;
430
		ResIterator iterDo = model.listResourcesWithProperty(RDF.type, CRMdig.D1_Digital_Object);
431
		while (iterDo.hasNext()) {
432
			total++;
433
			Resource res = iterDo.nextResource();
434
			String resourceURI = res.getURI();
435
			if (!uriProcessed.contains(resourceURI)) {
436
				ParthenosRegistryResource prr = processDigitalObject(res, jsonFactory, idMap);
437
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
438
				uriProcessed.add(resourceURI);
439
				idMap.put(resourceURI, prr);
440
				count++;
441
			} else {
442
				log.debug(resourceURI + " already processed, now skipping it");
443
			}
444
		}
445
		log.debug(String.format("Registered %d/%d digital objects", count, total));
446
		return count;
447
	}
448

    
449
	protected ParthenosRegistryResource processDigitalObject(final Resource res,
450
			final JsonFactory jsonFactory,
451
			final Map<String, ParthenosRegistryResource> idMap)
452
			throws IOException {
453
		log.debug("Processing " + res.getURI());
454
		String specificType = findSpecificType(res, CRMdig.D1_Digital_Object).getLocalName();
455
		StringWriter sw = new StringWriter();
456
		JsonGenerator jg = jsonFactory.createGenerator(sw);
457
		jg.writeStartObject();
458

    
459
		String uuid = writeCommon(res, specificType, jg, idMap);
460
		//******THE FACETS *******//
461
		jg.writeArrayFieldStart("consistsOf");
462
		//list of facets
463
		writeCommonFacets(res, jg);
464
		facetWriter.writeTemporalCoverageFacet(jg, res);
465
		facetWriter.writeRightsFacet(jg, res);
466

    
467
		jg.writeEndArray();
468
		jg.writeEndObject();
469
		jg.close();
470
		String json = sw.toString();
471
		log.debug(json);
472
		return new ParthenosRegistryResource().setUuid(uuid).setType(specificType).setJson(json);
473
	}
474

    
475
	protected int processActors(final InfModel model,
476
			Set<String> uriProcessed,
477
			final JsonFactory jsonFactory,
478
			final Map<String, ParthenosRegistryResource> idMap)
479
			throws IOException {
480
		log.debug("Processing actors");
481
		int count = 0;
482
		int total = 0;
483
		ResIterator iterActors = model.listResourcesWithProperty(RDF.type, CRM.E39_Actor);
484
		while (iterActors.hasNext()) {
485
			total++;
486
			Resource res = iterActors.nextResource();
487
			String resourceURI = res.getURI();
488
			if (!uriProcessed.contains(resourceURI)) {
489
				ParthenosRegistryResource prr = processActor(res, jsonFactory, idMap);
490
				uriProcessed.add(resourceURI);
491
				idMap.put(resourceURI, prr);
492
				count++;
493

    
494
			} else {
495
				log.debug(resourceURI + " already processed, now skipping it");
496
			}
497
		}
498
		log.debug(String.format("Registered %d/%d actors", count, total));
499
		return count;
500
	}
501

    
502
	protected ParthenosRegistryResource processActor(final Resource r, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
503
			throws IOException {
504
		log.debug("Processing " + r.getURI());
505
		String specificType = findSpecificType(r, CRM.E39_Actor).getLocalName();
506
		StringWriter sw = new StringWriter();
507
		JsonGenerator jg = jsonFactory.createGenerator(sw);
508
		jg.writeStartObject();
509

    
510
		String uuid = writeCommon(r, specificType, jg, idMap);
511
		//******THE FACETS *******//
512
		jg.writeArrayFieldStart("consistsOf");
513
		//list of facets
514
		writeCommonFacets(r, jg);
515
		facetWriter.writeContactReferenceFacet(jg, r);
516

    
517
		jg.writeEndArray();
518
		jg.writeEndObject();
519
		jg.close();
520
		String json = sw.toString();
521
		log.debug(json);
522
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
523
	}
524

    
525
	protected int processProjects(final InfModel model,
526
			Set<String> uriProcessed,
527
			final JsonFactory jsonFactory,
528
			final Map<String, ParthenosRegistryResource> idMap)
529
			throws IOException, ResourceRegistryException {
530
		log.debug("Processing projects");
531
		int count = 0;
532
		int total = 0;
533
		ResIterator iterProjects = model.listResourcesWithProperty(RDF.type, CRMpe.PE35_Project);
534
		while (iterProjects.hasNext()) {
535
			total++;
536
			Resource res = iterProjects.nextResource();
537
			String resourceURI = res.getURI();
538
			if (!uriProcessed.contains(resourceURI)) {
539
				ParthenosRegistryResource prr = processProject(res, jsonFactory, idMap);
540
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
541
				uriProcessed.add(resourceURI);
542
				idMap.put(resourceURI, prr);
543
				count++;
544
			} else {
545
				log.debug(resourceURI + " already processed, now skipping it");
546
			}
547
		}
548
		log.debug(String.format("Registered %d/%d projects", count, total));
549
		return count;
550
	}
551

    
552
	protected ParthenosRegistryResource processProject(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
553
			throws IOException {
554
		log.debug("Processing " + res.getURI());
555
		String specificType = findSpecificType(res, CRMpe.PE35_Project).getLocalName();
556
		StringWriter sw = new StringWriter();
557
		JsonGenerator jg = jsonFactory.createGenerator(sw);
558
		jg.writeStartObject();
559

    
560
		String uuid = writeCommon(res, specificType, jg, idMap);
561
		jg.writeArrayFieldStart("consistsOf");
562
		writeCommonFacets(res, jg);
563

    
564
		jg.writeEndArray();
565
		jg.writeEndObject();
566
		jg.close();
567
		String json = sw.toString();
568
		log.debug(json);
569
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
570
	}
571

    
572
	/**
573
	 * Finds the most specific type of res.
574
	 *
575
	 * @param res          Resource you want to find the most specific type
576
	 * @param fallbackType Resource representing the type to return if there is no type or if we get AmbiguousSpecificTypeException
577
	 * @return Resource: the most specific type, if any. fallbackType otherwise
578
	 */
579
	protected Resource findSpecificType(final Resource res, final Resource fallbackType) {
580
		Resource type = fallbackType;
581
		Set<Resource> types = AssemblerHelp.findSpecificTypes(res, fallbackType);
582
		if (types == null || types.isEmpty()) {
583
			log.warn("No specific type found. Returning the fallback type: " + fallbackType);
584
		}
585
		if(types.size() == 1){
586
			type = types.iterator().next();
587
		}
588
		if (types.size() > 1) {
589
			log.warn("Found more than one possible specific type: choosing the first");
590
			types.stream().forEach((t) -> log.warn(t));
591
			type = types.iterator().next();
592
		}
593
		return type;
594
	}
595

    
596
	public FacetWriter getFacetWriter() {
597
		return facetWriter;
598
	}
599

    
600
	public void setFacetWriter(final FacetWriter facetWriter) {
601
		this.facetWriter = facetWriter;
602
	}
603

    
604
	public String getApplicationToken() {
605
		return applicationToken;
606
	}
607

    
608
	public void setApplicationToken(final String applicationToken) {
609
		this.applicationToken = applicationToken;
610
	}
611

    
612
	public String getRegistryBaseURL() {
613
		return registryBaseURL;
614
	}
615

    
616
	public void setRegistryBaseURL(final String registryBaseURL) {
617
		this.registryBaseURL = registryBaseURL;
618
	}
619

    
620
	public RelWriter getRelWriter() {
621
		return relWriter;
622
	}
623

    
624
	public void setRelWriter(final RelWriter relWriter) {
625
		this.relWriter = relWriter;
626
	}
627

    
628
	public ResourceRegistryPublisher getResourceRegistryPublisher() {
629
		return resourceRegistryPublisher;
630
	}
631

    
632
	public void setResourceRegistryPublisher(final ResourceRegistryPublisher resourceRegistryPublisher) {
633
		this.resourceRegistryPublisher = resourceRegistryPublisher;
634
	}
635

    
636
	public ResourceRegistryClient getResourceRegistryClient() {
637
		return resourceRegistryClient;
638
	}
639

    
640
	public void setResourceRegistryClient(final ResourceRegistryClient resourceRegistryClient) {
641
		this.resourceRegistryClient = resourceRegistryClient;
642
	}
643

    
644
	public OntModel getBaseModel() {
645
		return baseModel;
646
	}
647

    
648
	public void setBaseModel(final OntModel baseModel) {
649
		this.baseModel = baseModel;
650
	}
651
}
(2-2/6)