Project

General

Profile

1 41699 sandro.lab
package eu.dnetlib.enabling.is.registry; // NOPMD
2
3
import java.io.IOException;
4
import java.util.Date;
5
import java.util.List;
6
import java.util.UUID;
7
import javax.annotation.Resource;
8
import javax.jws.WebService;
9
import javax.xml.parsers.ParserConfigurationException;
10
import javax.xml.xpath.XPath;
11
import javax.xml.xpath.XPathConstants;
12
import javax.xml.xpath.XPathExpressionException;
13
import javax.xml.xpath.XPathFactory;
14
15
import eu.dnetlib.DnetConstants;
16
import eu.dnetlib.enabling.is.registry.schema.OpaqueResourceValidator;
17
import eu.dnetlib.enabling.is.registry.schema.ValidationException;
18
import eu.dnetlib.enabling.is.registry.validation.ProfileValidationStrategy;
19
import eu.dnetlib.enabling.is.registry.validation.RegistrationPhase;
20
import eu.dnetlib.enabling.is.store.ISStore;
21
import eu.dnetlib.enabling.is.store.ISStoreException;
22
import eu.dnetlib.enabling.tools.*;
23
import eu.dnetlib.miscutils.functional.hash.Hashing;
24 41734 michele.ar
import eu.dnetlib.rmi.common.APIDeprecatedException;
25
import eu.dnetlib.rmi.common.UnimplementedException;
26 41841 sandro.lab
import eu.dnetlib.rmi.enabling.*;
27 41699 sandro.lab
import org.apache.commons.logging.Log;
28
import org.apache.commons.logging.LogFactory;
29
import org.springframework.beans.factory.annotation.Required;
30
import org.w3c.dom.Element;
31
import org.xml.sax.SAXException;
32
33
/**
34
 * Registry service implementation.
35
 *
36
 * @author marko
37
 *
38
 */
39
@WebService(targetNamespace = "http://services.dnetlib.eu/")
40
public class ISRegistryServiceImpl extends AbstractBaseService implements ISRegistryService { // NOPMD by marko on
41
42
	/**
43
	 * logger.
44
	 */
45
	private static final Log log = LogFactory.getLog(ISRegistryServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
46
47
	/**
48
	 * error message: secure profile registration.
49
	 */
50
	private static final String ERROR_SEC_PROFILE = "cannot register secure profile";
51
52
	/**
53
	 * error message: trying to retrieve the current stored version of the resource profile.
54
	 */
55
	private static final String CANT_FETCH = "cannot fetch original profile";
56
57
	/**
58
	 * error message: cannot create a resource.
59
	 */
60
	private static final String CANT_CREATE = "cannot create resource";
61
62
	/**
63
	 * IS Store
64
	 */
65
	private ISStore isStore;
66
67
	/**
68
	 * IS Lookup
69
	 */
70
	private ISLookUpService isLookup;
71
72
73
74
	/**
75
	 * manages the pending state of resource. Different implementations can be plugged in.
76
	 */
77
	private PendingResourceManager pendingManager = new CompatPendingResourceManagerImpl();
78
79
	/**
80
	 * manages resource identifier mappings with the abstract xmldb namespace (files/collections).
81
	 */
82
	@Resource
83
	private ResourceIdentifierResolver resIdResolver = new CompatResourceIdentifierResolverImpl();
84
85
	/**
86
	 * used to validate resources.
87
	 */
88
	private OpaqueResourceValidator resourceValidator;
89
90
	/**
91
	 * used to validate resources w.r.t. a set of defined properties.
92
	 */
93
	@Resource
94
	private ProfileValidationStrategy profileValidationStrategy;
95
96
	/**
97
	 * query utils. Used to obtain xmldb collection names and other things useful for interacting with the IS_Store.
98
	 */
99
	private XQueryUtils xqueryUtils;
100
101
	/**
102
	 * the blackboard management stuff is factored out here.
103
	 */
104
	@Resource
105
	private RegistryBlackboardManager blackboardManager;
106
107
	@Override
108
	public void start() {
109
		super.start();
110
	}
111
112
	/**
113
	 * {@inheritDoc}
114
	 *
115 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#addBlackBoardMessage(java.lang.String, java.lang.String, java.lang.String)
116 41699 sandro.lab
	 */
117
	@Override
118
	public void addBlackBoardMessage(final String profId, final String messageId, final String message) throws ISRegistryException {
119
		blackboardManager.addMessage(profId, messageId, message);
120
	}
121
122
	/**
123
	 * {@inheritDoc}
124
	 *
125 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#addOrUpdateResourceType(java.lang.String, java.lang.String)
126 41699 sandro.lab
	 */
127
	@Override
128
	public boolean addOrUpdateResourceType(final String resourceType, final String resourceSchema) throws ISRegistryException {
129
		return addResourceType(resourceType, resourceSchema);
130
	}
131
132
	/**
133
	 * {@inheritDoc}
134
	 *
135 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#addProfileNode(java.lang.String, java.lang.String, java.lang.String)
136 41699 sandro.lab
	 */
137
	@Override
138
	public boolean addProfileNode(final String profId, final String xpath, final String node) throws ISRegistryException {
139
		// TODO Auto-generated method stub
140
		throw new UnimplementedException();
141
	}
142
143
	/**
144
	 * {@inheritDoc}
145
	 *
146 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#addResourceType(java.lang.String, java.lang.String)
147 41699 sandro.lab
	 */
148
	@Override
149
	public boolean addResourceType(final String resourceType, final String resourceSchema) throws ISRegistryException {
150
		try {
151
			return isStore.insertXML(resourceType, xqueryUtils.getRootCollection() + DnetConstants.RESOURCE_TYPES,
152
					resourceSchema);
153
		} catch (ISStoreException e) {
154
			throw new ISRegistryException("cannot add resource type", e);
155
		}
156
	}
157
158
	/**
159
	 * {@inheritDoc}
160
	 *
161 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#deleteBlackBoardMessage(java.lang.String, java.lang.String)
162 41699 sandro.lab
	 */
163
	@Override
164
	public void deleteBlackBoardMessage(final String profId, final String messageId) throws ISRegistryException {
165
		blackboardManager.deleteMessage(profId, messageId);
166
	}
167
168
	/**
169
	 * {@inheritDoc}
170
	 *
171 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#deleteProfile(java.lang.String)
172 41699 sandro.lab
	 */
173
	@Override
174
	public boolean deleteProfile(final String resId) throws ISRegistryException {
175
		try {
176
			final boolean res = isStore.deleteXML(resIdResolver.getFileName(resId),
177
					"/db/DRIVER/" + resIdResolver.getCollectionName(resId));
178
			if (!res) { throw new ISRegistryDocumentNotFoundException("document " + resId + " not found"); }
179
180
			return true;
181
		} catch (ISStoreException e) {
182
			throw new ISRegistryException("cannot delete profile " + resId, e);
183
		}
184
	}
185
186
	/**
187
	 * {@inheritDoc}
188
	 *
189 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#deleteProfiles(java.util.List)
190 41699 sandro.lab
	 */
191
	@Override
192
	public boolean deleteProfiles(final List<String> arrayprofId) throws ISRegistryException {
193
		throw new APIDeprecatedException();
194
	}
195
196
	/**
197
	 * {@inheritDoc}
198
	 *
199 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#deleteResourceType(java.lang.String, java.lang.Boolean)
200 41699 sandro.lab
	 */
201
	@Override
202
	public boolean deleteResourceType(final String resourceType, final Boolean hierarchical) throws ISRegistryException {
203
		try {
204
			return isStore.deleteXML(resourceType, xqueryUtils.getRootCollection() + DnetConstants.RESOURCE_TYPES);
205
		} catch (ISStoreException e) {
206
			throw new ISRegistryException("error deleting resource type " + resourceType, e);
207
		}
208
	}
209
210
	/**
211
	 * {@inheritDoc}
212
	 *
213 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#executeXUpdate(java.lang.String)
214 41699 sandro.lab
	 */
215
	@Override
216
	public boolean executeXUpdate(final String xquery) throws ISRegistryException {
217
		try {
218
			return isStore.executeXUpdate(xquery);
219
		} catch (ISStoreException e) {
220
			throw new ISRegistryException(e);
221
		}
222
	}
223
224
	/**
225
	 * {@inheritDoc}
226
	 *
227 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#insertProfileForValidation(java.lang.String, java.lang.String)
228 41699 sandro.lab
	 */
229
	@Override
230
	public String insertProfileForValidation(final String resourceType, final String resourceProfile) throws ISRegistryException {
231
		try {
232
			final OpaqueResource resource = new StringOpaqueResource(resourceProfile);
233
			if (!resourceType.equals(resource.getResourceType())) { throw new ISRegistryException("expected resource type doesn't match to resource"); }
234
235
			pendingManager.setPending(resource, true);
236
237
			return registerProfile(resource.asString());
238
		} catch (XPathExpressionException e) {
239
			throw new ISRegistryException(e);
240
		} catch (SAXException e) {
241
			throw new ISRegistryException(e);
242
		} catch (IOException e) {
243
			throw new ISRegistryException(e);
244
		} catch (ParserConfigurationException e) {
245
			throw new ISRegistryException(e);
246
		}
247
	}
248
249
	/**
250
	 * {@inheritDoc}
251
	 *
252 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#refreshProfile(java.lang.String, java.lang.String)
253 41699 sandro.lab
	 */
254
	@Override
255
	public boolean refreshProfile(final String profId, final String resourceType) throws ISRegistryException {
256
		// TODO Auto-generated method stub
257
		throw new UnimplementedException();
258
	}
259
260
	/**
261
	 * {@inheritDoc}
262
	 *
263 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#registerProfile(java.lang.String)
264 41699 sandro.lab
	 */
265
	@Override
266
	public String registerProfile(final String resourceProfile) throws ISRegistryException {
267
		log.debug("registering profile");
268
269
		try {
270
			final OpaqueResource resource = new StringOpaqueResource(resourceProfile);
271
272
			// TODO: factor this out (possibly not within the OpaqueResource class)
273
			final String coll = xqueryUtils.getCollectionPath(resource);
274
			final String fileName = UUID.randomUUID().toString();
275
			final String newId = fileName + "_" + Hashing.encodeBase64(coll);
276
			resource.setResourceId(newId);
277
278
			resource.setModificationDate(new Date());
279
280
			// log.info("validating to xml schema: " + resource.asString());
281
			resourceValidator.validate(resource);
282
283
			profileValidationStrategy.accept(resource, RegistrationPhase.Register);
284
285
			// TODO: factor out ResourceType class
286
			isStore.insertXML(fileName, xqueryUtils.getRootCollection() + coll, resource.asString());
287
288
			return resource.getResourceId();
289
		} catch (XPathExpressionException e) {
290
			throw new ISRegistryException(e);
291
		} catch (SAXException e) {
292
			throw new ISRegistryException(e);
293
		} catch (IOException e) {
294
			throw new ISRegistryException(e);
295
		} catch (ParserConfigurationException e) {
296
			throw new ISRegistryException(e);
297
		} catch (ISStoreException e) {
298
			throw new ISRegistryException(e);
299
		} catch (ValidationException e) {
300
			throw new ISRegistryException("profile is not conforming to the schema: " + e.getMessage(), e);
301
		}
302
	}
303
304
	/**
305
	 * {@inheritDoc}
306
	 *
307 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#registerSecureProfile(java.lang.String, java.lang.String)
308 41699 sandro.lab
	 */
309
	@Override
310
	public String registerSecureProfile(final String resourceProfId, final String secureProfId) throws ISRegistryException {
311
		try {
312
			synchronized (this) {
313
				final String secureProfSrc;
314
				try {
315
					secureProfSrc = isLookup.getResourceProfile(secureProfId); // NOPMD
316
				} catch (ISLookUpDocumentNotFoundException e) {
317
					throw new ISRegistryException("cannot register secure profile, the given secure profile doesn't exist", e);
318
				}
319
				final OpaqueResource secureProf = new StringOpaqueResource(secureProfSrc);
320
321
				final String profId = validateProfile(resourceProfId);
322
323
				final XPath xpath = XPathFactory.newInstance().newXPath();
324
				final Element idEl = (Element) xpath.evaluate("/RESOURCE_PROFILE/BODY/CONFIGURATION/resourceId", secureProf.asDom(), XPathConstants.NODE);
325
				idEl.setTextContent(profId);
326
327
				if (!updateProfile(secureProfId, secureProf.asString(), secureProf.getResourceType())) { throw new ISRegistryException(
328
						"cannot update security profile (updateProfile returned false)"); }
329
330
				return profId;
331
			}
332
		} catch (XPathExpressionException e) {
333
			throw new ISRegistryException(ERROR_SEC_PROFILE, e);
334
		} catch (SAXException e) {
335
			throw new ISRegistryException(ERROR_SEC_PROFILE, e);
336
		} catch (IOException e) {
337
			throw new ISRegistryException(ERROR_SEC_PROFILE, e);
338
		} catch (ParserConfigurationException e) {
339
			throw new ISRegistryException(ERROR_SEC_PROFILE, e);
340
		} catch (ISLookUpException e) {
341
			throw new ISRegistryException("cannot register secure profile, problem fetching the given secure profile", e);
342
		}
343
	}
344
345
	/**
346
	 * {@inheritDoc}
347
	 *
348 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#removeProfileNode(java.lang.String, java.lang.String)
349 41699 sandro.lab
	 */
350
	@Override
351
	public boolean removeProfileNode(final String profId, final String nodeId) throws ISRegistryException {
352
		// TODO Auto-generated method stub
353
		throw new UnimplementedException();
354
	}
355
356
	/**
357
	 * {@inheritDoc}
358
	 *
359 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#replyBlackBoardMessage(java.lang.String, java.lang.String)
360 41699 sandro.lab
	 */
361
	@Override
362
	public void replyBlackBoardMessage(final String profId, final String message) throws ISRegistryException {
363
		blackboardManager.replyMessage(profId, message);
364
	}
365
366
	/**
367
	 * {@inheritDoc}
368
	 *
369 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#updateProfile(java.lang.String, java.lang.String, java.lang.String)
370 41699 sandro.lab
	 */
371
	@Override
372
	public boolean updateProfile(final String resId, final String resourceProfile, final String resourceType) throws ISRegistryException {
373
		try {
374
			final String fileName = resIdResolver.getFileName(resId);
375
			final String fileColl = "/db/DRIVER/" + resIdResolver.getCollectionName(resId);
376
377
			final String oldProfileSrc = isStore.getXML(fileName, fileColl);
378
379
			if (oldProfileSrc == null) { throw new ISRegistryException("cannot update a non existing profile " + resId); }
380
381
			final OpaqueResource oldResource = new StringOpaqueResource(oldProfileSrc);
382
383
			final StringOpaqueResource newResource = new StringOpaqueResource(resourceProfile);
384
			newResource.setResourceId(oldResource.getResourceId());
385
			newResource.setResourceKind(oldResource.getResourceKind());
386
			newResource.setResourceType(oldResource.getResourceType());
387
			newResource.setModificationDate(new Date());
388
389
			getResourceValidator().validate(newResource);
390
391
			return isStore.updateXML(fileName, fileColl, newResource.asString());
392
		} catch (ISStoreException e) {
393
			throw new ISRegistryException(e);
394
		} catch (XPathExpressionException e) {
395
			throw new ISRegistryException(e);
396
		} catch (ValidationException e) {
397
			throw new ISRegistryException("profile not conforming to xml schema", e);
398
		} catch (SAXException e) {
399
			throw new ISRegistryException(e);
400
		} catch (IOException e) {
401
			throw new ISRegistryException(e);
402
		} catch (ParserConfigurationException e) {
403
			throw new ISRegistryException(e);
404
		}
405
	}
406
407
	/**
408
	 * {@inheritDoc}
409
	 *
410 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#updateProfileDHN(java.lang.String)
411 41699 sandro.lab
	 */
412
	@Override
413
	public String updateProfileDHN(final String resourceProfile) throws ISRegistryException {
414
		// TODO Auto-generated method stub
415
		throw new UnimplementedException();
416
	}
417
418
	/**
419
	 * {@inheritDoc}
420
	 *
421 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#updateProfileNode(java.lang.String, java.lang.String, java.lang.String)
422 41699 sandro.lab
	 */
423
	@Override
424
	public boolean updateProfileNode(final String profId, final String xpath, final String node) throws ISRegistryException {
425
		return executeXUpdate("for $x in collection('/db/DRIVER')//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value eq '" + profId + "']" + xpath
426
				+ " return update replace $x with " + node);
427
	}
428
429
	/**
430
	 * {@inheritDoc}
431
	 *
432 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#updateRegionDescription(java.lang.String, java.lang.String)
433 41699 sandro.lab
	 */
434
	@Override
435
	public boolean updateRegionDescription(final String profId, final String resourceProfile) throws ISRegistryException {
436
		// TODO Auto-generated method stub
437
		throw new UnimplementedException();
438
	}
439
440
	/**
441
	 * {@inheritDoc}
442
	 *
443 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#validateProfile(java.lang.String)
444 41699 sandro.lab
	 */
445
	@Override
446
	public String validateProfile(final String profId) throws ISRegistryException {
447
		try {
448
			final String resourceProfile = isLookup.getResourceProfile(profId);
449
			final OpaqueResource resource = new StringOpaqueResource(resourceProfile);
450
			pendingManager.setValid(resource);
451
452
			return resource.getResourceId();
453
		} catch (ISLookUpException e) {
454
			throw new ISRegistryException(CANT_FETCH, e);
455
		} catch (XPathExpressionException e) {
456
			throw new ISRegistryException(CANT_CREATE, e);
457
		} catch (SAXException e) {
458
			throw new ISRegistryException(CANT_CREATE, e);
459
		} catch (IOException e) {
460
			throw new ISRegistryException(CANT_CREATE, e);
461
		} catch (ParserConfigurationException e) {
462
			throw new ISRegistryException(CANT_CREATE, e);
463
		}
464
	}
465
466
	/**
467
	 * {@inheritDoc}
468
	 *
469 41734 michele.ar
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#invalidateProfile(java.lang.String)
470 41699 sandro.lab
	 */
471
	@Override
472
	public String invalidateProfile(final String profId) throws ISRegistryException {
473
		try {
474
			final String resourceProfile = isLookup.getResourceProfile(profId);
475
			final OpaqueResource resource = new StringOpaqueResource(resourceProfile);
476
			pendingManager.setPending(resource);
477
478
			return resource.getResourceId();
479
		} catch (ISLookUpException e) {
480
			throw new ISRegistryException(CANT_FETCH, e);
481
		} catch (XPathExpressionException e) {
482
			throw new ISRegistryException(CANT_CREATE, e);
483
		} catch (SAXException e) {
484
			throw new ISRegistryException(CANT_CREATE, e);
485
		} catch (IOException e) {
486
			throw new ISRegistryException(CANT_CREATE, e);
487
		} catch (ParserConfigurationException e) {
488
			throw new ISRegistryException(CANT_CREATE, e);
489
		}
490
	}
491
492
	/**
493
	 * {@inheritDoc}
494 41841 sandro.lab
	 *
495
	 * @see eu.dnetlib.rmi.enabling.ISRegistryService#validateProfile(String)
496 41699 sandro.lab
	 */
497
	@Override
498
	public List<String> validateProfiles(final List<String> profIds) throws ISRegistryException {
499
		throw new APIDeprecatedException();
500
	}
501
502
503
	public PendingResourceManager getPendingManager() {
504
		return pendingManager;
505
	}
506
507
	public void setPendingManager(final PendingResourceManager pendingManager) {
508
		this.pendingManager = pendingManager;
509
	}
510
511
	public ResourceIdentifierResolver getResIdResolver() {
512
		return resIdResolver;
513
	}
514
515
	public void setResIdResolver(final ResourceIdentifierResolver resIdResolver) {
516
		this.resIdResolver = resIdResolver;
517
	}
518
519
	public OpaqueResourceValidator getResourceValidator() {
520
		return resourceValidator;
521
	}
522
523
	@Required
524
	public void setResourceValidator(final OpaqueResourceValidator resourceValidator) {
525
		this.resourceValidator = resourceValidator;
526
	}
527
528 41841 sandro.lab
	public XQueryUtils getXqueryUtils() {
529
		return xqueryUtils;
530
	}
531
532 41699 sandro.lab
	@Required
533
	public void setXqueryUtils(final XQueryUtils xqueryUtils) {
534
		this.xqueryUtils = xqueryUtils;
535
	}
536
537
	public RegistryBlackboardManager getBlackboardManager() {
538
		return blackboardManager;
539
	}
540
541
	public void setBlackboardManager(final RegistryBlackboardManager blackboardManager) {
542
		this.blackboardManager = blackboardManager;
543
	}
544
545
	public ProfileValidationStrategy getProfileValidationStrategy() {
546
		return profileValidationStrategy;
547
	}
548
549
	public void setProfileValidationStrategy(final ProfileValidationStrategy profileValidationStrategy) {
550
		this.profileValidationStrategy = profileValidationStrategy;
551
	}
552
553
	public ISStore getIsStore() {
554
		return isStore;
555
	}
556
557
	@Required
558
	public void setIsStore(final ISStore isStore) {
559
		this.isStore = isStore;
560
	}
561
562
	public ISLookUpService getIsLookup() {
563
		return isLookup;
564
	}
565
566
	@Required
567
	public void setIsLookup(final ISLookUpService isLookup) {
568
		this.isLookup = isLookup;
569
	}
570
571
}