diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/FullTextIndexBasedStartClause.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/FullTextIndexBasedStartClause.java index e6dd972de..aa714d521 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/FullTextIndexBasedStartClause.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/FullTextIndexBasedStartClause.java @@ -69,6 +69,17 @@ public class FullTextIndexBasedStartClause extends IndexBasedStartClause { return result; } + protected String renderQuery(Map values) { + StringBuilder sb=new StringBuilder(); + for (Map.Entry entry : values.entrySet()) { + if (sb.length()>0) sb.append(" AND "); + final PartInfo partInfo = entry.getKey(); + Object value = entry.getValue(); + sb.append(QueryTemplates.formatIndexQuery(partInfo,value)); + } + return sb.toString(); + } + diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/IndexBasedStartClause.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/IndexBasedStartClause.java index 4ad36f913..c4f18607e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/IndexBasedStartClause.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/IndexBasedStartClause.java @@ -15,6 +15,16 @@ */ package org.springframework.data.neo4j.repository.query; +import org.neo4j.index.lucene.ValueContext; +import org.springframework.data.neo4j.fieldaccess.PropertyConverter; +import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.data.repository.query.Parameter; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + /** * Abstract class which represents a start clause which makes * use of an index of some sort. @@ -27,5 +37,36 @@ abstract class IndexBasedStartClause extends StartClause { super(partInfo); } + protected Map matchToPartsAndConvert(Map myParameters, Map parameters, Neo4jTemplate template) { + Map result = new LinkedHashMap(); + for (Map.Entry entry : myParameters.entrySet()) { + Object value = parameters.get(entry.getKey()); + PartInfo partInfo = entry.getValue(); + + Neo4jPersistentProperty property = partInfo.getLeafProperty(); + result.put(partInfo,convertIfNecessary(template, value, property)); + } + return result; + } + + protected Object convertIfNecessary(Neo4jTemplate template, Object value, Neo4jPersistentProperty property) { + if (property.isIndexedNumerically()) return new ValueContext(value).indexNumeric(); + if (property.isNeo4jPropertyType() && property.isNeo4jPropertyValue(value)) return value; + + PropertyConverter converter = new PropertyConverter(template.getConversionService(), property); + return converter.serializePropertyValue(value); + } + + protected Map findMyParameters(Set parameters) { + Map result=new LinkedHashMap(); + for (Parameter parameter : parameters) { + PartInfo partInfo = partInfos.get(parameter.getIndex()); + if (partInfo!=null) { + result.put(parameter, partInfo); + } + } + return result; + } + } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/StartClause.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/StartClause.java index 779f2bf5a..bd61d962e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/StartClause.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/StartClause.java @@ -32,11 +32,10 @@ import java.util.*; */ abstract class StartClause { - private final SortedMap partInfos=new TreeMap (); + protected final SortedMap partInfos=new TreeMap (); /** - * Creates a new {@link StartClause} from the given {@link Neo4jPersistentProperty}, - * variable and the given parameter index. + * Creates a new {@link StartClause} from the given {@link PartInfo} */ public StartClause(PartInfo partInfo) { this.partInfos.put(partInfo.getParameterIndex(), partInfo); @@ -44,61 +43,32 @@ abstract class StartClause { /** * Returns true if this start clause comprises of multiple parts - * @return */ protected boolean hasMultipleParts() { return partInfos.size() > 1; } - public abstract Map resolveParameters(Map parameters, Neo4jTemplate template); - protected String renderQuery(Map values) { - StringBuilder sb=new StringBuilder(); - for (Map.Entry entry : values.entrySet()) { - if (sb.length()>0) sb.append(" AND "); - final PartInfo partInfo = entry.getKey(); - Object value = entry.getValue(); - sb.append(QueryTemplates.formatIndexQuery(partInfo,value)); - } - return sb.toString(); - } - - protected Map matchToPartsAndConvert(Map myParameters, Map parameters, Neo4jTemplate template) { - Map result = new LinkedHashMap(); - for (Map.Entry entry : myParameters.entrySet()) { - Object value = parameters.get(entry.getKey()); - PartInfo partInfo = entry.getValue(); - - Neo4jPersistentProperty property = partInfo.getLeafProperty(); - result.put(partInfo,convertIfNecessary(template, value, property)); - } - return result; - } - - protected Object convertIfNecessary(Neo4jTemplate template, Object value, Neo4jPersistentProperty property) { - if (property.isIndexedNumerically()) return new ValueContext(value).indexNumeric(); - if (property.isNeo4jPropertyType() && property.isNeo4jPropertyValue(value)) return value; - - PropertyConverter converter = new PropertyConverter(template.getConversionService(), property); - return converter.serializePropertyValue(value); - } - - protected Map findMyParameters(Set parameters) { - Map result=new LinkedHashMap(); - for (Parameter parameter : parameters) { - PartInfo partInfo = partInfos.get(parameter.getIndex()); - if (partInfo!=null) { - result.put(parameter, partInfo); - } - } - return result; - } - + /** + * Utility method which returns the primary (first) partInfo. In most cases + * there will only actually ever be one. + */ public PartInfo getPartInfo() { return IteratorUtil.first(partInfos.values()); } + /** + * Determines if it is possible to merge the provided PartInfo into + * this existing start clause, AND if so, also adds it to the list of + * parts managed by this clause. + * Merging will only occur if the provided partInfo refers to the same + * identifier as all all of the other parts contained in this start + * clause AND it also refers to the same index. + * + * @param partInfo + * @return true if the merge occurred otherwise false + */ public boolean merge(PartInfo partInfo) { for (PartInfo info : partInfos.values()) { if (info.sameIdentifier(partInfo) && info.sameIndex(partInfo)) { @@ -116,6 +86,7 @@ abstract class StartClause { } return true; } + public boolean sameIndex(PartInfo info) { for (PartInfo partInfo : partInfos.values()) { if (!partInfo.sameIndex(info)) return false;