vertx-gaia/vertx-ams/src/main/jib/io/horizon/uca/qr/syntax/QTree.java
package io.horizon.uca.qr.syntax;
import io.horizon.eon.VString;
import io.horizon.uca.qr.Criteria;
import io.horizon.util.HUt;
import io.vertx.core.json.JsonObject;
import java.util.Objects;
public class QTree {
private final QNode current;
private QTree(final JsonObject content) {
this.current = this.initTier(content, 0);
}
public static QTree create(final Criteria criteria) {
return new QTree(criteria.toJson());
}
public static QTree create(final JsonObject content) {
return new QTree(content);
}
private QNode initTier(final String field, final Object value, final Integer level) {
final QNode node;
if (HUt.isJObject(value)) {
/* Create new branch */
node = this.initTier(((JsonObject) value), level);
} else {
/* Create new leaf */
node = this.initValue(field, value).level(level);
}
return node;
}
public QNode getData() {
return this.current;
}
public boolean hasValue() {
if (this.current instanceof QTier) {
return 0 < ((QTier) this.current).nodes().size();
} else {
return Objects.nonNull(this.current);
}
}
private QValue initValue(final String field, final Object value) {
if (field.contains(",")) {
final String[] fieldOp = field.split(",");
final String target = fieldOp[0].trim();
final String opStr = fieldOp[1].trim();
final QOp op = QOp.toOp(opStr);
return QValue.create(target, op, value);
} else {
return QValue.create(field, QOp.EQ, value);
}
}
private QNode initTier(final JsonObject content, final Integer level) {
/* 1. Initialize node */
final QNode root = this.init(content, level);
/* 2. Then initialize children nodes */
content.fieldNames().stream().filter(HUt::isNotNil).forEach(field -> {
/* 3. Each */
final QNode tier = this.initTier(field, content.getValue(field), level + 1);
if (!root.isLeaf()) {
((QBranch) root).add(tier);
}
});
return root;
}
private QNode init(final JsonObject content, final Integer level) {
final QNode root;
if (content.containsKey(VString.EMPTY)) {
final Boolean isAnd = content.getBoolean(VString.EMPTY);
root = QTier.create(isAnd ? QOp.AND : QOp.OR).level(level);
} else {
root = QTier.create(QOp.AND).level(level);
}
return root;
}
@Override
public String toString() {
return "\n" + this.current.toString();
}
}