324 lines
11 KiB
Java
324 lines
11 KiB
Java
package org.gcube.informationsystem.resourceregistry.queries.templates;
|
|
|
|
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
|
|
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
|
|
import org.gcube.informationsystem.base.reference.AccessType;
|
|
import org.gcube.informationsystem.queries.templates.reference.entities.QueryTemplate;
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException;
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException;
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException;
|
|
import org.gcube.informationsystem.resourceregistry.contexts.security.QueryTemplatesSecurityContext;
|
|
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext;
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility;
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.entities.EntityElementManagement;
|
|
import org.gcube.informationsystem.resourceregistry.queries.json.JsonQuery;
|
|
import org.gcube.informationsystem.resourceregistry.utils.DBUtility;
|
|
import org.gcube.informationsystem.serialization.ElementMapper;
|
|
import org.gcube.informationsystem.types.reference.entities.EntityType;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import com.arcadedb.database.Document;
|
|
import com.arcadedb.graph.Vertex;
|
|
import com.arcadedb.query.sql.executor.Result;
|
|
import com.arcadedb.query.sql.executor.ResultSet;
|
|
import com.arcadedb.remote.RemoteDatabase;
|
|
|
|
/**
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
*/
|
|
public class QueryTemplateManagement extends EntityElementManagement<QueryTemplate, EntityType> {
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(QueryTemplateManagement.class);
|
|
|
|
protected String name;
|
|
protected JsonNode params;
|
|
|
|
public QueryTemplateManagement() {
|
|
super(AccessType.QUERY_TEMPLATE);
|
|
this.typeName = QueryTemplate.NAME;
|
|
}
|
|
|
|
public QueryTemplateManagement(RemoteDatabase database) throws ResourceRegistryException {
|
|
this();
|
|
this.database = database;
|
|
getWorkingContext();
|
|
}
|
|
|
|
protected void checkERMatch() throws ResourceRegistryException {
|
|
getDocumentType();
|
|
}
|
|
|
|
protected void checkNameMatch() throws ResourceRegistryException {
|
|
if(jsonNode!=null && name!=null) {
|
|
String jsonName = jsonNode.get(QueryTemplate.NAME_PROPERTY).asText();
|
|
if(name.compareTo(jsonName)!=0) {
|
|
String error = String.format(
|
|
"Name provided in json (%s) differs from the one (%s) used to identify the %s instance",
|
|
jsonName, name, typeName);
|
|
throw new ResourceRegistryException(error);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setName(String name) throws ResourceRegistryException {
|
|
this.name = name;
|
|
checkNameMatch();
|
|
}
|
|
|
|
protected void checkJsonNode() throws ResourceRegistryException {
|
|
super.checkJsonNode();
|
|
checkNameMatch();
|
|
}
|
|
|
|
public String getName() {
|
|
if (name == null) {
|
|
if (element == null) {
|
|
if (jsonNode != null) {
|
|
name = jsonNode.get(QueryTemplate.NAME_PROPERTY).asText();
|
|
}
|
|
} else {
|
|
name = element.getString(QueryTemplate.NAME_PROPERTY);
|
|
}
|
|
}
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
protected SecurityContext getWorkingContext() throws ResourceRegistryException {
|
|
if (workingContext == null) {
|
|
workingContext = QueryTemplatesSecurityContext.getInstance();
|
|
}
|
|
return workingContext;
|
|
}
|
|
|
|
@Override
|
|
protected JsonNode createCompleteJsonNode() throws ResourceRegistryException {
|
|
try {
|
|
JsonNode queryTemplate = serializeSelfAsJsonNode();
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
String templateString = element.getString(QueryTemplate.TEMPLATE_PROPERTY);
|
|
JsonNode templateJsonNode = objectMapper.readTree(templateString);
|
|
((ObjectNode) queryTemplate).replace(QueryTemplate.TEMPLATE_PROPERTY, templateJsonNode);
|
|
return queryTemplate;
|
|
}catch (ResourceRegistryException e) {
|
|
throw e;
|
|
}catch (Exception e) {
|
|
throw new ResourceRegistryException(e);
|
|
}
|
|
|
|
}
|
|
|
|
protected StringBuffer getSelectQuery() {
|
|
StringBuffer select = new StringBuffer();
|
|
select.append("SELECT FROM ");
|
|
select.append(QueryTemplate.NAME);
|
|
select.append(" WHERE ");
|
|
select.append(QueryTemplate.NAME_PROPERTY);
|
|
select.append(" = ");
|
|
select.append("\"");
|
|
select.append(getName());
|
|
select.append("\"");
|
|
return select;
|
|
}
|
|
|
|
protected void checkIfNameAlreadyExists() throws AlreadyPresentException {
|
|
StringBuffer select = getSelectQuery();
|
|
|
|
StringBuffer errorMessage = new StringBuffer();
|
|
errorMessage.append("A ");
|
|
errorMessage.append(QueryTemplate.NAME);
|
|
errorMessage.append(" with ");
|
|
errorMessage.append(this.getName());
|
|
errorMessage.append(" already exists");
|
|
|
|
logger.trace("Checking if {} -> {}", errorMessage, select);
|
|
|
|
ResultSet resultSet = database.command("sql", select.toString());
|
|
|
|
if (resultSet != null) {
|
|
try {
|
|
if(resultSet.hasNext()) {
|
|
throw new AlreadyPresentException(errorMessage.toString());
|
|
}
|
|
}finally {
|
|
resultSet.close();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
protected void tryTemplate() throws Exception {
|
|
QueryTemplate queryTemplate = ElementMapper.unmarshal(QueryTemplate.class, jsonNode.toString());
|
|
JsonNode jsonQueryNode = queryTemplate.getJsonQuery();
|
|
JsonQuery jsonQuery = new JsonQuery();
|
|
jsonQuery.setJsonQuery(jsonQueryNode);
|
|
try {
|
|
jsonQuery.query();
|
|
}catch (ResourceRegistryException e) {
|
|
throw e;
|
|
}catch (Exception e) {
|
|
throw new ResourceRegistryException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Vertex retrieveElement() throws NotFoundException, ResourceRegistryException {
|
|
try {
|
|
StringBuffer select = getSelectQuery();
|
|
ResultSet resultSet = database.query("sql", select.toString());
|
|
|
|
if(resultSet == null || !resultSet.hasNext()) {
|
|
if(resultSet!=null) {
|
|
resultSet.close();
|
|
}
|
|
throw new NotFoundException("Error retrieving " + QueryTemplate.NAME + " with name " + getName());
|
|
}
|
|
|
|
Result result = resultSet.next();
|
|
Vertex queryTemplate = ElementManagementUtility.getElementFromOptional(result.getVertex());
|
|
|
|
logger.trace("{} representing vertex is {}", QueryTemplate.NAME, DBUtility.getAsStringForLogging(queryTemplate));
|
|
|
|
if(resultSet.hasNext()) {
|
|
resultSet.close();
|
|
throw new NotFoundException("Found more than one " + QueryTemplate.NAME + " with name " + name + ". This should not occur, please contact the administrator");
|
|
}
|
|
|
|
resultSet.close();
|
|
return queryTemplate;
|
|
} catch(NotFoundException e) {
|
|
throw getSpecificNotFoundException(e);
|
|
} catch(ResourceRegistryException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new ResourceRegistryException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected Vertex reallyCreate() throws AlreadyPresentException, InvalidQueryException, ResourceRegistryException {
|
|
try {
|
|
checkIfNameAlreadyExists();
|
|
tryTemplate();
|
|
createVertex();
|
|
return getElement();
|
|
} catch(ResourceRegistryException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
logger.trace("Error while creating {} for {} ({}) using {}", Vertex.class.getSimpleName(),
|
|
accessType.getName(), typeName, jsonNode, e);
|
|
throw new ResourceRegistryException("Error Creating " + typeName + " with " + jsonNode, e.getCause());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected Vertex reallyUpdate() throws NotFoundException, ResourceRegistryException {
|
|
try {
|
|
tryTemplate();
|
|
Vertex queryTemplate = getElement();
|
|
queryTemplate = (Vertex) updateProperties(documentType, queryTemplate, jsonNode, ignoreKeys, ignoreStartWithKeys);
|
|
return getElement();
|
|
} catch(ResourceRegistryException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
logger.trace("Error while creating {} for {} ({}) using {}", Vertex.class.getSimpleName(),
|
|
accessType.getName(), typeName, jsonNode, e);
|
|
throw new ResourceRegistryException("Error Creating " + typeName + " with " + jsonNode, e.getCause());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void reallyDelete() throws NotFoundException, ResourceRegistryException {
|
|
logger.debug("Going to delete {} with name {}", accessType.getName(), name);
|
|
getElement().delete();
|
|
}
|
|
|
|
@Override
|
|
protected NotFoundException getSpecificNotFoundException(NotFoundException e) {
|
|
return new NotFoundException(e);
|
|
}
|
|
|
|
@Override
|
|
protected AlreadyPresentException getSpecificAlreadyPresentException(String message) {
|
|
return new AlreadyPresentException(message);
|
|
}
|
|
|
|
@Override
|
|
public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException {
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
ArrayNode arrayNode = objectMapper.createArrayNode();
|
|
Iterable<Document> iterable = database.browseClass(typeName, polymorphic);
|
|
for (Document vertex : iterable) {
|
|
QueryTemplateManagement queryTemplateManagement = new QueryTemplateManagement();
|
|
queryTemplateManagement.setElement((Vertex) vertex);
|
|
try {
|
|
JsonNode jsonObject = queryTemplateManagement.serializeAsJsonNode();
|
|
arrayNode.add(jsonObject);
|
|
} catch (ResourceRegistryException e) {
|
|
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
|
|
vertex.toString(), DBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
|
}
|
|
}
|
|
try {
|
|
return objectMapper.writeValueAsString(arrayNode);
|
|
} catch (JsonProcessingException e) {
|
|
throw new ResourceRegistryException(e);
|
|
}
|
|
}
|
|
|
|
public void setParams(String params) throws ResourceRegistryException {
|
|
try {
|
|
if(params!=null && params.compareTo("")!=0) {
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
JsonNode jsonNode = objectMapper.readTree(params);
|
|
setParams(jsonNode);
|
|
}
|
|
} catch (ResourceRegistryException e) {
|
|
throw e;
|
|
} catch (Exception e) {
|
|
throw new ResourceRegistryException(e);
|
|
}
|
|
|
|
}
|
|
|
|
public void setParams(JsonNode params) throws ResourceRegistryException {
|
|
this.params = params;
|
|
}
|
|
|
|
/**
|
|
* Run the query after having replaced query parameter with the provided values
|
|
* @return the result as JSON string
|
|
* @throws Exception
|
|
*/
|
|
public String run() throws ResourceRegistryException {
|
|
try {
|
|
String read = read();
|
|
QueryTemplate queryTemplate = ElementMapper.unmarshal(QueryTemplate.class, read);
|
|
JsonNode query = null;
|
|
if(params!=null) {
|
|
query = queryTemplate.getJsonQuery(params);
|
|
}else {
|
|
query = queryTemplate.getJsonQuery();
|
|
}
|
|
JsonQuery jsonQuery = new JsonQuery();
|
|
jsonQuery.setJsonQuery(query);
|
|
return jsonQuery.query();
|
|
} catch (ResourceRegistryException e) {
|
|
throw e;
|
|
} catch (Exception e) {
|
|
throw new ResourceRegistryException(e);
|
|
}
|
|
}
|
|
|
|
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
|
|
// No sanity check required
|
|
}
|
|
|
|
}
|