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

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

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

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

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

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

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

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

    
302
	}
303

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

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

    
333
	/**
334
	 * Write the common properties: header, class for all resources
335
	 *
336
	 * @param resource  input Resource.
337
	 * @param className name of the class for the registry
338
	 * @param jg        JsonGenerator to write with.
339
	 * @param idMap     map of the already assigned UUID
340
	 * @return the uuid of the resource
341
	 */
342
	protected String writeCommon(final Resource resource, final String className, final JsonGenerator jg, final Map<String, ParthenosRegistryResource> idMap)
343
			throws IOException {
344
		String uuid;
345
		if (idMap.containsKey(resource.getURI())) {
346
			uuid = idMap.get(resource.getURI()).getUuid();
347
		} else {
348
			uuid = UUID.randomUUID().toString();
349
			idMap.put(resource.getURI(), new ParthenosRegistryResource().setUuid(uuid));
350
		}
351
		jg.writeObjectFieldStart("header");
352
		jg.writeStringField("uuid", uuid);
353
		jg.writeEndObject();
354
		jg.writeStringField("@class", StringUtils.remove(className, '-'));
355
		return uuid;
356
	}
357

    
358
	/**
359
	 * Write the common facets: identifier and info facets
360
	 *
361
	 * @param res
362
	 * @param jg
363
	 */
364
	protected void writeCommonFacets(final Resource res, final JsonGenerator jg) throws IOException {
365
		facetWriter.writeIdentifierFacet(jg, res.getURI());
366
		facetWriter.writeP1Facets(jg, res);
367
		facetWriter.writeInfoFacet(jg, res);
368
	}
369

    
370
	protected int processDigitalObjects(final InfModel model,
371
			final Set<String> uriProcessed,
372
			final JsonFactory jsonFactory,
373
			final Map<String, ParthenosRegistryResource> idMap)
374
			throws IOException, ResourceRegistryException {
375
		log.debug("Processing digital objects (include dataset and software)");
376
		int count = 0;
377
		int total = 0;
378
		ResIterator iterDo = model.listResourcesWithProperty(RDF.type, CRMdig.D1_Digital_Object);
379
		while (iterDo.hasNext()) {
380
			total++;
381
			Resource res = iterDo.nextResource();
382
			String resourceURI = res.getURI();
383
			if (!uriProcessed.contains(resourceURI)) {
384
				ParthenosRegistryResource prr = processDigitalObject(res, jsonFactory, idMap);
385
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
386
				uriProcessed.add(resourceURI);
387
				idMap.put(resourceURI, prr);
388
				count++;
389
			} else {
390
				log.debug(resourceURI + " already processed, now skipping it");
391
			}
392
		}
393
		log.debug(String.format("Registered %d/%d digital objects", count, total));
394
		return count;
395
	}
396

    
397
	protected ParthenosRegistryResource processDigitalObject(final Resource res,
398
			final JsonFactory jsonFactory,
399
			final Map<String, ParthenosRegistryResource> idMap)
400
			throws IOException {
401
		log.debug("Processing " + res.getURI());
402
		String specificType = findSpecificType(res, CRMdig.D1_Digital_Object).getLocalName();
403
		StringWriter sw = new StringWriter();
404
		JsonGenerator jg = jsonFactory.createGenerator(sw);
405
		jg.writeStartObject();
406

    
407
		String uuid = writeCommon(res, specificType, jg, idMap);
408
		//******THE FACETS *******//
409
		jg.writeArrayFieldStart("consistsOf");
410
		//list of facets
411
		writeCommonFacets(res, jg);
412
		facetWriter.writeTemporalCoverageFacet(jg, res);
413
		facetWriter.writeRightsFacet(jg, res);
414

    
415
		jg.writeEndArray();
416
		jg.writeEndObject();
417
		jg.close();
418
		String json = sw.toString();
419
		log.debug(json);
420
		return new ParthenosRegistryResource().setUuid(uuid).setType(specificType).setJson(json);
421
	}
422

    
423
	protected int processActors(final InfModel model,
424
			Set<String> uriProcessed,
425
			final JsonFactory jsonFactory,
426
			final Map<String, ParthenosRegistryResource> idMap)
427
			throws IOException {
428
		log.debug("Processing actors");
429
		int count = 0;
430
		int total = 0;
431
		ResIterator iterActors = model.listResourcesWithProperty(RDF.type, CRM.E39_Actor);
432
		while (iterActors.hasNext()) {
433
			total++;
434
			Resource res = iterActors.nextResource();
435
			String resourceURI = res.getURI();
436
			if (!uriProcessed.contains(resourceURI)) {
437
				ParthenosRegistryResource prr = processActor(res, jsonFactory, idMap);
438
				uriProcessed.add(resourceURI);
439
				idMap.put(resourceURI, prr);
440
				count++;
441

    
442
			} else {
443
				log.debug(resourceURI + " already processed, now skipping it");
444
			}
445
		}
446
		log.debug(String.format("Registered %d/%d actors", count, total));
447
		return count;
448
	}
449

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

    
458
		String uuid = writeCommon(r, specificType, jg, idMap);
459
		//******THE FACETS *******//
460
		jg.writeArrayFieldStart("consistsOf");
461
		//list of facets
462
		writeCommonFacets(r, jg);
463
		facetWriter.writeContactReferenceFacet(jg, r);
464

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

    
473
	protected int processProjects(final InfModel model,
474
			Set<String> uriProcessed,
475
			final JsonFactory jsonFactory,
476
			final Map<String, ParthenosRegistryResource> idMap)
477
			throws IOException, ResourceRegistryException {
478
		log.debug("Processing projects");
479
		int count = 0;
480
		int total = 0;
481
		ResIterator iterProjects = model.listResourcesWithProperty(RDF.type, CRMpe.PE35_Project);
482
		while (iterProjects.hasNext()) {
483
			total++;
484
			Resource res = iterProjects.nextResource();
485
			String resourceURI = res.getURI();
486
			if (!uriProcessed.contains(resourceURI)) {
487
				ParthenosRegistryResource prr = processProject(res, jsonFactory, idMap);
488
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
489
				uriProcessed.add(resourceURI);
490
				idMap.put(resourceURI, prr);
491
				count++;
492
			} else {
493
				log.debug(resourceURI + " already processed, now skipping it");
494
			}
495
		}
496
		log.debug(String.format("Registered %d/%d projects", count, total));
497
		return count;
498
	}
499

    
500
	protected ParthenosRegistryResource processProject(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
501
			throws IOException {
502
		log.debug("Processing " + res.getURI());
503
		String specificType = findSpecificType(res, CRMpe.PE35_Project).getLocalName();
504
		StringWriter sw = new StringWriter();
505
		JsonGenerator jg = jsonFactory.createGenerator(sw);
506
		jg.writeStartObject();
507

    
508
		String uuid = writeCommon(res, specificType, jg, idMap);
509
		jg.writeArrayFieldStart("consistsOf");
510
		writeCommonFacets(res, jg);
511

    
512
		jg.writeEndArray();
513
		jg.writeEndObject();
514
		jg.close();
515
		String json = sw.toString();
516
		log.debug(json);
517
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
518
	}
519

    
520
	/**
521
	 * Finds the most specific type of res.
522
	 *
523
	 * @param res          Resource you want to find the most specific type
524
	 * @param fallbackType Resource representing the type to return if there is no type or if we get AmbiguousSpecificTypeException
525
	 * @return Resource: the most specific type, if any. fallbackType otherwise
526
	 */
527
	protected Resource findSpecificType(final Resource res, final Resource fallbackType) {
528
		Resource type = fallbackType;
529
		Set<Resource> types = AssemblerHelp.findSpecificTypes(res, fallbackType);
530
		if (types == null || types.isEmpty()) {
531
			log.warn("No specific type found. Returning the fallback type: " + fallbackType);
532
		}
533
		if(types.size() == 1){
534
			type = types.iterator().next();
535
		}
536
		if (types.size() > 1) {
537
			log.warn("Found more than one possible specific type: choosing the first");
538
			types.stream().forEach((t) -> log.warn(t));
539
			type = types.iterator().next();
540
		}
541
		return type;
542
	}
543

    
544
	public FacetWriter getFacetWriter() {
545
		return facetWriter;
546
	}
547

    
548
	public void setFacetWriter(final FacetWriter facetWriter) {
549
		this.facetWriter = facetWriter;
550
	}
551

    
552
	public String getApplicationToken() {
553
		return applicationToken;
554
	}
555

    
556
	public void setApplicationToken(final String applicationToken) {
557
		this.applicationToken = applicationToken;
558
	}
559

    
560
	public String getRegistryBaseURL() {
561
		return registryBaseURL;
562
	}
563

    
564
	public void setRegistryBaseURL(final String registryBaseURL) {
565
		this.registryBaseURL = registryBaseURL;
566
	}
567

    
568
	public RelWriter getRelWriter() {
569
		return relWriter;
570
	}
571

    
572
	public void setRelWriter(final RelWriter relWriter) {
573
		this.relWriter = relWriter;
574
	}
575

    
576
	public ResourceRegistryPublisher getResourceRegistryPublisher() {
577
		return resourceRegistryPublisher;
578
	}
579

    
580
	public void setResourceRegistryPublisher(final ResourceRegistryPublisher resourceRegistryPublisher) {
581
		this.resourceRegistryPublisher = resourceRegistryPublisher;
582
	}
583

    
584
	public ResourceRegistryClient getResourceRegistryClient() {
585
		return resourceRegistryClient;
586
	}
587

    
588
	public void setResourceRegistryClient(final ResourceRegistryClient resourceRegistryClient) {
589
		this.resourceRegistryClient = resourceRegistryClient;
590
	}
591

    
592
	public OntModel getBaseModel() {
593
		return baseModel;
594
	}
595

    
596
	public void setBaseModel(final OntModel baseModel) {
597
		this.baseModel = baseModel;
598
	}
599
}
(2-2/6)