From e158c4a5ca6d16ba3092cbd6761ae60facff2c07 Mon Sep 17 00:00:00 2001 From: Jedrzej Sobanski Date: Tue, 23 Oct 2012 18:01:21 +0200 Subject: [PATCH] * small refactoring of Neo4JAdaptor * bug fix in FlattenedIterator for occassional NullPointerException + test added --- .../er/neo4jadaptor/query/QueryConverter.java | 31 +--- .../er/neo4jadaptor/query/Results.java | 5 +- .../all_of_type/results/ObjectsOfType.java | 19 +-- .../query/expression/Converter.java | 138 ++++++++++++++++++ .../expression/sentence/BinaryJoined.java | 15 ++ .../query/expression/sentence/Comparison.java | 24 +++ .../query/expression/sentence/Negation.java | 9 ++ .../query/expression/sentence/Sentence.java | 5 + .../sentence/operators/BinaryOperator.java | 5 + .../operators/ComparisonOperator.java | 36 +++++ .../query/lucene/LuceneQueryConverter.java | 9 +- .../query/lucene/results/LuceneIndexHits.java | 26 ++-- .../neo4j_by_pk/results/NodesRelatedTo.java | 45 +++--- .../neo4j_by_pk/results/NodesWithIds.java | 75 +++++----- .../query/neo4j_eval/EvaluatingFilter.java | 104 ++++++------- .../neo4j_eval/EvaluationQueryConverter.java | 4 +- .../neo4j_eval/evaluators/Comparison.java | 2 +- .../storage/lucene/LuceneStore.java | 2 +- .../utils/iteration/FlattenedIterator.java | 2 +- .../iteration/FlattenedIteratorTest.java | 19 +++ 20 files changed, 378 insertions(+), 197 deletions(-) create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/Converter.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/BinaryJoined.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Comparison.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Negation.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Sentence.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/BinaryOperator.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/ComparisonOperator.java create mode 100644 Frameworks/EOAdaptors/JavaNeo4JAdaptor/Tests/er/neo4jadaptor/utils/iteration/FlattenedIteratorTest.java diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/QueryConverter.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/QueryConverter.java index 9baeb5244aa..a9953537974 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/QueryConverter.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/QueryConverter.java @@ -14,6 +14,7 @@ import er.extensions.eof.qualifiers.ERXInQualifier; import er.neo4jadaptor.ersatz.webobjects.NSTranslator; +import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator; /** * Converts {@link EOQualifier}s to custom type of queries. @@ -24,36 +25,6 @@ */ public abstract class QueryConverter { - public static enum ComparisonOperator { - LESS_THAN("<"), - LESS_OR_EQUAL("<="), - GREATER_THAN(">"), - GREATER_OR_EQUAL(">="), - EQUAL("="), - /** - * Case sensitive match using wildcards - */ - LIKE("like"), - /** - * Case insensitive match using wildcards - */ - ILIKE("ilike"), - /** - * Regular expression match - */ - MATCHES("matches"); - - private final String asString; - - private ComparisonOperator(String asString) { - this.asString = asString; - } - - @Override - public String toString() { - return asString; - } - } /** * @param entity diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/Results.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/Results.java index fb973121ad6..8ad2b9231b5 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/Results.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/Results.java @@ -7,12 +7,11 @@ /** - * Provides iterator for the search results. + * Marker interface for the search results cursor. * * @author Jedrzej Sobanski * * @param */ -public interface Results { - public Cursor iterator(); +public interface Results extends Cursor { } diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/all_of_type/results/ObjectsOfType.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/all_of_type/results/ObjectsOfType.java index 5b3a4ebc6e1..1753b83710a 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/all_of_type/results/ObjectsOfType.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/all_of_type/results/ObjectsOfType.java @@ -1,8 +1,5 @@ package er.neo4jadaptor.query.all_of_type.results; -import java.util.Iterator; - -import org.apache.lucene.search.Query; import org.neo4j.graphdb.PropertyContainer; import org.neo4j.graphdb.index.Index; @@ -10,25 +7,13 @@ import er.neo4jadaptor.query.Results; import er.neo4jadaptor.query.lucene.LuceneQueryConverter; -import er.neo4jadaptor.utils.cursor.Cursor; import er.neo4jadaptor.utils.cursor.IteratorCursor; -public class ObjectsOfType implements Results { +public class ObjectsOfType extends IteratorCursor implements Results { @SuppressWarnings("unused") private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ObjectsOfType.class); - private final Index typeIndex; - private final EOEntity entity; - public ObjectsOfType(Index nodeIndex, EOEntity entity) { - this.typeIndex = nodeIndex; - this.entity = entity; - } - - public Cursor iterator() { - Query q = LuceneQueryConverter.matchAllOfEntity(entity); - Iterator it = typeIndex.query(q).iterator(); - - return new IteratorCursor(it); + super(nodeIndex.query(LuceneQueryConverter.matchAllOfEntity(entity)).iterator()); } } diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/Converter.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/Converter.java new file mode 100644 index 00000000000..02b9537e00f --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/Converter.java @@ -0,0 +1,138 @@ +package er.neo4jadaptor.query.expression; + +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.EQUAL; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.GREATER_OR_EQUAL; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.GREATER_THAN; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.ILIKE; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.LESS_OR_EQUAL; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.LESS_THAN; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.LIKE; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.MATCHES; +import static er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator.NOT_EQUAL; + +import java.util.ArrayList; +import java.util.Collection; + +import com.webobjects.eoaccess.EOAttribute; +import com.webobjects.eoaccess.EOEntity; +import com.webobjects.eoaccess.EORelationship; +import com.webobjects.eocontrol.EOAndQualifier; +import com.webobjects.eocontrol.EOKeyValueQualifier; +import com.webobjects.eocontrol.EONotQualifier; +import com.webobjects.eocontrol.EOOrQualifier; +import com.webobjects.eocontrol.EOQualifier; +import com.webobjects.foundation.NSKeyValueCoding; +import com.webobjects.foundation.NSSelector; + +import er.neo4jadaptor.ersatz.webobjects.NSTranslator; +import er.neo4jadaptor.query.expression.sentence.BinaryJoined; +import er.neo4jadaptor.query.expression.sentence.Comparison; +import er.neo4jadaptor.query.expression.sentence.Negation; +import er.neo4jadaptor.query.expression.sentence.Sentence; +import er.neo4jadaptor.query.expression.sentence.operators.BinaryOperator; +import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator; + +public class Converter { + private final EOEntity entity; + + public Converter(EOEntity entity) { + this.entity = entity; + } + + public Sentence convert(EOQualifier q) { + if (q instanceof EOAndQualifier) { + Collection components = convertCollection(((EOAndQualifier) q).qualifiers()); + + return new BinaryJoined(BinaryOperator.AND, components); + } else if (q instanceof EOOrQualifier) { + Collection components = convertCollection(((EOOrQualifier) q).qualifiers()); + + return new BinaryJoined(BinaryOperator.OR, components); + } else if (q instanceof EONotQualifier) { + Sentence component = convert(((EONotQualifier) q).qualifier()); + + return new Negation(component); + } else if (q instanceof EOKeyValueQualifier) { + return convertComparison((EOKeyValueQualifier) q); + } else { + throw new IllegalArgumentException(); + } + } + + private Collection convertCollection(Collection qualifiers) { + Collection components = new ArrayList(); + + for (EOQualifier q : qualifiers) { + components.add(convert(q)); + } + return components; + } + + private ComparisonOperator operator(NSSelector operator) { + if (operator.equals(EOKeyValueQualifier.QualifierOperatorEqual)) { + return EQUAL; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorNotEqual)) { + return NOT_EQUAL; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorLessThanOrEqualTo)) { + return LESS_OR_EQUAL; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorLessThan)) { + return LESS_THAN; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorGreaterThanOrEqualTo)) { + return GREATER_OR_EQUAL; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorGreaterThan)) { + return GREATER_THAN; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorLike)) { + return LIKE; + } else if (operator.equals(EOKeyValueQualifier.QualifierOperatorCaseInsensitiveLike)) { + return ILIKE; + } else if (ComparisonOperator.MATCHES.asString.equals(operator.name())) { + return MATCHES; + } else { + // case not covered + throw new UnsupportedOperationException(operator.toString()); + } + } + + private Comparison convertComparison(EOKeyValueQualifier qual) { + ComparisonOperator operator = operator(qual.selector()); + String key = qual.key(); + Object value = NSTranslator.instance.toNeutralValue(qual.value(), entity.attributeNamed(key)); + EOEntity currentEntity = entity; + String [] splits = key.split("\\."); + Collection rels = new ArrayList(); + + for (int i=0; i T asOne(Collection col) { + if (col.size() != 1) { + throw new IllegalArgumentException(); + } else { + return col.iterator().next(); + } + } +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/BinaryJoined.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/BinaryJoined.java new file mode 100644 index 00000000000..56f4622eed8 --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/BinaryJoined.java @@ -0,0 +1,15 @@ +package er.neo4jadaptor.query.expression.sentence; + +import java.util.Collection; + +import er.neo4jadaptor.query.expression.sentence.operators.BinaryOperator; + +public class BinaryJoined extends Sentence { + private final Collection components; + private final BinaryOperator operator; + + public BinaryJoined(BinaryOperator op, Collection components) { + this.operator = op; + this.components = components; + } +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Comparison.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Comparison.java new file mode 100644 index 00000000000..956adf1a13d --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Comparison.java @@ -0,0 +1,24 @@ +package er.neo4jadaptor.query.expression.sentence; + +import java.util.Collection; + +import com.webobjects.eoaccess.EOAttribute; +import com.webobjects.eoaccess.EORelationship; + +import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator; + + + +public class Comparison extends Sentence { + private final Collection relationships; + private final EOAttribute attribute; + private final ComparisonOperator operator; + private final Object value; + + public Comparison(Collection rels, EOAttribute att, ComparisonOperator op, Object val) { + this.relationships = rels; + this.attribute = att; + this.operator = op; + this.value = val; + } +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Negation.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Negation.java new file mode 100644 index 00000000000..f59fea33cb1 --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Negation.java @@ -0,0 +1,9 @@ +package er.neo4jadaptor.query.expression.sentence; + +public class Negation extends Sentence { + private final Sentence wrapped; + + public Negation(Sentence toNegate) { + this.wrapped = toNegate; + } +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Sentence.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Sentence.java new file mode 100644 index 00000000000..00192c4cf8c --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/Sentence.java @@ -0,0 +1,5 @@ +package er.neo4jadaptor.query.expression.sentence; + +public abstract class Sentence { + +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/BinaryOperator.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/BinaryOperator.java new file mode 100644 index 00000000000..de347dc9254 --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/BinaryOperator.java @@ -0,0 +1,5 @@ +package er.neo4jadaptor.query.expression.sentence.operators; + +public enum BinaryOperator { + AND, OR; +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/ComparisonOperator.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/ComparisonOperator.java new file mode 100644 index 00000000000..3178a898e2a --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/expression/sentence/operators/ComparisonOperator.java @@ -0,0 +1,36 @@ +package er.neo4jadaptor.query.expression.sentence.operators; + + +public enum ComparisonOperator { + LESS_THAN("<"), + LESS_OR_EQUAL("<="), + GREATER_THAN(">"), + GREATER_OR_EQUAL(">="), + EQUAL("="), + NOT_EQUAL("!="), + + /** + * Case sensitive match using wildcards + */ + LIKE("like"), + /** + * Case insensitive match using wildcards + */ + ILIKE("ilike"), + /** + * Regular expression match + */ + MATCHES("matches"); + + public final String asString; + + private ComparisonOperator(String asString) { + this.asString = asString; + } + + @Override + public String toString() { + return asString; + } + +} diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/LuceneQueryConverter.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/LuceneQueryConverter.java index dc61681cbfd..650d6951b13 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/LuceneQueryConverter.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/LuceneQueryConverter.java @@ -21,6 +21,7 @@ import er.neo4jadaptor.ersatz.lucene.LuceneErsatz; import er.neo4jadaptor.ersatz.lucene.LuceneTranslator; import er.neo4jadaptor.query.QueryConverter; +import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator; import er.neo4jadaptor.storage.lucene.LuceneStore; /** @@ -102,7 +103,7 @@ protected Query convertKeyValueQualifier(EOEntity entity, EOKeyValueQualifier qu } } - private Query rangeQuery(String key, EOAttribute att, QueryConverter.ComparisonOperator operator, Object value) { + private Query rangeQuery(String key, EOAttribute att, ComparisonOperator operator, Object value) { String min = null; String max = null; boolean minInclusive = false; @@ -121,10 +122,10 @@ private Query rangeQuery(String key, EOAttribute att, QueryConverter.ComparisonO break; } - if (QueryConverter.ComparisonOperator.LESS_OR_EQUAL.equals(operator)) { + if (ComparisonOperator.LESS_OR_EQUAL.equals(operator)) { maxInclusive = true; } - if (QueryConverter.ComparisonOperator.GREATER_OR_EQUAL.equals(operator)) { + if (ComparisonOperator.GREATER_OR_EQUAL.equals(operator)) { minInclusive = true; } @@ -132,7 +133,7 @@ private Query rangeQuery(String key, EOAttribute att, QueryConverter.ComparisonO } @Override - protected Query comparison(EOEntity entity, String key, QueryConverter.ComparisonOperator operator, Object value) { + protected Query comparison(EOEntity entity, String key, ComparisonOperator operator, Object value) { EOAttribute att = entity.attributeNamed(key); String luceneValue = LuceneTranslator.instance.fromNeutralValue(value, att); diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/results/LuceneIndexHits.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/results/LuceneIndexHits.java index 7d2534d5cfc..7e1688eaafc 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/results/LuceneIndexHits.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/lucene/results/LuceneIndexHits.java @@ -4,27 +4,25 @@ import org.neo4j.graphdb.index.IndexHits; import er.neo4jadaptor.query.Results; -import er.neo4jadaptor.utils.cursor.Cursor; import er.neo4jadaptor.utils.cursor.IteratorCursor; -public class LuceneIndexHits implements Results { +public class LuceneIndexHits extends IteratorCursor implements Results { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LuceneIndexHits.class); - private final IndexHits hits; + final IndexHits hits; - public LuceneIndexHits(IndexHits hits) { + public LuceneIndexHits(final IndexHits hits) { + super(hits); + this.hits = hits; } - - public Cursor iterator() { - return new IteratorCursor(hits) { - public void close() { - if (log.isDebugEnabled()) { - log.debug("Closing lucene hits"); - } - hits.close(); - } - }; + + public void close() { + if (log.isDebugEnabled()) { + log.debug("Closing lucene hits"); + } + hits.close(); } + } diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesRelatedTo.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesRelatedTo.java index fb7ea67b789..fe5a123b20f 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesRelatedTo.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesRelatedTo.java @@ -24,16 +24,12 @@ public class NodesRelatedTo implements Results { @SuppressWarnings("unused") private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(NodesRelatedTo.class); - private final Results relatedTo; - private final RelationshipType relationshipType; + final Cursor relationshipsIterator; public NodesRelatedTo(Results relatedTo, EORelationship rel) { - this.relatedTo = relatedTo; - this.relationshipType = Neo4JUtils.getRelationshipType(rel); - } - - public Cursor iterator() { - final Cursor nodeCursor = relatedTo.iterator(); + final RelationshipType relationshipType = Neo4JUtils.getRelationshipType(rel); + + final Cursor nodeCursor = relatedTo; Cursor> twoLevelIt = new Cursor>() { public void remove() { @@ -56,25 +52,22 @@ public void close() { } }; - final Cursor relationshipsIterator = new FlattenedCursor(twoLevelIt); - - - return new Cursor() { - public boolean hasNext() { - return relationshipsIterator.hasNext(); - } - - public void close() { - relationshipsIterator.close(); - } + relationshipsIterator = new FlattenedCursor(twoLevelIt); + } + + public boolean hasNext() { + return relationshipsIterator.hasNext(); + } + + public void close() { + relationshipsIterator.close(); + } - public Node next() { - return relationshipsIterator.next().getStartNode(); - } + public Node next() { + return relationshipsIterator.next().getStartNode(); + } - public void remove() { - relationshipsIterator.remove(); - } - }; + public void remove() { + relationshipsIterator.remove(); } } diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesWithIds.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesWithIds.java index e262ad2358f..f059ef2b83e 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesWithIds.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_by_pk/results/NodesWithIds.java @@ -9,7 +9,6 @@ import org.neo4j.graphdb.NotFoundException; import er.neo4jadaptor.query.Results; -import er.neo4jadaptor.utils.cursor.Cursor; /** * Returns nodes with specified IDs. @@ -21,7 +20,9 @@ public class NodesWithIds implements Results { @SuppressWarnings("unused") private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(NodesWithIds.class); - private final Collection nodeIds; + private final Iterator nodeIdsIt; + private Node next; + private final GraphDatabaseService db; public NodesWithIds(GraphDatabaseService db, Collection nodeIds) { @@ -31,51 +32,43 @@ public NodesWithIds(GraphDatabaseService db, Collection nodeId } } - this.nodeIds = Collections.unmodifiableCollection(nodeIds); + this.nodeIdsIt = Collections.unmodifiableCollection(nodeIds).iterator(); this.db = db; } - public Cursor iterator() { - final Iterator it = nodeIds.iterator(); - - return new Cursor() { - Node next; + private void calculateNext() { + while (nodeIdsIt.hasNext()) { + long id = nodeIdsIt.next().longValue(); - private void calculateNext() { - while (it.hasNext()) { - long id = it.next().longValue(); - - try { - next = db.getNodeById(id); - return; - } catch (NotFoundException e) { - // ignore - } - } - } - - public void close() { - // do nothing - } - - public boolean hasNext() { - if (next == null) { - calculateNext(); - } - return next != null; + try { + next = db.getNodeById(id); + return; + } catch (NotFoundException e) { + // ignore } + } + } + + public void close() { + // do nothing + } + + public boolean hasNext() { + if (next == null) { + calculateNext(); + } + return next != null; + } - public Node next() { - Node ret = next; - - next = null; - - return ret; - } + public Node next() { + Node ret = next; + + next = null; + + return ret; + } - public void remove() { - it.remove(); - } - }; + public void remove() { + nodeIdsIt.remove(); } } diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluatingFilter.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluatingFilter.java index 8b5332b1b0c..b61f8070c68 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluatingFilter.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluatingFilter.java @@ -23,6 +23,10 @@ public class EvaluatingFilter implements Results @SuppressWarnings("unchecked") private static final EvaluationQueryConverter generator = new EvaluationQueryConverter(); + + private T next; + private Cursor it; + private boolean hasFinished = false; private final Results wrapped; private final Evaluator eval; @@ -38,73 +42,59 @@ public EvaluatingFilter(Results objects, EOEntity entity, EOQualifier q) { private EvaluatingFilter(Results wrapped, Evaluator eval) { this.wrapped = wrapped; this.eval = eval; + this.it = wrapped; } - public Cursor iterator() { - return new EvaluatingFacetResults(wrapped.iterator()); - } - - private final class EvaluatingFacetResults implements Cursor { - private T next; - private Cursor it; - private boolean hasFinished = false; - - private EvaluatingFacetResults(Cursor it) { - this.it = it; - } - - public boolean hasNext() { - if (hasFinished) { - return false; - } else if (next == null) { - next = calculateNext(); - - if (next == null) { - hasFinished = true; - } - + public boolean hasNext() { + if (hasFinished) { + return false; + } else if (next == null) { + next = calculateNext(); + + if (next == null) { + hasFinished = true; } - return next != null; + } + return next != null; + } - public void close() { - it.close(); - } + public void close() { + it.close(); + } + + public T next() { + T result = next; - public T next() { - T result = next; - - next = null; - - return result; - } + next = null; - private T calculateNext() { - while (it.hasNext()) { - T candidate = it.next(); - - if (eval.evaluate(candidate)) { - countHits++; - if (log.isDebugEnabled()) { - log.debug("Evaluating " + candidate + " with " + eval + ", result: match"); - } - return candidate; - } else { - countMisses++; - if (log.isDebugEnabled()) { - log.debug("Evaluating " + candidate + " with " + eval + ", result: miss"); - } + return result; + } + + private T calculateNext() { + while (it.hasNext()) { + T candidate = it.next(); + + if (eval.evaluate(candidate)) { + countHits++; + if (log.isDebugEnabled()) { + log.debug("Evaluating " + candidate + " with " + eval + ", result: match"); + } + return candidate; + } else { + countMisses++; + if (log.isDebugEnabled()) { + log.debug("Evaluating " + candidate + " with " + eval + ", result: miss"); } } - if (log.isDebugEnabled() && countMisses > 0) { - log.debug("Had " + countHits + " hits vs. " + countMisses + " misses for " + wrapped); - } - return null; } - - public void remove() { - throw new UnsupportedOperationException(); + if (log.isDebugEnabled() && countMisses > 0) { + log.debug("Had " + countHits + " hits vs. " + countMisses + " misses for " + wrapped); } - + return null; + } + + public void remove() { + throw new UnsupportedOperationException(); } } diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluationQueryConverter.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluationQueryConverter.java index 6925613c8c4..0ea6d70c7c8 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluationQueryConverter.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/EvaluationQueryConverter.java @@ -7,7 +7,6 @@ import org.neo4j.graphdb.PropertyContainer; - import com.webobjects.eoaccess.EOAttribute; import com.webobjects.eoaccess.EOEntity; import com.webobjects.eoaccess.EORelationship; @@ -15,6 +14,7 @@ import com.webobjects.foundation.NSArray; import er.neo4jadaptor.query.QueryConverter; +import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator; import er.neo4jadaptor.query.neo4j_eval.evaluators.AlwaysTrue; import er.neo4jadaptor.query.neo4j_eval.evaluators.BoolEvaluator; import er.neo4jadaptor.query.neo4j_eval.evaluators.Comparison; @@ -45,7 +45,7 @@ public EvaluationQueryConverter() { @SuppressWarnings("unchecked") @Override - protected Evaluator comparison(EOEntity entity, String key, er.neo4jadaptor.query.QueryConverter.ComparisonOperator operator, Object value) { + protected Evaluator comparison(EOEntity entity, String key, ComparisonOperator operator, Object value) { Retriever retriever = buildRetriever(entity, key); if (operator.equals(ComparisonOperator.LIKE) || operator.equals(ComparisonOperator.ILIKE)) { diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/evaluators/Comparison.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/evaluators/Comparison.java index 8856d0cd744..d5eefce99e4 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/evaluators/Comparison.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/query/neo4j_eval/evaluators/Comparison.java @@ -4,7 +4,7 @@ import org.neo4j.graphdb.PropertyContainer; -import er.neo4jadaptor.query.QueryConverter.ComparisonOperator; +import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator; import er.neo4jadaptor.query.neo4j_eval.Cost; import er.neo4jadaptor.query.neo4j_eval.retrievers.Retriever; diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/storage/lucene/LuceneStore.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/storage/lucene/LuceneStore.java index 8df594141e2..e1fe751046f 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/storage/lucene/LuceneStore.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/storage/lucene/LuceneStore.java @@ -80,7 +80,7 @@ public Cursor query(EOQualifier q) { log.debug("Fetching " + entity.name() + " where " + q); } - return new LinkingCursor(result.iterator(), entity); + return new LinkingCursor(result, entity); } public Ersatz newPrimaryKey() { diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/utils/iteration/FlattenedIterator.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/utils/iteration/FlattenedIterator.java index 8f1862e768b..e7f859803b0 100644 --- a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/utils/iteration/FlattenedIterator.java +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Sources/er/neo4jadaptor/utils/iteration/FlattenedIterator.java @@ -30,7 +30,7 @@ public boolean hasNext() { while (! internalHasNext() && it.hasNext()) { internal = it.next(); } - return internal.hasNext(); + return internal != null && internal.hasNext(); } public V next() { diff --git a/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Tests/er/neo4jadaptor/utils/iteration/FlattenedIteratorTest.java b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Tests/er/neo4jadaptor/utils/iteration/FlattenedIteratorTest.java new file mode 100644 index 00000000000..c0ddc810a1b --- /dev/null +++ b/Frameworks/EOAdaptors/JavaNeo4JAdaptor/Tests/er/neo4jadaptor/utils/iteration/FlattenedIteratorTest.java @@ -0,0 +1,19 @@ +package er.neo4jadaptor.utils.iteration; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import junit.framework.TestCase; + +public class FlattenedIteratorTest extends TestCase { + public void test1_discoveredNPETest() { + // it used to fail when internal iterator was not present, due to NullPointerException + List> iterators = new ArrayList>(); + FlattenedIterator it = new FlattenedIterator(iterators.iterator()); + + while (it.hasNext()) { + it.next(); + } + } +}