nl.bimbase.bimworks.client.BimQuery Maven / Gradle / Ivy
package nl.bimbase.bimworks.client;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
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.DoubleNode;
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import nl.bimbase.bimworks.actions.Discipline;
import nl.bimbase.simplebim.Qid;
@JsonInclude(Include.NON_NULL)
public class BimQuery {
public static final BimQuery ALL = new BimQuery();
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final int VERSION = 1;
private int version = 1;
private Set types;
private Set buildingStoreyLevels;
private Set buildingStoreyNames;
private Set buildingStoreyQids;
private Set qids;
private Map fields;
private Map> properties;
private Set calculatedValues;
private Set quantities;
private Set disciplines;
private Set layers;
private Set classifications;
private Set materialNames;
private Set guids;
private Set propertySets;
private Set zones;
private Map modelInfo;
private Set groupFeatures;
public BimQuery() {
}
@JsonIgnore
public boolean isEmpty() {
return
types == null &&
buildingStoreyLevels == null &&
qids == null &&
fields == null &&
properties == null &&
calculatedValues == null &&
quantities == null &&
disciplines == null &&
layers == null &&
classifications == null &&
materialNames == null &&
buildingStoreyNames == null &&
guids == null &&
propertySets == null &&
zones == null &&
buildingStoreyQids == null &&
modelInfo == null;
}
public BimQuery addType(String... types) {
if (this.types == null) {
this.types = new TreeSet<>(); // Canonical
}
for (String type : types) {
this.types.add(type);
}
return this;
}
public ObjectNode toJson() {
ObjectNode queryNode = OBJECT_MAPPER.createObjectNode();
queryNode.put("version", version);
if (types != null) {
ArrayNode typesNode = OBJECT_MAPPER.createArrayNode();
for (String type : types) {
typesNode.add(type);
}
queryNode.set("types", typesNode);
}
if (modelInfo != null) {
ObjectNode modelInfoNode = OBJECT_MAPPER.createObjectNode();
for (String key : modelInfo.keySet()) {
modelInfoNode.put(key, modelInfo.get(key));
}
}
if (buildingStoreyLevels != null) {
ArrayNode buildingStoreyLevelsNode = OBJECT_MAPPER.createArrayNode();
for (BuildingStoreyLevelQuery level : buildingStoreyLevels) {
buildingStoreyLevelsNode.add(level.toJson());
}
queryNode.set("buildingStoreyLevels", buildingStoreyLevelsNode);
}
if (buildingStoreyQids != null) {
ArrayNode buildingStoreyQidsNode = OBJECT_MAPPER.createArrayNode();
for (Qid qid : buildingStoreyQids) {
buildingStoreyQidsNode.add(qid.toString());
}
queryNode.set("buildingStoreyQids", buildingStoreyQidsNode);
}
if (buildingStoreyNames != null) {
ArrayNode buildingStoreysNode = OBJECT_MAPPER.createArrayNode();
for (String name : buildingStoreyNames) {
buildingStoreysNode.add(name);
}
queryNode.set("buildingStoreys", buildingStoreysNode);
}
if (layers != null) {
ArrayNode layersNode = OBJECT_MAPPER.createArrayNode();
for (String layer : layers) {
layersNode.add(layer);
}
queryNode.set("layers", layersNode);
}
if (zones != null) {
ArrayNode zonesNode = OBJECT_MAPPER.createArrayNode();
for (String zone : zones) {
zonesNode.add(zone);
}
queryNode.set("zones", zonesNode);
}
if (materialNames != null) {
ArrayNode materialsNode = OBJECT_MAPPER.createArrayNode();
for (String materialName : materialNames) {
materialsNode.add(materialName);
}
queryNode.set("materialNames", materialsNode);
}
if (quantities != null) {
ArrayNode quantitiesNode = OBJECT_MAPPER.createArrayNode();
for (QuantityValueQuery quantityValueQuery : quantities) {
quantitiesNode.add(quantityValueQuery.toJson());
}
queryNode.set("quantities", quantitiesNode);
}
if (classifications != null) {
ArrayNode classificationsNode = OBJECT_MAPPER.createArrayNode();
for (String classification : classifications) {
classificationsNode.add(classification);
}
queryNode.set("classifications", classificationsNode);
}
if (qids != null) {
ArrayNode qidsNode = OBJECT_MAPPER.createArrayNode();
for (Qid qid : qids) {
qidsNode.add(qid.toString());
}
queryNode.set("qids", qidsNode);
}
if (disciplines != null) {
ArrayNode disciplinesNode = OBJECT_MAPPER.createArrayNode();
for (Discipline discipline : disciplines) {
disciplinesNode.add(discipline.name());
}
queryNode.set("disciplines", disciplinesNode);
}
if (guids != null) {
ArrayNode guidsNode = OBJECT_MAPPER.createArrayNode();
for (String guid : guids) {
guidsNode.add(guid);
}
queryNode.set("guids", guidsNode);
}
if (fields != null) {
ArrayNode fieldsNode = OBJECT_MAPPER.createArrayNode();
for (String fieldName : fields.keySet()) {
FieldQuery fieldQuery = fields.get(fieldName);
fieldsNode.add(fieldQuery.toJson());
}
queryNode.set("fields", fieldsNode);
}
if (properties != null) {
ArrayNode propertiesNode = OBJECT_MAPPER.createArrayNode();
for (String propertySetName : properties.keySet()) {
Map map = properties.get(propertySetName);
for (String propertyName : map.keySet()) {
propertiesNode.add(map.get(propertyName).toJson());
}
}
queryNode.set("properties", propertiesNode);
}
if (propertySets != null) {
ArrayNode propertySetsNode = OBJECT_MAPPER.createArrayNode();
for (String propertySetName : propertySets) {
propertySetsNode.add(propertySetName);
}
queryNode.set("propertySets", propertySetsNode);
}
if (calculatedValues != null) {
ArrayNode calculatedValuesNode = OBJECT_MAPPER.createArrayNode();
for (CalculatedValueQuery calculatedValueQuery : calculatedValues) {
calculatedValuesNode.add(calculatedValueQuery.toJson());
}
queryNode.set("calculated", calculatedValuesNode);
}
if (groupFeatures != null) {
ArrayNode groupNodes = OBJECT_MAPPER.createArrayNode();
for (String group : groupFeatures) {
groupNodes.add(group);
}
queryNode.set("group", groupNodes);
}
return queryNode;
}
public BimQuery addProperty(String propertySetName, String propertyName, Operator operator, JsonNode value) {
if (this.properties == null) {
this.properties = new HashMap<>();
}
Map map = this.properties.get(propertySetName);
if (map == null) {
map = new HashMap<>();
this.properties.put(propertySetName, map);
}
map.put(propertyName, new PropertyQuery(propertySetName, propertyName, operator, value));
return this;
}
public static BimQuery of(ObjectNode jsonNode) throws UnsupportedBimQueryVersion, BimQueryValidationException {
if (jsonNode == null) {
return BimQuery.ALL;
}
// System.out.println(jsonNode.toString());
BimQuery bimQuery = new BimQuery();
jsonNode = jsonNode.deepCopy(); // Doing this because we don't want to alter the original... TODO make more efficient
if (!jsonNode.has("version")) {
throw new BimQueryValidationException("version field is required");
}
bimQuery.version = jsonNode.get("version").asInt();
jsonNode.remove("version");
if (bimQuery.version != VERSION) {
throw new UnsupportedBimQueryVersion(bimQuery.version, VERSION);
}
if (jsonNode.has("propertySets")) {
ArrayNode propertySetsNode = (ArrayNode)jsonNode.get("propertySets");
for (JsonNode propertySetNode : propertySetsNode) {
bimQuery.addPropertySet(propertySetNode.asText());
}
jsonNode.remove("propertySets");
}
if (jsonNode.hasNonNull("modelInfo")) {
ArrayNode modelInfoNode = (ArrayNode) jsonNode.get("modelInfo");
for (JsonNode modelNode : modelInfoNode) {
// bimQuery.addModelInfo();
}
jsonNode.remove("modelInfo");
}
if (jsonNode.has("types")) {
ArrayNode typesNode = (ArrayNode)jsonNode.get("types");
for (JsonNode typeNode : typesNode) {
bimQuery.addType(typeNode.asText());
}
jsonNode.remove("types");
}
if (jsonNode.has("zones")) {
ArrayNode zonesNode = (ArrayNode)jsonNode.get("zones");
for (JsonNode zoneNode : zonesNode) {
bimQuery.addZone(zoneNode.asText());
}
jsonNode.remove("zones");
}
if (jsonNode.has("guids")) {
ArrayNode guidsNode = (ArrayNode)jsonNode.get("guids");
for (JsonNode guidNode : guidsNode) {
bimQuery.addGuid(guidNode.asText());
}
jsonNode.remove("guids");
}
if (jsonNode.has("buildingStoreyLevels")) {
ArrayNode buildingStoreyLevelsNode = (ArrayNode) jsonNode.get("buildingStoreyLevels");
for (JsonNode buildingStoreyLevelNode : buildingStoreyLevelsNode) {
bimQuery.addBuildingStoreyLevel(BuildingStoreyLevelQuery.of(buildingStoreyLevelsNode));
}
jsonNode.remove("buildingStoreyLevels");
}
if (jsonNode.hasNonNull("buildingStoreyQids")) {
ArrayNode buildingStoreyQidsNode = (ArrayNode) jsonNode.get("buildingStoreyQids");
for (JsonNode buildingStoreyQidNode : buildingStoreyQidsNode) {
bimQuery.addBuildingStoreyQid(Qid.of(buildingStoreyQidNode.asText()));
}
jsonNode.remove("buildingStoreyQids");
}
if (jsonNode.has("buildingStoreyNames")) {
ArrayNode buildingStoreysNode = (ArrayNode) jsonNode.get("buildingStoreyNames");
for (JsonNode buildingStoreyNode : buildingStoreysNode) {
bimQuery.addBuildingStoreyName(buildingStoreyNode.asText());
}
jsonNode.remove("buildingStoreyNames");
}
if (jsonNode.has("qids")) {
ArrayNode qidsNode = (ArrayNode) jsonNode.get("qids");
for (JsonNode qidNode : qidsNode) {
bimQuery.addQid(Qid.of(qidNode.asText()));
}
jsonNode.remove("qids");
}
if (jsonNode.has("classifications")) {
ArrayNode classificationsNode = (ArrayNode) jsonNode.get("classifications");
for (JsonNode classificationNode : classificationsNode) {
bimQuery.addClassification(classificationNode.asText());
}
jsonNode.remove("classifications");
}
if (jsonNode.has("materialNames")) {
ArrayNode materialNamesNode = (ArrayNode) jsonNode.get("materialNames");
for (JsonNode materialNameNode : materialNamesNode) {
bimQuery.addMaterialName(materialNameNode.asText());
}
jsonNode.remove("materialNames");
}
if (jsonNode.has("fields")) {
ArrayNode fieldsNode = (ArrayNode) jsonNode.get("fields");
for (JsonNode fieldNode : fieldsNode) {
String name = fieldNode.get("name").asText();
Operator operator = Operator.EXISTS;
if (fieldNode.has("operator")) {
operator = Operator.bySymbol(fieldNode.get("operator").asText());
}
bimQuery.addField(name, operator, fieldNode.get("value"));
}
jsonNode.remove("fields");
}
if (jsonNode.has("quantities")) {
ArrayNode quantitiesNode = (ArrayNode)jsonNode.get("quantities");
for (JsonNode quantityNode : quantitiesNode) {
bimQuery.addQuantity(QuantityValueQuery.of(quantityNode));
}
jsonNode.remove("quantities");
}
if (jsonNode.has("layers")) {
ArrayNode layersNode = (ArrayNode) jsonNode.get("layers");
for (JsonNode layerNode : layersNode) {
bimQuery.addLayer(layerNode.asText());
}
jsonNode.remove("layers");
}
if (jsonNode.has("disciplines")) {
ArrayNode disciplinesNode = (ArrayNode) jsonNode.get("disciplines");
for (JsonNode disciplineNode : disciplinesNode) {
bimQuery.addDiscipline(Discipline.valueOf(disciplineNode.asText().toLowerCase()));
}
jsonNode.remove("disciplines");
}
if (jsonNode.has("properties")) {
ArrayNode propertiesNode = (ArrayNode) jsonNode.get("properties");
for (JsonNode propertyNode : propertiesNode) {
String propertySetName = propertyNode.has("propertySetName") ? propertyNode.get("propertySetName").asText() : null;
if (propertyNode.has("value")) {
bimQuery.addProperty(propertySetName, propertyNode.get("name").asText(), Operator.bySymbol(propertyNode.get("operator").asText()), propertyNode.get("value"));
} else {
bimQuery.addProperty(propertySetName, propertyNode.get("name").asText());
}
}
jsonNode.remove("properties");
}
if (jsonNode.has("calculated")) {
ArrayNode calculatedValuesNode = (ArrayNode) jsonNode.get("calculated");
for (JsonNode calculatedValueNode : calculatedValuesNode) {
if (calculatedValueNode.has("name")) {
String[] path = calculatedValueNode.get("name").asText().split("\\.");
Operator operator = Operator.EQUALS;
if (calculatedValueNode.hasNonNull("operator")) {
operator = Operator.bySymbol(calculatedValueNode.get("operator").asText());
}
bimQuery.addCalculatedValue(new CalculatedValueQuery(path, operator, calculatedValueNode.get("value")));
}
}
jsonNode.remove("calculated");
}
if (jsonNode.hasNonNull("group")) {
JsonNode group = jsonNode.get("group");
if (group instanceof ObjectNode) {
ObjectNode groupNode = (ObjectNode)group;
bimQuery.addGroup(groupNode.asText());
} else if (group instanceof ArrayNode) {
ArrayNode groupNodes = (ArrayNode) group;
for (JsonNode groupNode : groupNodes) {
bimQuery.addGroup(groupNode.asText());
}
}
jsonNode.remove("group");
}
if (jsonNode.has("features")) {
jsonNode.remove("features");
}
Iterator fieldNames = jsonNode.fieldNames();
if (fieldNames.hasNext()) {
throw new BimQueryValidationException("Unexpected field: " + fieldNames.next());
}
return bimQuery;
}
public BimQuery addGroup(String group) {
if (this.groupFeatures == null) {
this.groupFeatures = new LinkedHashSet<>();
}
this.groupFeatures.add(group);
return this;
}
public void addBuildingStoreyQid(Qid qid) {
if (this.buildingStoreyQids == null) {
this.buildingStoreyQids = new HashSet<>();
}
this.buildingStoreyQids.add(qid);
}
public void addModelInfo(String fieldName, String value) {
if (this.modelInfo == null) {
this.modelInfo = new HashMap<>();
}
this.modelInfo.put(fieldName, value);
}
public BimQuery addGuid(String guid) {
if (this.guids == null) {
this.guids = new HashSet<>();
}
this.guids.add(guid);
return this;
}
private void addBuildingStoreyName(String name) {
if (this.buildingStoreyNames == null) {
this.buildingStoreyNames = new HashSet<>();
}
this.buildingStoreyNames.add(name);
}
public BimQuery addLayer(String layer) {
if (this.layers == null) {
this.layers = new HashSet<>();
}
this.layers.add(layer);
return this;
}
public void addDiscipline(Discipline discipline) {
if (disciplines == null) {
this.disciplines = new HashSet<>();
}
this.disciplines.add(discipline);
}
@Override
public String toString() {
return toJson().toString();
}
private void addQid(Qid qid) {
if (this.qids == null) {
this.qids = new TreeSet<>();
}
this.qids.add(qid);
}
public BimQuery addField(String fieldName, Operator operator, JsonNode value) {
if (this.fields == null) {
this.fields = new TreeMap<>();
}
this.fields.put(fieldName, new FieldQuery(fieldName, operator, value));
return this;
}
public BimQuery addField(String fieldName) {
if (this.fields == null) {
this.fields = new TreeMap<>();
}
this.fields.put(fieldName, new FieldQuery(fieldName, Operator.EXISTS, null));
return this;
}
public void addField(String fieldName, Operator operator, double value) {
if (this.fields == null) {
this.fields = new TreeMap<>();
}
this.fields.put(fieldName, new FieldQuery(fieldName, operator, DoubleNode.valueOf(value)));
}
public BimQuery addProperty(String propertySetName, String propertyName) {
if (this.properties == null) {
this.properties = new TreeMap<>();
}
if (propertySetName == null) {
propertySetName = "*";
}
Map map = this.properties.get(propertySetName);
if (map == null) {
map = new TreeMap<>();
this.properties.put(propertySetName, map);
}
map.put(propertyName, new PropertyQuery(propertySetName, propertyName, Operator.EXISTS, null));
return this;
}
public BimQuery addCalculatedValue(CalculatedValueQuery calculatedValueQuery) {
if (this.calculatedValues == null) {
this.calculatedValues = new TreeSet<>();
}
calculatedValues.add(calculatedValueQuery);
return this;
}
public Set getDisciplines() {
return disciplines;
}
public void addClassification(String classification) {
if (this.classifications == null) {
this.classifications = new HashSet<>();
}
this.classifications.add(classification);
}
public BimQuery addMaterialName(String materialName) {
if (this.materialNames == null) {
this.materialNames = new HashSet<>();
}
this.materialNames.add(materialName);
return this;
}
public void addQuantity(QuantityValueQuery quantityValueQuery) {
if (this.quantities == null) {
this.quantities = new HashSet<>();
}
this.quantities.add(quantityValueQuery);
}
public void addPropertySet(String propertySetName) {
if (this.propertySets == null) {
this.propertySets = new HashSet<>();
}
this.propertySets.add(propertySetName);
}
public BimQuery addZone(String zone) {
if (this.zones == null) {
this.zones = new HashSet<>();
}
this.zones.add(zone);
return this;
}
public Set getBuildingStoreyQids() {
return buildingStoreyQids;
}
public void setBuildingStoreyQids(Set buildingStoreyQids) {
this.buildingStoreyQids = buildingStoreyQids;
}
public Set getTypes() {
return types;
}
public Set getGuids() {
return guids;
}
public Set getMaterialNames() {
return materialNames;
}
public Set getLayers() {
return layers;
}
public Set getZones() {
return zones;
}
public Map> getProperties() {
return properties;
}
@JsonIgnore
public Set getPropertiesQueries() {
Set set = new HashSet<>();
for (Map map : properties.values()) {
for (PropertyQuery propertyQuery : map.values()) {
set.add(propertyQuery);
}
}
return set;
}
public Map getFields() {
return fields;
}
public Set getCalculatedValues() {
return calculatedValues;
}
public Set getClassifications() {
return classifications;
}
public Set getBuildingStoreyNames() {
return buildingStoreyNames;
}
public Set getQuantities() {
return quantities;
}
public boolean hasQids() {
return qids != null && !qids.isEmpty();
}
public boolean hasTypes() {
return types != null && !types.isEmpty();
}
public boolean hasBuildingStoreyNames() {
return buildingStoreyNames != null && !buildingStoreyNames.isEmpty();
}
public boolean hasBuildingStoreyQids() {
return buildingStoreyQids != null && !buildingStoreyQids.isEmpty();
}
public boolean hasBuildingStoreyLevels() {
return buildingStoreyLevels != null && !buildingStoreyLevels.isEmpty();
}
public boolean hasMaterialNames() {
return materialNames != null && !materialNames.isEmpty();
}
public boolean hasLayers() {
return layers != null && !layers.isEmpty();
}
public boolean hasZones() {
return zones != null && !zones.isEmpty();
}
public boolean hasClassifications() {
return classifications != null && !classifications.isEmpty();
}
public Set getQids() {
return qids;
}
public boolean hasCalculated() {
return calculatedValues != null && !calculatedValues.isEmpty();
}
public boolean hasGuids() {
return guids != null && !guids.isEmpty();
}
public boolean hasFields() {
return fields != null && !fields.isEmpty();
}
public boolean hasProperties() {
return properties != null && !properties.isEmpty();
}
public boolean hasQuantities() {
return quantities != null && !quantities.isEmpty();
}
public boolean hasAggregations() {
return groupFeatures != null && !groupFeatures.isEmpty();
}
public Set getGroupFeatures() {
return groupFeatures;
}
public void setGroupFeatures(Set groupFeatures) {
this.groupFeatures = groupFeatures;
}
public BimQuery addBuildingStoreyLevel(BuildingStoreyLevelQuery buildingStoreyLevelQuery) {
if (this.buildingStoreyLevels == null) {
this.buildingStoreyLevels = new HashSet<>();
}
this.buildingStoreyLevels.add(buildingStoreyLevelQuery);
return this;
}
public BimQuery addBuildingStoreyLevel(int level, Operator operator) {
if (this.buildingStoreyLevels == null) {
this.buildingStoreyLevels = new HashSet<>();
}
this.buildingStoreyLevels.add(new BuildingStoreyLevelQuery(operator, IntNode.valueOf(level)));
return this;
}
public Set getBuildingStoreyLevels() {
return buildingStoreyLevels;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy