* limitations under the License.
* ============LICENSE_END=========================================================
*/
+
package org.onap.aai.query.builder;
import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
+import java.util.*;
+
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.db.props.AAIProperties;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.introspection.Introspector;
-import org.onap.aai.introspection.Loader;
-import org.onap.aai.restcore.search.GremlinGroovyShellSingleton;
-import org.onap.aai.schema.enums.ObjectMetadata;
import org.onap.aai.edges.EdgeRule;
import org.onap.aai.edges.EdgeRuleQuery;
import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.restcore.search.GremlinGroovyShell;
+import org.onap.aai.schema.enums.ObjectMetadata;
import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
-
-import java.util.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* The Class GremlinQueryBuilder.
private static final String ARGUMENT2 = "#!#argument#!#";
private static final String HAS = ".has('";
- private GremlinGroovyShellSingleton gremlinGroovy = GremlinGroovyShellSingleton.getInstance();
+ private static final String SINGLE_QUOTE = "'";
+ private static final String ESCAPE_SINGLE_QUOTE = "\\\'";
+ private GremlinGroovyShell gremlinGroovy = new GremlinGroovyShell();
private GraphTraversal<?, ?> completeTraversal = null;
protected List<String> list = null;
+ private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class);
+
/**
* Instantiates a new gremlin query builder.
*
return (QueryBuilder<Vertex>) this;
}
+ @Override
+ protected void vertexHas(String key, Object value) {
+ list.add(HAS + key + "', " + value + ")");
+ }
+
+ @Override
+ protected void vertexHasNot(String key) {
+ list.add(".hasNot('" + key + "')");
+
+ }
+
+ @Override
+ protected void vertexHas(String key) {
+ list.add(HAS + key + "')");
+ }
+
/**
* @{inheritDoc}
*/
public QueryBuilder<Vertex> getVerticesByProperty(String key, Object value) {
String term = "";
- if (value != null && !(value instanceof String) ) {
+ if (value != null && !(value instanceof String)) {
+ String valueString = value.toString();
+
+ if (valueString.indexOf('\'') != -1) {
+ value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
+ }
+ LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
term = value.toString();
+ } else if (value != null && value instanceof String) {
+ String valueString = value.toString();
+
+ if (valueString.indexOf('\'') != -1) {
+ value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
+ }
+ LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
+ term = "'" + value + "'";
} else {
term = "'" + value + "'";
}
- list.add(HAS + key + "', " + term + ")");
+ this.vertexHas(key, term);
+ stepIndex++;
+ return (QueryBuilder<Vertex>) this;
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, Object value) {
+ this.vertexHas(key, value);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@Override
public QueryBuilder<Vertex> getVerticesByBooleanProperty(String key, Object value) {
- boolean bValue = false;
- if(value instanceof String){
- bValue = Boolean.valueOf(value.toString());
- } else if(value instanceof Boolean){
- bValue = (Boolean) value;
- }
+ if (value != null && !"".equals(value)) {
+ boolean bValue = false;
+ if (value instanceof String) {
+ bValue = Boolean.valueOf(value.toString());
+ } else if (value instanceof Boolean) {
+ bValue = (Boolean) value;
+ }
- list.add(HAS + key + "', " + bValue + ")");
- stepIndex++;
+ this.vertexHas(key, bValue);
+ stepIndex++;
+ }
return (QueryBuilder<Vertex>) this;
}
}
String argument = Joiner.on(",").join(arguments);
predicate = predicate.replace(ARGUMENT2, argument);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
- public QueryBuilder<Vertex> getVerticesByProperty(String key) {
+ public QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value) {
+ ArrayList<String> arguments = new ArrayList<>(Arrays.asList(value.split(",")));
+ // add the single quotes
+ for (int i = 0; i < arguments.size(); i++) {
+ if (arguments.get(i) != null && !arguments.get(i).startsWith("'") && !arguments.get(i).endsWith("'")) {
+ arguments.set(i, "'" + arguments.get(i).trim() + "'");
+ } else {
+ arguments.set(i, arguments.get(i).trim());
+ }
+ }
+ String predicate = "P.within(#!#argument#!#)";
+ String argument = Joiner.on(",").join(arguments);
+ predicate = predicate.replace(ARGUMENT2, argument);
+ this.vertexHas(key, predicate);
+ stepIndex++;
+ return (QueryBuilder<Vertex>) this;
+ }
- list.add(HAS + key + "')");
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryBuilder<Vertex> getVerticesByProperty(String key) {
+ this.vertexHas(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key) {
-
- list.add(".hasNot('" + key + "')");
+ this.vertexHasNot(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
*/
@Override
public QueryBuilder<Vertex> getVerticesStartsWithProperty(String key, Object value) {
-
String term = "";
String predicate = "org.janusgraph.core.attribute.Text.textPrefix(#!#argument#!#)";
- if (value != null && !(value instanceof String) ) {
+ if (value != null && !(value instanceof String)) {
term = value.toString();
} else {
term = "'" + value + "'";
}
predicate = predicate.replace(ARGUMENT2, term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
String term = "";
String predicate = "P.neq(#!#argument#!#)";
- if (value != null && !(value instanceof String) ) {
+ if (value != null && !(value instanceof String)) {
term = value.toString();
} else {
term = "'" + value + "'";
}
predicate = predicate.replace(ARGUMENT2, term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
}
String argument = Joiner.on(",").join(arguments);
predicate = predicate.replace(ARGUMENT2, argument);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<Vertex> getVerticesGreaterThanProperty(String key, Object value) {
String predicate = "P.gte(#!#argument1#!#)";
String term;
- if (value != null && !(value instanceof String) ) {
+ if (value != null && !(value instanceof String)) {
term = value.toString();
} else {
term = "'" + value + "'";
}
predicate = predicate.replace("#!#argument1#!#", term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<Vertex> getVerticesLessThanProperty(String key, Object value) {
String predicate = "P.lte(#!#argument1#!#)";
String term;
- if (value != null && !(value instanceof String) ) {
+ if (value != null && !(value instanceof String)) {
term = value.toString();
} else {
term = "'" + value + "'";
}
predicate = predicate.replace("#!#argument1#!#", term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
-
-
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getChildVerticesFromParent(String parentKey, String parentValue, String childType) {
- //TODO
+ // TODO
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) {
-
+
for (Map.Entry<String, String> es : map.entrySet()) {
+ // TODO what is this and where is it used - need to check
list.add(HAS + es.getKey() + "', '" + es.getValue() + "')");
stepIndex++;
}
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
Set<String> keys = obj.getKeys();
for (String key : keys) {
-
+
this.getVerticesByProperty(key, obj.<Object>getValue(key));
-
- }
+
+ }
return (QueryBuilder<Vertex>) this;
}
-
+
/**
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
* @{inheritDoc}
*/
@Override
- public QueryBuilder createEdgeTraversal(EdgeType type, Introspector parent, Introspector child) throws AAIException {
+ public QueryBuilder createEdgeTraversal(EdgeType type, Introspector parent, Introspector child)
+ throws AAIException {
String parentName = parent.getDbName();
String childName = child.getDbName();
if (parent.isContainer()) {
}
this.edgeQueryToVertex(type, parentName, childName, null);
return this;
-
+
}
@Override
- public QueryBuilder createPrivateEdgeTraversal(EdgeType type, Introspector parent, Introspector child) throws AAIException{
+ public QueryBuilder createPrivateEdgeTraversal(EdgeType type, Introspector parent, Introspector child)
+ throws AAIException {
String parentName = parent.getDbName();
String childName = child.getDbName();
if (parent.isContainer()) {
* @{inheritDoc}
*/
@Override
- public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in, List<String> labels) throws AAIException {
+ public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in,
+ List<String> labels) throws AAIException {
String parentName = out.getDbName();
String childName = in.getDbName();
if (out.isContainer()) {
return (QueryBuilder<Vertex>) this;
}
-
- public QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType, List<String> labels) throws AAIException {
+ public QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType,
+ List<String> labels) throws AAIException {
this.edgeQuery(type, outNodeType, inNodeType, labels);
- return (QueryBuilder<Edge>)this;
+ return (QueryBuilder<Edge>) this;
}
- private void edgeQueryToVertex(EdgeType type, String outType, String inType, List<String> labels) throws AAIException {
+ private void edgeQueryToVertex(EdgeType type, String outType, String inType, List<String> labels)
+ throws AAIException {
this.edgeQueryToVertex(type, outType, inType, labels, false);
}
* @throws NoEdgeRuleFoundException
* @throws AAIException
*/
- private void edgeQueryToVertex(EdgeType type, String outType, String inType, List<String> labels, boolean isPrivateEdge) throws AAIException {
+ private void edgeQueryToVertex(EdgeType type, String outType, String inType, List<String> labels,
+ boolean isPrivateEdge) throws AAIException {
markParentBoundary();
Multimap<String, EdgeRule> rules = ArrayListMultimap.create();
EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(outType, inType).edgeType(type).setPrivate(isPrivateEdge);
} else {
if (Direction.IN.equals(rule.getDirection())) {
inLabels.add(rule.getLabel());
+ if (inType.equals(outType)) {// code to handle when a type edges to itself, to add both in and out
+ outLabels.add(rule.getLabel());
+ }
} else {
outLabels.add(rule.getLabel());
+ if (inType.equals(outType)) {// code to handle when a type edges to itself, to add both in and out
+ inLabels.add(rule.getLabel());
+ }
}
}
}
- if(inLabels.isEmpty() && outLabels.isEmpty()) {
- throw new NoEdgeRuleFoundException("no " + type.toString() + " edge rule between " + outType + " and " + inType );
+ if (inLabels.isEmpty() && outLabels.isEmpty()) {
+ throw new NoEdgeRuleFoundException(
+ "no " + type.toString() + " edge rule between " + outType + " and " + inType);
} else if (inLabels.isEmpty() && !outLabels.isEmpty()) {
list.add(".out('" + String.join("','", outLabels) + "')");
} else if (outLabels.isEmpty() && !inLabels.isEmpty()) {
list.add(".in('" + String.join("','", inLabels) + "')");
} else {
- list.add(".union(__.in('" + String.join("','", inLabels) + "')" + ", __.out('" + String.join("','", outLabels) + "'))");
+ list.add(".union(__.in('" + String.join("','", inLabels) + "')" + ", __.out('"
+ + String.join("','", outLabels) + "'))");
}
stepIndex++;
list.add(HAS + AAIProperties.NODE_TYPE + "', '" + inType + "')");
stepIndex++;
-
+
}
-
+
/**
* Edge query.
*
* @param outType the out type
* @param inType the in type
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
*/
private void edgeQuery(EdgeType type, String outType, String inType, List<String> labels) throws AAIException {
markParentBoundary();
} catch (EdgeRuleNotFoundException e) {
throw new NoEdgeRuleFoundException(e);
}
-
+
final List<String> inLabels = new ArrayList<>();
final List<String> outLabels = new ArrayList<>();
}
}
- if(inLabels.isEmpty() && outLabels.isEmpty()) {
- throw new NoEdgeRuleFoundException("no " + type.toString() + " edge rule between " + outType + " and " + inType );
+ if (inLabels.isEmpty() && outLabels.isEmpty()) {
+ throw new NoEdgeRuleFoundException(
+ "no " + type.toString() + " edge rule between " + outType + " and " + inType);
} else if (inLabels.isEmpty() && !outLabels.isEmpty()) {
list.add(".outE('" + String.join("','", outLabels) + "')");
} else if (outLabels.isEmpty() && !inLabels.isEmpty()) {
list.add(".inE('" + String.join("','", inLabels) + "')");
} else {
- list.add(".union(__.inE('" + String.join("','", inLabels) + "')" + ", __.outE('" + String.join("','", outLabels) + "'))");
+ list.add(".union(__.inE('" + String.join("','", inLabels) + "')" + ", __.outE('"
+ + String.join("','", outLabels) + "'))");
}
-
+
stepIndex++;
-
+
}
+
@Override
public QueryBuilder<E> limit(long amount) {
list.add(".limit(" + amount + ")");
return this;
}
+
/**
* @{inheritDoc}
*/
command.append(Joiner.on(",").join(wrapped));
command.append(")");
list.add(".has('aai-node-type', " + command + ")");
-
+
} else {
list.add(".has('aai-node-type', '" + type + "')");
}
stepIndex++;
- this.markContainer();
+ this.markContainerIndex();
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<E> union(QueryBuilder<E>... builder) {
markParentBoundary();
command.append(")");
list.add(command.toString());
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> where(QueryBuilder<E>... builder) {
markParentBoundary();
stepIndex++;
}
list.addAll(traversals);
-
-
+
return this;
}
return this;
}
-
+
@Override
public QueryBuilder<E> store(String name) {
- this.list.add(".store('"+ name + "')");
+ this.list.add(".store('" + name + "')");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> cap(String name) {
- this.list.add(".cap('"+ name + "')");
+ this.list.add(".cap('" + name + "')");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> unfold() {
this.list.add(".unfold()");
stepIndex++;
-
+
return this;
}
-
+
+ @Override
+ public QueryBuilder<E> fold() {
+ this.list.add(".fold()");
+ stepIndex++;
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> id() {
+ this.list.add(".id()");
+ stepIndex++;
+ return this;
+ }
+
@Override
public QueryBuilder<E> dedup() {
this.list.add(".dedup()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> emit() {
this.list.add(".emit()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> repeat(QueryBuilder<E> builder) {
- this.list.add(".repeat(__" + builder.getQuery() + ")");
+ this.list.add(".repeat(__" + builder.getQuery() + ")");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> until(QueryBuilder<E> builder) {
this.list.add(".until(__" + builder.getQuery() + ")");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> groupCount() {
this.list.add(".groupCount()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> both() {
this.list.add(".both()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<Tree> tree() {
this.list.add(".tree()");
stepIndex++;
-
- return (QueryBuilder<Tree>)this;
+
+ return (QueryBuilder<Tree>) this;
}
-
+
@Override
public QueryBuilder<E> by(String name) {
- this.list.add(".by('"+ name + "')");
+ this.list.add(".by('" + name + "')");
stepIndex++;
-
+
return this;
}
-
+
+ @Override
+ public QueryBuilder<E> valueMap() {
+ this.list.add(".valueMap()");
+ stepIndex++;
+
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> valueMap(String... names) {
+ String stepString = ".valueMap('";
+ for (int i = 0; i < names.length; i++) {
+ stepString = stepString + names[i] + "'";
+ if (i != (names.length - 1)) {
+ stepString = stepString + ",'";
+ }
+ }
+ stepString = stepString + ")";
+ this.list.add(stepString);
+ stepIndex++;
+
+ return this;
+ }
+
/**
* {@inheritDoc}
*/
@Override
- public QueryBuilder<E> simplePath(){
+ public QueryBuilder<E> simplePath() {
this.list.add(".simplePath()");
stepIndex++;
return this;
* {@inheritDoc}
*/
@Override
- public QueryBuilder<Path> path(){
+ public QueryBuilder<Path> path() {
this.list.add(".path()");
stepIndex++;
- return (QueryBuilder<Path>)this;
+ return (QueryBuilder<Path>) this;
}
-
+
@Override
public QueryBuilder<Edge> outE() {
this.list.add(".outE()");
stepIndex++;
-
- return (QueryBuilder<Edge>)this;
+
+ return (QueryBuilder<Edge>) this;
}
-
+
@Override
public QueryBuilder<Edge> inE() {
this.list.add(".inE()");
stepIndex++;
-
- return (QueryBuilder<Edge>)this;
+
+ return (QueryBuilder<Edge>) this;
}
-
+
@Override
public QueryBuilder<Vertex> outV() {
this.list.add(".outV()");
stepIndex++;
-
- return (QueryBuilder<Vertex>)this;
+
+ return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<Vertex> inV() {
this.list.add(".inV()");
stepIndex++;
-
- return (QueryBuilder<Vertex>)this;
+
+ return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<E> not(QueryBuilder<E> builder) {
this.list.add(".not(" + "__" + builder.getQuery() + ")");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> as(String name) {
this.list.add(".as('" + name + "')");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> select(String name) {
this.list.add(".select('" + name + "')");
stepIndex++;
-
+
return this;
}
+
+ @Override
+ public QueryBuilder<E> select(String... names) {
+ String stepString = ".select('";
+ for (int i = 0; i < names.length; i++) {
+ stepString = stepString + names[i] + "'";
+ if (i != (names.length - 1)) {
+ stepString = stepString + ",'";
+ }
+ }
+ stepString = stepString + ")";
+ this.list.add(stepString);
+ stepIndex++;
+
+ return this;
+ }
+
/**
* @{inheritDoc}
*/
public QueryBuilder<E> getParentQuery() {
return cloneQueryAtStep(parentStepIndex);
}
-
+
@Override
public QueryBuilder<E> getContainerQuery() {
return cloneQueryAtStep(containerStepIndex);
}
-
+
/**
* @{inheritDoc}
*/
@Override
public <T2> T2 getQuery() {
StringBuilder sb = new StringBuilder();
-
+
for (String piece : this.list) {
sb.append(piece);
}
-
- return (T2)sb.toString();
+
+ return (T2) sb.toString();
}
-
+
/**
* @{inheritDoc}
*/
public void markParentBoundary() {
parentStepIndex = stepIndex;
}
-
+
@Override
- public void markContainer() {
+ public void markContainerIndex() {
this.containerStepIndex = stepIndex;
}
-
+
/**
* @{inheritDoc}
*/
protected int getStepIndex() {
return stepIndex;
}
-
+
private void executeQuery() {
String queryString = "g" + Joiner.on("").join(list);
Map<String, Object> params = new HashMap<>();
}
this.completeTraversal = this.gremlinGroovy.executeTraversal(queryString, params);
}
+
@Override
public boolean hasNext() {
if (this.completeTraversal == null) {
executeQuery();
}
-
+
return this.completeTraversal.hasNext();
}
-
+
@Override
public E next() {
if (this.completeTraversal == null) {
executeQuery();
}
-
- return (E)this.completeTraversal.next();
+
+ return (E) this.completeTraversal.next();
}
-
+
@Override
public List<E> toList() {
if (this.completeTraversal == null) {
executeQuery();
}
-
- return (List<E>)this.completeTraversal.toList();
+
+ return (List<E>) this.completeTraversal.toList();
}
protected QueryBuilder<Edge> has(String key, String value) {
this.list.add(HAS + key + "','" + value + "')");
- return (QueryBuilder<Edge>)this;
+ return (QueryBuilder<Edge>) this;
}
-
+
+ /*
+ * This is required for the subgraphstrategies to work
+ */
+
}