org.bimserver.database.queries.om.JsonQueryObjectModelConverter Maven / Gradle / Ivy
package org.bimserver.database.queries.om;
/******************************************************************************
* Copyright (C) 2009-2016 BIMserver.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see {@literal }.
*****************************************************************************/
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.bimserver.emf.PackageMetaData;
import org.bimserver.shared.QueryException;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class JsonQueryObjectModelConverter {
private PackageMetaData packageMetaData;
public JsonQueryObjectModelConverter(PackageMetaData packageMetaData) {
this.packageMetaData = packageMetaData;
}
public ObjectNode toJson(Query query) {
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode queryNode = objectMapper.createObjectNode();
Map defines = query.getDefines();
ObjectNode definesNode = objectMapper.createObjectNode();
queryNode.set("defines", definesNode);
for (String key : defines.keySet()) {
ObjectNode includeNode = objectMapper.createObjectNode();
Include include = defines.get(key);
ArrayNode fieldsNode = objectMapper.createArrayNode();
for (EReference eReference : include.getFields()) {
fieldsNode.add(eReference.getName());
}
definesNode.set(key, includeNode);
}
ArrayNode queryPartsNode = objectMapper.createArrayNode();
queryNode.set("queries", queryPartsNode);
for (QueryPart queryPart : query.getQueryParts()) {
ObjectNode queryPartNode = objectMapper.createObjectNode();
if (queryPart.hasTypes()) {
ArrayNode typesNode = objectMapper.createArrayNode();
queryPartNode.set("types", typesNode);
for (EClass type : queryPart.getTypes()) {
typesNode.add(type.getName());
}
}
if (queryPart.hasOids()) {
ArrayNode oidsNode = objectMapper.createArrayNode();
queryPartNode.set("oids", oidsNode);
for (long oid : queryPart.getOids()) {
oidsNode.add(oid);
}
}
queryPartsNode.add(queryPartNode);
}
return queryNode;
}
public Query parseJson(String queryName, ObjectNode fullQuery) throws QueryException {
Query query = new Query(queryName, packageMetaData);
if (fullQuery.has("defines")) {
JsonNode defines = fullQuery.get("defines");
if (defines instanceof ObjectNode) {
parseDefines(query, (ObjectNode)fullQuery.get("defines"));
} else {
throw new QueryException("\"defines\" must be of type object");
}
}
if (fullQuery.has("queries")) {
JsonNode queriesNode = fullQuery.get("queries");
if (queriesNode instanceof ArrayNode) {
ArrayNode queries = (ArrayNode) fullQuery.get("queries");
if (queries.size() == 0) {
throw new QueryException("\"queries\" must contain at least one query");
}
for (int i=0; i fieldNames = jsonNode.fieldNames();
int i=0;
// First pass, get all the name and create stub includes, using two passing to allow the usage of includes defined later in the structure
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
JsonNode defineNode = jsonNode.get(fieldName);
if (defineNode instanceof ObjectNode) {
Include include = new Include(packageMetaData);
query.addDefine(fieldName, include);
} else {
throw new QueryException("\"defines\"[" + i + "] must be of type object");
}
i++;
}
// Second pass, actually construct the includes
fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
JsonNode defineNode = jsonNode.get(fieldName);
ObjectNode define = (ObjectNode)defineNode;
parseInclude(query, define, query.getDefine(fieldName));
}
}
private Include parseInclude(Query query, ObjectNode jsonNode, Include include) throws QueryException {
if (include == null) {
include = new Include(packageMetaData);
}
if (!jsonNode.has("type") && !jsonNode.has("types")) {
throw new QueryException("includes require a \"type\" or \"types\" field " + jsonNode);
}
if (jsonNode.has("type")) {
JsonNode typeNode = jsonNode.get("type");
if (typeNode.isTextual()) {
EClass eClass = packageMetaData.getEClassIncludingDependencies(typeNode.asText());
if (eClass == null) {
throw new QueryException("Cannot find type \"" + typeNode.asText() + "\"");
}
include.addType(eClass, false);
} else {
throw new QueryException("\"type\" field mst be of type string");
}
}
if (jsonNode.has("types")) {
JsonNode typesNode = jsonNode.get("types");
if (typesNode instanceof ArrayNode) {
ArrayNode types = (ArrayNode)typesNode;
if (types.size() == 0) {
throw new QueryException("\"types\" must have a least one element");
}
for (int i=0; i> fields = properties.fields();
while (fields.hasNext()) {
Entry entry = fields.next();
JsonNode value = entry.getValue();
if (value.isValueNode()) {
queryPart.addProperty(entry.getKey(), value.asBoolean());
} else {
throw new QueryException("property \"" + entry.getKey() + "\" type not supported");
}
}
} else {
throw new QueryException("\"properties\" must be of type object");
}
}
if (objectNode.has("inBoundingBox")) {
JsonNode boundingBoxNode = objectNode.get("inBoundingBox");
if (boundingBoxNode instanceof ObjectNode) {
ObjectNode boundingBox = (ObjectNode) boundingBoxNode;
double x = checkFloat(boundingBox, "x");
double y = checkFloat(boundingBox, "y");
double z = checkFloat(boundingBox, "z");
double width = checkFloat(boundingBox, "width");
double height = checkFloat(boundingBox, "height");
double depth = checkFloat(boundingBox, "depth");
queryPart.setInBoundingBox(new InBoundingBox(x, y, z, width, height, depth));
} else {
throw new QueryException("\"inBoundingBox\" should be of type object");
}
}
if (objectNode.has("include")) {
JsonNode includeNode = objectNode.get("include");
processSubInclude(query, queryPart, includeNode);
}
if (objectNode.has("includes")) {
JsonNode includesNode = objectNode.get("includes");
if (includesNode instanceof ArrayNode) {
ArrayNode includes = (ArrayNode)includesNode;
for (int i=0; i fieldNames = objectNode.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (fieldName.equals("includeAllFields") || fieldName.equals("type") || fieldName.equals("types") || fieldName.equals("oid") || fieldName.equals("oids") || fieldName.equals("guid") || fieldName.equals("guids") || fieldName.equals("properties") || fieldName.equals("inBoundingBox") || fieldName.equals("include") || fieldName.equals("includes") || fieldName.equals("includeAllSubtypes")) {
// fine
} else {
throw new QueryException("Unknown field: \"" + fieldName + "\"");
}
}
query.addQueryPart(queryPart);
}
private double checkFloat(ObjectNode node, String key) throws QueryException {
if (!node.has(key)) {
throw new QueryException("\"" + key + "\" not found on \"inBoundingBox\"");
}
JsonNode jsonNode = node.get(key);
if (jsonNode.isNumber()) {
return jsonNode.asDouble();
} else {
throw new QueryException("\"" + key + "\" should be of type number");
}
}
private void addType(ObjectNode objectNode, QueryPart queryPart, String type) throws QueryException {
if (type.equals("Object")) {
// no type filter
return;
}
EClass eClass = packageMetaData.getEClassIncludingDependencies(type);
if (eClass == null) {
throw new QueryException("Type \"" + type + "\" not found");
}
queryPart.addType(eClass, objectNode.has("includeAllSubtypes") && objectNode.get("includeAllSubtypes").asBoolean());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy