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.assembler.exceptions.AmbiguousSpecificTypeException;
24
import org.apache.jena.ontology.OntModel;
25
import org.apache.jena.ontology.OntModelSpec;
26
import org.apache.jena.rdf.model.*;
27
import org.apache.jena.vocabulary.RDF;
28
import org.gcube.common.authorization.client.Constants;
29
import org.gcube.common.authorization.library.AuthorizationEntry;
30
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
31
import org.gcube.common.scope.api.ScopeProvider;
32
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
33
import org.gcube.informationsystem.resourceregistry.client.ParthenosRegistryClientSetter;
34
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
35
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
36
import org.gcube.informationsystem.resourceregistry.publisher.ParthenosRegistryPublisherSetter;
37
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher;
38
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory;
39
import org.springframework.beans.factory.annotation.Autowired;
40
import org.springframework.beans.factory.annotation.Value;
41
import org.springframework.stereotype.Component;
42

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

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

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

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

    
63
	private ResourceRegistryPublisher resourceRegistryPublisher;
64
	private ResourceRegistryClient resourceRegistryClient;
65

    
66
	private OntModel baseModel;
67

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

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

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

    
100

    
101

    
102
	public int unregister(final String datasourceApi){
103
		//TODO: implement me
104
		return -1;
105
	}
106

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

    
119
			JsonFactory jsonFactory = new JsonFactory();
120
			Set<String> uriProcessed = Sets.newHashSet();
121
			/* Maps URI to ParthenosRegistryResource (with uuids) */
122
			Map<String, ParthenosRegistryResource> idMap = Maps.newHashMap();
123

    
124
			/* Resource */
125
			int registeredServices = processServices(model, uriProcessed, jsonFactory, idMap);
126
			int registeredDigitalObjects = processDigitalObjects(model, uriProcessed, jsonFactory, idMap);
127
			int registeredActors = processActors(model, uriProcessed, jsonFactory, idMap);
128
			int registeredProjects = processProjects(model, uriProcessed, jsonFactory, idMap);
129

    
130
			int total = registeredActors+registeredDigitalObjects+registeredProjects+registeredServices;
131
			log.debug(String.format("Registered %d resources from record with objIdentifier %s", total, objIdentifier));
132

    
133
			/* Relationships */
134
			int relTotal = 0;
135
			for(String uri : uriProcessed){
136
				relTotal += processRelationships(model, uri, idMap);
137
			}
138
			log.debug(String.format("Registered %d relationships from record with objIdentifier %s", relTotal, objIdentifier));
139
		}
140
	}
141

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

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

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

    
259

    
260
	protected InfModel loadBaseModel() {
261
		return ModelFactory.createRDFSModel(baseModel);
262
	}
263

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

    
289
	}
290

    
291
	private ParthenosRegistryResource processService(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap) throws IOException {
292
		log.debug("Processing " + res.getURI());
293

    
294
		StringWriter sw = new StringWriter();
295
		JsonGenerator jg = jsonFactory.createGenerator(sw);
296
		jg.writeStartObject();
297
		String specificType = findSpecificType(res, CRMpe.PE1_Service).getLocalName();
298
		String uuid = writeCommon(res, specificType, jg, idMap);
299
		//******THE FACETS *******//
300
		jg.writeArrayFieldStart("consistsOf");
301
		//list of facets
302
		writeCommonFacets(res, jg);
303
		facetWriter.writeEventFacet(jg);
304
		facetWriter.writeRightsFacet(jg, res);
305
		if (res.hasProperty(CRMpe.PP2_provided_by)) {
306
			//TODO: shouldn't this be a rel to an actor?
307
			Resource provider = res.getPropertyResourceValue(CRMpe.PP2_provided_by);
308
			facetWriter.writeContactReferenceFacet(jg, provider);
309
		}
310
		facetWriter.writeDesignatedAccessPointFacet(jg, res);
311
		jg.writeEndArray();
312
		jg.writeEndObject();
313
		jg.close();
314
		String json = sw.toString();
315
		log.debug(json);
316
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
317
	}
318

    
319
	/**
320
	 * Write the common properties: header, class for all resources
321
	 *
322
	 * @param resource  input Resource.
323
	 * @param className name of the class for the registry
324
	 * @param jg        JsonGenerator to write with.
325
	 * @param idMap     map of the already assigned UUID
326
	 * @return the uuid of the resource
327
	 */
328
	protected String writeCommon(final Resource resource, final String className, final JsonGenerator jg, final Map<String, ParthenosRegistryResource> idMap) throws IOException {
329
		String uuid;
330
		if (idMap.containsKey(resource.getURI())) {
331
			uuid = idMap.get(resource.getURI()).getUuid();
332
		} else {
333
			uuid = UUID.randomUUID().toString();
334
			idMap.put(resource.getURI(), new ParthenosRegistryResource().setUuid(uuid));
335
		}
336
		jg.writeObjectFieldStart("header");
337
		jg.writeStringField("uuid", uuid);
338
		jg.writeEndObject();
339
		jg.writeStringField("@class", StringUtils.remove(className, '-'));
340
		return uuid;
341
	}
342

    
343
	/**
344
	 * Write the common facets: identifier and info facets
345
	 *
346
	 * @param res
347
	 * @param jg
348
	 */
349
	protected void writeCommonFacets(final Resource res, final JsonGenerator jg) throws IOException {
350
		facetWriter.writeIdentifierFacet(jg, res.getURI());
351
		facetWriter.writeP1Facets(jg, res);
352
		facetWriter.writeInfoFacet(jg, res);
353
	}
354

    
355
	protected int processDigitalObjects(final InfModel model, final Set<String> uriProcessed, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
356
			throws IOException, ResourceRegistryException {
357
		log.debug("Processing digital objects (include dataset and software)");
358
		int count = 0;
359
		int total = 0;
360
		ResIterator iterDo = model.listResourcesWithProperty(RDF.type, CRMdig.D1_Digital_Object);
361
		while (iterDo.hasNext()) {
362
			total++;
363
			Resource res = iterDo.nextResource();
364
			String resourceURI = res.getURI();
365
			if (!uriProcessed.contains(resourceURI)) {
366
				ParthenosRegistryResource prr = processDigitalObject(res, jsonFactory, idMap);
367
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
368
				uriProcessed.add(resourceURI);
369
				idMap.put(resourceURI, prr);
370
				count++;
371
			} else {
372
				log.debug(resourceURI + " already processed, now skipping it");
373
			}
374
		}
375
		log.debug(String.format("Registered %d/%d digital objects", count, total));
376
		return count;
377
	}
378

    
379
	protected ParthenosRegistryResource processDigitalObject(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
380
			throws IOException {
381
		log.debug("Processing " + res.getURI());
382
		String specificType = findSpecificType(res, CRMdig.D1_Digital_Object).getLocalName();
383
		StringWriter sw = new StringWriter();
384
		JsonGenerator jg = jsonFactory.createGenerator(sw);
385
		jg.writeStartObject();
386

    
387
		String uuid = writeCommon(res, specificType, jg, idMap);
388
		//******THE FACETS *******//
389
		jg.writeArrayFieldStart("consistsOf");
390
		//list of facets
391
		writeCommonFacets(res, jg);
392
		facetWriter.writeTemporalCoverageFacet(jg, res);
393
		facetWriter.writeRightsFacet(jg, res);
394

    
395
		jg.writeEndArray();
396
		jg.writeEndObject();
397
		jg.close();
398
		String json = sw.toString();
399
		log.debug(json);
400
		return new ParthenosRegistryResource().setUuid(uuid).setType(specificType).setJson(json);
401
	}
402

    
403
	protected int processActors(final InfModel model, Set<String> uriProcessed, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
404
			throws IOException {
405
		log.debug("Processing actors");
406
		int count = 0;
407
		int total = 0;
408
		ResIterator iterActors = model.listResourcesWithProperty(RDF.type, CRM.E39_Actor);
409
		while (iterActors.hasNext()) {
410
			total++;
411
			Resource res = iterActors.nextResource();
412
			String resourceURI = res.getURI();
413
			if (!uriProcessed.contains(resourceURI)) {
414
				ParthenosRegistryResource prr = processActor(res, jsonFactory, idMap);
415
				uriProcessed.add(resourceURI);
416
				idMap.put(resourceURI, prr);
417
				count++;
418

    
419
			} else {
420
				log.debug(resourceURI + " already processed, now skipping it");
421
			}
422
		}
423
		log.debug(String.format("Registered %d/%d actors", count, total));
424
		return count;
425
	}
426

    
427
	protected ParthenosRegistryResource processActor(final Resource r, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap) throws IOException {
428
		log.debug("Processing " + r.getURI());
429
		String specificType = findSpecificType(r, CRM.E39_Actor).getLocalName();
430
		StringWriter sw = new StringWriter();
431
		JsonGenerator jg = jsonFactory.createGenerator(sw);
432
		jg.writeStartObject();
433

    
434
		String uuid = writeCommon(r, specificType, jg, idMap);
435
		//******THE FACETS *******//
436
		jg.writeArrayFieldStart("consistsOf");
437
		//list of facets
438
		writeCommonFacets(r, jg);
439
		facetWriter.writeContactReferenceFacet(jg, r);
440

    
441
		jg.writeEndArray();
442
		jg.writeEndObject();
443
		jg.close();
444
		String json = sw.toString();
445
		log.debug(json);
446
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
447
	}
448

    
449
	protected int processProjects(final InfModel model, Set<String> uriProcessed, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap)
450
			throws IOException, ResourceRegistryException {
451
		log.debug("Processing projects");
452
		int count = 0;
453
		int total = 0;
454
		ResIterator iterProjects = model.listResourcesWithProperty(RDF.type, CRMpe.PE35_Project);
455
		while (iterProjects.hasNext()) {
456
			total++;
457
			Resource res = iterProjects.nextResource();
458
			String resourceURI = res.getURI();
459
			if (!uriProcessed.contains(resourceURI)) {
460
				ParthenosRegistryResource prr = processProject(res, jsonFactory, idMap);
461
				this.resourceRegistryPublisher.createResource(prr.getRegistryType(), prr.getJson());
462
				uriProcessed.add(resourceURI);
463
				idMap.put(resourceURI, prr);
464
				count++;
465
			} else {
466
				log.debug(resourceURI + " already processed, now skipping it");
467
			}
468
		}
469
		log.debug(String.format("Registered %d/%d projects", count, total));
470
		return count;
471
	}
472

    
473
	protected ParthenosRegistryResource processProject(final Resource res, final JsonFactory jsonFactory, final Map<String, ParthenosRegistryResource> idMap) throws IOException {
474
		log.debug("Processing " + res.getURI());
475
		String specificType = findSpecificType(res, CRMpe.PE35_Project).getLocalName();
476
		StringWriter sw = new StringWriter();
477
		JsonGenerator jg = jsonFactory.createGenerator(sw);
478
		jg.writeStartObject();
479

    
480
		String uuid = writeCommon(res, specificType, jg, idMap);
481
		jg.writeArrayFieldStart("consistsOf");
482
		writeCommonFacets(res, jg);
483

    
484
		jg.writeEndArray();
485
		jg.writeEndObject();
486
		jg.close();
487
		String json = sw.toString();
488
		log.debug(json);
489
		return new ParthenosRegistryResource().setJson(json).setType(specificType).setUuid(uuid);
490
	}
491

    
492
	/**
493
	 * Finds the most specific type of res.
494
	 *
495
	 * @param res          Resource you want to find the most specific type
496
	 * @param fallbackType Resource representing the type to return if there is no type or if we get AmbiguousSpecificTypeException
497
	 * @return Resource: the most specific type, if any. fallbackType otherwise
498
	 */
499
	protected Resource findSpecificType(final Resource res, final Resource fallbackType) {
500
		Resource specType = fallbackType;
501
		try {
502
			specType = AssemblerHelp.findSpecificType(res, fallbackType);
503
		} catch (AmbiguousSpecificTypeException e) {
504
			log.warn(res.getURI() + ": " + e.getMessage());
505
		}
506
		return specType;
507
	}
508

    
509
	public FacetWriter getFacetWriter() {
510
		return facetWriter;
511
	}
512

    
513
	public void setFacetWriter(final FacetWriter facetWriter) {
514
		this.facetWriter = facetWriter;
515
	}
516

    
517
	public String getApplicationToken() {
518
		return applicationToken;
519
	}
520

    
521
	public void setApplicationToken(final String applicationToken) {
522
		this.applicationToken = applicationToken;
523
	}
524

    
525
	public String getRegistryBaseURL() {
526
		return registryBaseURL;
527
	}
528

    
529
	public void setRegistryBaseURL(final String registryBaseURL) {
530
		this.registryBaseURL = registryBaseURL;
531
	}
532

    
533
	public RelWriter getRelWriter() {
534
		return relWriter;
535
	}
536

    
537
	public void setRelWriter(final RelWriter relWriter) {
538
		this.relWriter = relWriter;
539
	}
540

    
541
	public ResourceRegistryPublisher getResourceRegistryPublisher() {
542
		return resourceRegistryPublisher;
543
	}
544

    
545
	public void setResourceRegistryPublisher(final ResourceRegistryPublisher resourceRegistryPublisher) {
546
		this.resourceRegistryPublisher = resourceRegistryPublisher;
547
	}
548

    
549
	public ResourceRegistryClient getResourceRegistryClient() {
550
		return resourceRegistryClient;
551
	}
552

    
553
	public void setResourceRegistryClient(final ResourceRegistryClient resourceRegistryClient) {
554
		this.resourceRegistryClient = resourceRegistryClient;
555
	}
556

    
557
	public OntModel getBaseModel() {
558
		return baseModel;
559
	}
560

    
561
	public void setBaseModel(final OntModel baseModel) {
562
		this.baseModel = baseModel;
563
	}
564
}
(2-2/6)