package eu.dnetlib.enabling.is.registry; import java.util.Date; import javax.annotation.Resource; import javax.xml.xpath.XPathExpressionException; import org.springframework.beans.factory.annotation.Required; import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException; import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService; import eu.dnetlib.enabling.is.registry.schema.OpaqueResourceValidator; import eu.dnetlib.enabling.is.registry.schema.ValidationException; import eu.dnetlib.enabling.is.registry.validation.ProfileValidationStrategy; import eu.dnetlib.enabling.is.registry.validation.RegistrationPhase; import eu.dnetlib.enabling.is.store.rmi.ISStoreException; import eu.dnetlib.enabling.is.store.rmi.ISStoreService; import eu.dnetlib.enabling.tools.CompatResourceIdentifierResolverImpl; import eu.dnetlib.enabling.tools.OpaqueResource; import eu.dnetlib.enabling.tools.ResourceIdentifierComposer; import eu.dnetlib.enabling.tools.ResourceIdentifierResolver; import eu.dnetlib.enabling.tools.ServiceLocator; import eu.dnetlib.enabling.tools.XQueryUtils; public class IdPreservingPendingResourceManagerImpl implements PendingResourceManager, ResourceKindResolver { /** * service locator for IS Store service. Necessary because this implementation of the pending resource manager needs * to move profiles from one collection to the other. */ private ServiceLocator registryLocator; /** * service locator for ISStore service. */ private ServiceLocator storeLocator; /** * This bean resolver */ private ResourceKindResolver resourceKindResolver; /** * used to validate resources. */ private OpaqueResourceValidator resourceValidator; /** * used to get the root collection. */ private XQueryUtils xqueryUtils; /** * manages resource identifier mappings with the abstract xmldb namespace (files/collections). */ @Resource private ResourceIdentifierResolver resIdResolver = new CompatResourceIdentifierResolverImpl(); /** * used to create a new resource id. */ @Resource private ResourceIdentifierComposer resIdComposer = new CompatResourceIdentifierResolverImpl(); /** * used to validate resources w.r.t. a set of defined properties. */ @Resource private ProfileValidationStrategy profileValidationStrategy; /** * {@inheritDoc} * * @see eu.dnetlib.enabling.is.registry.PendingResourceManager#setPending(eu.dnetlib.enabling.tools.OpaqueResource) */ @Override public void setPending(final OpaqueResource resource, final boolean local) { try { resource.setResourceKind(getPendingKindForType(resource.getResourceType())); if (!local) { registryLocator.getService().deleteProfile(resource.getResourceId()); registerProfile(resource); } } catch (XPathExpressionException e) { throw new IllegalStateException(e); } catch (ISRegistryException e) { throw new IllegalStateException(e); } } /** * {@inheritDoc} * * @see eu.dnetlib.enabling.is.registry.PendingResourceManager#setPending(eu.dnetlib.enabling.tools.OpaqueResource) */ @Override public void setPending(final OpaqueResource resource) { setPending(resource, false); } /** * {@inheritDoc} * * @see eu.dnetlib.enabling.is.registry.PendingResourceManager#setValid(eu.dnetlib.enabling.tools.OpaqueResource) */ @Override public void setValid(final OpaqueResource resource) { try { if (resource.getResourceKind() != null && resource.getResourceKind().equals(getNormalKindForType(resource.getResourceType()))) { throw new IllegalArgumentException("trying to validate an already valid resource"); } profileValidationStrategy.accept(resource, RegistrationPhase.Validate); resource.setResourceKind(getNormalKindForType(resource.getResourceType())); registryLocator.getService().deleteProfile(resource.getResourceId()); registerProfile(resource); } catch (XPathExpressionException e) { throw new IllegalStateException(e); } catch (ISRegistryException e) { throw new IllegalStateException(e); } catch (ValidationException e) { throw new IllegalStateException(e); } } public String registerProfile(final OpaqueResource resource) throws ISRegistryException { try { final String oldId = resource.getResourceId(); final String fileName = resIdResolver.getFileName(oldId); final String newColl = xqueryUtils.getCollectionPath(resource); final String newId = resIdComposer.createResourceId(fileName, newColl); resource.setResourceId(newId); resource.setModificationDate(new Date()); // log.info("validating to xml schema: " + resource.asString()); resourceValidator.validate(resource); // TODO: factor out ResourceType class storeLocator.getService().insertXML(fileName, xqueryUtils.getRootCollection() + newColl, resource.asString()); return resource.getResourceId(); } catch (ISStoreException e) { throw new ISRegistryException(e); } catch (ValidationException e) { throw new ISRegistryException("profile is not conforming to the schema: " + e.getMessage(), e); } } @Override public String getNormalKindForType(String resourceType) throws XPathExpressionException { return resourceKindResolver.getNormalKindForType(resourceType); } @Override public String getPendingKindForType(String resourceType) throws XPathExpressionException { return resourceKindResolver.getPendingKindForType(resourceType); } /////////////////////////////// public ServiceLocator getRegistryLocator() { return registryLocator; } @Required public void setRegistryLocator(final ServiceLocator registryLocator) { this.registryLocator = registryLocator; } public ResourceKindResolver getResourceKindResolver() { return resourceKindResolver; } @Required public void setResourceKindResolver(ResourceKindResolver resourceKindResolver) { this.resourceKindResolver = resourceKindResolver; } @Required public void setXqueryUtils(final XQueryUtils xqueryUtils) { this.xqueryUtils = xqueryUtils; } public ServiceLocator getStoreLocator() { return storeLocator; } @Required public void setStoreLocator(final ServiceLocator storeLocator) { this.storeLocator = storeLocator; } public OpaqueResourceValidator getResourceValidator() { return resourceValidator; } @Required public void setResourceValidator(final OpaqueResourceValidator resourceValidator) { this.resourceValidator = resourceValidator; } }