package org.gcube.gcat.profile; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.NotFoundException; import javax.ws.rs.WebApplicationException; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; import org.gcube.common.resources.gcore.GenericResource; import org.gcube.common.resources.gcore.Resources; import org.gcube.datacatalogue.metadatadiscovery.reader.MetadataFormatDiscovery; import org.gcube.datacatalogue.metadatadiscovery.reader.QueryForResourceUtil; import org.gcube.gcat.api.roles.Role; import org.gcube.gcat.persistence.ckan.CKANUser; import org.gcube.gcat.persistence.ckan.CKANUserCache; import org.gcube.gcat.utils.Constants; import org.gcube.informationsystem.publisher.RegistryPublisher; import org.gcube.informationsystem.publisher.RegistryPublisherFactory; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient; import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory; import org.gcube.resourcemanagement.model.impl.entities.facets.SchemaFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.facets.SimpleFacetImpl; import org.gcube.resourcemanagement.model.impl.entities.resources.ConfigurationImpl; import org.gcube.resourcemanagement.model.reference.entities.facets.IdentifierFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.SchemaFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.SimpleFacet; import org.gcube.resourcemanagement.model.reference.entities.resources.Configuration; import org.gcube.resourcemanagement.model.reference.relations.consistsof.IsIdentifiedBy; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.Query; import org.gcube.resources.discovery.client.queries.impl.QueryBox; import org.gcube.resources.discovery.icclient.ICFactory; import org.json.JSONObject; import org.json.XML; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; /** * @author Luca Frosini (ISTI - CNR) */ public class ResourceRegistryProfile { public static int PRETTY_PRINT_INDENT_FACTOR = 4; public static final String PROFILE = "profile"; public static final String PROFILE_SCHEMA = "profileSchema"; public static final String SCHEMA_URL_ADDRESS = "https://code-repo.d4science.org/gCubeSystem/gcubedatacatalogue-metadata-discovery/raw/branch/master/src/main/resources/org/gcube/datacatalogue/metadatadiscovery/Gdcmetadataprofilev3.xsd"; public static final URL SCHEMA_URL; static { try { SCHEMA_URL = new URL(SCHEMA_URL_ADDRESS); } catch (MalformedURLException e) { throw new RuntimeException(e); } } private static Logger logger = LoggerFactory.getLogger(ResourceRegistryProfile.class); protected ObjectMapper mapper; public ResourceRegistryProfile() { mapper = new ObjectMapper(); } public ObjectMapper getMapper() { return mapper; } public ArrayNode list() { ArrayNode arrayNode = mapper.createArrayNode(); try { Set names = (new MetadataUtility()).getProfilesNames(); for(String name : names) { arrayNode.add(name); } return arrayNode; } catch(Exception e) { throw new InternalServerErrorException(e); } } /* * https://wiki.gcube-system.org/gcube/GCube_Model#Configuration */ protected Configuration instantiateConfiguration(String name, String xml) throws Exception { Configuration configuration = new ConfigurationImpl(); /* IdentifierFacet identifierFacet = new IdentifierFacetImpl(); identifierFacet.setValue(name); identifierFacet.setType(IdentificationType.STRING); IsIdentifiedBy isIdentifiedBy = new IsIdentifiedByImpl(configuration, identifierFacet); configuration.addFacet(isIdentifiedBy); */ SimpleFacet profile = new SimpleFacetImpl(); profile.setAdditionalProperty(PROFILE, xml); configuration.addFacet(profile); SchemaFacet schemaFacet = new SchemaFacetImpl(); schemaFacet.setName("gCube Item Profile"); schemaFacet.setDescription("gCube Metadata Profile defines a Metadata schema XML-based for adding custom metadata fields."); /* ValueSchema valueSchema = new ValueSchemaImpl(); valueSchema.setSchema(SCHEMA_URL.toURI()); valueSchema.setValue(DataCalogueMetadataFormatReader.getProfileSchemaString()); schemaFacet.setSchema(valueSchema); */ configuration.addFacet(schemaFacet); return configuration; } protected Configuration getConfiguration(String name) throws ResourceRegistryException { ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create(); Map map = new HashMap<>(); map.put(IdentifierFacet.VALUE_PROPERTY, name); List configurations = resourceRegistryClient.getFilteredResources(Configuration.class, IsIdentifiedBy.class, IdentifierFacet.class, false, map); return configurations.get(0); } /* * TODO Check the Queries because the name in the Profile differs from the name in * * */ protected GenericResource instantiateGenericResource(String name, String xml) throws Exception { GenericResource genericResource = new GenericResource(); org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile(); profile.type(MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE); profile.name(name); profile.description("Profile create using " + Constants.CATALOGUE_NAME); // appendXmlFragment(profile, xml); profile.newBody(xml); StringWriter stringWriter = new StringWriter(); Resources.marshal(genericResource, stringWriter); logger.debug("The generated {} is\n{}", GenericResource.class.getSimpleName(), stringWriter.toString()); return genericResource; } protected void createGenericResource(String name, String xml) throws Exception { GenericResource genericResource = instantiateGenericResource(name, xml); RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); genericResource = registryPublisher.create(genericResource); StringWriter stringWriter = new StringWriter(); Resources.marshal(genericResource, stringWriter); logger.trace("The {} with ID {} has been created \n{}", GenericResource.class.getSimpleName(), genericResource.id(), stringWriter.toString()); } protected GenericResource getGenericResource(String name) { String query = QueryForResourceUtil.getGcubeGenericQueryStringForSecondaryTypeAndName(name, MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE); Query q = new QueryBox(query); DiscoveryClient client = ICFactory.clientFor(GenericResource.class); List resources = client.submit(q); if(resources == null || resources.size() == 0) { throw new InternalServerErrorException( "No Resources with secondaryType '" + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE + "' and name '" + name + "' exists in the current context"); } else { if(resources.size() == 1) { GenericResource genericResource = resources.get(0); return genericResource; } else { throw new InternalServerErrorException("More than one Resource with secondaryType '" + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE + "' and name '" + name + "' exists in the current context"); } } } protected void updateGenericResource(String name, String xml) { GenericResource genericResource = getGenericResource(name); logger.info("The {} with ID {} is going to be updated", GenericResource.class.getSimpleName(), genericResource.id()); genericResource.profile().newBody(xml); RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); registryPublisher.update(genericResource); StringWriter stringWriter = new StringWriter(); Resources.marshal(genericResource, stringWriter); logger.trace("The {} with ID {} has been updated to \n{}", GenericResource.class.getSimpleName(), genericResource.id(), stringWriter.toString()); } protected void removeGenericResource(String name) { GenericResource genericResource = getGenericResource(name); RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); registryPublisher.remove(genericResource); } public String read(String name, boolean xml) { try { String profile = (new MetadataUtility()).getMetadataFormat(name).getMetadataSource(); if(profile != null) { if(xml) { return profile; } else { JSONObject xmlJSONObj = XML.toJSONObject(profile); String jsonString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR); return jsonString; } } else { throw new NotFoundException("Profile with name " + name + " not found"); } } catch(WebApplicationException e) { throw e; } catch(Exception e) { throw new InternalServerErrorException(e.getMessage()); } } public boolean createOrUpdate(String name, String xml) throws SAXException { try { CKANUser ckanUser = CKANUserCache.getCurrrentCKANUser(); if(ckanUser.getRole().ordinal()