Skip to content
This repository was archived by the owner on Feb 12, 2019. It is now read-only.

Commit 9ee28f5

Browse files
authored
Merge pull request #61 from eclipse/repleace_token_graph
Improves Query by method in the Graph
2 parents 9e524d3 + 43f9cd3 commit 9ee28f5

17 files changed

+944
-691
lines changed

artemis-graph/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@
7272
<artifactId>artemis-core</artifactId>
7373
<version>${project.version}</version>
7474
</dependency>
75+
<dependency>
76+
<groupId>org.jnosql.query</groupId>
77+
<artifactId>jnosql-query-antlr</artifactId>
78+
<version>${project.version}</version>
79+
</dependency>
7580
<dependency>
7681
<groupId>org.apache.tinkerpop</groupId>
7782
<artifactId>gremlin-core</artifactId>
@@ -84,7 +89,6 @@
8489
<version>${tinkerpop.version}</version>
8590
<scope>provided</scope>
8691
</dependency>
87-
8892
<dependency>
8993
<groupId>org.apache.tinkerpop</groupId>
9094
<artifactId>neo4j-gremlin</artifactId>

artemis-graph/src/main/java/org/jnosql/artemis/graph/query/AbstractGraphRepositoryProxy.java

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
package org.jnosql.artemis.graph.query;
1616

1717
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
18-
import org.apache.tinkerpop.gremlin.structure.Element;
1918
import org.apache.tinkerpop.gremlin.structure.Graph;
2019
import org.apache.tinkerpop.gremlin.structure.Vertex;
20+
import org.jnosql.artemis.Converters;
2121
import org.jnosql.artemis.Param;
2222
import org.jnosql.artemis.PreparedStatement;
2323
import org.jnosql.artemis.Query;
@@ -47,18 +47,21 @@
4747
abstract class AbstractGraphRepositoryProxy<T, ID> implements InvocationHandler {
4848

4949

50+
private final SelectQueryConverter converter = new SelectQueryConverter();
51+
private final DeleteQueryConverter deleteConverter = new DeleteQueryConverter();
52+
5053
protected abstract ClassRepresentation getClassRepresentation();
5154

5255
protected abstract Repository getRepository();
5356

54-
protected abstract GraphQueryParser getQueryParser();
55-
5657
protected abstract Graph getGraph();
5758

5859
protected abstract GraphConverter getConverter();
5960

6061
protected abstract GraphTemplate getTemplate();
6162

63+
protected abstract Converters getConverters();
64+
6265

6366
@Override
6467
public Object invoke(Object instance, Method method, Object[] args) throws Throwable {
@@ -70,9 +73,9 @@ public Object invoke(Object instance, Method method, Object[] args) throws Throw
7073
case DEFAULT:
7174
return method.invoke(getRepository(), args);
7275
case FIND_BY:
73-
return executeFindByMethod(method, args, methodName);
76+
return executeFindByMethod(method, args);
7477
case DELETE_BY:
75-
return executeDeleteMethod(args, methodName);
78+
return executeDeleteMethod(method, args);
7679
case FIND_ALL:
7780
return executeFindAll(method, args);
7881
case OBJECT_METHOD:
@@ -86,26 +89,24 @@ public Object invoke(Object instance, Method method, Object[] args) throws Throw
8689
}
8790
}
8891

89-
private Object executeDeleteMethod(Object[] args, String methodName) {
90-
GraphTraversal<Vertex, Vertex> traversal = getGraph().traversal().V();
91-
getQueryParser().deleteByParse(methodName, args, getClassRepresentation(), traversal);
92+
private Object executeDeleteMethod(Method method, Object[] args) {
9293

93-
List<?> vertices = traversal.toList();
94+
GraphQueryMethod queryMethod = new GraphQueryMethod(getClassRepresentation(),
95+
getGraph().traversal().V(),
96+
getConverters(), method, args);
9497

95-
for (Object element : vertices) {
96-
if (Element.class.isInstance(element)) {
97-
Element.class.cast(element).remove();
98-
}
99-
}
98+
List<Vertex> vertices = deleteConverter.apply(queryMethod);
99+
vertices.forEach(Vertex::remove);
100100
return Void.class;
101101
}
102102

103-
private Object executeFindByMethod(Method method, Object[] args, String methodName) {
103+
private Object executeFindByMethod(Method method, Object[] args) {
104104
Class<?> classInstance = getClassRepresentation().getClassInstance();
105-
GraphTraversal<Vertex, Vertex> traversal = getGraph().traversal().V();
106-
getQueryParser().findByParse(methodName, args, getClassRepresentation(), traversal);
105+
GraphQueryMethod queryMethod = new GraphQueryMethod(getClassRepresentation(),
106+
getGraph().traversal().V(),
107+
getConverters(), method, args);
107108

108-
List<Vertex> vertices = traversal.hasLabel(getClassRepresentation().getName()).toList();
109+
List<Vertex> vertices = converter.apply(queryMethod);
109110
Stream<T> stream = vertices.stream().map(getConverter()::toEntity);
110111

111112
return returnObject(stream, classInstance, method);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2017 Otávio Santana and others
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* and Apache License v2.0 which accompanies this distribution.
6+
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7+
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
8+
*
9+
* You may elect to redistribute this code under either of these licenses.
10+
*
11+
* Contributors:
12+
*
13+
* Otavio Santana
14+
*/
15+
package org.jnosql.artemis.graph.query;
16+
17+
import org.apache.tinkerpop.gremlin.process.traversal.P;
18+
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
19+
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
20+
import org.apache.tinkerpop.gremlin.structure.Vertex;
21+
import org.jnosql.artemis.reflection.ClassRepresentation;
22+
import org.jnosql.query.Condition;
23+
import org.jnosql.query.ConditionValue;
24+
import org.jnosql.query.Operator;
25+
26+
abstract class AbstractQueryConvert {
27+
28+
29+
protected GraphTraversal<Vertex, Vertex> getPredicate(GraphQueryMethod graphQuery, Condition condition,
30+
ClassRepresentation representation) {
31+
Operator operator = condition.getOperator();
32+
String name = condition.getName();
33+
String nativeName = representation.getColumnField(name);
34+
switch (operator) {
35+
case EQUALS:
36+
return __.has(nativeName, P.eq(graphQuery.getValue(name)));
37+
case GREATER_THAN:
38+
return __.has(nativeName, P.gt(graphQuery.getValue(name)));
39+
case GREATER_EQUALS_THAN:
40+
return __.has(nativeName, P.gte(graphQuery.getValue(name)));
41+
case LESSER_THAN:
42+
return __.has(nativeName, P.lt(graphQuery.getValue(name)));
43+
case LESSER_EQUALS_THAN:
44+
return __.has(nativeName, P.lte(graphQuery.getValue(name)));
45+
case BETWEEN:
46+
return __.has(nativeName, P.between(graphQuery.getValue(name), graphQuery.getValue(name)));
47+
case IN:
48+
return __.has(nativeName, P.within(graphQuery.getInValue(name)));
49+
case NOT:
50+
Condition notCondition = ConditionValue.class.cast(condition.getValue()).get().get(0);
51+
return __.not(getPredicate(graphQuery, notCondition, representation));
52+
case AND:
53+
return ConditionValue.class.cast(condition.getValue()).get().stream()
54+
.map(c -> getPredicate(graphQuery, c, representation)).reduce((a, b) -> a.and(b))
55+
.orElseThrow(() -> new UnsupportedOperationException("There is an inconsistency at the AND operator"));
56+
case OR:
57+
return ConditionValue.class.cast(condition.getValue()).get().stream()
58+
.map(c -> getPredicate(graphQuery, c, representation)).reduce((a, b) -> a.or(b))
59+
.orElseThrow(() -> new UnsupportedOperationException("There is an inconsistency at the OR operator"));
60+
default:
61+
throw new UnsupportedOperationException("There is not support to the type " + operator + " in graph");
62+
63+
64+
}
65+
}
66+
}

artemis-graph/src/main/java/org/jnosql/artemis/graph/query/DefaultGraphRepositoryProducer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package org.jnosql.artemis.graph.query;
1616

1717
import org.apache.tinkerpop.gremlin.structure.Graph;
18+
import org.jnosql.artemis.Converters;
1819
import org.jnosql.artemis.Repository;
1920
import org.jnosql.artemis.graph.GraphConverter;
2021
import org.jnosql.artemis.graph.GraphRepositoryProducer;
@@ -39,14 +40,16 @@ class DefaultGraphRepositoryProducer implements GraphRepositoryProducer {
3940
private GraphConverter converter;
4041
@Inject
4142
private GraphTemplateProducer producer;
43+
@Inject
44+
private Converters converters;
4245

4346
@Override
4447
public <E, ID, T extends Repository<E, ID>> T get(Class<T> repositoryClass, Graph manager) {
4548
Objects.requireNonNull(repositoryClass, "repository class is required");
4649
Objects.requireNonNull(manager, "manager class is required");
4750
GraphTemplate template = producer.get(manager);
4851
GraphRepositoryProxy<T, ID> handler = new GraphRepositoryProxy(template,
49-
classRepresentations, repositoryClass, reflections, manager, converter);
52+
classRepresentations, repositoryClass, reflections, manager, converter, converters);
5053
return (T) Proxy.newProxyInstance(repositoryClass.getClassLoader(),
5154
new Class[]{repositoryClass},
5255
handler);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2017 Otávio Santana and others
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* and Apache License v2.0 which accompanies this distribution.
6+
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7+
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
8+
*
9+
* You may elect to redistribute this code under either of these licenses.
10+
*
11+
* Contributors:
12+
*
13+
* Otavio Santana
14+
*/
15+
package org.jnosql.artemis.graph.query;
16+
17+
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
18+
import org.apache.tinkerpop.gremlin.structure.Vertex;
19+
import org.jnosql.aphrodite.antlr.method.DeleteMethodFactory;
20+
import org.jnosql.artemis.reflection.ClassRepresentation;
21+
import org.jnosql.query.Condition;
22+
import org.jnosql.query.DeleteQuery;
23+
import org.jnosql.query.Where;
24+
25+
import java.util.List;
26+
import java.util.function.Function;
27+
28+
final class DeleteQueryConverter extends AbstractQueryConvert implements Function<GraphQueryMethod, List<Vertex>> {
29+
30+
@Override
31+
public List<Vertex> apply(GraphQueryMethod graphQuery) {
32+
DeleteMethodFactory factory = DeleteMethodFactory.get();
33+
DeleteQuery deleteQuery = factory.apply(graphQuery.getMethod(), graphQuery.getEntityName());
34+
ClassRepresentation representation = graphQuery.getRepresentation();
35+
GraphTraversal<Vertex, Vertex> traversal = graphQuery.getTraversal();
36+
if (deleteQuery.getWhere().isPresent()) {
37+
Where where = deleteQuery.getWhere().get();
38+
39+
Condition condition = where.getCondition();
40+
traversal.filter(getPredicate(graphQuery, condition, representation));
41+
}
42+
43+
traversal.hasLabel(representation.getName());
44+
return traversal.toList();
45+
}
46+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2017 Otávio Santana and others
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* and Apache License v2.0 which accompanies this distribution.
6+
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7+
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
8+
*
9+
* You may elect to redistribute this code under either of these licenses.
10+
*
11+
* Contributors:
12+
*
13+
* Otavio Santana
14+
*/
15+
package org.jnosql.artemis.graph.query;
16+
17+
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
18+
import org.apache.tinkerpop.gremlin.structure.Vertex;
19+
import org.jnosql.artemis.Converters;
20+
import org.jnosql.artemis.DynamicQueryException;
21+
import org.jnosql.artemis.reflection.ClassRepresentation;
22+
import org.jnosql.artemis.util.ConverterUtil;
23+
24+
import java.lang.reflect.Method;
25+
import java.util.Collection;
26+
import java.util.stream.Collectors;
27+
import java.util.stream.StreamSupport;
28+
29+
import static java.util.Collections.singletonList;
30+
31+
final class GraphQueryMethod {
32+
33+
private final ClassRepresentation representation;
34+
private final GraphTraversal<Vertex, Vertex> traversal;
35+
private final Object[] args;
36+
private final Converters converters;
37+
private final Method method;
38+
private int counter = 0;
39+
40+
GraphQueryMethod(ClassRepresentation representation,
41+
GraphTraversal<Vertex, Vertex> traversal,
42+
Converters converters, Method method, Object[] args) {
43+
this.representation = representation;
44+
this.traversal = traversal;
45+
this.args = args;
46+
this.converters = converters;
47+
this.method = method;
48+
}
49+
50+
public Method getMethod() {
51+
return method;
52+
}
53+
54+
public String getEntityName() {
55+
return representation.getName();
56+
}
57+
58+
public ClassRepresentation getRepresentation() {
59+
return representation;
60+
}
61+
62+
public GraphTraversal<Vertex, Vertex> getTraversal() {
63+
return traversal;
64+
}
65+
66+
public Object getValue(String name) {
67+
Object value = getValue();
68+
return ConverterUtil.getValue(value, representation, name, converters);
69+
}
70+
71+
public Collection<?> getInValue(String name) {
72+
Object value = getValue();
73+
if(value instanceof Iterable<?>) {
74+
return (Collection<?>) StreamSupport.stream(Iterable.class.cast(value).spliterator(), false)
75+
.map(v -> ConverterUtil.getValue(v, representation, name, converters))
76+
.collect(Collectors.toList());
77+
}
78+
return singletonList(ConverterUtil.getValue(value, representation, name, converters));
79+
}
80+
81+
private Object getValue() {
82+
if ((counter + 1) > args.length) {
83+
throw new DynamicQueryException(String.format("There is a missed argument in the method %s",
84+
method));
85+
}
86+
Object value = args[counter];
87+
counter++;
88+
return value;
89+
}
90+
91+
92+
}

0 commit comments

Comments
 (0)