You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/07/06 00:22:45 UTC
(grails-core) 01/01: chore(grails-data-neo4j): clean up Checkstyle/CodeNarc violations in grails-datastore-gorm-neo4j
This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch chore/neo4j-codestyle-cleanup
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 6edeaa940d02a947ae98f37fdac65dbdc3ea39d7
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sun Jul 5 18:56:47 2026 -0500
chore(grails-data-neo4j): clean up Checkstyle/CodeNarc violations in grails-datastore-gorm-neo4j
Fixes all 655 Checkstyle violations across 23 Java files and the remaining
CodeNarc violations across 7 Groovy files in the module: import ordering,
wildcard import expansion, unused imports, whitespace/paren spacing, blank
line separators, trailing newlines, indentation, and operator/separator
wrapping. No behavioral changes.
Co-Authored-By: Claude Sonnet 5 <no...@anthropic.com>
---
.../src/main/groovy/grails/neo4j/Direction.groovy | 3 +-
.../main/groovy/grails/neo4j/Neo4jEntity.groovy | 33 +-
.../src/main/groovy/grails/neo4j/Node.groovy | 4 +-
.../src/main/groovy/grails/neo4j/Path.groovy | 4 +-
.../main/groovy/grails/neo4j/Relationship.groovy | 26 +-
.../grails/neo4j/mapping/MappingBuilder.groovy | 9 +-
.../groovy/grails/neo4j/services/Cypher.groovy | 3 +-
.../grails/datastore/gorm/neo4j/CypherBuilder.java | 118 +-
.../datastore/gorm/neo4j/GraphClassMapping.groovy | 3 +-
.../gorm/neo4j/GraphGormMappingFactory.groovy | 5 +-
.../gorm/neo4j/GraphPersistentEntity.groovy | 138 +-
.../grails/datastore/gorm/neo4j/IdGenerator.java | 11 +-
.../datastore/gorm/neo4j/Neo4jDatastore.java | 240 ++--
.../neo4j/Neo4jDatastoreTransactionManager.java | 15 +-
.../gorm/neo4j/Neo4jEntityTraitProvider.groovy | 5 +-
.../datastore/gorm/neo4j/Neo4jMappingContext.java | 132 +-
.../grails/datastore/gorm/neo4j/Neo4jSession.java | 168 +--
.../datastore/gorm/neo4j/Neo4jTransaction.groovy | 15 +-
.../gorm/neo4j/RelationshipPersistentEntity.groovy | 46 +-
.../datastore/gorm/neo4j/RelationshipUtils.groovy | 41 +-
.../datastore/gorm/neo4j/SessionFlushedEvent.java | 3 +-
.../datastore/gorm/neo4j/TypeDirectionPair.java | 19 +-
.../gorm/neo4j/api/Neo4jGormStaticApi.groovy | 175 ++-
.../gorm/neo4j/collection/GraphAdapter.groovy | 44 +-
.../collection/Neo4jAssociationResultList.groovy | 6 +-
.../gorm/neo4j/collection/Neo4jList.groovy | 20 +-
.../gorm/neo4j/collection/Neo4jPath.groovy | 49 +-
.../neo4j/collection/Neo4jPersistentList.groovy | 14 +-
.../neo4j/collection/Neo4jPersistentSet.groovy | 22 +-
.../collection/Neo4jPersistentSortedSet.groovy | 18 +-
.../gorm/neo4j/collection/Neo4jRelationship.groovy | 5 +-
.../gorm/neo4j/collection/Neo4jResultList.groovy | 57 +-
.../gorm/neo4j/collection/Neo4jSet.groovy | 20 +-
.../gorm/neo4j/collection/Neo4jSortedSet.groovy | 18 +-
.../neo4j/config/Neo4jDriverConfigBuilder.groovy | 16 +-
.../datastore/gorm/neo4j/config/Settings.java | 3 +-
.../connections/Neo4jConnectionSourceFactory.java | 66 +-
.../Neo4jConnectionSourceSettings.groovy | 2 +
.../Neo4jConnectionSourceSettingsBuilder.groovy | 4 +-
.../connections/Neo4jEmbeddedConnectionSource.java | 6 +-
.../neo4j/engine/DynamicAssociationSupport.java | 57 +-
.../engine/Neo4jAssociationQueryExecutor.groovy | 109 +-
.../gorm/neo4j/engine/Neo4jEntityPersister.java | 520 ++++---
.../Neo4jModificationTrackingEntityAccess.groovy | 1 +
.../datastore/gorm/neo4j/engine/Neo4jQuery.groovy | 467 ++++---
.../neo4j/engine/RelationshipPendingDelete.java | 37 +-
.../neo4j/engine/RelationshipPendingInsert.java | 105 +-
.../gorm/neo4j/extensions/Neo4jExtensions.groovy | 73 +-
.../gorm/neo4j/identity/SnowflakeIdGenerator.java | 21 +-
.../gorm/neo4j/mapping/config/Attribute.groovy | 3 +-
.../neo4j/mapping/config/DynamicAssociation.java | 1 +
.../mapping/config/DynamicToManyAssociation.java | 2 +-
.../mapping/config/DynamicToOneAssociation.java | 5 +-
.../gorm/neo4j/mapping/config/NodeConfig.groovy | 5 +-
.../neo4j/mapping/config/RelationshipConfig.groovy | 4 +-
.../neo4j/mapping/reflect/Neo4jNameUtils.groovy | 8 +-
.../datastore/gorm/neo4j/parsers/PlingStemmer.java | 1467 ++++++++++----------
.../proxy/HashcodeEqualsAwareProxyFactory.java | 136 +-
.../proxy/Neo4jAssociationQueryProxyHandler.java | 5 +-
.../gorm/neo4j/proxy/Neo4jProxyFactory.java | 5 +-
.../FindAllCypherQueryImplementer.groovy | 7 +-
.../FindOneCypherQueryImplementer.groovy | 7 +-
.../FindPathCypherQueryImplementer.groovy | 4 +-
.../FindShortestPathImplementer.groovy | 24 +-
.../StatementResultCypherQueryImplementer.groovy | 4 +-
.../UpdateCypherQueryImplementer.groovy | 21 +-
.../transform/CypherQueryStringTransformer.groovy | 9 +-
.../gorm/neo4j/util/EmbeddedNeo4jServer.java | 55 +-
.../datastore/gorm/neo4j/util/IteratorUtil.java | 7 +-
69 files changed, 2382 insertions(+), 2373 deletions(-)
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Direction.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Direction.groovy
index bef0caa20c..e9028aa395 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Direction.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Direction.groovy
@@ -29,6 +29,7 @@ import groovy.transform.CompileStatic
*/
@CompileStatic
enum Direction {
+
INCOMING, OUTGOING, BOTH
@Override
@@ -53,4 +54,4 @@ enum Direction {
boolean isOutgoing() {
return this == OUTGOING || this == BOTH
}
-}
\ No newline at end of file
+}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Neo4jEntity.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Neo4jEntity.groovy
index 532cedb594..00f09f7934 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Neo4jEntity.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Neo4jEntity.groovy
@@ -18,10 +18,14 @@
*/
package grails.neo4j
+import groovy.transform.CompileStatic
+
+import org.neo4j.driver.QueryRunner
+import org.neo4j.driver.Result
+
import grails.gorm.MultiTenant
import grails.gorm.api.GormAllOperations
import grails.gorm.multitenancy.Tenants
-import groovy.transform.CompileStatic
import org.grails.datastore.gorm.GormEnhancer
import org.grails.datastore.gorm.GormEntity
import org.grails.datastore.gorm.GormStaticApi
@@ -34,8 +38,6 @@ import org.grails.datastore.gorm.schemaless.DynamicAttributes
import org.grails.datastore.mapping.model.config.GormProperties
import org.grails.datastore.mapping.multitenancy.MultiTenancySettings
import org.grails.datastore.mapping.multitenancy.exceptions.TenantNotFoundException
-import org.neo4j.driver.Result
-import org.neo4j.driver.QueryRunner
/**
* Extends the default {@org.grails.datastore.gorm.GormEntity} trait, adding new methods specific to Neo4j
@@ -67,7 +69,6 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
DynamicAttributes.super.putAt(name, val)
}
-
/**
* Obtains a dynamic attribute
*
@@ -77,12 +78,12 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
@Override
def getAt(String name) {
def val = DynamicAttributes.super.getAt(name)
- if(val == null) {
+ if (val == null) {
GormStaticApi staticApi = GormEnhancer.findStaticApi(getClass())
GraphPersistentEntity entity = (GraphPersistentEntity) staticApi.gormPersistentEntity
- if(entity.hasDynamicAssociations()) {
+ if (entity.hasDynamicAssociations()) {
def id = ident()
- if(id != null) {
+ if (id != null) {
staticApi.withSession { Neo4jSession session ->
DynamicAssociationSupport.loadDynamicAssociations(session, entity, this, id)
}
@@ -105,10 +106,9 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
QueryRunner boltSession = getStatementRunner(session)
String queryString
- if(cypher instanceof GString) {
+ if (cypher instanceof GString) {
queryString = Neo4jGormStaticApi.buildNamedParameterQueryFromGString((GString) cypher, params)
- }
- else {
+ } else {
queryString = cypher.toString()
}
params['this'] = session.getObjectIdentifier(this)
@@ -129,7 +129,7 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
QueryRunner boltSession = getStatementRunner(session)
Map<String, Object> paramsMap = new LinkedHashMap()
- paramsMap.put("this", session.getObjectIdentifier(this))
+ paramsMap.put('this', session.getObjectIdentifier(this))
includeTenantIdIfNecessary(session, cypher, paramsMap)
@@ -141,7 +141,6 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
}
}
-
/**
* perform a cypher query
* @param queryString
@@ -152,14 +151,14 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
Map<String, Object> arguments
if (session.getDatastore().multiTenancyMode == MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR) {
if (!queryString.contains("\$tenantId")) {
- throw new TenantNotFoundException("Query does not specify a tenant id, but multi tenant mode is DISCRIMINATOR!")
+ throw new TenantNotFoundException('Query does not specify a tenant id, but multi tenant mode is DISCRIMINATOR!')
} else {
arguments = new LinkedHashMap<String, Object>()
arguments.put(GormProperties.TENANT_IDENTITY, Tenants.currentId(Neo4jDatastore))
- arguments.put("this", session.getObjectIdentifier(this))
+ arguments.put('this', session.getObjectIdentifier(this))
}
} else {
- arguments = (Map<String, Object>) Collections.singletonMap("this", session.getObjectIdentifier(this))
+ arguments = (Map<String, Object>) Collections.singletonMap('this', session.getObjectIdentifier(this))
}
QueryRunner boltSession = getStatementRunner(session)
boltSession.run(queryString, arguments)
@@ -269,10 +268,10 @@ trait Neo4jEntity<D> implements GormEntity<D>, DynamicAttributes {
private void includeTenantIdIfNecessary(Neo4jSession session, String queryString, Map<String, Object> paramsMap) {
if ((this instanceof MultiTenant) && session.getDatastore().multiTenancyMode == MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR) {
if (!queryString.contains("\$tenantId")) {
- throw new TenantNotFoundException("Query does not specify a tenant id, but multi tenant mode is DISCRIMINATOR!")
+ throw new TenantNotFoundException('Query does not specify a tenant id, but multi tenant mode is DISCRIMINATOR!')
} else {
paramsMap.put(GormProperties.TENANT_IDENTITY, Tenants.currentId(Neo4jDatastore))
}
}
}
-}
\ No newline at end of file
+}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Node.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Node.groovy
index c39ba331ef..c7c562e25d 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Node.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Node.groovy
@@ -20,6 +20,7 @@
package grails.neo4j
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.GormEnhancer
import org.grails.datastore.gorm.GormEntity
import org.grails.datastore.gorm.neo4j.api.Neo4jGormStaticApi
@@ -33,6 +34,7 @@ import org.grails.datastore.gorm.schemaless.DynamicAttributes
*/
@CompileStatic
trait Node<D> implements Neo4jEntity<D>, GormEntity<D>, DynamicAttributes {
+
/**
* Allows accessing to dynamic properties with the dot operator
*
@@ -139,4 +141,4 @@ trait Node<D> implements Neo4jEntity<D>, GormEntity<D>, DynamicAttributes {
static <T> Path<D, T> findPathTo(Class<T> type, CharSequence cypher, Map params) {
((Neo4jGormStaticApi) GormEnhancer.findStaticApi(this)).findPathTo(type, cypher, params)
}
-}
\ No newline at end of file
+}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Path.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Path.groovy
index 0a8ca4da35..5ad951be18 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Path.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Path.groovy
@@ -26,7 +26,7 @@ package grails.neo4j
* @see org.neo4j.driver.types.Path
* @since 6.1
*/
-interface Path<S, E> extends Iterable<Segment<S,E>> {
+interface Path<S, E> extends Iterable<Segment<S, E>> {
/**
* A segment
@@ -34,6 +34,7 @@ interface Path<S, E> extends Iterable<Segment<S,E>> {
* @see org.neo4j.driver.types.Path.Segment
*/
interface Segment<S, E> {
+
Relationship<S, E> relationship()
S start()
@@ -41,7 +42,6 @@ interface Path<S, E> extends Iterable<Segment<S,E>> {
E end()
}
-
/** @return the start node of this path */
S start()
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Relationship.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Relationship.groovy
index f8b9c2260c..bb7b05fb28 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Relationship.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/Relationship.groovy
@@ -20,6 +20,7 @@
package grails.neo4j
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.GormEnhancer
import org.grails.datastore.gorm.GormEntity
import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity
@@ -32,7 +33,7 @@ import org.grails.datastore.gorm.schemaless.DynamicAttributes
* @since 6.1
*/
@CompileStatic
-trait Relationship<F,T> implements DynamicAttributes, Serializable {
+trait Relationship<F, T> implements DynamicAttributes, Serializable {
/**
* The relationship type
@@ -54,13 +55,12 @@ trait Relationship<F,T> implements DynamicAttributes, Serializable {
*/
T to
-
/**
* @return The type of the relationship
*/
String type() {
- if(this.theType == null) {
- theType = ((RelationshipPersistentEntity)GormEnhancer.findEntity(getClass())).type()
+ if (this.theType == null) {
+ theType = ((RelationshipPersistentEntity) GormEnhancer.findEntity(getClass())).type()
}
return theType
}
@@ -84,11 +84,11 @@ trait Relationship<F,T> implements DynamicAttributes, Serializable {
* @return True if they are equal
*/
boolean equals(Object object) {
- if(object instanceof Relationship) {
- Relationship other = (Relationship)object
- GormEntity fromEntity = (GormEntity)this.from
- GormEntity toEntity = (GormEntity)this.to
- return fromEntity?.ident() == ((GormEntity)other.from)?.ident() && toEntity?.ident() == ((GormEntity)other.to)?.ident()
+ if (object instanceof Relationship) {
+ Relationship other = (Relationship) object
+ GormEntity fromEntity = (GormEntity) this.from
+ GormEntity toEntity = (GormEntity) this.to
+ return fromEntity?.ident() == ((GormEntity) other.from)?.ident() && toEntity?.ident() == ((GormEntity) other.to)?.ident()
}
return false
}
@@ -97,16 +97,16 @@ trait Relationship<F,T> implements DynamicAttributes, Serializable {
* @return hashCode
*/
int hashCode() {
- GormEntity fromEntity = (GormEntity)this.from
- GormEntity toEntity = (GormEntity)this.to
+ GormEntity fromEntity = (GormEntity) this.from
+ GormEntity toEntity = (GormEntity) this.to
int result = type != null ? type.hashCode() : 0
def fromId = fromEntity?.ident()
- if(fromId != null) {
+ if (fromId != null) {
result = 31 * result + fromId.hashCode()
}
def toId = toEntity?.ident()
- if(toId != null) {
+ if (toId != null) {
result = 31 * result + toId.hashCode()
}
return result
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/mapping/MappingBuilder.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/mapping/MappingBuilder.groovy
index f8d5a09245..03ca2ddc1f 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/mapping/MappingBuilder.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/mapping/MappingBuilder.groovy
@@ -20,6 +20,7 @@
package grails.neo4j.mapping
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.mapping.config.Attribute
import org.grails.datastore.gorm.neo4j.mapping.config.NodeConfig
import org.grails.datastore.gorm.neo4j.mapping.config.RelationshipConfig
@@ -54,9 +55,9 @@ class MappingBuilder {
new ClosureRelMappingDefinition(mappingDefinition)
}
-
@CompileStatic
private static class ClosureRelMappingDefinition implements MappingDefinition<RelationshipConfig, Attribute> {
+
final Closure definition
private RelationshipConfig mapping
@@ -71,7 +72,7 @@ class MappingBuilder {
@Override
RelationshipConfig build() {
- if(mapping == null) {
+ if (mapping == null) {
RelationshipConfig nc = new RelationshipConfig()
mapping = RelationshipConfig.configureExisting(nc, definition)
}
@@ -79,8 +80,10 @@ class MappingBuilder {
}
}
+
@CompileStatic
private static class ClosureNodeMappingDefinition implements MappingDefinition<NodeConfig, Attribute> {
+
final Closure definition
private NodeConfig mapping
@@ -95,7 +98,7 @@ class MappingBuilder {
@Override
NodeConfig build() {
- if(mapping == null) {
+ if (mapping == null) {
NodeConfig nc = new NodeConfig()
mapping = NodeConfig.configureExisting(nc, definition)
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/services/Cypher.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/services/Cypher.groovy
index 29bc77fa38..f15793603d 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/services/Cypher.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/grails/neo4j/services/Cypher.groovy
@@ -33,5 +33,6 @@ import java.lang.annotation.Target
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
@interface Cypher {
+
String value()
-}
\ No newline at end of file
+}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/CypherBuilder.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/CypherBuilder.java
index 475b938127..f1e89ad9f6 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/CypherBuilder.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/CypherBuilder.java
@@ -18,7 +18,11 @@
*/
package org.grails.datastore.gorm.neo4j;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
/**
* A builder for Cypher queries
@@ -58,17 +62,16 @@ public class CypherBuilder {
private static final String CYPHER_RELATIONSHIP_MATCH = "MATCH %s WHERE ";
private static final String CYPHER_RELATIONSHIP = "(from%s)%s(to%s)";
-
- private String forLabels;
- private List<String> matches = new ArrayList<>();
- private List<String> relationshipMatches = new ArrayList<>();
- private List<String> optionalMatches = new ArrayList<String>();
+ private final String forLabels;
+ private final List<String> matches = new ArrayList<>();
+ private final List<String> relationshipMatches = new ArrayList<>();
+ private final List<String> optionalMatches = new ArrayList<String>();
private String conditions;
private String orderAndLimits;
- private List<String> returnColumns = new ArrayList<String>();
- private List<String> deleteColumns = new ArrayList<String>();
+ private final List<String> returnColumns = new ArrayList<String>();
+ private final List<String> deleteColumns = new ArrayList<String>();
private Map<String, Object> sets = null;
- private Map<String, Object> params = new LinkedHashMap<String, Object>();
+ private final Map<String, Object> params = new LinkedHashMap<String, Object>();
private int setIndex;
private String startNode = NODE_VAR;
private String defaultReturnStatement = DEFAULT_RETURN_STATEMENT;
@@ -77,20 +80,51 @@ public class CypherBuilder {
this.forLabels = forLabels;
}
+ /**
+ * Produces "MATCH (from%s)%s(to%s) WHERE "
+ * @param fromLabels The from node labels
+ * @param toLabels The to node labels
+ * @param relationship The relationship match
+ * @return The MATCH
+ */
+ public static String buildRelationshipMatch(String fromLabels, String relationship, String toLabels) {
+ return String.format(CYPHER_RELATIONSHIP_MATCH, buildRelationship(fromLabels, relationship, toLabels));
+ }
+
+ /**
+ * Produces "MATCH %s WHERE "
+ * @param relationship The relationship match
+ * @return The MATCH
+ */
+ public static String buildRelationshipMatch(String relationship) {
+ return String.format(CYPHER_RELATIONSHIP_MATCH, relationship);
+ }
+
+ /**
+ * Produces "(from%s)%s(to%s)"
+ * @param fromLabels The from node labels
+ * @param toLabels The to node labels
+ * @param relationship The relationship match
+ * @return The MATCH
+ */
+ public static String buildRelationship(String fromLabels, String relationship, String toLabels) {
+ return String.format(CypherBuilder.CYPHER_RELATIONSHIP, fromLabels, relationship, toLabels);
+ }
+
/**
* Sets the node name to start matching from (defaults to 'n')
*
* @param startNode The start node
*/
public void setStartNode(String startNode) {
- if(startNode != null) {
+ if (startNode != null) {
this.startNode = startNode;
this.defaultReturnStatement = RETURN + startNode + " as data\n";
}
}
public void addMatch(String match) {
- if(!matches.contains(match)) {
+ if (!matches.contains(match)) {
// Add empty match if the target entity is already defined
final String lastNode = match.substring(match.lastIndexOf('('));
final boolean alreadyDefined = matches.stream().anyMatch(m -> m.endsWith(lastNode));
@@ -99,19 +133,19 @@ public class CypherBuilder {
}
public void addRelationshipMatch(String match) {
- if(!relationshipMatches.contains(match)) {
+ if (!relationshipMatches.contains(match)) {
relationshipMatches.add(match);
}
}
public void replaceFirstRelationshipMatch(String match) {
- if(relationshipMatches.isEmpty()) {
+ if (relationshipMatches.isEmpty()) {
relationshipMatches.add(match);
- }
- else {
- relationshipMatches.set(0,match);
+ } else {
+ relationshipMatches.set(0, match);
}
}
+
/**
* Optional matches are added to do joins for relationships
*
@@ -179,7 +213,7 @@ public class CypherBuilder {
* @param sets The property to be set
*/
public void addPropertySet(Map<String, Object> sets) {
- if(sets != null) {
+ if (sets != null) {
final int index = addParam(sets);
this.setIndex = index;
this.sets = sets;
@@ -190,7 +224,7 @@ public class CypherBuilder {
StringBuilder cypher = new StringBuilder();
cypher.append(START_MATCH).append(startNode).append(forLabels).append(")");
- for(String r : relationshipMatches) {
+ for (String r : relationshipMatches) {
cypher.append(r);
}
@@ -200,21 +234,20 @@ public class CypherBuilder {
cypher.append(COMMAND_SEPARATOR).append(m);
}
-
- if ((conditions!=null) && (!conditions.isEmpty())) {
+ if ((conditions != null) && (!conditions.isEmpty())) {
cypher.append(WHERE).append(conditions);
}
- if(!optionalMatches.isEmpty()) {
+ if (!optionalMatches.isEmpty()) {
for (String m : optionalMatches) {
cypher.append(NEW_LINE)
- .append(OPTIONAL_MATCH)
- .append(m);
+ .append(OPTIONAL_MATCH)
+ .append(m);
}
}
- if(!deleteColumns.isEmpty()) {
+ if (!deleteColumns.isEmpty()) {
cypher.append(DELETE);
Iterator<String> iter = deleteColumns.iterator(); // same as Collection.join(String separator)
if (iter.hasNext()) {
@@ -226,13 +259,13 @@ public class CypherBuilder {
return cypher.toString();
}
- if(sets != null) {
+ if (sets != null) {
cypher.append("\nSET n += {").append(setIndex).append("}\n");
}
if (returnColumns.isEmpty()) {
cypher.append(defaultReturnStatement);
- if (orderAndLimits!=null) {
+ if (orderAndLimits != null) {
cypher.append(orderAndLimits).append(NEW_LINE);
}
} else {
@@ -244,7 +277,7 @@ public class CypherBuilder {
cypher.append(COMMAND_SEPARATOR).append(iter.next());
}
}
- if (orderAndLimits!=null) {
+ if (orderAndLimits != null) {
cypher.append(SPACE);
cypher.append(orderAndLimits);
}
@@ -252,35 +285,4 @@ public class CypherBuilder {
return cypher.toString();
}
-
- /**
- * Produces "MATCH (from%s)%s(to%s) WHERE "
- * @param fromLabels The from node labels
- * @param toLabels The to node labels
- * @param relationship The relationship match
- * @return The MATCH
- */
- public static String buildRelationshipMatch(String fromLabels, String relationship, String toLabels) {
- return String.format( CYPHER_RELATIONSHIP_MATCH, buildRelationship(fromLabels, relationship, toLabels));
- }
-
- /**
- * Produces "MATCH %s WHERE "
- * @param relationship The relationship match
- * @return The MATCH
- */
- public static String buildRelationshipMatch(String relationship) {
- return String.format( CYPHER_RELATIONSHIP_MATCH, relationship);
- }
-
- /**
- * Produces "(from%s)%s(to%s)"
- * @param fromLabels The from node labels
- * @param toLabels The to node labels
- * @param relationship The relationship match
- * @return The MATCH
- */
- public static String buildRelationship(String fromLabels, String relationship, String toLabels) {
- return String.format(CypherBuilder.CYPHER_RELATIONSHIP, fromLabels, relationship, toLabels);
- }
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphClassMapping.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphClassMapping.groovy
index 9907495415..da8b7b477c 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphClassMapping.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphClassMapping.groovy
@@ -19,6 +19,7 @@
package org.grails.datastore.gorm.neo4j
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.mapping.config.NodeConfig
import org.grails.datastore.mapping.model.AbstractClassMapping
import org.grails.datastore.mapping.model.MappingContext
@@ -41,6 +42,6 @@ class GraphClassMapping extends AbstractClassMapping<NodeConfig> {
NodeConfig getMappedForm() {
// Explicit field access (.@) - entity.mappedForm would resolve to the getter,
// which recurses back here via PersistentEntity#getMappedForm()'s default method.
- ((GraphPersistentEntity)entity).@mappedForm
+ ((GraphPersistentEntity) entity).@mappedForm
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphGormMappingFactory.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphGormMappingFactory.groovy
index 7a8d46ca50..a267160414 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphGormMappingFactory.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphGormMappingFactory.groovy
@@ -53,7 +53,7 @@ class GraphGormMappingFactory extends AbstractGormMappingFactory {
@Override
Entity createMappedForm(PersistentEntity entity) {
- if(entity instanceof RelationshipPersistentEntity) {
+ if (entity instanceof RelationshipPersistentEntity) {
Class previousType = currentNodeConfigType
try {
currentNodeConfigType = RelationshipConfig
@@ -61,8 +61,7 @@ class GraphGormMappingFactory extends AbstractGormMappingFactory {
} finally {
currentNodeConfigType = previousType
}
- }
- else {
+ } else {
return super.createMappedForm(entity)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphPersistentEntity.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphPersistentEntity.groovy
index 3a17454c8e..2078031878 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphPersistentEntity.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphPersistentEntity.groovy
@@ -19,9 +19,15 @@
package org.grails.datastore.gorm.neo4j
-import grails.neo4j.Relationship
+import java.beans.Introspector
+
import groovy.transform.CompileStatic
-import org.codehaus.groovy.runtime.HandleMetaClass
+
+import org.neo4j.driver.types.Entity
+
+import org.springframework.util.ClassUtils
+
+import grails.neo4j.Relationship
import org.grails.datastore.gorm.neo4j.mapping.config.NodeConfig
import org.grails.datastore.mapping.config.Property
import org.grails.datastore.mapping.model.AbstractPersistentEntity
@@ -34,11 +40,9 @@ import org.grails.datastore.mapping.model.PersistentProperty
import org.grails.datastore.mapping.model.config.GormMappingConfigurationStrategy
import org.grails.datastore.mapping.model.config.GormProperties
import org.grails.datastore.mapping.model.types.Association
-import org.neo4j.driver.types.Entity
-import org.springframework.util.ClassUtils
-import java.beans.Introspector
-import static org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity.*
+import static org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity.FROM
+import static org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity.TO
/**
@@ -78,10 +82,9 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
GraphPersistentEntity(Class javaClass, MappingContext context, boolean external) {
super(javaClass, context)
- if(isExternal()) {
+ if (isExternal()) {
this.mappedForm = null
- }
- else {
+ } else {
this.mappedForm = (NodeConfig) context.getMappingFactory().createMappedForm(this)
}
this.relationshipEntity = this instanceof RelationshipPersistentEntity
@@ -96,20 +99,20 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
@Override
void initialize() {
- if(!isInitialized()) {
+ if (!isInitialized()) {
super.initialize()
- if(!isExternal()) {
+ if (!isExternal()) {
PersistentProperty identity = getIdentity()
- if(identity != null) {
+ if (identity != null) {
String generatorType = ((Property) identity.getMapping().getMappedForm()).getGenerator()
this.idGenerator = createIdGenerator(generatorType)
- if(identity.name != GormProperties.IDENTITY) {
+ if (identity.name != GormProperties.IDENTITY) {
Class clazz = getJavaClass()
MetaClass metaClass = clazz.getMetaClass()
MetaProperty idProp = metaClass.getMetaProperty(GormProperties.IDENTITY)
- if(idProp != null && Long.class.isAssignableFrom(idProp.getType())) {
+ if (idProp != null && Long.class.isAssignableFrom(idProp.getType())) {
MappingFactory mappingFactory = mappingContext.mappingFactory
nodeId = mappingFactory.createSimple(this, context, mappingFactory.createPropertyDescriptor(javaClass, idProp))
propertiesByName.put(GormProperties.IDENTITY, nodeId)
@@ -129,7 +132,7 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
IdGenerator.Type type = generatorType == null ? IdGenerator.Type.NATIVE : IdGenerator.Type.valueOf(generatorType.toUpperCase())
idGeneratorType = type
- switch(type) {
+ switch (type) {
case IdGenerator.Type.NATIVE:
// for the native generator use null to indicate that generation requires an insert
nativeId = true
@@ -139,10 +142,10 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
((Property) getIdentity().getMapping().getMappedForm()).setUnique(true)
return null
case IdGenerator.Type.SNOWFLAKE:
- return ((Neo4jMappingContext)mappingContext).getSnowflakeIdGenerator()
+ return ((Neo4jMappingContext) mappingContext).getSnowflakeIdGenerator()
default:
def generator = ((Neo4jMappingContext) mappingContext).getIdGenerator()
- if(generator == null) {
+ if (generator == null) {
nativeId = true
}
return generator
@@ -150,16 +153,15 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
} catch (IllegalArgumentException e) {
try {
def generatorClass = ClassUtils.forName(generatorType)
- if(IdGenerator.isAssignableFrom(generatorClass)) {
+ if (IdGenerator.isAssignableFrom(generatorClass)) {
idGeneratorType = IdGenerator.Type.CUSTOM
- return (IdGenerator)generatorClass.newInstance()
- }
- else {
+ return (IdGenerator) generatorClass.newInstance()
+ } else {
throw new DatastoreConfigurationException("Entity $javaClass defines an invalid id generator [$generatorClass]. The class must implement the IdGenerator interface")
}
} catch (Throwable e2) {
def types = IdGenerator.Type.values().collect() { Enum en -> "'${en.name()}'" }.join(',')
- throw new DatastoreConfigurationException("Entity $javaClass defines an invalid id generator [$generatorType]. Should be one of ${types} or a class that implements the IdGenerator interface",e2 )
+ throw new DatastoreConfigurationException("Entity $javaClass defines an invalid id generator [$generatorType]. Should be one of ${types} or a class that implements the IdGenerator interface", e2)
}
}
}
@@ -201,7 +203,7 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
* @return The batch create statement
*/
String getBatchCreateStatement() {
- if(this.batchCreateStatement == null) {
+ if (this.batchCreateStatement == null) {
this.batchCreateStatement = formatBatchCreate("\$${batchId}")
}
return batchCreateStatement
@@ -269,13 +271,11 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
* @return The formatted id
*/
String formatProperty(String variable, String property) {
- if(property == identity.name) {
+ if (property == identity.name) {
return formatId(variable)
- }
- else if(nodeId != null && property == nodeId.name) {
+ } else if (nodeId != null && property == nodeId.name) {
return "ID($variable)"
- }
- else {
+ } else {
return "${variable}.${property}"
}
}
@@ -316,30 +316,29 @@ class GraphPersistentEntity extends AbstractPersistentEntity<NodeConfig> {
* @return The match for the ID
*/
String formatMatchAndUpdate(String variable, Map<String, Object> props) {
- StringBuilder builder = new StringBuilder( formatMatchId(variable) )
+ StringBuilder builder = new StringBuilder(formatMatchId(variable))
Class clazz = Long
- if(isVersioned() && hasProperty(GormProperties.VERSION, clazz)) {
+ if (isVersioned() && hasProperty(GormProperties.VERSION, clazz)) {
builder.append(" AND ${variable}.version=\$version")
}
builder.append(" SET ").append(variable).append(" +=\$props")
Set keysToRemove = []
- for(key in props.keySet()) {
+ for (key in props.keySet()) {
Object v = props.get(key)
- if(v == null) {
+ if (v == null) {
builder.append(", ${variable}.").append(key).append(" = NULL")
- }
- else if(v instanceof Collection && ((Collection)v).isEmpty()) {
+ } else if (v instanceof Collection && ((Collection) v).isEmpty()) {
keysToRemove.add(key)
}
}
- if(!keysToRemove.isEmpty()) {
+ if (!keysToRemove.isEmpty()) {
builder.append(" REMOVE ")
def i = keysToRemove.iterator()
- while(i.hasNext()) {
+ while (i.hasNext()) {
String key = i.next()
builder.append(variable).append(".").append(key)
props.remove(key)
- if(i.hasNext()) {
+ if (i.hasNext()) {
builder.append(", ")
}
}
@@ -397,8 +396,8 @@ ${formatAssociationMerge(association, parentVariable, variableId)})"""
* @return The match
*/
String formatAssociationMatch(Association association, String var = CypherBuilder.REL_VAR, String start = FROM, String end = TO) {
- GraphPersistentEntity parent = (GraphPersistentEntity)association.owner
- GraphPersistentEntity child = (GraphPersistentEntity)association.associatedEntity
+ GraphPersistentEntity parent = (GraphPersistentEntity) association.owner
+ GraphPersistentEntity child = (GraphPersistentEntity) association.associatedEntity
String associationMatch = calculateAssociationMatch(parent, child, association, var)
return "MATCH ${parent.formatNode(start)}${associationMatch}${child.formatNode(end)}"
@@ -427,17 +426,17 @@ ${formatAssociationMerge(association, parentVariable, variableId)})"""
* @return The match
*/
String formatAssociationPatternFromExisting(Association association, String var = CypherBuilder.REL_VAR, String start = FROM, String end = TO) {
- GraphPersistentEntity parent = (GraphPersistentEntity)association.owner
- GraphPersistentEntity child = (GraphPersistentEntity)association.associatedEntity
- String associationMatch = calculateAssociationMatch(parent,child, association, var)
- if(child.isRelationshipEntity()) {
- RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity)child
+ GraphPersistentEntity parent = (GraphPersistentEntity) association.owner
+ GraphPersistentEntity child = (GraphPersistentEntity) association.associatedEntity
+ String associationMatch = calculateAssociationMatch(parent, child, association, var)
+ if (child.isRelationshipEntity()) {
+ RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) child
child = (GraphPersistentEntity) (relEntity.from.associatedEntity == parent ? relEntity.to.associatedEntity : relEntity.from.associatedEntity)
}
return "(${start})${associationMatch}${child.formatNode(end)}"
}
- protected String calculateAssociationMatch(GraphPersistentEntity parent, GraphPersistentEntity child,Association association, String var) {
+ protected String calculateAssociationMatch(GraphPersistentEntity parent, GraphPersistentEntity child, Association association, String var) {
String associationMatch
if (parent.isRelationshipEntity()) {
if (association.name == FROM || association.name == TO) {
@@ -447,12 +446,10 @@ ${formatAssociationMerge(association, parentVariable, variableId)})"""
throw new IllegalStateException("Relationship entities cannot have associations")
}
- }
- else if(child.isRelationshipEntity()) {
+ } else if (child.isRelationshipEntity()) {
RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) child
associationMatch = RelationshipUtils.matchForRelationshipEntity(association, relEntity, var)
- }
- else {
+ } else {
associationMatch = RelationshipUtils.matchForAssociation(association, var)
}
return associationMatch
@@ -467,31 +464,28 @@ ${formatAssociationMerge(association, parentVariable, variableId)})"""
*/
String formatAssociationDelete(Association association, Object entity = null) {
- GraphPersistentEntity parent = (GraphPersistentEntity)association.owner
- GraphPersistentEntity child = (GraphPersistentEntity)association.associatedEntity
+ GraphPersistentEntity parent = (GraphPersistentEntity) association.owner
+ GraphPersistentEntity child = (GraphPersistentEntity) association.associatedEntity
String associationMatch
- if(parent.isRelationshipEntity() && entity instanceof Relationship) {
- if(association.name == FROM) {
- RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity)parent
+ if (parent.isRelationshipEntity() && entity instanceof Relationship) {
+ if (association.name == FROM) {
+ RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) parent
child = relEntity.getToEntity()
parent = relEntity.getFromEntity()
associationMatch = RelationshipUtils.toMatch(association, (Relationship) entity)
- }
- else {
+ } else {
return null
}
- }
- else {
+ } else {
associationMatch = RelationshipUtils.matchForAssociation(association, CypherBuilder.REL_VAR)
}
- if(RelationshipUtils.useReversedMappingFor(association)) {
+ if (RelationshipUtils.useReversedMappingFor(association)) {
return """MATCH ${parent.formatNode(FROM)}${associationMatch}${child.formatNode(TO)}
WHERE ${parent.formatId(FROM)} = {${GormProperties.IDENTITY}}
DELETE r"""
- }
- else {
+ } else {
return """MATCH ${parent.formatNode(FROM)}${associationMatch}${child.formatNode(TO)}
WHERE ${parent.formatId(FROM)} = {${CypherBuilder.START}} AND ${parent.formatId(TO)} IN {${CypherBuilder.END}}
DELETE r"""
@@ -527,17 +521,16 @@ DELETE r"""
* @return the abels
*/
Collection<String> getLabels(Object domainInstance) {
- if(hasDynamicLabels) {
+ if (hasDynamicLabels) {
Collection<String> labels = []
- for(obj in labelObjects) {
+ for (obj in labelObjects) {
String label = getLabelFor(obj, domainInstance)
- if(label) {
+ if (label) {
labels.add(label)
}
}
return labels
- }
- else {
+ } else {
return staticLabels
}
}
@@ -554,10 +547,9 @@ DELETE r"""
* @return
*/
String getLabelsAsString(Object domainInstance) {
- if(hasDynamicLabels) {
+ if (hasDynamicLabels) {
return ":${getLabels(domainInstance).join(LABEL_SEPARATOR)}"
- }
- else {
+ } else {
return getLabelsAsString()
}
}
@@ -604,7 +596,7 @@ DELETE r"""
}
protected Collection<Object> establishLabelObjects() {
- Object labels = mappedForm.getLabels();
+ Object labels = mappedForm.getLabels()
List objs = labels instanceof Object[] ? labels as List : [labels]
@@ -620,9 +612,9 @@ DELETE r"""
case null:
return discriminator
case CharSequence:
- return ((CharSequence)obj).toString()
+ return ((CharSequence) obj).toString()
case Closure:
- Closure closure = (Closure)obj
+ Closure closure = (Closure) obj
Object result = null
switch (closure.maximumNumberOfParameters) {
case 1:
@@ -640,7 +632,7 @@ DELETE r"""
}
}
- private void appendRecursive(StringBuilder sb, domainInstance){
+ private void appendRecursive(StringBuilder sb, domainInstance) {
sb.append(getLabelsAsString(domainInstance))
GraphPersistentEntity parentEntity = (GraphPersistentEntity) getParentEntity()
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/IdGenerator.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/IdGenerator.java
index 1041ed914d..55c73ec200 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/IdGenerator.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/IdGenerator.java
@@ -27,6 +27,12 @@ import java.io.Serializable;
* @author Graeme Rocher
*/
public interface IdGenerator {
+
+ /**
+ * @return Generate and return the next identifier
+ */
+ Serializable nextId();
+
/**
* Default id generator types
*/
@@ -49,9 +55,4 @@ public interface IdGenerator {
CUSTOM
}
- /**
- * @return Generate and return the next identifier
- */
- Serializable nextId();
-
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastore.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastore.java
index fe27df98b8..670af2e08d 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastore.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastore.java
@@ -18,8 +18,31 @@
*/
package org.grails.datastore.gorm.neo4j;
-import grails.neo4j.Relationship;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
import groovy.lang.Closure;
+
+import jakarta.annotation.PreDestroy;
+import jakarta.persistence.FlushModeType;
+
+import org.neo4j.driver.Driver;
+import org.neo4j.driver.Transaction;
+import org.neo4j.driver.exceptions.Neo4jException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.context.MessageSource;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.context.support.StaticMessageSource;
+import org.springframework.core.env.PropertyResolver;
+
+import grails.neo4j.Relationship;
import org.grails.datastore.gorm.GormEnhancer;
import org.grails.datastore.gorm.GormInstanceApi;
import org.grails.datastore.gorm.GormStaticApi;
@@ -44,7 +67,14 @@ import org.grails.datastore.mapping.core.AbstractDatastore;
import org.grails.datastore.mapping.core.Datastore;
import org.grails.datastore.mapping.core.DatastoreUtils;
import org.grails.datastore.mapping.core.StatelessDatastore;
-import org.grails.datastore.mapping.core.connections.*;
+import org.grails.datastore.mapping.core.connections.ConnectionSource;
+import org.grails.datastore.mapping.core.connections.ConnectionSources;
+import org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer;
+import org.grails.datastore.mapping.core.connections.ConnectionSourcesSupport;
+import org.grails.datastore.mapping.core.connections.DefaultConnectionSource;
+import org.grails.datastore.mapping.core.connections.InMemoryConnectionSources;
+import org.grails.datastore.mapping.core.connections.MultipleConnectionSourceCapableDatastore;
+import org.grails.datastore.mapping.core.connections.SingletonConnectionSources;
import org.grails.datastore.mapping.core.exceptions.ConfigurationException;
import org.grails.datastore.mapping.graph.GraphDatastore;
import org.grails.datastore.mapping.model.DatastoreConfigurationException;
@@ -54,29 +84,9 @@ import org.grails.datastore.mapping.model.PersistentProperty;
import org.grails.datastore.mapping.model.types.Simple;
import org.grails.datastore.mapping.multitenancy.MultiTenancySettings;
import org.grails.datastore.mapping.multitenancy.MultiTenantCapableDatastore;
-import org.grails.datastore.mapping.core.connections.MultipleConnectionSourceCapableDatastore;
import org.grails.datastore.mapping.multitenancy.TenantResolver;
import org.grails.datastore.mapping.transactions.TransactionCapableDatastore;
import org.grails.datastore.mapping.validation.ValidatorRegistry;
-import org.neo4j.driver.Driver;
-import org.neo4j.driver.Transaction;
-import org.neo4j.driver.exceptions.Neo4jException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.MessageSource;
-import org.springframework.context.MessageSourceAware;
-import org.springframework.context.support.StaticMessageSource;
-import org.springframework.core.env.PropertyResolver;
-
-import jakarta.annotation.PreDestroy;
-import jakarta.persistence.FlushModeType;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import static org.grails.datastore.gorm.neo4j.config.Settings.DATABASE_TYPE_EMBEDDED;
import static org.grails.datastore.gorm.neo4j.config.Settings.SETTING_NEO4J_EMBEDDED_EPHEMERAL;
@@ -92,9 +102,7 @@ import static org.grails.datastore.gorm.neo4j.config.Settings.SETTING_NEO4J_TYPE
*/
public class Neo4jDatastore extends AbstractDatastore implements Closeable, StatelessDatastore, GraphDatastore, Settings, MultipleConnectionSourceCapableDatastore, MultiTenantCapableDatastore<Driver, Neo4jConnectionSourceSettings>, MessageSourceAware, TransactionCapableDatastore {
- private static Logger log = LoggerFactory.getLogger(Neo4jDatastore.class);
-
- protected boolean skipIndexSetup = false;
+ private static final Logger log = LoggerFactory.getLogger(Neo4jDatastore.class);
protected final Driver boltDriver;
protected final FlushModeType defaultFlushMode;
protected final ConfigurableApplicationEventPublisher eventPublisher;
@@ -105,6 +113,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
protected final TenantResolver tenantResolver;
protected final MultiTenancySettings.MultiTenancyMode multiTenancyMode;
protected final AutoTimestampEventListener autoTimestampEventListener;
+ protected boolean skipIndexSetup = false;
/**
* Configures a new {@link Neo4jDatastore} for the given arguments
@@ -127,22 +136,21 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
this.tenantResolver = multiTenancySettings.getTenantResolver();
this.autoTimestampEventListener = new AutoTimestampEventListener(this);
- if(!skipIndexSetup) {
+ if (!skipIndexSetup) {
setupIndexing();
}
transactionManager = new Neo4jDatastoreTransactionManager(this);
- if(!(connectionSources instanceof SingletonConnectionSources)) {
+ if (!(connectionSources instanceof SingletonConnectionSources)) {
Iterable<ConnectionSource<Driver, Neo4jConnectionSourceSettings>> allConnectionSources = connectionSources.getAllConnectionSources();
for (ConnectionSource<Driver, Neo4jConnectionSourceSettings> connectionSource : allConnectionSources) {
SingletonConnectionSources singletonConnectionSources = new SingletonConnectionSources(connectionSource, connectionSources.getBaseConfiguration());
Neo4jDatastore childDatastore;
- if(ConnectionSource.DEFAULT.equals(connectionSource.getName())) {
+ if (ConnectionSource.DEFAULT.equals(connectionSource.getName())) {
childDatastore = this;
- }
- else {
+ } else {
childDatastore = new Neo4jDatastore(singletonConnectionSources, mappingContext, eventPublisher) {
@Override
protected GormEnhancer initialize(Neo4jConnectionSourceSettings settings) {
@@ -163,8 +171,8 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param classes The persistent classes
*/
- public Neo4jDatastore(ConnectionSources<Driver, Neo4jConnectionSourceSettings> connectionSources, ConfigurableApplicationEventPublisher eventPublisher, Class...classes) {
- this(connectionSources, createMappingContext(connectionSources,classes), eventPublisher);
+ public Neo4jDatastore(ConnectionSources<Driver, Neo4jConnectionSourceSettings> connectionSources, ConfigurableApplicationEventPublisher eventPublisher, Class... classes) {
+ this(connectionSources, createMappingContext(connectionSources, classes), eventPublisher);
}
/**
@@ -172,8 +180,8 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
*
* @param classes The persistent classes
*/
- public Neo4jDatastore(ConnectionSources<Driver, Neo4jConnectionSourceSettings> connectionSources, Class...classes) {
- this(connectionSources, createMappingContext(connectionSources,classes), new DefaultApplicationEventPublisher());
+ public Neo4jDatastore(ConnectionSources<Driver, Neo4jConnectionSourceSettings> connectionSources, Class... classes) {
+ this(connectionSources, createMappingContext(connectionSources, classes), new DefaultApplicationEventPublisher());
}
/**
@@ -184,11 +192,10 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param classes The persistent classes
*/
- public Neo4jDatastore(Driver boltDriver, PropertyResolver configuration, ConfigurableApplicationEventPublisher eventPublisher, Class...classes) {
+ public Neo4jDatastore(Driver boltDriver, PropertyResolver configuration, ConfigurableApplicationEventPublisher eventPublisher, Class... classes) {
this(createDefaultConnectionSources(boltDriver, configuration), eventPublisher, classes);
}
-
/**
* Configures a new {@link Neo4jDatastore} for the given arguments
*
@@ -196,7 +203,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param classes The persistent classes
*/
- public Neo4jDatastore(Driver boltDriver, ConfigurableApplicationEventPublisher eventPublisher, Class...classes) {
+ public Neo4jDatastore(Driver boltDriver, ConfigurableApplicationEventPublisher eventPublisher, Class... classes) {
this(createDefaultConnectionSources(boltDriver, DatastoreUtils.createPropertyResolver(null)), eventPublisher, classes);
}
@@ -207,16 +214,17 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param configuration The configuration for the datastore
* @param classes The persistent classes
*/
- public Neo4jDatastore(Driver boltDriver, PropertyResolver configuration, Class...classes) {
+ public Neo4jDatastore(Driver boltDriver, PropertyResolver configuration, Class... classes) {
this(boltDriver, configuration, new DefaultApplicationEventPublisher(), classes);
}
+
/**
* Configures a new {@link Neo4jDatastore} for the given arguments
*
* @param boltDriver The driver
* @param classes The persistent classes
*/
- public Neo4jDatastore(Driver boltDriver, Class...classes) {
+ public Neo4jDatastore(Driver boltDriver, Class... classes) {
this(boltDriver, DatastoreUtils.createPropertyResolver(null), new DefaultApplicationEventPublisher(), classes);
}
@@ -228,7 +236,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param classes The persistent classes
*/
- public Neo4jDatastore(PropertyResolver configuration, Neo4jConnectionSourceFactory connectionSourceFactory, ConfigurableApplicationEventPublisher eventPublisher, Class...classes) {
+ public Neo4jDatastore(PropertyResolver configuration, Neo4jConnectionSourceFactory connectionSourceFactory, ConfigurableApplicationEventPublisher eventPublisher, Class... classes) {
this(ConnectionSourcesInitializer.create(connectionSourceFactory, configuration), eventPublisher, classes);
}
@@ -239,8 +247,8 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param packagesToScan The packages to scan
*/
- public Neo4jDatastore(PropertyResolver configuration, Neo4jConnectionSourceFactory connectionSourceFactory, ConfigurableApplicationEventPublisher eventPublisher, Package...packagesToScan) {
- this(configuration,connectionSourceFactory, eventPublisher, new ClasspathEntityScanner().scan(packagesToScan));
+ public Neo4jDatastore(PropertyResolver configuration, Neo4jConnectionSourceFactory connectionSourceFactory, ConfigurableApplicationEventPublisher eventPublisher, Package... packagesToScan) {
+ this(configuration, connectionSourceFactory, eventPublisher, new ClasspathEntityScanner().scan(packagesToScan));
}
/**
@@ -250,7 +258,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param classes The persistent classes
*/
- public Neo4jDatastore(PropertyResolver configuration, ConfigurableApplicationEventPublisher eventPublisher, Class...classes) {
+ public Neo4jDatastore(PropertyResolver configuration, ConfigurableApplicationEventPublisher eventPublisher, Class... classes) {
this(ConnectionSourcesInitializer.create(new Neo4jConnectionSourceFactory(), configuration), eventPublisher, classes);
}
@@ -261,18 +269,17 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param eventPublisher The Spring ApplicationContext
* @param packagesToScan The packages to scan
*/
- public Neo4jDatastore(PropertyResolver configuration, ConfigurableApplicationEventPublisher eventPublisher, Package...packagesToScan) {
+ public Neo4jDatastore(PropertyResolver configuration, ConfigurableApplicationEventPublisher eventPublisher, Package... packagesToScan) {
this(configuration, eventPublisher, new ClasspathEntityScanner().scan(packagesToScan));
}
-
/**
* Configures a new {@link Neo4jDatastore} for the given arguments
*
* @param configuration The configuration for the datastore
* @param classes The persistent classes
*/
- public Neo4jDatastore(PropertyResolver configuration, Class...classes) {
+ public Neo4jDatastore(PropertyResolver configuration, Class... classes) {
this(configuration, new DefaultApplicationEventPublisher(), classes);
}
@@ -282,7 +289,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
*
* @param classes The persistent classes
*/
- public Neo4jDatastore(Class...classes) {
+ public Neo4jDatastore(Class... classes) {
this(resolveEmbeddedConfiguration(), classes);
}
@@ -292,8 +299,8 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param configuration The configuration
* @param classes The persistent classes
*/
- public Neo4jDatastore(Map<String, Object> configuration, ConfigurableApplicationEventPublisher eventPublisher,Class...classes) {
- this(mapToPropertyResolver(configuration),eventPublisher, classes);
+ public Neo4jDatastore(Map<String, Object> configuration, ConfigurableApplicationEventPublisher eventPublisher, Class... classes) {
+ this(mapToPropertyResolver(configuration), eventPublisher, classes);
}
/**
@@ -302,7 +309,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param configuration The configuration
* @param classes The persistent classes
*/
- public Neo4jDatastore(Map<String, Object> configuration, Class...classes) {
+ public Neo4jDatastore(Map<String, Object> configuration, Class... classes) {
this(configuration, new DefaultApplicationEventPublisher(), classes);
}
@@ -311,7 +318,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
*
* @param packagesToScan The packages to scan
*/
- public Neo4jDatastore(Package...packagesToScan) {
+ public Neo4jDatastore(Package... packagesToScan) {
this(new ClasspathEntityScanner().scan(packagesToScan));
}
@@ -324,14 +331,13 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
this(new ClasspathEntityScanner().scan(packageToScan));
}
-
/**
* Construct a Mongo datastore scanning the given packages
*
* @param configuration The configuration
* @param packagesToScan The packages to scan
*/
- public Neo4jDatastore(PropertyResolver configuration, Package...packagesToScan) {
+ public Neo4jDatastore(PropertyResolver configuration, Package... packagesToScan) {
this(configuration, new ClasspathEntityScanner().scan(packagesToScan));
}
@@ -341,34 +347,10 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
* @param configuration The configuration
* @param packagesToScan The packages to scan
*/
- public Neo4jDatastore(Map<String,Object> configuration, Package...packagesToScan) {
+ public Neo4jDatastore(Map<String, Object> configuration, Package... packagesToScan) {
this(DatastoreUtils.createPropertyResolver(configuration), packagesToScan);
}
- /**
- * @return The transaction manager
- */
- @Override
- public Neo4jDatastoreTransactionManager getTransactionManager() {
- return transactionManager;
- }
-
-
- @Override
- public ConfigurableApplicationEventPublisher getApplicationEventPublisher() {
- return this.eventPublisher;
- }
-
- @Override
- public Datastore getDatastoreForConnection(String connectionName) {
- return datastoresByConnectionSource.get(connectionName);
- }
-
- @Override
- public Neo4jMappingContext getMappingContext() {
- return (Neo4jMappingContext)super.getMappingContext();
- }
-
/**
* Creates the connection sources for an existing {@link Driver}
*
@@ -390,19 +372,18 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
MessageSource messageSource = new StaticMessageSource();
ValidatorRegistry defaultValidatorRegistry = createValidatorRegistry(settings, neo4jMappingContext, messageSource);
neo4jMappingContext.setValidatorRegistry(
- defaultValidatorRegistry
+ defaultValidatorRegistry
);
return neo4jMappingContext;
}
private static PropertyResolver resolveEmbeddedConfiguration() {
- if(Neo4jConnectionSourceFactory.isEmbeddedAvailable()) {
+ if (Neo4jConnectionSourceFactory.isEmbeddedAvailable()) {
Map<String, Object> config = new LinkedHashMap<>();
config.put(SETTING_NEO4J_TYPE, DATABASE_TYPE_EMBEDDED);
- config.put(SETTING_NEO4J_EMBEDDED_EPHEMERAL, true );
+ config.put(SETTING_NEO4J_EMBEDDED_EPHEMERAL, true);
return mapToPropertyResolver(config);
- }
- else {
+ } else {
return mapToPropertyResolver(null);
}
}
@@ -415,22 +396,44 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
}
private static void configureValidatorRegistry(Neo4jMappingContext neo4jMappingContext, MessageSource messageSource, ValidatorRegistry defaultValidatorRegistry) {
- if(defaultValidatorRegistry instanceof ConstraintRegistry) {
- ((ConstraintRegistry)defaultValidatorRegistry).addConstraintFactory(
- new MappingContextAwareConstraintFactory(UniqueConstraint.class, messageSource, neo4jMappingContext)
+ if (defaultValidatorRegistry instanceof ConstraintRegistry) {
+ ((ConstraintRegistry) defaultValidatorRegistry).addConstraintFactory(
+ new MappingContextAwareConstraintFactory(UniqueConstraint.class, messageSource, neo4jMappingContext)
);
}
}
+ /**
+ * @return The transaction manager
+ */
+ @Override
+ public Neo4jDatastoreTransactionManager getTransactionManager() {
+ return transactionManager;
+ }
+
+ @Override
+ public ConfigurableApplicationEventPublisher getApplicationEventPublisher() {
+ return this.eventPublisher;
+ }
+
+ @Override
+ public Datastore getDatastoreForConnection(String connectionName) {
+ return datastoresByConnectionSource.get(connectionName);
+ }
+
+ @Override
+ public Neo4jMappingContext getMappingContext() {
+ return (Neo4jMappingContext) super.getMappingContext();
+ }
+
protected void registerEventListeners(ConfigurableApplicationEventPublisher eventPublisher) {
eventPublisher.addApplicationListener(new DomainEventListener(this));
eventPublisher.addApplicationListener(autoTimestampEventListener);
- if(multiTenancyMode == MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR) {
+ if (multiTenancyMode == MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR) {
eventPublisher.addApplicationListener(new MultiTenantEventListener(this));
}
}
-
protected GormEnhancer initialize(Neo4jConnectionSourceSettings settings) {
registerEventListeners(this.eventPublisher);
@@ -462,7 +465,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
@Override
protected <D> GormInstanceApi<D> getInstanceApi(Class<D> cls, String qualifier) {
Neo4jDatastore neo4jDatastore = getDatastoreForQualifier(cls, qualifier);
- GormInstanceApi<D> instanceApi = new GormInstanceApi<>(cls,neo4jDatastore);
+ GormInstanceApi<D> instanceApi = new GormInstanceApi<>(cls, neo4jDatastore);
instanceApi.setFailOnError(getFailOnError());
instanceApi.setMarkDirty(getMarkDirty());
return instanceApi;
@@ -471,16 +474,15 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
private <D> Neo4jDatastore getDatastoreForQualifier(Class<D> cls, String qualifier) {
String defaultConnectionSourceName = ConnectionSourcesSupport.getDefaultConnectionSourceName(getMappingContext().getPersistentEntity(cls.getName()));
boolean isDefaultQualifier = qualifier.equals(ConnectionSource.DEFAULT);
- if(isDefaultQualifier && defaultConnectionSourceName.equals(ConnectionSource.DEFAULT)) {
+ if (isDefaultQualifier && defaultConnectionSourceName.equals(ConnectionSource.DEFAULT)) {
return Neo4jDatastore.this;
- }
- else {
- if(isDefaultQualifier) {
+ } else {
+ if (isDefaultQualifier) {
qualifier = defaultConnectionSourceName;
}
ConnectionSource<Driver, Neo4jConnectionSourceSettings> connectionSource = connectionSources.getConnectionSource(qualifier);
- if(connectionSource == null) {
- throw new ConfigurationException("Invalid connection ["+defaultConnectionSourceName+"] configured for class ["+cls+"]");
+ if (connectionSource == null) {
+ throw new ConfigurationException("Invalid connection [" + defaultConnectionSourceName + "] configured for class [" + cls + "]");
}
return Neo4jDatastore.this.datastoresByConnectionSource.get(qualifier);
}
@@ -499,42 +501,39 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
return neo4jSession;
}
-
public void setupIndexing() {
- if(skipIndexSetup) return;
+ if (skipIndexSetup) return;
List<String> schemaStrings = new ArrayList<String>(); // using set to avoid duplicate index creation
- for (PersistentEntity persistentEntity: mappingContext.getPersistentEntities()) {
- if(persistentEntity.isExternal() || Relationship.class.isAssignableFrom(persistentEntity.getJavaClass())) continue;
+ for (PersistentEntity persistentEntity : mappingContext.getPersistentEntities()) {
+ if (persistentEntity.isExternal() || Relationship.class.isAssignableFrom(persistentEntity.getJavaClass()))
+ continue;
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("Setting up indexing for entity " + persistentEntity.getName());
}
final GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) persistentEntity;
- for (String label: graphPersistentEntity.getLabels()) {
+ for (String label : graphPersistentEntity.getLabels()) {
StringBuilder sb = new StringBuilder();
IdGenerator.Type idGeneratorType = graphPersistentEntity.getIdGeneratorType();
- if(graphPersistentEntity.getIdGenerator() != null && idGeneratorType.equals(IdGenerator.Type.SNOWFLAKE)) {
+ if (graphPersistentEntity.getIdGenerator() != null && idGeneratorType.equals(IdGenerator.Type.SNOWFLAKE)) {
sb.append("CREATE CONSTRAINT ON (n:").append(label).append(") ASSERT n.").append(CypherBuilder.IDENTIFIER).append(" IS UNIQUE");
schemaStrings.add(sb.toString());
- }
- else if(!graphPersistentEntity.isNativeId()) {
+ } else if (!graphPersistentEntity.isNativeId()) {
createUniqueConstraintOnProperty(label, graphPersistentEntity.getIdentity(), schemaStrings);
}
-
for (PersistentProperty persistentProperty : persistentEntity.getPersistentProperties()) {
Property mappedForm = persistentProperty.getMapping().getMappedForm();
- if ((persistentProperty instanceof Simple) && (mappedForm != null) ) {
+ if ((persistentProperty instanceof Simple) && (mappedForm != null)) {
- if(mappedForm.isUnique()) {
+ if (mappedForm.isUnique()) {
createUniqueConstraintOnProperty(label, persistentProperty, schemaStrings);
- }
- else if(mappedForm.isIndex()) {
+ } else if (mappedForm.isIndex()) {
sb = new StringBuilder();
sb.append("CREATE INDEX ON :").append(label).append("(").append(persistentProperty.getName()).append(")");
schemaStrings.add(sb.toString());
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("setting up indexing for " + label + " property " + persistentProperty.getName());
}
}
@@ -545,24 +544,23 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
org.neo4j.driver.Session boltSession = boltDriver.session();
- final Transaction transaction = boltSession.beginTransaction();;
+ final Transaction transaction = boltSession.beginTransaction();
try {
- for (String cypher: schemaStrings) {
- if(log.isDebugEnabled()) {
+ for (String cypher : schemaStrings) {
+ if (log.isDebugEnabled()) {
log.debug("CREATE INDEX Cypher [{}]", cypher);
}
transaction.run(cypher);
}
transaction.commit();
- } catch(Throwable e) {
+ } catch (Throwable e) {
log.error("Error creating Neo4j index: " + e.getMessage(), e);
transaction.rollback();
throw new DatastoreConfigurationException("Error creating Neo4j index: " + e.getMessage(), e);
- }
- finally {
+ } finally {
boltSession.close();
}
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("done setting up indexes");
}
}
@@ -619,7 +617,7 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
@Override
public Neo4jDatastore getDatastoreForTenantId(Serializable tenantId) {
- if(getMultiTenancyMode() == MultiTenancySettings.MultiTenancyMode.DATABASE) {
+ if (getMultiTenancyMode() == MultiTenancySettings.MultiTenancyMode.DATABASE) {
return this.datastoresByConnectionSource.get(tenantId.toString());
}
return this;
@@ -632,13 +630,11 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
try {
DatastoreUtils.bindNewSession(session);
return callable.call(session);
- }
- finally {
+ } finally {
DatastoreUtils.unbindSession(session);
}
}
-
@Override
public void setMessageSource(MessageSource messageSource) {
if (messageSource != null) {
@@ -652,4 +648,4 @@ public class Neo4jDatastore extends AbstractDatastore implements Closeable, Stat
public AutoTimestampEventListener getAutoTimestampEventListener() {
return this.autoTimestampEventListener;
}
-}
\ No newline at end of file
+}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastoreTransactionManager.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastoreTransactionManager.java
index db6bcf1581..bef86af4c2 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastoreTransactionManager.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jDatastoreTransactionManager.java
@@ -16,20 +16,21 @@
*/
package org.grails.datastore.gorm.neo4j;
-import org.grails.datastore.mapping.core.DatastoreUtils;
-import org.grails.datastore.mapping.transactions.DatastoreTransactionManager;
-import org.grails.datastore.mapping.transactions.Transaction;
-import org.grails.datastore.mapping.transactions.TransactionObject;
+import jakarta.persistence.FlushModeType;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationManager;
-import jakarta.persistence.FlushModeType;
-import java.io.IOException;
+import org.grails.datastore.mapping.core.DatastoreUtils;
+import org.grails.datastore.mapping.transactions.DatastoreTransactionManager;
+import org.grails.datastore.mapping.transactions.Transaction;
+import org.grails.datastore.mapping.transactions.TransactionObject;
/**
* @author Stefan Armbruster
@@ -54,7 +55,7 @@ public class Neo4jDatastoreTransactionManager extends DatastoreTransactionManage
super.doSetRollbackOnly(status);
TransactionObject txObject = (TransactionObject) status.getTransaction();
Neo4jTransaction neo4jTransaction = (Neo4jTransaction) txObject.getTransaction();
- if(neo4jTransaction != null) {
+ if (neo4jTransaction != null) {
neo4jTransaction.rollbackOnly();
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jEntityTraitProvider.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jEntityTraitProvider.groovy
index 97fdd74a80..8a6c91d664 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jEntityTraitProvider.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jEntityTraitProvider.groovy
@@ -18,12 +18,12 @@
*/
package org.grails.datastore.gorm.neo4j
-import grails.neo4j.Neo4jEntity
import groovy.transform.CompileStatic
+
+import grails.neo4j.Neo4jEntity
import org.grails.compiler.gorm.GormEntityTraitProvider
import org.grails.datastore.mapping.reflect.ClassUtils
-
/**
* Tells GORM to use the Neo4jEntity trait
*
@@ -32,6 +32,7 @@ import org.grails.datastore.mapping.reflect.ClassUtils
*/
@CompileStatic
class Neo4jEntityTraitProvider implements GormEntityTraitProvider {
+
final Class entityTrait = Neo4jEntity
final boolean available = ClassUtils.isPresent("org.neo4j.driver.Driver")
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jMappingContext.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jMappingContext.java
index 2bce596c9f..53937e0630 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jMappingContext.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jMappingContext.java
@@ -18,8 +18,20 @@
*/
package org.grails.datastore.gorm.neo4j;
-import grails.neo4j.Relationship;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
import groovy.lang.Closure;
+
+import org.springframework.core.convert.ConversionService;
+
+import grails.neo4j.Relationship;
import org.grails.datastore.gorm.neo4j.connections.Neo4jConnectionSourceSettings;
import org.grails.datastore.gorm.neo4j.identity.SnowflakeIdGenerator;
import org.grails.datastore.gorm.neo4j.proxy.HashcodeEqualsAwareProxyFactory;
@@ -30,10 +42,6 @@ import org.grails.datastore.mapping.model.MappingFactory;
import org.grails.datastore.mapping.model.PersistentEntity;
import org.grails.datastore.mapping.model.config.GormMappingConfigurationStrategy;
import org.grails.datastore.mapping.proxy.ProxyFactory;
-import org.springframework.core.convert.ConversionService;
-
-import java.math.BigDecimal;
-import java.util.*;
/**
* A {@link org.grails.datastore.mapping.model.MappingContext} implementation for Neo4j
@@ -43,48 +51,44 @@ import java.util.*;
*
* @since 1.0
*/
-public class Neo4jMappingContext extends AbstractMappingContext {
+public class Neo4jMappingContext extends AbstractMappingContext {
private static final Class<Long> LONG_TYPE = long.class;
private static final Class<Double> DOUBLE_TYPE = double.class;
private static final Class<String> STRING_TYPE = String.class;
- public static final Set<Class> BASIC_TYPES = Collections.unmodifiableSet( new HashSet<Class>( Arrays.asList(
- STRING_TYPE,
- Long.class,
- Float.class,
- Integer.class,
- Double.class,
- Short.class,
- Boolean.class,
- Byte.class,
- // primitives
- byte.class,
- int.class,
- LONG_TYPE,
- float.class,
- DOUBLE_TYPE,
- short.class,
- boolean.class,
- // primitive arrays
- byte[].class,
- int[].class,
- long[].class,
- float[].class,
- double[].class,
- short[].class,
- boolean[].class,
- String[].class
- ) ) );
-
- GraphGormMappingFactory mappingFactory = new GraphGormMappingFactory();
- MappingConfigurationStrategy mappingSyntaxStrategy = new GormMappingConfigurationStrategy(mappingFactory);
-
+ public static final Set<Class> BASIC_TYPES = Collections.unmodifiableSet(new HashSet<Class>(Arrays.asList(
+ STRING_TYPE,
+ Long.class,
+ Float.class,
+ Integer.class,
+ Double.class,
+ Short.class,
+ Boolean.class,
+ Byte.class,
+ // primitives
+ byte.class,
+ int.class,
+ LONG_TYPE,
+ float.class,
+ DOUBLE_TYPE,
+ short.class,
+ boolean.class,
+ // primitive arrays
+ byte[].class,
+ int[].class,
+ long[].class,
+ float[].class,
+ double[].class,
+ short[].class,
+ boolean[].class,
+ String[].class
+ )));
protected Map<Iterable<String>, GraphPersistentEntity> entitiesByLabel = new LinkedHashMap<>();
-
// default id generator strategy is native
protected IdGenerator idGenerator = null;
-
protected SnowflakeIdGenerator snowflakeIdGenerator = null;
+ GraphGormMappingFactory mappingFactory = new GraphGormMappingFactory();
+ MappingConfigurationStrategy mappingSyntaxStrategy = new GormMappingConfigurationStrategy(mappingFactory);
public Neo4jMappingContext() {
super();
@@ -98,13 +102,13 @@ public class Neo4jMappingContext extends AbstractMappingContext {
}
@Deprecated
- public Neo4jMappingContext(Closure defaultMapping, Class...classes) {
+ public Neo4jMappingContext(Closure defaultMapping, Class... classes) {
super();
mappingFactory.setDefaultMapping(defaultMapping);
addPersistentEntities(classes);
}
- public Neo4jMappingContext(Neo4jConnectionSourceSettings settings, Class...classes) {
+ public Neo4jMappingContext(Neo4jConnectionSourceSettings settings, Class... classes) {
super();
mappingFactory.setDefaultMapping(settings.getDefault().getMapping());
mappingFactory.setDefaultConstraints(settings.getDefault().getConstraints());
@@ -112,13 +116,12 @@ public class Neo4jMappingContext extends AbstractMappingContext {
addPersistentEntities(classes);
}
-
public IdGenerator getIdGenerator() {
return idGenerator;
}
public SnowflakeIdGenerator getSnowflakeIdGenerator() {
- if(snowflakeIdGenerator == null) {
+ if (snowflakeIdGenerator == null) {
snowflakeIdGenerator = new SnowflakeIdGenerator();
}
return snowflakeIdGenerator;
@@ -142,8 +145,8 @@ public class Neo4jMappingContext extends AbstractMappingContext {
@Override
protected PersistentEntity createPersistentEntity(Class javaClass, boolean external) {
final GraphPersistentEntity entity = Relationship.class.isAssignableFrom(javaClass) ?
- new RelationshipPersistentEntity(javaClass, this, external) :
- new GraphPersistentEntity(javaClass, this, external);
+ new RelationshipPersistentEntity(javaClass, this, external) :
+ new GraphPersistentEntity(javaClass, this, external);
final Collection<String> labels = entity.getLabels();
entitiesByLabel.put(labels, entity);
return entity;
@@ -157,13 +160,9 @@ public class Neo4jMappingContext extends AbstractMappingContext {
*/
public GraphPersistentEntity findPersistentEntityForLabels(Iterable<String> labels) {
final GraphPersistentEntity entity = entitiesByLabel.get(labels);
- if(entity != null) {
- return entity;
- }
- return null;
+ return entity;
}
-
/**
* Obtain the native type to use for the given value
*
@@ -171,36 +170,30 @@ public class Neo4jMappingContext extends AbstractMappingContext {
* @return The value converted to a native Neo4j type
*/
public Object convertToNative(Object value) {
- if(value != null) {
+ if (value != null) {
final Class<?> type = value.getClass();
- if(type.equals(byte[].class)) {
+ if (type.equals(byte[].class)) {
// workaround for https://github.com/neo4j/neo4j-java-driver/issues/182, remove when fixed
- byte[] bytes = (byte[])value;
+ byte[] bytes = (byte[]) value;
int[] intArray = new int[bytes.length];
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
intArray[i] = b;
}
return intArray;
- }
- else if(BASIC_TYPES.contains(type)) {
+ } else if (BASIC_TYPES.contains(type)) {
return value;
- }
- else if(value instanceof CharSequence) {
+ } else if (value instanceof CharSequence) {
return value.toString();
- }
- else if(value instanceof Collection) {
+ } else if (value instanceof Collection) {
return value;
- }
- else if(value instanceof BigDecimal) {
- return ((BigDecimal)value).doubleValue();
- }
- else {
+ } else if (value instanceof BigDecimal) {
+ return ((BigDecimal) value).doubleValue();
+ } else {
final ConversionService conversionService = getConversionService();
- if(byte[].class.isInstance(value)){
+ if (value instanceof byte[]) {
return conversionService.convert(value, String.class);
- }
- else {
+ } else {
if (conversionService.canConvert(type, LONG_TYPE)) {
return conversionService.convert(value, LONG_TYPE);
} else if (conversionService.canConvert(type, DOUBLE_TYPE)) {
@@ -212,15 +205,14 @@ public class Neo4jMappingContext extends AbstractMappingContext {
}
}
}
- }
- else {
+ } else {
return value;
}
}
@Override
public ProxyFactory getProxyFactory() {
- if (!(this.proxyFactory instanceof Neo4jProxyFactory)){
+ if (!(this.proxyFactory instanceof Neo4jProxyFactory)) {
this.proxyFactory = new Neo4jProxyFactory();
}
return proxyFactory;
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jSession.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jSession.java
index 765d4152d6..0ac84053f7 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jSession.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jSession.java
@@ -16,19 +16,55 @@
*/
package org.grails.datastore.gorm.neo4j;
-import com.github.benmanes.caffeine.cache.Cache;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+
+import jakarta.persistence.CascadeType;
+
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.RemovalCause;
import com.github.benmanes.caffeine.cache.RemovalListener;
+import org.neo4j.driver.Driver;
+import org.neo4j.driver.Result;
+import org.neo4j.driver.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.dao.DataAccessResourceFailureException;
+import org.springframework.transaction.NoTransactionException;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
import grails.neo4j.Relationship;
-import org.grails.datastore.gorm.neo4j.engine.*;
+import org.grails.datastore.gorm.neo4j.engine.Neo4jEntityPersister;
+import org.grails.datastore.gorm.neo4j.engine.Neo4jQuery;
+import org.grails.datastore.gorm.neo4j.engine.RelationshipPendingDelete;
+import org.grails.datastore.gorm.neo4j.engine.RelationshipPendingInsert;
import org.grails.datastore.gorm.neo4j.mapping.config.DynamicAssociation;
import org.grails.datastore.gorm.neo4j.mapping.config.DynamicToOneAssociation;
import org.grails.datastore.gorm.schemaless.DynamicAttributes;
import org.grails.datastore.mapping.core.AbstractSession;
import org.grails.datastore.mapping.core.Datastore;
import org.grails.datastore.mapping.core.OptimisticLockingException;
-import org.grails.datastore.mapping.core.impl.*;
+import org.grails.datastore.mapping.core.impl.PendingDelete;
+import org.grails.datastore.mapping.core.impl.PendingInsert;
+import org.grails.datastore.mapping.core.impl.PendingOperation;
+import org.grails.datastore.mapping.core.impl.PendingOperationAdapter;
+import org.grails.datastore.mapping.core.impl.PendingUpdate;
import org.grails.datastore.mapping.dirty.checking.DirtyCheckable;
import org.grails.datastore.mapping.engine.EntityAccess;
import org.grails.datastore.mapping.engine.Persister;
@@ -37,31 +73,18 @@ import org.grails.datastore.mapping.model.MappingContext;
import org.grails.datastore.mapping.model.PersistentEntity;
import org.grails.datastore.mapping.model.PersistentProperty;
import org.grails.datastore.mapping.model.config.GormProperties;
-import org.grails.datastore.mapping.model.types.*;
+import org.grails.datastore.mapping.model.types.Association;
+import org.grails.datastore.mapping.model.types.Basic;
+import org.grails.datastore.mapping.model.types.Custom;
+import org.grails.datastore.mapping.model.types.ManyToMany;
+import org.grails.datastore.mapping.model.types.Simple;
+import org.grails.datastore.mapping.model.types.TenantId;
import org.grails.datastore.mapping.query.Query;
import org.grails.datastore.mapping.query.Restrictions;
import org.grails.datastore.mapping.query.api.QueryableCriteria;
import org.grails.datastore.mapping.reflect.EntityReflector;
import org.grails.datastore.mapping.transactions.SessionHolder;
import org.grails.datastore.mapping.transactions.Transaction;
-import org.neo4j.driver.Driver;
-import org.neo4j.driver.Session;
-import org.neo4j.driver.Result;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.dao.DataAccessResourceFailureException;
-import org.springframework.transaction.NoTransactionException;
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.support.DefaultTransactionDefinition;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
-
-import jakarta.persistence.CascadeType;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.*;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ConcurrentMap;
/**
* Represents a session for interacting with Neo4j
@@ -74,34 +97,29 @@ import java.util.concurrent.ConcurrentMap;
*/
public class Neo4jSession extends AbstractSession<Session> {
- private static Logger log = LoggerFactory.getLogger(Neo4jSession.class);
private static final RemovalListener<RelationshipUpdateKey, Collection<Serializable>> EXCEPTION_THROWING_INSERT_LISTENER =
- (key, value, cause) -> {
- if (RemovalCause.SIZE == cause) {
- throw new DataAccessResourceFailureException("Maximum number (5000) of relationship update operations to flush() exceeded. Flush the session periodically to avoid this error for batch operations.");
- }
-
- };
-
- protected ConcurrentMap<RelationshipUpdateKey, Collection<Serializable>> pendingRelationshipInserts =
- Caffeine.newBuilder()
- .executor(Runnable::run)
- .removalListener(EXCEPTION_THROWING_INSERT_LISTENER)
- .maximumSize(5000).build().asMap();
-
- protected ConcurrentMap<RelationshipUpdateKey, Collection<Serializable>> pendingRelationshipDeletes =
- Caffeine.newBuilder()
- .executor(Runnable::run)
- .removalListener(EXCEPTION_THROWING_INSERT_LISTENER)
- .maximumSize(5000).build().asMap();
-
+ (key, value, cause) -> {
+ if (RemovalCause.SIZE == cause) {
+ throw new DataAccessResourceFailureException("Maximum number (5000) of relationship update operations to flush() exceeded. Flush the session periodically to avoid this error for batch operations.");
+ }
+ };
+ private static final Logger log = LoggerFactory.getLogger(Neo4jSession.class);
/**
* map node id to hashmap of relationship types showing startNode id and endNode id
*/
protected final Session boltSession;
protected final Driver boltDriver;
-
+ protected ConcurrentMap<RelationshipUpdateKey, Collection<Serializable>> pendingRelationshipInserts =
+ Caffeine.newBuilder()
+ .executor(Runnable::run)
+ .removalListener(EXCEPTION_THROWING_INSERT_LISTENER)
+ .maximumSize(5000).build().asMap();
+ protected ConcurrentMap<RelationshipUpdateKey, Collection<Serializable>> pendingRelationshipDeletes =
+ Caffeine.newBuilder()
+ .executor(Runnable::run)
+ .removalListener(EXCEPTION_THROWING_INSERT_LISTENER)
+ .maximumSize(5000).build().asMap();
public Neo4jSession(Datastore datastore, MappingContext mappingContext, ApplicationEventPublisher publisher, boolean stateless, Driver boltDriver) {
super(datastore, mappingContext, publisher, stateless);
@@ -112,6 +130,15 @@ public class Neo4jSession extends AbstractSession<Session> {
this.boltSession = boltDriver.session();
}
+ public static boolean isCollectionWithPersistentEntities(Object o, MappingContext mappingContext) {
+ if (!(o instanceof Collection)) {
+ return false;
+ } else {
+ @SuppressWarnings("unchecked") Collection<Object> c = (Collection<Object>) o;
+ return c.stream().anyMatch(mappingContext::isPersistentEntity);
+ }
+ }
+
public Driver getBoltDriver() {
return boltDriver;
}
@@ -155,11 +182,10 @@ public class Neo4jSession extends AbstractSession<Session> {
super.clearPendingOperations();
} finally {
pendingRelationshipInserts.clear();
- pendingRelationshipDeletes.clear();;
+ pendingRelationshipDeletes.clear();
}
}
-
/**
* Gets a Neo4jEntityPersister for the given object
*
@@ -248,7 +274,6 @@ public class Neo4jSession extends AbstractSession<Session> {
final Set<PersistentEntity> entities = updates.keySet();
final Neo4jMappingContext mappingContext = getMappingContext();
-
for (PersistentEntity entity : entities) {
final Collection<PendingUpdate> pendingUpdates = updates.get(entity);
GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) entity;
@@ -271,7 +296,6 @@ public class Neo4jSession extends AbstractSession<Session> {
params.put(GormProperties.IDENTITY, id);
final Map<String, Object> simpleProps = new HashMap<>();
-
final DirtyCheckable dirtyCheckable = (DirtyCheckable) object;
final List<String> dirtyPropertyNames = dirtyCheckable.listDirtyPropertyNames();
for (String dirtyPropertyName : dirtyPropertyNames) {
@@ -308,7 +332,7 @@ public class Neo4jSession extends AbstractSession<Session> {
if (isVersioned) {
Long version = (Long) access.getProperty(GormProperties.VERSION);
if (version == null) {
- version = 0l;
+ version = 0L;
}
params.put(GormProperties.VERSION, version);
long newVersion = version + 1;
@@ -476,34 +500,34 @@ public class Neo4jSession extends AbstractSession<Session> {
Relationship relationship = (Relationship) entityAccess.getEntity();
Object type = entityAccess.getProperty(RelationshipPersistentEntity.TYPE);
// if the type hasn't been modified we can batch
- if(relEntity.type().equals(type)) {
+ if (relEntity.type().equals(type)) {
Object from = entityAccess.getPropertyValue(RelationshipPersistentEntity.FROM);
Serializable id = null;
if (from != null) {
id = relEntity.getFromEntity().getReflector().getIdentifier(from);
}
- if(id != null) {
+ if (id != null) {
RelationshipUpdateKey updateKey = new RelationshipUpdateKey(id, relEntity.getFrom());
Collection<Serializable> childIds = pendingRelationshipInserts.get(updateKey);
- if(childIds != null) {
+ if (childIds != null) {
pendingRelationshipInserts.remove(updateKey);
Map<String, Object> rowData = new LinkedHashMap<>();
LinkedHashMap<String, Object> nodeProperties = new LinkedHashMap<>();
for (PersistentProperty pp : relEntity.getPersistentProperties()) {
- if(pp instanceof Simple || pp instanceof Basic || pp instanceof TenantId) {
+ if (pp instanceof Simple || pp instanceof Basic || pp instanceof TenantId) {
String propertyName = pp.getName();
- if(RelationshipPersistentEntity.TYPE.equals(propertyName)) {
+ if (RelationshipPersistentEntity.TYPE.equals(propertyName)) {
continue;
}
Object v = reflector.getProperty(relationship, propertyName);
- if(v != null) {
+ if (v != null) {
nodeProperties.put(propertyName, mappingContext.convertToNative(v));
}
}
}
- nodeProperties.putAll( relationship.attributes() );
+ nodeProperties.putAll(relationship.attributes());
rowData.put(CypherBuilder.PROPS, nodeProperties);
rowData.put(RelationshipPersistentEntity.FROM, id);
@@ -512,8 +536,7 @@ public class Neo4jSession extends AbstractSession<Session> {
}
}
- }
- else {
+ } else {
// otherwise process individual inserts
processPendingRelationshipUpdates(entity, entityAccess, (Serializable) entityInsert.getNativeKey(), cascadingOperations, false);
}
@@ -527,7 +550,6 @@ public class Neo4jSession extends AbstractSession<Session> {
data.put(CypherBuilder.PROPS, nodeProperties);
rows.add(data);
-
for (Association association : entity.getAssociations()) {
if (association.isBasic()) continue;
boolean isTree = association.isCircular();
@@ -553,7 +575,7 @@ public class Neo4jSession extends AbstractSession<Session> {
childIds.remove(childId);
Map<String, Object> childProperties = readNodePropertiesForInsert(pendingInsert, associatedEntity, associatedEntity.getPersistentProperties(), pendingInsert.getEntityAccess());
- childRows.add(Collections.<String, Object>singletonMap(CypherBuilder.PROPS, childProperties));
+ childRows.add(Collections.singletonMap(CypherBuilder.PROPS, childProperties));
cascadingOperations.addAll(pendingInsert.getCascadeOperations());
}
@@ -569,12 +591,10 @@ public class Neo4jSession extends AbstractSession<Session> {
}
}
-
processDynamicAssociationsIfNecessary(entity, entityAccess, obj, entityInsert, cascadingOperations, params, dynamicRelProps);
params.remove(Neo4jEntityPersister.DYNAMIC_ASSOCIATION_PARAM);
}
-
cascadingOperations.addAll(entityInsert.getCascadeOperations());
}
@@ -598,7 +618,6 @@ public class Neo4jSession extends AbstractSession<Session> {
}
}
-
}
}
@@ -617,7 +636,7 @@ public class Neo4jSession extends AbstractSession<Session> {
// dynamic labels require individual create statements and are less efficient
final Map<String, Object> createParams = new HashMap<>(entityInserts.size());
final String finalCypher = buildCypherCreateStatement(entityInserts, graphEntity, cascadingOperations, createParams);
- if(graphEntity.hasDynamicAssociations()) {
+ if (graphEntity.hasDynamicAssociations()) {
createParams.remove(Neo4jEntityPersister.DYNAMIC_ASSOCIATION_PARAM);
}
if (finalCypher.length() > 0) {
@@ -677,7 +696,6 @@ public class Neo4jSession extends AbstractSession<Session> {
final EntityAccess access = entityInsert.getEntityAccess();
final Map<String, Object> simpleProps = readNodePropertiesForInsert(entityInsert, graphEntity, persistentProperties, access);
-
Map<String, List<Object>> dynamicRelProps = amendMapWithUndeclaredProperties(graphEntity, simpleProps, obj, getMappingContext());
final String labels = graphEntity.getLabelsWithInheritance(obj);
@@ -713,7 +731,6 @@ public class Neo4jSession extends AbstractSession<Session> {
}
}
-
// build a properties map for each CREATE statement
for (PersistentProperty pp : persistentProperties) {
if ((pp instanceof Simple) || (pp instanceof TenantId) || (pp instanceof Basic)) {
@@ -733,7 +750,7 @@ public class Neo4jSession extends AbstractSession<Session> {
private void applyCustomType(EntityAccess access, PersistentProperty property, Map<String, Object> simpleProps) {
Custom<?> custom = (Custom<?>) property;
final CustomTypeMarshaller<Object, Map<String, Object>, Map<String, Object>> customTypeMarshaller =
- (CustomTypeMarshaller<Object, Map<String, Object>, Map<String, Object>>) custom.getCustomTypeMarshaller();
+ (CustomTypeMarshaller<Object, Map<String, Object>, Map<String, Object>>) custom.getCustomTypeMarshaller();
Object value = access.getProperty(property.getName());
customTypeMarshaller.write(custom, value, simpleProps);
}
@@ -789,7 +806,7 @@ public class Neo4jSession extends AbstractSession<Session> {
protected Map<String, List<Object>> amendMapWithUndeclaredProperties(GraphPersistentEntity graphEntity, Map<String, Object> simpleProps, Object pojo, MappingContext mappingContext) {
boolean hasDynamicAssociations = graphEntity.hasDynamicAssociations();
- Map<String, List<Object>> dynRelProps = hasDynamicAssociations ? new LinkedHashMap<String, List<Object>>() : Collections.<String, List<Object>>emptyMap();
+ Map<String, List<Object>> dynRelProps = hasDynamicAssociations ? new LinkedHashMap<String, List<Object>>() : Collections.emptyMap();
if (pojo instanceof DynamicAttributes) {
Map<String, Object> map = ((DynamicAttributes) pojo).attributes();
if (map != null) {
@@ -833,17 +850,6 @@ public class Neo4jSession extends AbstractSession<Session> {
return objects;
}
-
- public static boolean isCollectionWithPersistentEntities(Object o, MappingContext mappingContext) {
- if (!(o instanceof Collection)) {
- return false;
- } else {
- @SuppressWarnings("unchecked") Collection<Object> c = (Collection<Object>) o;
- return c.stream().anyMatch(mappingContext::isPersistentEntity);
- }
- }
-
-
@Override
public void flush() {
if (wasTransactionTerminated()) return;
@@ -930,7 +936,6 @@ public class Neo4jSession extends AbstractSession<Session> {
}
}
-
@Override
public long deleteAll(QueryableCriteria criteria) {
@@ -1013,9 +1018,8 @@ public class Neo4jSession extends AbstractSession<Session> {
RelationshipUpdateKey that = (RelationshipUpdateKey) o;
- if (association != null ? !association.equals(that.association) : that.association != null) return false;
- return !(id != null ? !id.equals(that.id) : that.id != null);
-
+ if (!Objects.equals(association, that.association)) return false;
+ return Objects.equals(id, that.id);
}
@Override
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jTransaction.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jTransaction.groovy
index db2f618ecd..b3d0646c77 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jTransaction.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/Neo4jTransaction.groovy
@@ -20,14 +20,17 @@ package org.grails.datastore.gorm.neo4j
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
+
import org.neo4j.driver.AccessMode
import org.neo4j.driver.Driver
import org.neo4j.driver.Session
-import org.grails.datastore.mapping.transactions.Transaction
import org.neo4j.driver.SessionConfig
+
import org.springframework.transaction.TransactionDefinition
import org.springframework.transaction.support.DefaultTransactionDefinition
+import org.grails.datastore.mapping.transactions.Transaction
+
/**
* Represents a Neo4j transaction
*
@@ -58,7 +61,7 @@ class Neo4jTransaction implements Transaction<org.neo4j.driver.Transaction>, Clo
}
void commit() {
- if(isActive() && !rollbackOnly) {
+ if (isActive() && !rollbackOnly) {
log.debug("TX COMMIT: Neo4J commit()")
transaction.commit()
close()
@@ -66,7 +69,7 @@ class Neo4jTransaction implements Transaction<org.neo4j.driver.Transaction>, Clo
}
void rollback() {
- if(isActive()) {
+ if (isActive()) {
log.debug("TX ROLLBACK: Neo4J rollback()")
transaction.rollback()
close()
@@ -74,7 +77,7 @@ class Neo4jTransaction implements Transaction<org.neo4j.driver.Transaction>, Clo
}
void rollbackOnly() {
- if(active) {
+ if (active) {
rollbackOnly = true
log.debug("TX ROLLBACK ONLY: Neo4J rollback()")
transaction.rollback()
@@ -85,8 +88,8 @@ class Neo4jTransaction implements Transaction<org.neo4j.driver.Transaction>, Clo
@Override
void close() throws IOException {
- if(active) {
- log.debug("TX CLOSE: Neo4j tx.close()");
+ if (active) {
+ log.debug("TX CLOSE: Neo4j tx.close()")
transaction.close()
boltSession.close()
active = false
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipPersistentEntity.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipPersistentEntity.groovy
index 94c0960812..d6e103e860 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipPersistentEntity.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipPersistentEntity.groovy
@@ -19,9 +19,9 @@
package org.grails.datastore.gorm.neo4j
-import grails.neo4j.Direction
-import grails.neo4j.Relationship
import groovy.transform.CompileStatic
+
+import grails.neo4j.Direction
import org.grails.datastore.gorm.neo4j.mapping.config.NodeConfig
import org.grails.datastore.gorm.neo4j.mapping.config.RelationshipConfig
import org.grails.datastore.mapping.config.Property
@@ -41,11 +41,11 @@ import org.grails.datastore.mapping.model.types.Basic
class RelationshipPersistentEntity extends GraphPersistentEntity {
/**
* The name of the from property
- */
+ */
public static final String FROM = "from"
/**
- * The name of the to property
- */
+ * The name of the to property
+ */
public static final String TO = "to"
/**
@@ -66,19 +66,18 @@ class RelationshipPersistentEntity extends GraphPersistentEntity {
}
-
@Override
void initialize() {
- if(!isInitialized()) {
+ if (!isInitialized()) {
super.initialize()
- for(association in associations) {
- if(!isRelationshipAssociation(association) && !(association instanceof Basic)) {
+ for (association in associations) {
+ if (!isRelationshipAssociation(association) && !(association instanceof Basic)) {
throw new IllegalMappingException("Invalid association $association. You cannot have associations to other nodes within a relationship entity")
}
}
NodeConfig mappedForm = getMapping().getMappedForm()
- if(mappedForm instanceof RelationshipConfig) {
+ if (mappedForm instanceof RelationshipConfig) {
RelationshipConfig rc = (RelationshipConfig) mappedForm
this.type = rc.type ?: type
this.direction = rc.direction
@@ -115,21 +114,19 @@ ON CREATE SET r = row.props"""
@Override
String formatAssociationPatternFromExisting(Association association, String var = CypherBuilder.REL_VAR, String start = FROM, String end = TO) {
String associationMatch
- if(association.name == FROM || association.name == TO) {
- associationMatch = RelationshipUtils.matchForRelationshipEntity(association, this,var)
+ if (association.name == FROM || association.name == TO) {
+ associationMatch = RelationshipUtils.matchForRelationshipEntity(association, this, var)
return "(${start})${associationMatch}${toEntity.formatNode(end)}"
- }
- else {
+ } else {
throw new IllegalStateException("Relationship entities cannot have associations")
}
}
@Override
String formatProperty(String variable, String property) {
- if(property.startsWith(FROM) || property.startsWith(TO)) {
+ if (property.startsWith(FROM) || property.startsWith(TO)) {
return property
- }
- else {
+ } else {
return super.formatProperty(variable, property)
}
}
@@ -155,19 +152,19 @@ ON CREATE SET r = row.props"""
}
Association getFrom() {
- (Association)getPropertyByName(FROM)
+ (Association) getPropertyByName(FROM)
}
Association getTo() {
- (Association)getPropertyByName(TO)
+ (Association) getPropertyByName(TO)
}
GraphPersistentEntity getFromEntity() {
- (GraphPersistentEntity)getFrom().getAssociatedEntity()
+ (GraphPersistentEntity) getFrom().getAssociatedEntity()
}
GraphPersistentEntity getToEntity() {
- (GraphPersistentEntity)getTo().getAssociatedEntity()
+ (GraphPersistentEntity) getTo().getAssociatedEntity()
}
@@ -186,16 +183,15 @@ ON CREATE SET r = row.props"""
}
String buildRelationshipMatchTo(String type, String var = "r") {
- buildRelationshipMatch(type ,var) + toEntity.formatNode(TO)
+ buildRelationshipMatch(type, var) + toEntity.formatNode(TO)
}
String buildRelationshipMatch(String type, String var = "r") {
boolean incoming = direction.isIncoming()
boolean outgoing = direction.isOutgoing()
- if(type != null) {
+ if (type != null) {
return "${incoming ? RelationshipUtils.INCOMING_CHAR : ''}-[$var:${type}]-${outgoing ? RelationshipUtils.OUTGOING_CHAR : ''}"
- }
- else {
+ } else {
return "${incoming ? RelationshipUtils.INCOMING_CHAR : ''}-[$var]-${outgoing ? RelationshipUtils.OUTGOING_CHAR : ''}"
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipUtils.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipUtils.groovy
index 9c2a4aa0b7..5c29a1aede 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipUtils.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/RelationshipUtils.groovy
@@ -18,16 +18,16 @@
*/
package org.grails.datastore.gorm.neo4j
+import groovy.transform.CompileStatic
+
import grails.neo4j.Direction
import grails.neo4j.Relationship
-import groovy.transform.CompileStatic
import org.grails.datastore.gorm.neo4j.mapping.config.Attribute
import org.grails.datastore.gorm.neo4j.mapping.config.DynamicAssociation
import org.grails.datastore.mapping.model.PersistentEntity
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.model.types.ManyToMany
import org.grails.datastore.mapping.model.types.ManyToOne
-import org.grails.datastore.mapping.model.types.OneToMany
/**
* Utility methods for manipulating relationships
@@ -37,6 +37,7 @@ import org.grails.datastore.mapping.model.types.OneToMany
*/
@CompileStatic
class RelationshipUtils {
+
static final char INCOMING_CHAR = '<'
static final char OUTGOING_CHAR = '>'
private static final char OPEN_BRACE = '{'
@@ -54,12 +55,11 @@ class RelationshipUtils {
* @return True if it is
*/
static boolean useReversedMappingFor(Association association) {
- GraphPersistentEntity entity = (GraphPersistentEntity)association.getOwner()
- if(entity.isRelationshipEntity()) {
+ GraphPersistentEntity entity = (GraphPersistentEntity) association.getOwner()
+ if (entity.isRelationshipEntity()) {
return false
- }
- else {
- Attribute attr = (Attribute)association.getMapping()?.getMappedForm()
+ } else {
+ Attribute attr = (Attribute) association.getMapping()?.getMappedForm()
return isIncomingRelationship(association, attr)
}
}
@@ -71,7 +71,7 @@ class RelationshipUtils {
*/
static String relationshipTypeUsedFor(Association association) {
Attribute mappedForm = (Attribute) association.getMapping()?.getMappedForm()
- return getRelationshipType( association, mappedForm )
+ return getRelationshipType(association, mappedForm)
}
/**
@@ -91,17 +91,17 @@ class RelationshipUtils {
sb.append(INCOMING_CHAR)
}
sb.append(START_RELATIONSHIP).append(var).append(COLON).append(relationshipType)
- if(!attributes.isEmpty()) {
+ if (!attributes.isEmpty()) {
sb.append(OPEN_BRACE)
def i = attributes.entrySet().iterator()
- while(i.hasNext()) {
+ while (i.hasNext()) {
def entry = i.next()
sb.append(entry.key)
.append(COLON).append(SINGLE_QUOTE)
.append(entry.value)
.append(SINGLE_QUOTE)
- if(i.hasNext()) {
+ if (i.hasNext()) {
sb.append(COMMA)
}
}
@@ -136,7 +136,7 @@ class RelationshipUtils {
}
sb.append(START_RELATIONSHIP).append(var).append(COLON).append(relationshipType)
sb.append(END_RELATIONSHIP)
- if (direction == Direction.OUTGOING || direction == Direction.BOTH ) {
+ if (direction == Direction.OUTGOING || direction == Direction.BOTH) {
sb.append(OUTGOING_CHAR)
}
sb.toString()
@@ -160,9 +160,9 @@ class RelationshipUtils {
sb.append(INCOMING_CHAR)
}
sb.append(START_RELATIONSHIP)
- .append(var)
- .append(END_RELATIONSHIP)
- if (direction == Direction.OUTGOING || direction == Direction.BOTH ) {
+ .append(var)
+ .append(END_RELATIONSHIP)
+ if (direction == Direction.OUTGOING || direction == Direction.BOTH) {
sb.append(OUTGOING_CHAR)
}
sb.toString()
@@ -183,19 +183,16 @@ class RelationshipUtils {
String relationshipType = mappedForm?.getType()
if (relationshipType != null) {
return relationshipType
- }
- else if (association instanceof DynamicAssociation) {
+ } else if (association instanceof DynamicAssociation) {
return association.getName()
- }
- else {
+ } else {
boolean reversed = useReversedMappingFor(association)
String name = reversed ?
association.getReferencedPropertyName() :
association.getName()
- if(name != null) {
+ if (name != null) {
return name.toUpperCase(Locale.ENGLISH)
- }
- else {
+ } else {
return association.getName().toUpperCase(Locale.ENGLISH)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/SessionFlushedEvent.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/SessionFlushedEvent.java
index ded112f698..b73067e3d1 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/SessionFlushedEvent.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/SessionFlushedEvent.java
@@ -16,9 +16,10 @@
*/
package org.grails.datastore.gorm.neo4j;
-import org.grails.datastore.mapping.core.Session;
import org.springframework.context.ApplicationEvent;
+import org.grails.datastore.mapping.core.Session;
+
/**
* event emitted when session is flushed
*/
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/TypeDirectionPair.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/TypeDirectionPair.java
index 61f3ff6223..34f688050f 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/TypeDirectionPair.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/TypeDirectionPair.java
@@ -18,7 +18,6 @@
*/
package org.grails.datastore.gorm.neo4j;
-
/**
* combination of relationship type and direction to be used a key in a map
*/
@@ -57,9 +56,7 @@ public class TypeDirectionPair {
TypeDirectionPair that = (TypeDirectionPair) o;
if (outgoing != that.outgoing) return false;
- if (!type.equals(that.type)) return false;
-
- return true;
+ return type.equals(that.type);
}
@Override
@@ -72,16 +69,16 @@ public class TypeDirectionPair {
@Override
public String toString() {
return "TypeDirectionPair{" +
- "type='" + type + '\'' +
- ", outgoing=" + outgoing +
- '}';
- }
-
- public void setTargetType(String targetType) {
- this.targetType = targetType;
+ "type='" + type + '\'' +
+ ", outgoing=" + outgoing +
+ '}';
}
public String getTargetType() {
return targetType;
}
+
+ public void setTargetType(String targetType) {
+ this.targetType = targetType;
+ }
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/api/Neo4jGormStaticApi.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/api/Neo4jGormStaticApi.groovy
index 9847089cec..8f416ea2f3 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/api/Neo4jGormStaticApi.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/api/Neo4jGormStaticApi.groovy
@@ -19,15 +19,29 @@
package org.grails.datastore.gorm.neo4j.api
+import java.util.function.Function
+
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+
+import org.neo4j.driver.QueryRunner
+import org.neo4j.driver.Record
+import org.neo4j.driver.Result
+import org.neo4j.driver.types.Node
+
+import org.springframework.transaction.PlatformTransactionManager
+
import grails.gorm.multitenancy.Tenants
import grails.neo4j.Path
import grails.neo4j.Relationship
-import groovy.transform.CompileStatic
-import groovy.util.logging.Slf4j
import org.grails.datastore.gorm.GormEntity
import org.grails.datastore.gorm.GormStaticApi
import org.grails.datastore.gorm.finders.FinderMethod
-import org.grails.datastore.gorm.neo4j.*
+import org.grails.datastore.gorm.neo4j.CypherBuilder
+import org.grails.datastore.gorm.neo4j.GraphPersistentEntity
+import org.grails.datastore.gorm.neo4j.Neo4jDatastore
+import org.grails.datastore.gorm.neo4j.Neo4jSession
+import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity
import org.grails.datastore.gorm.neo4j.collection.Neo4jPath
import org.grails.datastore.gorm.neo4j.collection.Neo4jRelationship
import org.grails.datastore.gorm.neo4j.collection.Neo4jResultList
@@ -41,13 +55,6 @@ import org.grails.datastore.mapping.model.config.GormProperties
import org.grails.datastore.mapping.multitenancy.MultiTenancySettings
import org.grails.datastore.mapping.multitenancy.exceptions.TenantNotFoundException
import org.grails.datastore.mapping.query.QueryException
-import org.neo4j.driver.QueryRunner
-import org.neo4j.driver.Record
-import org.neo4j.driver.Result
-import org.neo4j.driver.types.Node
-import org.springframework.transaction.PlatformTransactionManager
-
-import java.util.function.Function
/**
* Static API implementation for Neo4j
@@ -93,25 +100,23 @@ class Neo4jGormStaticApi<D> extends GormStaticApi<D> {
QueryRunner boltSession = getStatementRunner(neo4jSession)
params = new LinkedHashMap(params)
String queryString
- if(query instanceof GString) {
+ if (query instanceof GString) {
queryString = buildNamedParameterQueryFromGString((GString) query, params)
- }
- else {
+ } else {
queryString = query.toString()
}
includeTenantIdIfNecessary(neo4jSession, queryString, params)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$queryString] for params [$params]")
}
- Result result = boltSession.run( queryString, (Map<String,Object>)params)
+ Result result = boltSession.run(queryString, (Map<String, Object>) params)
def persister = neo4jSession
.getEntityPersister(persistentEntity)
- if(result.hasNext()) {
+ if (result.hasNext()) {
return new Neo4jResultList(0, result, persister)
- }
- else {
+ } else {
return Collections.emptyList()
}
} as SessionCallback<List<D>>)
@@ -120,24 +125,23 @@ class Neo4jGormStaticApi<D> extends GormStaticApi<D> {
@Override
List<D> findAll(CharSequence query, Collection params, Map args) {
- if(query instanceof GString) {
- throw new QueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped.");
+ if (query instanceof GString) {
+ throw new QueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped.")
}
execute({ Session session ->
Neo4jSession neo4jSession = (Neo4jSession) session
QueryRunner boltSession = getStatementRunner(neo4jSession)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$query] for params [$params]")
}
- Result result = Neo4jExtensions.execute(boltSession, query.toString(), (List<Object>)params.toList())
+ Result result = Neo4jExtensions.execute(boltSession, query.toString(), (List<Object>) params.toList())
def persister = neo4jSession
.getEntityPersister(persistentEntity)
- if(result.hasNext()) {
+ if (result.hasNext()) {
return new Neo4jResultList(0, result, persister)
- }
- else {
+ } else {
return Collections.emptyList()
}
} as SessionCallback<List<D>>)
@@ -150,49 +154,48 @@ class Neo4jGormStaticApi<D> extends GormStaticApi<D> {
QueryRunner boltSession = getStatementRunner(neo4jSession)
params = new LinkedHashMap(params)
String queryString
- if(query instanceof GString) {
+ if (query instanceof GString) {
queryString = buildNamedParameterQueryFromGString((GString) query, params)
- }
- else {
+ } else {
queryString = query.toString()
}
includeTenantIdIfNecessary(neo4jSession, queryString, params)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$queryString] for params [$params]")
}
- Result result = boltSession.run( queryString, (Map<String,Object>)params)
+ Result result = boltSession.run(queryString, (Map<String, Object>) params)
def persister = neo4jSession
.getEntityPersister(persistentEntity)
def resultList = new Neo4jResultList(0, 1, (Iterator) result, persister)
- if( !resultList.isEmpty() ) {
- return (D)resultList.get(0)
+ if (!resultList.isEmpty()) {
+ return (D) resultList.get(0)
}
} as SessionCallback<D>)
}
@Override
D find(CharSequence query, Collection params, Map args) {
- if(query instanceof GString) {
- throw new QueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped.");
+ if (query instanceof GString) {
+ throw new QueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped.")
}
execute({ Session session ->
Neo4jSession neo4jSession = (Neo4jSession) session
QueryRunner boltSession = getStatementRunner(neo4jSession)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$query] for params [$params]")
}
- Result result = Neo4jExtensions.execute(boltSession, query.toString(), (List<Object>)params.toList())
+ Result result = Neo4jExtensions.execute(boltSession, query.toString(), (List<Object>) params.toList())
def persister = neo4jSession
.getEntityPersister(persistentEntity)
def resultList = new Neo4jResultList(0, 1, (Iterator) result, persister)
- if( !resultList.isEmpty() ) {
- return (D)resultList.get(0)
+ if (!resultList.isEmpty()) {
+ return (D) resultList.get(0)
}
return null
@@ -229,14 +232,13 @@ class Neo4jGormStaticApi<D> extends GormStaticApi<D> {
QueryRunner boltSession = getStatementRunner(neo4jSession)
params = new LinkedHashMap(params)
String queryString
- if(query instanceof GString) {
+ if (query instanceof GString) {
queryString = buildNamedParameterQueryFromGString((GString) query, params)
- }
- else {
+ } else {
queryString = query.toString()
}
includeTenantIdIfNecessary(neo4jSession, queryString, params)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("UPDATE Cypher [$queryString] for params [$params]")
}
@@ -246,33 +248,32 @@ class Neo4jGormStaticApi<D> extends GormStaticApi<D> {
}
-
@Override
Integer executeUpdate(CharSequence query, Collection params, Map args) {
- return (int) Neo4jEntityPersister.countUpdates(cypherStatic(query, params.toList()) )
+ return (int) Neo4jEntityPersister.countUpdates(cypherStatic(query, params.toList()))
}
Path findPath(CharSequence query, Map params) {
Result result = cypherStatic(query, params)
- if(result.hasNext()) {
+ if (result.hasNext()) {
Record record = result.next()
GraphPersistentEntity graphEntity = (GraphPersistentEntity) persistentEntity
- return new Neo4jPath((Neo4jDatastore)datastore, record.values().first().asPath(), graphEntity, graphEntity)
+ return new Neo4jPath((Neo4jDatastore) datastore, record.values().first().asPath(), graphEntity, graphEntity)
}
return null
}
Path findPathTo(Class type, CharSequence query, Map params) {
Result result = cypherStatic(query, params)
- if(result.hasNext()) {
+ if (result.hasNext()) {
Record record = result.next()
GraphPersistentEntity graphEntity = (GraphPersistentEntity) persistentEntity
- GraphPersistentEntity toEntity = (GraphPersistentEntity)persistentEntity.mappingContext.getPersistentEntity(type.name)
- if(toEntity == null) {
+ GraphPersistentEntity toEntity = (GraphPersistentEntity) persistentEntity.mappingContext.getPersistentEntity(type.name)
+ if (toEntity == null) {
throw new QueryException("Target type [$type] is not a persistent entity")
}
- return new Neo4jPath((Neo4jDatastore)datastore, record.values().first().asPath(), graphEntity, toEntity)
+ return new Neo4jPath((Neo4jDatastore) datastore, record.values().first().asPath(), graphEntity, toEntity)
}
return null
}
@@ -291,14 +292,14 @@ class Neo4jGormStaticApi<D> extends GormStaticApi<D> {
throw new QueryException("Target type [$to] is not a persistent entity")
}
Relationship<F, T> relationship = null
- if(from != null && to != null) {
+ if (from != null && to != null) {
String query = """MATCH (from)-[r]-(to)
WHERE ${fromEntity.formatId(RelationshipPersistentEntity.FROM)} = \$start AND ${toEntity.formatId(RelationshipPersistentEntity.TO)} = \$end
RETURN r
LIMIT 1"""
- List<org.neo4j.driver.types.Relationship> results = executeQuery(query, [start:from.ident(), end:to.ident()])
+ List<org.neo4j.driver.types.Relationship> results = executeQuery(query, [start: from.ident(), end: to.ident()])
- if(!results.isEmpty()) {
+ if (!results.isEmpty()) {
org.neo4j.driver.types.Relationship neoRel = (org.neo4j.driver.types.Relationship) results.first()
relationship = new Neo4jRelationship<>(from, to, neoRel)
relationship.attributes(neoRel.asMap())
@@ -309,7 +310,7 @@ LIMIT 1"""
} as SessionCallback<Relationship<F, T>>)
}
- <F extends GormEntity, T extends GormEntity> List<Relationship<F, T>> findRelationships(F from, T to, Map params = Collections.emptyMap()) {
+ <F extends GormEntity, T extends GormEntity> List<Relationship<F, T>> findRelationships(F from, T to, Map params = Collections.emptyMap()) {
execute({ Session session ->
Neo4jSession neo4jSession = (Neo4jSession) session
EntityPersister fromPersister = (EntityPersister) neo4jSession.getPersister(from)
@@ -323,16 +324,16 @@ LIMIT 1"""
throw new QueryException("Target type [$to] is not a persistent entity")
}
List<Relationship> rels = []
- if(from != null && to != null) {
+ if (from != null && to != null) {
String skip = params.offset ? " SKIP ${Integer.valueOf(params.offset.toString())}" : ''
String limit = params.max ? " LIMIT ${Integer.valueOf(params.max.toString())}" : ''
String query = """MATCH (from)-[r]-(to)
WHERE ${fromEntity.formatId(RelationshipPersistentEntity.FROM)} = \$start AND ${toEntity.formatId(RelationshipPersistentEntity.TO)} = \$end
RETURN DISTINCT(r)$skip$limit"""
- List<org.neo4j.driver.types.Relationship> results = (List<org.neo4j.driver.types.Relationship>) executeQuery(query, [start:from.ident(), end:to.ident()])
+ List<org.neo4j.driver.types.Relationship> results = (List<org.neo4j.driver.types.Relationship>) executeQuery(query, [start: from.ident(), end: to.ident()])
- for(org.neo4j.driver.types.Relationship neoRel in results) {
- def relationship = new Neo4jRelationship<F,T>(from, to, neoRel)
+ for (org.neo4j.driver.types.Relationship neoRel in results) {
+ def relationship = new Neo4jRelationship<F, T>(from, to, neoRel)
relationship.attributes(neoRel.asMap())
rels.add(relationship)
}
@@ -342,7 +343,7 @@ RETURN DISTINCT(r)$skip$limit"""
} as SessionCallback<List<Relationship<F, T>>>)
}
- <F extends GormEntity, T extends GormEntity> List<Relationship<F, T>> findRelationships(Class<F> from, Class<T> to, Map params = Collections.emptyMap()) {
+ <F extends GormEntity, T extends GormEntity> List<Relationship<F, T>> findRelationships(Class<F> from, Class<T> to, Map params = Collections.emptyMap()) {
execute({ Session session ->
Neo4jEntityPersister fromPersister = (Neo4jEntityPersister) session.getPersister(from)
Neo4jEntityPersister toPersister = (Neo4jEntityPersister) session.getPersister(to)
@@ -355,21 +356,21 @@ RETURN DISTINCT(r)$skip$limit"""
throw new QueryException("Target type [$to] is not a persistent entity")
}
List<Relationship> rels = []
- if(from != null && to != null) {
+ if (from != null && to != null) {
String skip = params.offset ? " SKIP ${Integer.valueOf(params.offset.toString())}" : ''
String limit = params.max ? " LIMIT ${Integer.valueOf(params.max.toString())}" : ''
String query = """MATCH ${fromEntity.formatNode(RelationshipPersistentEntity.FROM)}-[r]-${toEntity.formatNode(RelationshipPersistentEntity.TO)}
RETURN DISTINCT(r), from, to$skip$limit"""
Result results = cypherStatic(query)
- while(results.hasNext()) {
+ while (results.hasNext()) {
Record record = results.next()
org.neo4j.driver.types.Relationship neoRel = record.get(CypherBuilder.REL_VAR).asRelationship()
Node fromNode = record.get(RelationshipPersistentEntity.FROM).asNode()
Node toNode = record.get(RelationshipPersistentEntity.TO).asNode()
F fromObject = (F) fromPersister.unmarshallOrFromCache(fromEntity, fromNode)
T toObject = (T) fromPersister.unmarshallOrFromCache(toEntity, toNode)
- def relationship = new Neo4jRelationship<F,T>(fromObject, toObject, neoRel)
+ def relationship = new Neo4jRelationship<F, T>(fromObject, toObject, neoRel)
relationship.attributes(neoRel.asMap())
rels.add(relationship)
}
@@ -385,19 +386,19 @@ RETURN DISTINCT(r), from, to$skip$limit"""
EntityPersister toPersister = (EntityPersister) session.getPersister(to)
GraphPersistentEntity fromEntity = (GraphPersistentEntity) fromPersister?.getPersistentEntity()
GraphPersistentEntity toEntity = (GraphPersistentEntity) toPersister?.getPersistentEntity()
- if(fromEntity == null) {
+ if (fromEntity == null) {
throw new QueryException("From type [$from] is not a persistent entity")
}
- if(toEntity == null) {
+ if (toEntity == null) {
throw new QueryException("Target type [$to] is not a persistent entity")
}
Serializable fromId = fromPersister.getObjectIdentifier(from)
Serializable toId = toPersister.getObjectIdentifier(to)
- if(fromId == null) {
+ if (fromId == null) {
throw new QueryException("From type [$from] has not been persisted (null id)")
}
- if(toId == null) {
+ if (toId == null) {
throw new QueryException("Target type [$to] has not been persisted (null id)")
}
String query = """MATCH ${
@@ -408,9 +409,9 @@ RETURN DISTINCT(r), from, to$skip$limit"""
fromEntity.formatId(RelationshipPersistentEntity.FROM)
} = \$start AND ${toEntity.formatId(RelationshipPersistentEntity.TO)} = \$end RETURN p"""
Result result = cypherStatic(query, [start: fromId, end: toId])
- if(result.hasNext()) {
+ if (result.hasNext()) {
Record record = result.next()
- return new Neo4jPath((Neo4jDatastore)datastore, record.values().first().asPath(), (GraphPersistentEntity)fromEntity, (GraphPersistentEntity)toEntity)
+ return new Neo4jPath((Neo4jDatastore) datastore, record.values().first().asPath(), (GraphPersistentEntity) fromEntity, (GraphPersistentEntity) toEntity)
}
return null
@@ -423,23 +424,23 @@ RETURN DISTINCT(r), from, to$skip$limit"""
* @return
*/
Result cypherStatic(CharSequence query, List params) {
- if(query instanceof GString) {
- throw new QueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped.");
+ if (query instanceof GString) {
+ throw new QueryException("Unsafe query [$query]. GORM cannot automatically escape a GString value when combined with ordinal parameters, so this query is potentially vulnerable to HQL injection attacks. Please embed the parameters within the GString so they can be safely escaped.")
}
execute({ Session session ->
Neo4jSession neo4jSession = (Neo4jSession) session
Map paramsMap = new LinkedHashMap()
int i = 0
- for(p in params) {
+ for (p in params) {
paramsMap.put(String.valueOf(++i), p)
}
String queryString = query.toString()
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$queryString] for params [$params]")
}
- includeTenantIdIfNecessary(neo4jSession, queryString, (Map)paramsMap)
+ includeTenantIdIfNecessary(neo4jSession, queryString, (Map) paramsMap)
QueryRunner boltSession = getStatementRunner(neo4jSession)
boltSession.run(queryString, paramsMap)
} as SessionCallback<Result>)
@@ -451,20 +452,19 @@ RETURN DISTINCT(r), from, to$skip$limit"""
* @param query
* @return
*/
- Result cypherStatic(CharSequence query, Map params ) {
+ Result cypherStatic(CharSequence query, Map params) {
execute({ Session session ->
Neo4jSession neo4jSession = (Neo4jSession) session
QueryRunner boltSession = getStatementRunner(neo4jSession)
params = new LinkedHashMap(params)
String queryString
- if(query instanceof GString) {
+ if (query instanceof GString) {
queryString = buildNamedParameterQueryFromGString((GString) query, params)
- }
- else {
+ } else {
queryString = query.toString()
}
includeTenantIdIfNecessary(neo4jSession, queryString, params)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$queryString] for params [$params]")
}
@@ -484,36 +484,33 @@ RETURN DISTINCT(r), from, to$skip$limit"""
Neo4jSession neo4jSession = (Neo4jSession) session
Map<String, ?> params = [:]
String queryString
- if(query instanceof GString) {
+ if (query instanceof GString) {
queryString = buildNamedParameterQueryFromGString((GString) query, params)
- }
- else {
+ } else {
queryString = query.toString()
}
if (persistentEntity.isMultiTenant() && neo4jSession.getDatastore().multiTenancyMode == MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR) {
if (!queryString.contains("\$tenantId")) {
throw new TenantNotFoundException("Query does not specify a tenant id, but multi tenant mode is DISCRIMINATOR!")
} else {
- Map<String,Object> paramsMap = new LinkedHashMap<>()
+ Map<String, Object> paramsMap = new LinkedHashMap<>()
paramsMap.put(GormProperties.TENANT_IDENTITY, Tenants.currentId(Neo4jDatastore))
QueryRunner boltSession = getStatementRunner(neo4jSession)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$queryString] for params [$paramsMap]")
}
return boltSession.run(queryString, paramsMap)
}
- }
- else {
+ } else {
QueryRunner boltSession = getStatementRunner(neo4jSession)
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [$queryString]")
}
- if(params.isEmpty()) {
+ if (params.isEmpty()) {
return boltSession.run(queryString)
- }
- else {
+ } else {
return boltSession.run(queryString, params)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/GraphAdapter.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/GraphAdapter.groovy
index e25d12e7fb..a24768d9ce 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/GraphAdapter.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/GraphAdapter.groovy
@@ -20,18 +20,15 @@ package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
import groovy.transform.PackageScope
-import org.grails.datastore.gorm.GormEnhancer
-import org.grails.datastore.gorm.GormEntity
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.gorm.neo4j.RelationshipUtils
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.model.types.ManyToMany
import org.grails.datastore.mapping.model.types.ToOne
-import org.grails.datastore.mapping.proxy.ProxyFactory
import org.grails.datastore.mapping.reflect.EntityReflector
-
/**
* Helps to Adapt a collection to the Neo4j graph
*
@@ -59,66 +56,63 @@ class GraphAdapter {
}
void adaptGraphUponRemove(Object o, boolean currentlyInitializing = false) {
- if(currentlyInitializing) return
+ if (currentlyInitializing) return
- Neo4jSession session = (Neo4jSession)this.session
+ Neo4jSession session = (Neo4jSession) this.session
def childAccess = session.mappingContext.getEntityReflector(association.getAssociatedEntity())
def proxyFactory = session.getMappingContext().getProxyFactory()
Serializable id
if (proxyFactory.isProxy(o)) {
id = proxyFactory.getIdentifier(o)
- }
- else {
+ } else {
id = (Serializable) childAccess.getIdentifier(o)
}
- if(association.isOrphanRemoval()) {
+ if (association.isOrphanRemoval()) {
session.delete(o)
- }
- else if (!reversed && id != null) {
- session.addPendingRelationshipDelete((Serializable)parentAccess.getIdentifier(), association, id)
+ } else if (!reversed && id != null) {
+ session.addPendingRelationshipDelete((Serializable) parentAccess.getIdentifier(), association, id)
}
}
void adaptGraphUponAdd(Object t, boolean currentlyInitializing = false) {
def proxyFactory = session.getMappingContext().getProxyFactory()
- Neo4jSession session = (Neo4jSession)this.session
- if(currentlyInitializing) {
+ Neo4jSession session = (Neo4jSession) this.session
+ if (currentlyInitializing) {
// if the association is initializing then replace parent entities with non proxied version to prevent N+1 problem
if (association.isBidirectional() && !proxyFactory.isProxy(t)) {
def inverseSide = association.inverseSide
- if(inverseSide instanceof ToOne) {
+ if (inverseSide instanceof ToOne) {
EntityReflector target = session.mappingContext.getEntityReflector(association.getAssociatedEntity())
- target.setProperty( t, inverseSide.name, parentAccess.entity )
+ target.setProperty(t, inverseSide.name, parentAccess.entity)
}
}
- }
- else {
+ } else {
if (proxyFactory.isProxy(t)) {
- if ( !proxyFactory.isInitialized(t) ) return
- if ( !childType.isInstance(t) ) return
+ if (!proxyFactory.isInitialized(t)) return
+ if (!childType.isInstance(t)) return
}
EntityReflector target = session.mappingContext.getEntityReflector(association.getAssociatedEntity())
if (association.isBidirectional()) {
if (association instanceof ManyToMany) {
- Collection coll = (Collection) target.getProperty(t, association.getReferencedPropertyName());
- coll.add(parentAccess.entity);
+ Collection coll = (Collection) target.getProperty(t, association.getReferencedPropertyName())
+ coll.add(parentAccess.entity)
} else {
- target.setProperty(t, association.getReferencedPropertyName(), parentAccess.entity);
+ target.setProperty(t, association.getReferencedPropertyName(), parentAccess.entity)
}
}
def identifier = target.getIdentifier(t)
if (identifier == null) { // non-persistent instance
- identifier = session.persist(t);
+ identifier = session.persist(t)
}
if (!reversed && identifier != null) { // prevent duplicated rels
- session.addPendingRelationshipInsert((Serializable)parentAccess.getIdentifier(), association, identifier)
+ session.addPendingRelationshipInsert((Serializable) parentAccess.getIdentifier(), association, identifier)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jAssociationResultList.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jAssociationResultList.groovy
index 647415183d..4d36727f1c 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jAssociationResultList.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jAssociationResultList.groovy
@@ -19,11 +19,11 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
-
/**
* Extended result list aware of the parent entity and association to prevent N+1 queries
*
@@ -42,8 +42,8 @@ class Neo4jAssociationResultList extends Neo4jResultList {
this.parent = parent
this.association = association
this.session = session
- if(association.isBidirectional()) {
- setInitializedAssociations(Collections.<Association,Object>singletonMap(association.inverseSide, parent.entity))
+ if (association.isBidirectional()) {
+ setInitializedAssociations(Collections.<Association, Object> singletonMap(association.inverseSide, parent.entity))
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jList.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jList.groovy
index eddd1dfcba..2919439d64 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jList.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jList.groovy
@@ -19,13 +19,13 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.mapping.dirty.checking.DirtyCheckable
import org.grails.datastore.mapping.dirty.checking.DirtyCheckingList
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
-
/**
*
* A {@link org.grails.datastore.mapping.dirty.checking.DirtyCheckingList} for Neo4j
@@ -36,13 +36,15 @@ import org.grails.datastore.mapping.model.types.Association
@CompileStatic
class Neo4jList extends DirtyCheckingList {
+
final transient Association association
final transient Neo4jSession session
- protected final @Delegate GraphAdapter graphAdapter
+ protected final @Delegate
+ GraphAdapter graphAdapter
Neo4jList(EntityAccess parentAccess, Association association, List delegate, Neo4jSession session) {
- super(delegate, (DirtyCheckable)parentAccess.getEntity(), association.getName())
+ super(delegate, (DirtyCheckable) parentAccess.getEntity(), association.getName())
this.association = association
this.session = session
this.graphAdapter = new GraphAdapter(session, parentAccess, association)
@@ -60,7 +62,7 @@ class Neo4jList extends DirtyCheckingList {
boolean add(Object o) {
def added = super.add(o)
- if(added) {
+ if (added) {
adaptGraphUponAdd(o)
}
return added
@@ -69,8 +71,8 @@ class Neo4jList extends DirtyCheckingList {
@Override
boolean addAll(Collection c) {
def added = super.addAll(c)
- if(added) {
- for( o in c ) {
+ if (added) {
+ for (o in c) {
adaptGraphUponAdd(o)
}
}
@@ -81,8 +83,8 @@ class Neo4jList extends DirtyCheckingList {
@Override
boolean removeAll(Collection c) {
def removed = super.removeAll(c)
- if(removed) {
- for(o in c) {
+ if (removed) {
+ for (o in c) {
adaptGraphUponRemove(o)
}
}
@@ -92,7 +94,7 @@ class Neo4jList extends DirtyCheckingList {
@Override
boolean remove(Object o) {
def removed = super.remove(o)
- if(removed) {
+ if (removed) {
adaptGraphUponRemove(o)
}
return removed
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPath.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPath.groovy
index b5a1e3fd21..5686d80ddd 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPath.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPath.groovy
@@ -19,17 +19,18 @@
package org.grails.datastore.gorm.neo4j.collection
+import groovy.transform.CompileStatic
+
+import org.neo4j.driver.types.Node
+
import grails.neo4j.Neo4jEntity
import grails.neo4j.Path
import grails.neo4j.Relationship
-import groovy.transform.CompileStatic
import org.grails.datastore.gorm.GormEnhancer
import org.grails.datastore.gorm.neo4j.GraphPersistentEntity
import org.grails.datastore.gorm.neo4j.Neo4jDatastore
-import org.grails.datastore.gorm.neo4j.Neo4jMappingContext
import org.grails.datastore.gorm.neo4j.engine.Neo4jEntityPersister
import org.grails.datastore.mapping.query.QueryException
-import org.neo4j.driver.types.Node
/**
* A neo4j {@link org.neo4j.driver.types.Path} adapter
@@ -39,6 +40,7 @@ import org.neo4j.driver.types.Node
*/
@CompileStatic
class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements Path<S, E> {
+
final Neo4jDatastore datastore
final org.neo4j.driver.types.Path neo4jPath
final GraphPersistentEntity from
@@ -51,16 +53,16 @@ class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements P
Neo4jPath(Neo4jDatastore datastore, org.neo4j.driver.types.Path neo4jPath, GraphPersistentEntity from, GraphPersistentEntity to) {
this.datastore = datastore
this.neo4jPath = neo4jPath
- if(from == null) {
+ if (from == null) {
from = datastore.mappingContext.findPersistentEntityForLabels(neo4jPath.start().labels())
}
- if(to == null) {
+ if (to == null) {
to = datastore.mappingContext.findPersistentEntityForLabels(neo4jPath.end().labels())
}
- if(from == null) {
+ if (from == null) {
throw new IllegalArgumentException("From domain class type cannot be established for path [$neo4jPath]")
}
- if(to == null) {
+ if (to == null) {
throw new IllegalArgumentException("From domain class type cannot be established for path [$neo4jPath]")
}
this.from = from
@@ -69,33 +71,32 @@ class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements P
Neo4jPath(Neo4jDatastore datastore, org.neo4j.driver.types.Path neo4jPath, Class from, Class to) {
this(datastore, neo4jPath,
- (GraphPersistentEntity)datastore.mappingContext.getPersistentEntity(from.name),
- (GraphPersistentEntity)datastore.mappingContext.getPersistentEntity(to.name))
+ (GraphPersistentEntity) datastore.mappingContext.getPersistentEntity(from.name),
+ (GraphPersistentEntity) datastore.mappingContext.getPersistentEntity(to.name))
}
Neo4jPath(Neo4jDatastore datastore, org.neo4j.driver.types.Path neo4jPath) {
- this(datastore, neo4jPath,(GraphPersistentEntity)null,null)
+ this(datastore, neo4jPath, (GraphPersistentEntity) null, null)
}
-
@Override
S start() {
- if(start == null) {
+ if (start == null) {
Class clazz = from.javaClass
- Neo4jEntityPersister persister = (Neo4jEntityPersister )GormEnhancer.findDatastore(clazz).currentSession.getPersister(clazz)
- start = (S)persister.unmarshallOrFromCache(from, neo4jPath.start())
+ Neo4jEntityPersister persister = (Neo4jEntityPersister) GormEnhancer.findDatastore(clazz).currentSession.getPersister(clazz)
+ start = (S) persister.unmarshallOrFromCache(from, neo4jPath.start())
}
return start
}
@Override
E end() {
- if(end == null) {
+ if (end == null) {
Class clazz = to.javaClass
- Neo4jEntityPersister persister = (Neo4jEntityPersister )GormEnhancer.findDatastore(clazz).currentSession.getPersister(clazz)
+ Neo4jEntityPersister persister = (Neo4jEntityPersister) GormEnhancer.findDatastore(clazz).currentSession.getPersister(clazz)
- end = (E)persister.unmarshallOrFromCache(to, neo4jPath.end())
+ end = (E) persister.unmarshallOrFromCache(to, neo4jPath.end())
}
return end
}
@@ -107,9 +108,9 @@ class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements P
@Override
Iterable nodes() {
- if(nodes == null) {
+ if (nodes == null) {
List nodeList = []
- for(Node n in neo4jPath.nodes()) {
+ for (Node n in neo4jPath.nodes()) {
nodeList.add(unmarshallNode(datastore, n))
}
nodes = nodeList
@@ -129,6 +130,7 @@ class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements P
}
static class Neo4jPathIterator implements Iterator<Path.Segment> {
+
final Neo4jDatastore datastore
final Iterator<org.neo4j.driver.types.Path.Segment> iterator
@@ -145,11 +147,12 @@ class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements P
@Override
Path.Segment next() {
org.neo4j.driver.types.Path.Segment neoSegment = iterator.next()
- return new Neo4jPathSegment(datastore,neoSegment)
+ return new Neo4jPathSegment(datastore, neoSegment)
}
}
- static class Neo4jPathSegment implements Path.Segment {
+ static class Neo4jPathSegment implements Path.Segment {
+
final Neo4jDatastore datastore
final org.neo4j.driver.types.Path.Segment neoSegment
@@ -168,14 +171,14 @@ class Neo4jPath<S extends Neo4jEntity<S>, E extends Neo4jEntity<E>> implements P
@Override
Neo4jEntity start() {
- if(start == null)
+ if (start == null)
start = unmarshallNode(datastore, neoSegment.start())
return start
}
@Override
Neo4jEntity end() {
- if(end == null) {
+ if (end == null) {
end = unmarshallNode(datastore, neoSegment.end())
}
return end
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentList.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentList.groovy
index b8789f548a..949b6d247c 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentList.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentList.groovy
@@ -1,4 +1,3 @@
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -20,6 +19,7 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.gorm.neo4j.engine.Neo4jAssociationQueryExecutor
import org.grails.datastore.mapping.collection.PersistentList
@@ -27,6 +27,7 @@ import org.grails.datastore.mapping.dirty.checking.DirtyCheckable
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.model.types.ToMany
+
/**
* Neo4j version of the {@link PersistentList} class
*
@@ -38,7 +39,8 @@ class Neo4jPersistentList extends PersistentList {
protected transient final EntityAccess parentAccess
protected transient final Association association
- protected transient final @Delegate GraphAdapter graphAdapter
+ protected transient final @Delegate
+ GraphAdapter graphAdapter
Neo4jPersistentList(Collection keys, Neo4jSession session, EntityAccess parentAccess, ToMany association) {
super(keys, association.associatedEntity.javaClass, session)
@@ -71,7 +73,7 @@ class Neo4jPersistentList extends PersistentList {
@Override
boolean add(Object o) {
def added = super.add(o)
- if(added) {
+ if (added) {
adaptGraphUponAdd(o, currentlyInitializing())
}
@@ -81,8 +83,8 @@ class Neo4jPersistentList extends PersistentList {
@Override
boolean removeAll(Collection c) {
def removed = super.removeAll(c)
- if(removed) {
- for(o in c) {
+ if (removed) {
+ for (o in c) {
adaptGraphUponRemove(o, currentlyInitializing())
}
}
@@ -92,7 +94,7 @@ class Neo4jPersistentList extends PersistentList {
@Override
boolean remove(Object o) {
def removed = super.remove(o)
- if(removed) {
+ if (removed) {
adaptGraphUponRemove(o, currentlyInitializing())
}
return removed
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSet.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSet.groovy
index 2970d1354d..02c12402ef 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSet.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSet.groovy
@@ -19,6 +19,7 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.gorm.neo4j.engine.Neo4jAssociationQueryExecutor
import org.grails.datastore.mapping.collection.PersistentSet
@@ -26,6 +27,7 @@ import org.grails.datastore.mapping.dirty.checking.DirtyCheckable
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.model.types.ToMany
+
/**
* Neo4j version of the {@link PersistentSet} class
*
@@ -34,9 +36,11 @@ import org.grails.datastore.mapping.model.types.ToMany
*/
@CompileStatic
class Neo4jPersistentSet extends PersistentSet {
+
protected final EntityAccess parentAccess
protected final Association association
- protected final @Delegate GraphAdapter graphAdapter
+ protected final @Delegate
+ GraphAdapter graphAdapter
Neo4jPersistentSet(Collection keys, Neo4jSession session, EntityAccess parentAccess, ToMany association) {
super(keys, association.associatedEntity.javaClass, session)
@@ -58,8 +62,8 @@ class Neo4jPersistentSet extends PersistentSet {
@Override
boolean addAll(Collection c) {
def added = super.addAll(c)
- if(added) {
- for( o in c ) {
+ if (added) {
+ for (o in c) {
adaptGraphUponAdd(o, currentlyInitializing())
}
}
@@ -70,7 +74,7 @@ class Neo4jPersistentSet extends PersistentSet {
@Override
boolean add(Object o) {
def added = super.add(o)
- if(added) {
+ if (added) {
adaptGraphUponAdd(o, currentlyInitializing())
}
@@ -80,8 +84,8 @@ class Neo4jPersistentSet extends PersistentSet {
@Override
boolean removeAll(Collection c) {
def removed = super.removeAll(c)
- if(removed) {
- for(o in c) {
+ if (removed) {
+ for (o in c) {
adaptGraphUponRemove(o)
}
}
@@ -91,7 +95,7 @@ class Neo4jPersistentSet extends PersistentSet {
@Override
boolean remove(Object o) {
def removed = super.remove(o)
- if(removed) {
+ if (removed) {
adaptGraphUponRemove(o, currentlyInitializing())
}
return removed
@@ -114,8 +118,8 @@ class Neo4jPersistentSet extends PersistentSet {
@Override
void markDirty() {
- if(!currentlyInitializing()) {
- ((DirtyCheckable)parentAccess.entity).markDirty(association.getName())
+ if (!currentlyInitializing()) {
+ ((DirtyCheckable) parentAccess.entity).markDirty(association.getName())
super.markDirty()
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSortedSet.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSortedSet.groovy
index e8f3ca468f..07021e3153 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSortedSet.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jPersistentSortedSet.groovy
@@ -19,6 +19,7 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.gorm.neo4j.engine.Neo4jAssociationQueryExecutor
import org.grails.datastore.mapping.collection.PersistentSet
@@ -27,6 +28,7 @@ import org.grails.datastore.mapping.dirty.checking.DirtyCheckable
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.model.types.ToMany
+
/**
* Neo4j version of the {@link PersistentSet} class
*
@@ -35,9 +37,11 @@ import org.grails.datastore.mapping.model.types.ToMany
*/
@CompileStatic
class Neo4jPersistentSortedSet extends PersistentSortedSet {
+
protected final EntityAccess parentAccess
protected final Association association
- protected final @Delegate GraphAdapter graphAdapter
+ protected final @Delegate
+ GraphAdapter graphAdapter
Neo4jPersistentSortedSet(Collection keys, Neo4jSession session, EntityAccess parentAccess, ToMany association) {
super(keys, association.associatedEntity.javaClass, session)
@@ -58,8 +62,8 @@ class Neo4jPersistentSortedSet extends PersistentSortedSet {
@Override
boolean addAll(Collection c) {
def added = super.addAll(c)
- if(added) {
- for( o in c ) {
+ if (added) {
+ for (o in c) {
adaptGraphUponAdd(o, currentlyInitializing())
}
}
@@ -70,7 +74,7 @@ class Neo4jPersistentSortedSet extends PersistentSortedSet {
@Override
boolean add(Object o) {
def added = super.add(o)
- if(added) {
+ if (added) {
adaptGraphUponAdd(o, currentlyInitializing())
}
@@ -80,8 +84,8 @@ class Neo4jPersistentSortedSet extends PersistentSortedSet {
@Override
boolean removeAll(Collection c) {
def removed = super.removeAll(c)
- if(removed) {
- for(o in c) {
+ if (removed) {
+ for (o in c) {
adaptGraphUponRemove(o, currentlyInitializing())
}
}
@@ -91,7 +95,7 @@ class Neo4jPersistentSortedSet extends PersistentSortedSet {
@Override
boolean remove(Object o) {
def removed = super.remove(o)
- if(removed) {
+ if (removed) {
adaptGraphUponRemove(o, currentlyInitializing())
}
return removed
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jRelationship.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jRelationship.groovy
index c144dbdc02..324b1e6126 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jRelationship.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jRelationship.groovy
@@ -19,9 +19,9 @@
package org.grails.datastore.gorm.neo4j.collection
-import grails.neo4j.Relationship
import groovy.transform.CompileStatic
-import org.grails.datastore.gorm.schemaless.DynamicAttributes
+
+import grails.neo4j.Relationship
/**
* Default implementation of the {@link Relationship} trait
@@ -31,6 +31,7 @@ import org.grails.datastore.gorm.schemaless.DynamicAttributes
*/
@CompileStatic
class Neo4jRelationship<F, T> implements Relationship<F, T> {
+
String type
Neo4jRelationship(F from, T to, String type) {
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jResultList.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jResultList.groovy
index a34b81a811..c7a2a0a047 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jResultList.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jResultList.groovy
@@ -19,23 +19,22 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
+import jakarta.persistence.LockModeType
+
+import org.neo4j.driver.Record
+import org.neo4j.driver.Result
+import org.neo4j.driver.Value
+import org.neo4j.driver.types.Node
+import org.neo4j.driver.types.Relationship
+
import org.grails.datastore.gorm.neo4j.CypherBuilder
import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity
import org.grails.datastore.gorm.neo4j.engine.Neo4jEntityPersister
import org.grails.datastore.gorm.query.AbstractResultList
-import org.grails.datastore.mapping.engine.EntityPersister
import org.grails.datastore.mapping.model.PersistentEntity
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.query.QueryException
-import org.neo4j.driver.Record
-import org.neo4j.driver.Result
-import org.neo4j.driver.Value
-import org.neo4j.driver.types.Entity
-import org.neo4j.driver.types.Node
-import org.neo4j.driver.types.Relationship
-
-import jakarta.persistence.LockModeType
-
/**
* A Neo4j result list for decoding objects from the {@link Result} interface
@@ -49,7 +48,7 @@ class Neo4jResultList extends AbstractResultList {
private static final Map<Association, Object> EMPTY_ASSOCIATIONS = Collections.<Association, Object> emptyMap()
private static final Map<String, Object> EMPTY_RESULT_DATA = Collections.<String, Object> emptyMap()
- final protected transient Neo4jEntityPersister entityPersister
+ final protected transient Neo4jEntityPersister entityPersister
protected transient Map<Association, Object> initializedAssociations = EMPTY_ASSOCIATIONS
protected transient Map<Serializable, Node> initializedNodes = [:]
@@ -57,7 +56,7 @@ class Neo4jResultList extends AbstractResultList {
protected final LockModeType lockMode
Neo4jResultList(int offset, Result cursor, Neo4jEntityPersister entityPersister, LockModeType lockMode = LockModeType.NONE) {
- super(offset, (Iterator<Object>)cursor)
+ super(offset, (Iterator<Object>) cursor)
this.entityPersister = entityPersister
this.lockMode = lockMode
}
@@ -102,55 +101,49 @@ class Neo4jResultList extends AbstractResultList {
if (next instanceof Node) {
Node node = (Node) next
return entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), node, EMPTY_RESULT_DATA, initializedAssociations, lockMode)
- }
- else if(next instanceof Relationship) {
+ } else if (next instanceof Relationship) {
PersistentEntity persistentEntity = entityPersister.getPersistentEntity()
- if(persistentEntity instanceof RelationshipPersistentEntity) {
+ if (persistentEntity instanceof RelationshipPersistentEntity) {
Relationship data = (Relationship) next
return entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), data, initializedAssociations, initializedNodes)
- }
- else {
+ } else {
throw new QueryException("Query must return a node as the first column of the RETURN statement")
}
- }
- else {
+ } else {
Record record = (Record) next
if (record.containsKey(CypherBuilder.NODE_DATA)) {
Node data = (Node) record.get(CypherBuilder.NODE_DATA).asNode()
return entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), data, record.asMap(), initializedAssociations, lockMode)
- }
- else if(record.containsKey(CypherBuilder.REL_DATA)) {
+ } else if (record.containsKey(CypherBuilder.REL_DATA)) {
PersistentEntity persistentEntity = entityPersister.getPersistentEntity()
- if(persistentEntity instanceof RelationshipPersistentEntity) {
+ if (persistentEntity instanceof RelationshipPersistentEntity) {
def recordMap = record.asMap()
- RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity)persistentEntity
+ RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) persistentEntity
Relationship data = (Relationship) record.get(CypherBuilder.REL_DATA).asRelationship()
this.initializedAssociations = new LinkedHashMap<>(initializedAssociations)
- if(record.containsKey(RelationshipPersistentEntity.FROM)) {
+ if (record.containsKey(RelationshipPersistentEntity.FROM)) {
Association fromAssociation = relEntity.getFrom()
PersistentEntity fromEntity = fromAssociation.getAssociatedEntity()
Neo4jEntityPersister fromPersister = entityPersister.getSession().getEntityPersister(fromEntity)
this.initializedAssociations.put(fromAssociation,
- fromPersister.unmarshallOrFromCache( fromEntity, record.get(RelationshipPersistentEntity.FROM).asNode(),recordMap, initializedAssociations)
+ fromPersister.unmarshallOrFromCache(fromEntity, record.get(RelationshipPersistentEntity.FROM).asNode(), recordMap, initializedAssociations)
)
}
- if(record.containsKey(RelationshipPersistentEntity.TO)) {
+ if (record.containsKey(RelationshipPersistentEntity.TO)) {
Association toAssociation = relEntity.getTo()
PersistentEntity toEntity = toAssociation.getAssociatedEntity()
Neo4jEntityPersister fromPersister = entityPersister.getSession().getEntityPersister(toEntity)
this.initializedAssociations.put(toAssociation,
- fromPersister.unmarshallOrFromCache( toEntity, record.get(RelationshipPersistentEntity.TO).asNode() ,recordMap, initializedAssociations)
+ fromPersister.unmarshallOrFromCache(toEntity, record.get(RelationshipPersistentEntity.TO).asNode(), recordMap, initializedAssociations)
)
}
return entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), data, initializedAssociations, initializedNodes)
- }
- else {
+ } else {
throw new QueryException("Query must return a node as the first column of the RETURN statement")
}
- }
- else {
+ } else {
- Node node = record.values().find() { Value v ->
+ Node node = record.values().find() { Value v ->
v.type() == entityPersister.getSession().boltDriver.defaultTypeSystem().NODE()
}?.asNode()
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSet.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSet.groovy
index e46852abcb..d1bb0116ea 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSet.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSet.groovy
@@ -19,11 +19,13 @@
package org.grails.datastore.gorm.neo4j.collection
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.Neo4jSession
import org.grails.datastore.mapping.dirty.checking.DirtyCheckable
import org.grails.datastore.mapping.dirty.checking.DirtyCheckingSet
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.model.types.Association
+
/**
* A {@link DirtyCheckingSet} for Neo4j
*
@@ -32,13 +34,15 @@ import org.grails.datastore.mapping.model.types.Association
*/
@CompileStatic
class Neo4jSet extends DirtyCheckingSet {
+
final transient Association association
final transient Neo4jSession session
- protected final transient @Delegate GraphAdapter graphAdapter
+ protected final transient @Delegate
+ GraphAdapter graphAdapter
Neo4jSet(EntityAccess parentAccess, Association association, Set delegate, Neo4jSession session) {
- super(delegate, (DirtyCheckable)parentAccess.getEntity(), association.getName())
+ super(delegate, (DirtyCheckable) parentAccess.getEntity(), association.getName())
this.association = association
this.session = session
this.graphAdapter = new GraphAdapter(session, parentAccess, association)
@@ -48,7 +52,7 @@ class Neo4jSet extends DirtyCheckingSet {
boolean add(Object o) {
def added = super.add(o)
- if(added) {
+ if (added) {
adaptGraphUponAdd(o)
}
return added
@@ -57,8 +61,8 @@ class Neo4jSet extends DirtyCheckingSet {
@Override
boolean addAll(Collection c) {
def added = super.addAll(c)
- if(added) {
- for( o in c ) {
+ if (added) {
+ for (o in c) {
adaptGraphUponAdd(o)
}
}
@@ -69,8 +73,8 @@ class Neo4jSet extends DirtyCheckingSet {
@Override
boolean removeAll(Collection c) {
def removed = super.removeAll(c)
- if(removed) {
- for(o in c) {
+ if (removed) {
+ for (o in c) {
adaptGraphUponRemove(o)
}
}
@@ -80,7 +84,7 @@ class Neo4jSet extends DirtyCheckingSet {
@Override
boolean remove(Object o) {
def removed = super.remove(o)
- if(removed) {
+ if (removed) {
adaptGraphUponRemove(o)
}
return removed
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSortedSet.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSortedSet.groovy
index c52dccd117..c0a6b79c17 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSortedSet.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/collection/Neo4jSortedSet.groovy
@@ -32,13 +32,15 @@ import org.grails.datastore.mapping.model.types.Association
* @since 5.0
*/
class Neo4jSortedSet extends DirtyCheckingSortedSet {
+
final transient Association association
final transient Neo4jSession session
- protected final transient @Delegate GraphAdapter graphAdapter
+ protected final transient @Delegate
+ GraphAdapter graphAdapter
Neo4jSortedSet(EntityAccess parentAccess, Association association, SortedSet delegate, Neo4jSession session) {
- super(delegate, (DirtyCheckable)parentAccess.getEntity(), association.getName())
+ super(delegate, (DirtyCheckable) parentAccess.getEntity(), association.getName())
this.association = association
this.session = session
this.graphAdapter = new GraphAdapter(session, parentAccess, association)
@@ -48,7 +50,7 @@ class Neo4jSortedSet extends DirtyCheckingSortedSet {
boolean add(Object o) {
def added = super.add(o)
- if(added) {
+ if (added) {
adaptGraphUponAdd(o)
}
return added
@@ -57,8 +59,8 @@ class Neo4jSortedSet extends DirtyCheckingSortedSet {
@Override
boolean addAll(Collection c) {
def added = super.addAll(c)
- if(added) {
- for( o in c ) {
+ if (added) {
+ for (o in c) {
adaptGraphUponAdd(o)
}
}
@@ -69,8 +71,8 @@ class Neo4jSortedSet extends DirtyCheckingSortedSet {
@Override
boolean removeAll(Collection c) {
def removed = super.removeAll(c)
- if(removed) {
- for(o in c) {
+ if (removed) {
+ for (o in c) {
adaptGraphUponRemove(o)
}
}
@@ -80,7 +82,7 @@ class Neo4jSortedSet extends DirtyCheckingSortedSet {
@Override
boolean remove(Object o) {
def removed = super.remove(o)
- if(removed) {
+ if (removed) {
adaptGraphUponRemove(o)
}
return removed
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Neo4jDriverConfigBuilder.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Neo4jDriverConfigBuilder.groovy
index 813cf99dee..ecf909edfc 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Neo4jDriverConfigBuilder.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Neo4jDriverConfigBuilder.groovy
@@ -18,15 +18,18 @@
*/
package org.grails.datastore.gorm.neo4j.config
+import java.lang.reflect.Method
+import java.lang.reflect.Modifier
+
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
-import org.grails.datastore.mapping.config.ConfigurationBuilder
+
import org.neo4j.driver.Config
+
import org.springframework.core.env.PropertyResolver
import org.springframework.util.ReflectionUtils
-import java.lang.reflect.Method
-import java.lang.reflect.Modifier
+import org.grails.datastore.mapping.config.ConfigurationBuilder
/**
* Constructs the Neo4j driver configuration
@@ -62,13 +65,12 @@ class Neo4jDriverConfigBuilder extends ConfigurationBuilder<Config.ConfigBuilder
@Override
protected Object getFallBackValue(Object fallBackConfig, String methodName) {
- if(fallBackConfig != null) {
+ if (fallBackConfig != null) {
Method fallBackMethod = ReflectionUtils.findMethod(fallBackConfig.getClass(), methodName)
- if(fallBackMethod != null && Modifier.isPublic(fallBackMethod.getModifiers())) {
+ if (fallBackMethod != null && Modifier.isPublic(fallBackMethod.getModifiers())) {
return fallBackMethod.invoke(fallBackConfig)
- }
- else {
+ } else {
return super.getFallBackValue(fallBackConfig, methodName)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Settings.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Settings.java
index 287cf51e48..0a0a93bfa2 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Settings.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/config/Settings.java
@@ -25,6 +25,7 @@ package org.grails.datastore.gorm.neo4j.config;
* @since 6.0
*/
public interface Settings extends org.grails.datastore.mapping.config.Settings {
+
/**
* The default configuration prefix
*/
@@ -57,7 +58,7 @@ public interface Settings extends org.grails.datastore.mapping.config.Settings {
/**
* The Neo4j embedded data location
*/
- String SETTING_NEO4J_LOCATION = PREFIX+ ".location";
+ String SETTING_NEO4J_LOCATION = PREFIX + ".location";
/**
* The connection type (either embedded or remote)
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceFactory.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceFactory.java
index 833e254085..5b203b2ef7 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceFactory.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceFactory.java
@@ -18,26 +18,32 @@
*/
package org.grails.datastore.gorm.neo4j.connections;
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+
import groovy.transform.CompileStatic;
import groovy.util.logging.Slf4j;
-import org.grails.datastore.gorm.neo4j.config.Settings;
-import org.grails.datastore.gorm.neo4j.util.EmbeddedNeo4jServer;
-import org.grails.datastore.mapping.core.connections.*;
-import org.grails.datastore.mapping.model.DatastoreConfigurationException;
-import org.grails.datastore.mapping.reflect.ClassUtils;
+
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Config;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.harness.ServerControls;
+
import org.springframework.core.env.PropertyResolver;
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.net.URI;
-import java.util.Map;
+import org.grails.datastore.gorm.neo4j.config.Settings;
+import org.grails.datastore.gorm.neo4j.util.EmbeddedNeo4jServer;
+import org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory;
+import org.grails.datastore.mapping.core.connections.ConnectionSource;
+import org.grails.datastore.mapping.core.connections.ConnectionSourceSettings;
+import org.grails.datastore.mapping.core.connections.DefaultConnectionSource;
+import org.grails.datastore.mapping.model.DatastoreConfigurationException;
+import org.grails.datastore.mapping.reflect.ClassUtils;
/**
* A {@link org.grails.datastore.mapping.core.connections.ConnectionSourceFactory} for Neo4j
@@ -49,9 +55,16 @@ import java.util.Map;
@Slf4j
public class Neo4jConnectionSourceFactory extends AbstractConnectionSourceFactory<Driver, Neo4jConnectionSourceSettings> {
+ /**
+ * @return Whether the embedded server capability is available or not
+ */
+ public static boolean isEmbeddedAvailable() {
+ return ClassUtils.isPresent("org.neo4j.harness.ServerControls", Neo4jConnectionSourceFactory.class.getClassLoader());
+ }
+
@Override
protected <F extends ConnectionSourceSettings> Neo4jConnectionSourceSettings buildSettings(String name, PropertyResolver configuration, F fallbackSettings, boolean isDefaultDataSource) {
- String prefix = isDefaultDataSource? Settings.PREFIX : Settings.SETTING_CONNECTIONS + "." + name;
+ String prefix = isDefaultDataSource ? Settings.PREFIX : Settings.SETTING_CONNECTIONS + "." + name;
Neo4jConnectionSourceSettingsBuilder settingsBuilder = new Neo4jConnectionSourceSettingsBuilder(configuration, prefix, fallbackSettings);
Neo4jConnectionSourceSettings settings = settingsBuilder.build();
return settings;
@@ -63,29 +76,27 @@ public class Neo4jConnectionSourceFactory extends AbstractConnectionSourceFactor
final String username = settings.getUsername();
final String password = settings.getPassword();
final Neo4jConnectionSourceSettings.ConnectionType type = settings.getType();
- if(type == Neo4jConnectionSourceSettings.ConnectionType.embedded && ConnectionSource.DEFAULT.equals(name)) {
- if(isEmbeddedAvailable()) {
+ if (type == Neo4jConnectionSourceSettings.ConnectionType.embedded && ConnectionSource.DEFAULT.equals(name)) {
+ if (isEmbeddedAvailable()) {
Neo4jConnectionSourceSettings.EmbeddedSettings embeddedSettings = settings.getEmbedded();
final String location = settings.getLocation() != null ? settings.getLocation() : embeddedSettings.getDirectory();
final Map options = embeddedSettings.getOptions();
final File dataDir;
try {
- if(location != null) {
+ if (location != null) {
dataDir = new File(location);
- }
- else if(embeddedSettings.isEphemeral()) {
+ } else if (embeddedSettings.isEphemeral()) {
dataDir = File.createTempFile("neo4j-temporary-data", "-tempdir");
- }
- else {
+ } else {
dataDir = new File(Settings.DEFAULT_LOCATION);
}
} catch (IOException e) {
throw new DatastoreConfigurationException("Unable to create temporary data directory: " + e.getMessage(), e);
}
- if(embeddedSettings.isDropData() || embeddedSettings.isEphemeral()) {
+ if (embeddedSettings.isDropData() || embeddedSettings.isEphemeral()) {
dataDir.delete();
}
- if(embeddedSettings.isEphemeral()) {
+ if (embeddedSettings.isEphemeral()) {
dataDir.deleteOnExit();
}
ServerControls serverControls;
@@ -93,24 +104,22 @@ public class Neo4jConnectionSourceFactory extends AbstractConnectionSourceFactor
serverControls = url != null ? EmbeddedNeo4jServer.start(url, dataDir, options) : EmbeddedNeo4jServer.start(dataDir, options);
Config config = Config.builder().withoutEncryption().build();
URI boltURI = serverControls.boltURI();
- Driver driver = GraphDatabase.driver(boltURI, config);
+ Driver driver = GraphDatabase.driver(boltURI, config);
return new Neo4jEmbeddedConnectionSource(name, driver, settings, serverControls);
} catch (Throwable e) {
throw new DatastoreConfigurationException("Unable to start embedded Neo4j server: " + e.getMessage(), e);
}
- }
- else {
+ } else {
throw new DatastoreConfigurationException("Embedded Neo4j server was configured but 'neo4j-harness' classes not found on classpath.");
}
}
AuthToken authToken = null;
- if(username != null && password != null) {
+ if (username != null && password != null) {
authToken = AuthTokens.basic(username, password);
}
-
Config driverConfig = settings.getOptions().build();
Driver driver = GraphDatabase.driver(url != null ? url : Settings.DEFAULT_URL, authToken, driverConfig);
return new DefaultConnectionSource<>(name, driver, settings);
@@ -121,11 +130,4 @@ public class Neo4jConnectionSourceFactory extends AbstractConnectionSourceFactor
return Settings.SETTING_CONNECTIONS;
}
- /**
- * @return Whether the embedded server capability is available or not
- */
- public static boolean isEmbeddedAvailable() {
- return ClassUtils.isPresent("org.neo4j.harness.ServerControls", Neo4jConnectionSourceFactory.class.getClassLoader());
- }
-
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettings.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettings.groovy
index b34f63096f..a481ac1acc 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettings.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettings.groovy
@@ -21,6 +21,7 @@ package org.grails.datastore.gorm.neo4j.connections
import groovy.transform.AutoClone
import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy
+
import org.grails.datastore.gorm.neo4j.config.Neo4jDriverConfigBuilder
import org.grails.datastore.gorm.neo4j.config.Settings
import org.grails.datastore.mapping.core.connections.ConnectionSourceSettings
@@ -99,6 +100,7 @@ class Neo4jConnectionSourceSettings extends ConnectionSourceSettings implements
}
static enum ConnectionType {
+
remote, embedded
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettingsBuilder.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettingsBuilder.groovy
index 8f339f12ce..432040f63f 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettingsBuilder.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jConnectionSourceSettingsBuilder.groovy
@@ -19,10 +19,12 @@
package org.grails.datastore.gorm.neo4j.connections
import groovy.transform.CompileStatic
+
+import org.springframework.core.env.PropertyResolver
+
import org.grails.datastore.gorm.neo4j.config.Settings
import org.grails.datastore.mapping.config.ConfigurationBuilder
import org.grails.datastore.mapping.core.connections.ConnectionSourceSettings
-import org.springframework.core.env.PropertyResolver
/**
* A builder for creating {@link Neo4jConnectionSourceSettings} objects
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jEmbeddedConnectionSource.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jEmbeddedConnectionSource.java
index b6b9a509bb..b976ba49e3 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jEmbeddedConnectionSource.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/connections/Neo4jEmbeddedConnectionSource.java
@@ -18,11 +18,12 @@
*/
package org.grails.datastore.gorm.neo4j.connections;
-import org.grails.datastore.mapping.core.connections.DefaultConnectionSource;
+import java.io.IOException;
+
import org.neo4j.driver.Driver;
import org.neo4j.harness.ServerControls;
-import java.io.IOException;
+import org.grails.datastore.mapping.core.connections.DefaultConnectionSource;
/**
* A {@link org.grails.datastore.mapping.core.connections.ConnectionSource} for embedded Neo4j
@@ -31,6 +32,7 @@ import java.io.IOException;
* @since 6.0
*/
public class Neo4jEmbeddedConnectionSource extends DefaultConnectionSource<Driver, Neo4jConnectionSourceSettings> {
+
protected final ServerControls serverControls;
Neo4jEmbeddedConnectionSource(String name, Driver source, Neo4jConnectionSourceSettings settings, ServerControls serverControls) {
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java
index 24695931ed..ef02d1a2f2 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java
@@ -18,6 +18,21 @@
*/
package org.grails.datastore.gorm.neo4j.engine;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.neo4j.driver.QueryRunner;
+import org.neo4j.driver.Record;
+import org.neo4j.driver.Result;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.grails.datastore.gorm.neo4j.GraphPersistentEntity;
import org.grails.datastore.gorm.neo4j.Neo4jMappingContext;
import org.grails.datastore.gorm.neo4j.Neo4jSession;
@@ -28,16 +43,7 @@ import org.grails.datastore.gorm.neo4j.mapping.reflect.Neo4jNameUtils;
import org.grails.datastore.gorm.neo4j.util.IteratorUtil;
import org.grails.datastore.gorm.schemaless.DynamicAttributes;
import org.grails.datastore.mapping.engine.EntityAccess;
-import org.grails.datastore.mapping.engine.NonPersistentTypeException;
import org.grails.datastore.mapping.model.config.GormProperties;
-import org.neo4j.driver.Record;
-import org.neo4j.driver.Result;
-import org.neo4j.driver.QueryRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.util.*;
/**
* Support class for dynamic associations
@@ -49,32 +55,32 @@ public class DynamicAssociationSupport {
private static final Logger log = LoggerFactory.getLogger(DynamicAssociationSupport.class);
- public static Map<TypeDirectionPair, Map<String, Object>> loadDynamicAssociations(Neo4jSession session, GraphPersistentEntity graphPersistentEntity, DynamicAttributes object, Serializable id) {
+ public static Map<TypeDirectionPair, Map<String, Object>> loadDynamicAssociations(Neo4jSession session, GraphPersistentEntity graphPersistentEntity, DynamicAttributes object, Serializable id) {
Map<TypeDirectionPair, Map<String, Object>> relationshipsMap = new HashMap<>();
final boolean hasDynamicAssociations = graphPersistentEntity.hasDynamicAssociations();
Object alreadyLoaded = session.getAttribute(object, Neo4jEntityPersister.DYNAMIC_ASSOCIATION_PARAM);
- if(alreadyLoaded == null && hasDynamicAssociations) {
+ if (alreadyLoaded == null && hasDynamicAssociations) {
session.setAttribute(object, Neo4jEntityPersister.DYNAMIC_ASSOCIATION_PARAM, Boolean.TRUE);
final String cypher = graphPersistentEntity.formatDynamicAssociationQuery();
- final Map<String, Object> isMap = Collections.<String, Object>singletonMap(GormProperties.IDENTITY, id);
+ final Map<String, Object> isMap = Collections.singletonMap(GormProperties.IDENTITY, id);
final QueryRunner boltSession = session.hasTransaction() ? session.getTransaction().getNativeTransaction() : session.getNativeInterface();
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("QUERY Cypher [{}] for parameters [{}]", cypher, isMap);
}
final Result relationships = boltSession.run(cypher, isMap);
- while(relationships.hasNext()) {
+ while (relationships.hasNext()) {
final Record row = relationships.next();
String relType = row.get("relType").asString();
Boolean outGoing = row.get("out").asBoolean();
Map<String, Object> values = row.get("values").asMap();
TypeDirectionPair key = new TypeDirectionPair(relType, outGoing);
- if(row.containsKey(RelationshipPendingInsert.TARGET_TYPE) && !row.get(RelationshipPendingInsert.TARGET_TYPE).isNull()) {
+ if (row.containsKey(RelationshipPendingInsert.TARGET_TYPE) && !row.get(RelationshipPendingInsert.TARGET_TYPE).isNull()) {
key.setTargetType(
- row.get(RelationshipPendingInsert.TARGET_TYPE).asString()
+ row.get(RelationshipPendingInsert.TARGET_TYPE).asString()
);
relationshipsMap.put(key, values);
}
@@ -82,14 +88,14 @@ public class DynamicAssociationSupport {
// if the relationship map is not empty as this point there are dynamic relationships that need to be loaded as undeclared
if (!relationshipsMap.isEmpty()) {
Neo4jMappingContext mappingContext = session.getMappingContext();
- for (Map.Entry<TypeDirectionPair, Map<String,Object>> entry: relationshipsMap.entrySet()) {
+ for (Map.Entry<TypeDirectionPair, Map<String, Object>> entry : relationshipsMap.entrySet()) {
EntityAccess entityAccess = session.createEntityAccess(graphPersistentEntity, object);
TypeDirectionPair key = entry.getKey();
if (key.isOutgoing()) {
Map<String, Object> relationshipData = entry.getValue();
Object idsObject = relationshipData.get("ids");
Object labelsObject = relationshipData.get("labels");
- if((idsObject instanceof Iterable) && (labelsObject instanceof Iterable)) {
+ if ((idsObject instanceof Iterable) && (labelsObject instanceof Iterable)) {
Iterator<Serializable> idIter = ((Iterable<Serializable>) idsObject).iterator();
String targetType = key.getTargetType();
@@ -102,25 +108,24 @@ public class DynamicAssociationSupport {
Collection<String> nextLabels = labelIter.next();
Collection<String> labels = nextLabels.isEmpty() ? Collections.singletonList(targetType) : nextLabels;
associatedEntity = mappingContext.findPersistentEntityForLabels(labels);
- if(associatedEntity == null) {
+ if (associatedEntity == null) {
associatedEntity = mappingContext.findPersistentEntityForLabels(Collections.singletonList(targetType));
}
- if(associatedEntity == null) {
+ if (associatedEntity == null) {
continue;
}
Object proxy = mappingContext.getProxyFactory().createProxy(
- session,
- associatedEntity.getJavaClass(),
- targetId
+ session,
+ associatedEntity.getJavaClass(),
+ targetId
);
values.add(proxy);
}
// for single instances and singular property name do not use an array
Object value;
- if(values.size() == 1 && isSingular(key.getType())) {
+ if (values.size() == 1 && isSingular(key.getType())) {
value = IteratorUtil.singleOrNull(values);
- }
- else {
+ } else {
DynamicToManyAssociation dynamicAssociation = new DynamicToManyAssociation(graphPersistentEntity, graphPersistentEntity.getMappingContext(), key.getType(), associatedEntity);
value = new Neo4jList(entityAccess, dynamicAssociation, values, session);
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jAssociationQueryExecutor.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jAssociationQueryExecutor.groovy
index 455b0bf564..3d6158aef5 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jAssociationQueryExecutor.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jAssociationQueryExecutor.groovy
@@ -20,6 +20,11 @@ package org.grails.datastore.gorm.neo4j.engine
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
+
+import org.neo4j.driver.QueryRunner
+import org.neo4j.driver.Result
+import org.neo4j.driver.Session
+
import org.grails.datastore.gorm.neo4j.CypherBuilder
import org.grails.datastore.gorm.neo4j.GraphPersistentEntity
import org.grails.datastore.gorm.neo4j.Neo4jSession
@@ -35,12 +40,6 @@ import org.grails.datastore.mapping.model.types.Basic
import org.grails.datastore.mapping.model.types.ManyToOne
import org.grails.datastore.mapping.model.types.ToMany
import org.grails.datastore.mapping.model.types.ToOne
-import org.neo4j.driver.Session
-import org.neo4j.driver.Result
-import org.neo4j.driver.QueryRunner
-
-import jakarta.persistence.FetchType
-
/**
* Responsible for lazy loading associations
@@ -61,13 +60,12 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
Neo4jAssociationQueryExecutor(Neo4jSession session, Association association, boolean lazy = (association.mapping.mappedForm as Property).isLazy(), boolean singleResult = false) {
this.session = session
PersistentEntity associatedEntity = association.associatedEntity
- if(associatedEntity != null) {
+ if (associatedEntity != null) {
this.indexedEntity = associatedEntity
+ } else if (association instanceof Basic) {
+ this.indexedEntity = session.mappingContext.getPersistentEntity(((Basic) association).componentType.name)
}
- else if(association instanceof Basic) {
- this.indexedEntity = session.mappingContext.getPersistentEntity(((Basic)association).componentType.name)
- }
- if(this.indexedEntity == null) {
+ if (this.indexedEntity == null) {
throw new IllegalStateException("Cannot create association query loader for ${association}. No mapped associated entity could be located.")
}
this.association = association
@@ -83,29 +81,27 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
@Override
List<Object> query(Serializable primaryKey) {
- QueryRunner statementRunner = session.hasTransaction() ? session.getTransaction().getNativeTransaction() : (Session)session.nativeInterface
+ QueryRunner statementRunner = session.hasTransaction() ? session.getTransaction().getNativeTransaction() : (Session) session.nativeInterface
String relType
- GraphPersistentEntity parent = (GraphPersistentEntity)association.owner
- GraphPersistentEntity related = (GraphPersistentEntity)indexedEntity
+ GraphPersistentEntity parent = (GraphPersistentEntity) association.owner
+ GraphPersistentEntity related = (GraphPersistentEntity) indexedEntity
boolean isRelationship = related.isRelationshipEntity()
- if(isRelationship) {
- RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity)related
+ if (isRelationship) {
+ RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) related
GraphPersistentEntity fromEntity = (GraphPersistentEntity) relEntity.getFrom().getAssociatedEntity()
GraphPersistentEntity toEntity = (GraphPersistentEntity) relEntity.getTo().getAssociatedEntity()
- if(parent == fromEntity) {
+ if (parent == fromEntity) {
relType = "-[rel]->"
related = toEntity
- }
- else {
+ } else {
relType = "<-[rel]-"
parent = toEntity
related = fromEntity
}
- }
- else {
+ } else {
relType = RelationshipUtils.matchForAssociation(association)
}
@@ -113,20 +109,19 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
StringBuilder cypher = new StringBuilder(CypherBuilder.buildRelationshipMatch(parent.labelsAsString, relType, related.labelsAsString))
cypher.append('( ')
- .append(parent.formatId(RelationshipPersistentEntity.FROM))
- .append(" = \$id )")
+ .append(parent.formatId(RelationshipPersistentEntity.FROM))
+ .append(" = \$id )")
boolean isLazyToMany = lazy && !isRelationship && association instanceof ToMany
- if(isLazyToMany) {
+ if (isLazyToMany) {
cypher.append(related.formatId(RelationshipPersistentEntity.TO))
- .append("RETURN as id")
- }
- else {
- if(!isRelationship) {
+ .append("RETURN as id")
+ } else {
+ if (!isRelationship) {
StringBuilder returnString = new StringBuilder("\nRETURN to as data")
- Set<Association> associations = new TreeSet<Association>((Comparator<Association>){ Association a1, Association a2 -> a1.name <=> a2.name })
+ Set<Association> associations = new TreeSet<Association>((Comparator<Association>) { Association a1, Association a2 -> a1.name <=> a2.name })
PersistentEntity entity = association.associatedEntity
if (entity) {
Collection<PersistentEntity> childEntities = entity.mappingContext.getChildEntities(entity)
@@ -137,32 +132,31 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
}
associations.addAll(entity.associations)
- if(associations.size() > 0) {
+ if (associations.size() > 0) {
int i = 0
List previousAssociations = []
- for(Association association in associations) {
- if(association.isBasic()) continue
+ for (Association association in associations) {
+ if (association.isBasic()) continue
boolean isEager = ((Property) association.mapping.mappedForm).isLazy()
String r = "r${i++}"
String associationName = association.name
- GraphPersistentEntity associatedGraphEntity = (GraphPersistentEntity)association.associatedEntity
+ GraphPersistentEntity associatedGraphEntity = (GraphPersistentEntity) association.associatedEntity
boolean isAssociationRelationshipEntity = associatedGraphEntity.isRelationshipEntity()
boolean isToMany = association instanceof ToMany
boolean isToOne = association instanceof ToOne
- boolean lazy = false
- if(isToOne && !isEager) {
+ boolean lazy = false
+ if (isToOne && !isEager) {
Property propertyMapping = association.mapping.mappedForm
Boolean isLazy = propertyMapping.getLazy()
lazy = (isLazy != null ? isLazy : (association instanceof ManyToOne ? !association.isCircular() : true))
- }
- else if(isToMany) {
- lazy = ((ToMany)association).lazy
+ } else if (isToMany) {
+ lazy = ((ToMany) association).lazy
}
// if there are associations, add a join to get them
@@ -178,16 +172,15 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
// A mandatory, lazy to-one (e.g. a required hasOne) must still have its id
// collected here - see the matching comment in Neo4jQuery.executeQuery()
// for why omitting it corrupts <property>Id lookups.
- if((isToMany && lazy) || (isToOne && !isEager)) {
+ if ((isToMany && lazy) || (isToOne && !isEager)) {
withMatch += "collect(DISTINCT ${associatedGraphEntity.formatId(associationNodeRef)}) as ${associationIdsRef}"
returnString.append(", ").append(associationIdsRef)
previousAssociations << associationIdsRef
addOptionalMatch = true
- }
- else if(isEager) {
+ } else if (isEager) {
withMatch += "collect(DISTINCT $associationNodeRef) as $associationNodesRef"
returnString.append(", ").append(associationNodesRef)
- if(isAssociationRelationshipEntity) {
+ if (isAssociationRelationshipEntity) {
withMatch += ", collect($r) as ${associationName}Rels"
returnString.append(", ").append("${associationName}Rels")
}
@@ -195,15 +188,15 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
addOptionalMatch = true
}
- if(addOptionalMatch) {
+ if (addOptionalMatch) {
String relationshipPattern = related
.formatAssociationPatternFromExisting(
- association,
- r,
- "to",
- associationNodeRef
- )
+ association,
+ r,
+ "to",
+ associationNodeRef
+ )
cypher.append(CypherBuilder.NEW_LINE)
.append(CypherBuilder.OPTIONAL_MATCH)
@@ -217,8 +210,7 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
}
cypher.append(returnString.toString())
- }
- else {
+ } else {
cypher.append('RETURN rel as rel')
}
}
@@ -231,22 +223,21 @@ class Neo4jAssociationQueryExecutor implements AssociationQueryExecutor<Serializ
log.debug("QUERY Cypher [$cypher] for params [$params]")
Result result = statementRunner.run(cypher.toString(), params)
- if(isLazyToMany) {
+ if (isLazyToMany) {
List<Object> results = []
- while(result.hasNext()) {
+ while (result.hasNext()) {
def id = result.next().get(GormProperties.IDENTITY).asObject()
- results.add( session.proxy(related.javaClass, id as Serializable) )
+ results.add(session.proxy(related.javaClass, id as Serializable))
}
return results
- }
- else {
+ } else {
def resultList = new Neo4jResultList(0, result, isRelationship ? session.getEntityPersister(indexedEntity) : session.getEntityPersister(related))
- if(association.isBidirectional()) {
+ if (association.isBidirectional()) {
def inverseSide = association.inverseSide
- if(inverseSide instanceof ToOne) {
+ if (inverseSide instanceof ToOne) {
def parentObject = session.getCachedInstance(association.getOwner().getJavaClass(), primaryKey)
- if(parentObject != null) {
- resultList.setInitializedAssociations(Collections.<Association,Object>singletonMap(inverseSide, parentObject))
+ if (parentObject != null) {
+ resultList.setInitializedAssociations(Collections.<Association, Object> singletonMap(inverseSide, parentObject))
}
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jEntityPersister.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jEntityPersister.java
index 1b30bd0938..299d39168b 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jEntityPersister.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jEntityPersister.java
@@ -18,18 +18,68 @@
*/
package org.grails.datastore.gorm.neo4j.engine;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
import groovy.lang.GroovyObject;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+
+import jakarta.persistence.FetchType;
+import jakarta.persistence.LockModeType;
+
+import org.neo4j.driver.QueryRunner;
+import org.neo4j.driver.Record;
+import org.neo4j.driver.Result;
+import org.neo4j.driver.summary.ResultSummary;
+import org.neo4j.driver.summary.SummaryCounters;
+import org.neo4j.driver.types.Entity;
+import org.neo4j.driver.types.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.util.Assert;
+
import org.grails.datastore.gorm.GormEntity;
-import org.grails.datastore.gorm.neo4j.*;
-import org.grails.datastore.gorm.neo4j.collection.*;
+import org.grails.datastore.gorm.neo4j.CypherBuilder;
+import org.grails.datastore.gorm.neo4j.GraphPersistentEntity;
+import org.grails.datastore.gorm.neo4j.IdGenerator;
+import org.grails.datastore.gorm.neo4j.Neo4jMappingContext;
+import org.grails.datastore.gorm.neo4j.Neo4jSession;
+import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity;
+import org.grails.datastore.gorm.neo4j.RelationshipUtils;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jList;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jPersistentList;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jPersistentSet;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jPersistentSortedSet;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jResultList;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jSet;
+import org.grails.datastore.gorm.neo4j.collection.Neo4jSortedSet;
import org.grails.datastore.gorm.neo4j.mapping.config.DynamicToOneAssociation;
import org.grails.datastore.gorm.neo4j.util.IteratorUtil;
import org.grails.datastore.gorm.schemaless.DynamicAttributes;
import org.grails.datastore.mapping.collection.PersistentCollection;
import org.grails.datastore.mapping.core.IdentityGenerationException;
import org.grails.datastore.mapping.core.Session;
-import org.grails.datastore.mapping.core.impl.*;
+import org.grails.datastore.mapping.core.impl.PendingDeleteAdapter;
+import org.grails.datastore.mapping.core.impl.PendingInsertAdapter;
+import org.grails.datastore.mapping.core.impl.PendingOperation;
+import org.grails.datastore.mapping.core.impl.PendingOperationAdapter;
+import org.grails.datastore.mapping.core.impl.PendingUpdateAdapter;
import org.grails.datastore.mapping.dirty.checking.DirtyCheckable;
import org.grails.datastore.mapping.dirty.checking.DirtyCheckableCollection;
import org.grails.datastore.mapping.engine.EntityAccess;
@@ -37,31 +87,24 @@ import org.grails.datastore.mapping.engine.EntityPersister;
import org.grails.datastore.mapping.model.MappingContext;
import org.grails.datastore.mapping.model.PersistentEntity;
import org.grails.datastore.mapping.model.PersistentProperty;
-import org.grails.datastore.mapping.model.config.GormMappingConfigurationStrategy;
import org.grails.datastore.mapping.model.config.GormProperties;
-import org.grails.datastore.mapping.model.types.*;
+import org.grails.datastore.mapping.model.types.Association;
+import org.grails.datastore.mapping.model.types.Basic;
+import org.grails.datastore.mapping.model.types.ManyToMany;
+import org.grails.datastore.mapping.model.types.OneToMany;
+import org.grails.datastore.mapping.model.types.OneToOne;
+import org.grails.datastore.mapping.model.types.Simple;
+import org.grails.datastore.mapping.model.types.TenantId;
+import org.grails.datastore.mapping.model.types.ToMany;
+import org.grails.datastore.mapping.model.types.ToOne;
import org.grails.datastore.mapping.proxy.EntityProxy;
import org.grails.datastore.mapping.query.Query;
import org.grails.datastore.mapping.reflect.EntityReflector;
-import org.neo4j.driver.Record;
-import org.neo4j.driver.Result;
-import org.neo4j.driver.QueryRunner;
-import org.neo4j.driver.summary.ResultSummary;
-import org.neo4j.driver.summary.SummaryCounters;
-import org.neo4j.driver.types.Entity;
-import org.neo4j.driver.types.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.util.Assert;
-
-import jakarta.persistence.FetchType;
-import jakarta.persistence.LockModeType;
-import java.io.Serializable;
-import java.util.*;
-import static org.grails.datastore.mapping.query.Query.*;
+import static org.grails.datastore.mapping.query.Query.Conjunction;
+import static org.grails.datastore.mapping.query.Query.Criterion;
+import static org.grails.datastore.mapping.query.Query.In;
+import static org.grails.datastore.mapping.query.Query.Junction;
/**
* Core {@link EntityPersister} implementation responsible for CRUD operations against the Graph.
@@ -72,16 +115,23 @@ import static org.grails.datastore.mapping.query.Query.*;
*/
public class Neo4jEntityPersister extends EntityPersister {
-
public static final String DYNAMIC_ASSOCIATION_PARAM = "org.grails.neo4j.DYNAMIC_ASSOCIATIONS";
- private static Logger log = LoggerFactory.getLogger(Neo4jEntityPersister.class);
-
+ private static final Logger log = LoggerFactory.getLogger(Neo4jEntityPersister.class);
public Neo4jEntityPersister(MappingContext mappingContext, PersistentEntity entity, Session session, ApplicationEventPublisher publisher) {
super(mappingContext, entity, session, publisher);
}
+ public static long countUpdates(Result execute) {
+ ResultSummary resultSummary = execute.consume();
+ SummaryCounters counters = resultSummary.counters();
+ if (counters.containsUpdates()) {
+ return counters.nodesCreated() + counters.nodesDeleted() + counters.propertiesSet() + counters.relationshipsCreated() + counters.relationshipsDeleted();
+ } else {
+ return 0;
+ }
+ }
@Override
public Neo4jSession getSession() {
@@ -107,23 +157,22 @@ public class Neo4jEntityPersister extends EntityPersister {
GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) pe;
List<Serializable> idList = new ArrayList<>();
- if(graphPersistentEntity.hasDynamicAssociations()) {
+ if (graphPersistentEntity.hasDynamicAssociations()) {
// dynamic association entities cannot be batch inserted
for (Object obj : objs) {
Serializable id = persistEntity(pe, obj);
- if(id != null) {
+ if (id != null) {
idList.add(id);
}
}
- }
- else if(graphPersistentEntity.isNativeId() && !graphPersistentEntity.isRelationshipEntity()) {
+ } else if (graphPersistentEntity.isNativeId() && !graphPersistentEntity.isRelationshipEntity()) {
List<EntityAccess> entityAccesses = new ArrayList<>();
// optimize batch inserts for multiple entities with native id
final Neo4jSession session = getSession();
StringBuilder createCypher = new StringBuilder(CypherBuilder.CYPHER_CREATE);
int listIndex = 0;
- List<PendingOperation<Object,Serializable>> cascadingOperations = new ArrayList<>();
+ List<PendingOperation<Object, Serializable>> cascadingOperations = new ArrayList<>();
final Map<String, Object> params = new HashMap<>(1);
final Map<Integer, Integer> indexMap = new HashMap<>();
int insertIndex = 0;
@@ -153,8 +202,7 @@ public class Neo4jEntityPersister extends EntityPersister {
registerPendingUpdate(session, persistentEntity, entityAccess, obj, identifier);
idList.add(identifier);
- }
- else {
+ } else {
final PendingInsertAdapter<Object, Serializable> pendingInsert = new PendingInsertAdapter<Object, Serializable>(persistentEntity, identifier, obj, entityAccess) {
@Override
public void run() {
@@ -187,7 +235,7 @@ public class Neo4jEntityPersister extends EntityPersister {
// temporarily add null so it is replaced later
idList.add(null);
- if(pendingInsert.isVetoed()) {
+ if (pendingInsert.isVetoed()) {
continue;
}
@@ -195,33 +243,33 @@ public class Neo4jEntityPersister extends EntityPersister {
indexMap.put(insertIndex++, listIndex - 1);
entityAccesses.add(entityAccess);
- if(previous) {
+ if (previous) {
createCypher.append(CypherBuilder.COMMAND_SEPARATOR);
}
session.buildEntityCreateOperation(createCypher, String.valueOf(insertIndex), entityAccess.getPersistentEntity(), pendingInsert, params, cascadingOperations);
- if(iterator.hasNext()) {
+ if (iterator.hasNext()) {
previous = true;
}
}
}
- if(insertIndex > 0) {
+ if (insertIndex > 0) {
QueryRunner statementRunner = session.hasTransaction() ? session.getTransaction().getNativeTransaction() : session.getNativeInterface();
- final String finalCypher = createCypher.toString() + " RETURN *";
- if(log.isDebugEnabled()) {
+ final String finalCypher = createCypher + " RETURN *";
+ if (log.isDebugEnabled()) {
log.debug("CREATE Cypher [{}] for parameters [{}]", finalCypher, params);
}
- if(graphPersistentEntity.hasDynamicAssociations()) {
+ if (graphPersistentEntity.hasDynamicAssociations()) {
params.remove(DYNAMIC_ASSOCIATION_PARAM);
}
final Result result = statementRunner.run(finalCypher, params);
- if(!result.hasNext()) {
+ if (!result.hasNext()) {
throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + pe.getJavaClass());
}
@@ -231,7 +279,7 @@ public class Neo4jEntityPersister extends EntityPersister {
Assert.notNull(targetIndex, "Should never be null. Please file an issue");
final Node node = record.get("n" + (j + 1)).asNode();
- if(node == null) {
+ if (node == null) {
throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + pe.getJavaClass());
}
final long identifier = node.id();
@@ -242,13 +290,12 @@ public class Neo4jEntityPersister extends EntityPersister {
}
}
- }
- else {
+ } else {
for (Object obj : objs) {
final EntityAccess entityAccess = createEntityAccess(pe, obj);
Serializable id = persistEntity(entityAccess.getPersistentEntity(), obj);
- if(id != null) {
+ if (id != null) {
idList.add(id);
}
}
@@ -259,7 +306,7 @@ public class Neo4jEntityPersister extends EntityPersister {
@Override
protected Object retrieveEntity(PersistentEntity pe, Serializable key) {
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("Retrieving entity [{}] by node id [{}]", pe.getJavaClass(), key);
}
@@ -270,25 +317,26 @@ public class Neo4jEntityPersister extends EntityPersister {
public Object unmarshallOrFromCache(PersistentEntity defaultPersistentEntity, Map<String, Object> resultData) {
- Node data = (Node)resultData.get(CypherBuilder.NODE_DATA);
+ Node data = (Node) resultData.get(CypherBuilder.NODE_DATA);
return unmarshallOrFromCache(defaultPersistentEntity, data, resultData);
}
public Object unmarshallOrFromCache(PersistentEntity defaultPersistentEntity, Node data) {
- return unmarshallOrFromCache(defaultPersistentEntity, data, Collections.<String,Object>emptyMap());
+ return unmarshallOrFromCache(defaultPersistentEntity, data, Collections.<String, Object>emptyMap());
}
public Object unmarshallOrFromCache(PersistentEntity defaultPersistentEntity, Node data, Map<String, Object> resultData) {
- return unmarshallOrFromCache(defaultPersistentEntity, data, resultData, Collections.<Association, Object>emptyMap());
+ return unmarshallOrFromCache(defaultPersistentEntity, data, resultData, Collections.emptyMap());
}
- public Object unmarshallOrFromCache(PersistentEntity defaultPersistentEntity, Node data, Map<String, Object> resultData, Map<Association, Object> initializedAssociations ) {
+ public Object unmarshallOrFromCache(PersistentEntity defaultPersistentEntity, Node data, Map<String, Object> resultData, Map<Association, Object> initializedAssociations) {
return unmarshallOrFromCache(defaultPersistentEntity, data, resultData, initializedAssociations, LockModeType.NONE);
}
+
public Object unmarshallOrFromCache(PersistentEntity defaultPersistentEntity, Node data, Map<String, Object> resultData, Map<Association, Object> initializedAssociations, LockModeType lockModeType) {
final Neo4jSession session = getSession();
if (LockModeType.PESSIMISTIC_WRITE.equals(lockModeType)) {
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("Locking entity [{}] node [{}] for pessimistic write", defaultPersistentEntity.getName(), data.id());
}
throw new UnsupportedOperationException("Write locks are not supported by the Bolt Java Driver.");
@@ -306,48 +354,45 @@ public class Neo4jEntityPersister extends EntityPersister {
return instance;
}
-
public Object unmarshallOrFromCache(PersistentEntity entity, org.neo4j.driver.types.Relationship data, Map<Association, Object> initializedAssociations, Map<Serializable, Node> initializedNodes) {
Object object = unmarshallOrFromCache(entity, data, initializedAssociations);
RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) entity;
- if(object != null) {
+ if (object != null) {
EntityReflector reflector = entity.getReflector();
Object from = reflector.getProperty(object, RelationshipPersistentEntity.FROM);
- if(from == null || from instanceof EntityProxy) {
+ if (from == null || from instanceof EntityProxy) {
long nodeId = data.startNodeId();
- if(initializedNodes.containsKey(nodeId)) {
+ if (initializedNodes.containsKey(nodeId)) {
reflector.setProperty(
- object,
- RelationshipPersistentEntity.FROM, unmarshallOrFromCache(relEntity.getFromEntity(), initializedNodes.get(nodeId))
+ object,
+ RelationshipPersistentEntity.FROM, unmarshallOrFromCache(relEntity.getFromEntity(), initializedNodes.get(nodeId))
);
- }
- else {
+ } else {
reflector.setProperty(
- object,
- RelationshipPersistentEntity.FROM, session.proxy( relEntity.getFrom().getType(), nodeId)
+ object,
+ RelationshipPersistentEntity.FROM, session.proxy(relEntity.getFrom().getType(), nodeId)
);
}
}
Object to = reflector.getProperty(object, RelationshipPersistentEntity.TO);
- if(to == null || to instanceof EntityProxy) {
+ if (to == null || to instanceof EntityProxy) {
long nodeId = data.endNodeId();
- if(initializedNodes.containsKey(nodeId)) {
+ if (initializedNodes.containsKey(nodeId)) {
reflector.setProperty(
- object,
- RelationshipPersistentEntity.TO, unmarshallOrFromCache(relEntity.getToEntity(), initializedNodes.get(nodeId))
+ object,
+ RelationshipPersistentEntity.TO, unmarshallOrFromCache(relEntity.getToEntity(), initializedNodes.get(nodeId))
);
- }
- else {
+ } else {
reflector.setProperty(
- object,
- RelationshipPersistentEntity.TO, session.proxy( relEntity.getTo().getType(), nodeId)
+ object,
+ RelationshipPersistentEntity.TO, session.proxy(relEntity.getTo().getType(), nodeId)
);
}
}
reflector.setProperty(object,
- RelationshipPersistentEntity.TYPE,
- data.type());
+ RelationshipPersistentEntity.TYPE,
+ data.type());
}
return object;
}
@@ -359,7 +404,7 @@ public class Neo4jEntityPersister extends EntityPersister {
Object instance = session.getCachedInstance(entity.getJavaClass(), id);
if (instance == null) {
- instance = unmarshall(entity, id, data, Collections.<String, Object>emptyMap(), initializedAssociations);
+ instance = unmarshall(entity, id, data, Collections.emptyMap(), initializedAssociations);
}
return instance;
}
@@ -368,9 +413,9 @@ public class Neo4jEntityPersister extends EntityPersister {
PersistentEntity result = null;
int longestInheritenceChain = -1;
- for (String l: labels) {
+ for (String l : labels) {
PersistentEntity persistentEntity = findDerivedPersistentEntityWithLabel(pe, l);
- if (persistentEntity!=null) {
+ if (persistentEntity != null) {
int inheritenceChain = calcInheritenceChain(persistentEntity);
if (inheritenceChain > longestInheritenceChain) {
longestInheritenceChain = inheritenceChain;
@@ -378,18 +423,17 @@ public class Neo4jEntityPersister extends EntityPersister {
}
}
}
- if(result != null) {
+ if (result != null) {
return result;
- }
- else {
+ } else {
return pe;
}
}
private PersistentEntity findDerivedPersistentEntityWithLabel(PersistentEntity parent, String label) {
- for (PersistentEntity pe: getMappingContext().getPersistentEntities()) {
+ for (PersistentEntity pe : getMappingContext().getPersistentEntities()) {
if (isInParentsChain(parent, pe)) {
- if (((GraphPersistentEntity)pe).getLabels().contains(label)) {
+ if (((GraphPersistentEntity) pe).getLabels().contains(label)) {
return pe;
}
}
@@ -398,7 +442,7 @@ public class Neo4jEntityPersister extends EntityPersister {
}
private boolean isInParentsChain(PersistentEntity parent, PersistentEntity it) {
- if (it==null) {
+ if (it == null) {
return false;
} else if (it.equals(parent)) {
return true;
@@ -413,11 +457,10 @@ public class Neo4jEntityPersister extends EntityPersister {
}
}
-
protected Object unmarshall(PersistentEntity persistentEntity, Serializable id, Entity node, Map<String, Object> resultData, Map<Association, Object> initializedAssociations) {
- if(log.isDebugEnabled()) {
- log.debug( "unmarshalling entity [{}] with id [{}], props {}, {}", persistentEntity.getName(), id, node);
+ if (log.isDebugEnabled()) {
+ log.debug("unmarshalling entity [{}] with id [{}], props {}, {}", persistentEntity.getName(), id, node);
}
final Neo4jSession session = getSession();
GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) persistentEntity;
@@ -426,8 +469,8 @@ public class Neo4jEntityPersister extends EntityPersister {
entityAccess.setIdentifierNoConversion(id);
PersistentProperty nodeId = graphPersistentEntity.getNodeId();
- if( nodeId != null ) {
- ((GroovyObject)entityAccess.getEntity()).setProperty(nodeId.getName(), node.id());
+ if (nodeId != null) {
+ ((GroovyObject) entityAccess.getEntity()).setProperty(nodeId.getName(), node.id());
}
final Object entity = entityAccess.getEntity();
@@ -435,24 +478,22 @@ public class Neo4jEntityPersister extends EntityPersister {
final List<String> nodeProperties = DefaultGroovyMethods.toList(node.keys());
- for (PersistentProperty property: entityAccess.getPersistentEntity().getPersistentProperties()) {
+ for (PersistentProperty property : entityAccess.getPersistentEntity().getPersistentProperties()) {
String propertyName = property.getName();
- if ( (property instanceof Simple) || (property instanceof TenantId) || (property instanceof Basic)) {
+ if ((property instanceof Simple) || (property instanceof TenantId) || (property instanceof Basic)) {
// implicitly sets version property as well
- if(node.containsKey(propertyName)) {
+ if (node.containsKey(propertyName)) {
entityAccess.setProperty(propertyName, node.get(propertyName).asObject());
nodeProperties.remove(propertyName);
}
- } else if (property instanceof Association) {
-
- Association association = (Association) property;
+ } else if (property instanceof Association association) {
final String associationName = association.getName();
- if(initializedAssociations.containsKey(association)) {
+ if (initializedAssociations.containsKey(association)) {
entityAccess.setPropertyNoConversion(associationName, initializedAssociations.get(association));
continue;
}
@@ -462,68 +503,61 @@ public class Neo4jEntityPersister extends EntityPersister {
final String associationIdsKey = associationName + "Ids";
// if the node key is present we have an eager fetch, so initialise the association
- if(resultData.containsKey(associationNodesKey)) {
+ if (resultData.containsKey(associationNodesKey)) {
final PersistentEntity associatedEntity = association.getAssociatedEntity();
if (association instanceof ToOne) {
final Neo4jEntityPersister associationPersister = session.getEntityPersister(associatedEntity.getJavaClass());
final Iterable<Node> associationNodes = (Iterable<Node>) resultData.get(associationNodesKey);
final Node associationNode = IteratorUtil.singleOrNull(associationNodes);
- if(associationNode != null) {
+ if (associationNode != null) {
entityAccess.setPropertyNoConversion(
- associationName,
- associationPersister.unmarshallOrFromCache(associatedEntity, associationNode)
+ associationName,
+ associationPersister.unmarshallOrFromCache(associatedEntity, associationNode)
);
}
- }
- else if(association instanceof ToMany) {
+ } else if (association instanceof ToMany) {
Collection values;
final Class type = association.getType();
final Collection<Object> associationNodes;
boolean isRelationshipEntity = associatedEntity instanceof RelationshipPersistentEntity;
- if(isRelationshipEntity && resultData.containsKey(associationRelKey)) {
+ if (isRelationshipEntity && resultData.containsKey(associationRelKey)) {
associationNodes = (Collection<Object>) resultData.get(associationRelKey);
- }
- else {
+ } else {
associationNodes = (Collection<Object>) resultData.get(associationNodesKey);
}
final Neo4jResultList resultSet = new Neo4jResultList(0, associationNodes.size(), associationNodes.iterator(), session.getEntityPersister(associatedEntity));
- if(isRelationshipEntity) {
+ if (isRelationshipEntity) {
RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) associatedEntity;
Association from = relEntity.getFrom();
Association to = relEntity.getTo();
handleRelationshipSide(persistentEntity, resultData, entity, associationNodesKey, resultSet, from);
handleRelationshipSide(persistentEntity, resultData, entity, associationNodesKey, resultSet, to);
- }
- else if(association.isBidirectional()) {
+ } else if (association.isBidirectional()) {
final Association inverseSide = association.getInverseSide();
- if(inverseSide instanceof ToOne) {
+ if (inverseSide instanceof ToOne) {
resultSet.setInitializedAssociations(Collections.singletonMap(
- inverseSide, entity
+ inverseSide, entity
));
}
}
- if(List.class.isAssignableFrom(type)) {
+ if (List.class.isAssignableFrom(type)) {
values = new Neo4jList(entityAccess, association, resultSet, session);
- }
- else if(SortedSet.class.isAssignableFrom(type)) {
+ } else if (SortedSet.class.isAssignableFrom(type)) {
values = new Neo4jSortedSet(entityAccess, association, new TreeSet<>(resultSet), session);
- }
- else {
+ } else {
values = new Neo4jSet(entityAccess, association, new HashSet<>(resultSet), session);
}
entityAccess.setPropertyNoConversion(propertyName, values);
}
- }
- else if(resultData.containsKey(associationIdsKey)) {
+ } else if (resultData.containsKey(associationIdsKey)) {
final Object associationValues = resultData.get(associationIdsKey);
List<Serializable> targetIds = Collections.emptyList();
- if(associationValues instanceof Collection) {
+ if (associationValues instanceof Collection) {
targetIds = (List<Serializable>) associationValues;
}
- if (association instanceof ToOne) {
- ToOne toOne = (ToOne) association;
+ if (association instanceof ToOne toOne) {
if (!targetIds.isEmpty()) {
Serializable targetId;
try {
@@ -532,93 +566,85 @@ public class Neo4jEntityPersister extends EntityPersister {
throw new DataIntegrityViolationException("Single-ended association has more than one associated identifier: " + association);
}
entityAccess.setPropertyNoConversion(propertyName,
- getMappingContext().getProxyFactory().createProxy(
- this.session,
- toOne.getAssociatedEntity().getJavaClass(),
- targetId
- )
+ getMappingContext().getProxyFactory().createProxy(
+ this.session,
+ toOne.getAssociatedEntity().getJavaClass(),
+ targetId
+ )
);
}
} else if (association instanceof ToMany) {
Collection values;
final Class type = association.getType();
- if(List.class.isAssignableFrom(type)) {
+ if (List.class.isAssignableFrom(type)) {
values = new Neo4jPersistentList(targetIds, session, entityAccess, (ToMany) association);
- }
- else if(SortedSet.class.isAssignableFrom(type)) {
+ } else if (SortedSet.class.isAssignableFrom(type)) {
values = new Neo4jPersistentSortedSet(targetIds, session, entityAccess, (ToMany) association);
- }
- else {
+ } else {
values = new Neo4jPersistentSet(targetIds, session, entityAccess, (ToMany) association);
}
entityAccess.setPropertyNoConversion(propertyName, values);
} else {
throw new IllegalArgumentException("association " + associationName + " is of type " + association.getClass().getSuperclass().getName());
}
- }
- else {
+ } else {
// No OPTIONAL MATCH specified so the association queries are lazily executed
- if(association instanceof ToOne) {
+ if (association instanceof ToOne) {
// first check whether the object has already been loaded from the cache
// if a lazy proxy should be created for this association then create it,
// note that this strategy does not allow for null checks
final Neo4jAssociationQueryExecutor associationQueryExecutor = new Neo4jAssociationQueryExecutor(session, association);
- if(association.getMapping().getMappedForm().getFetchStrategy() == FetchType.LAZY) {
+ if (association.getMapping().getMappedForm().getFetchStrategy() == FetchType.LAZY) {
final Object proxy = getMappingContext().getProxyFactory().createProxy(
- this.session,
- associationQueryExecutor,
- id
+ this.session,
+ associationQueryExecutor,
+ id
);
entityAccess.setPropertyNoConversion(propertyName,
- proxy
+ proxy
);
- }
- else {
+ } else {
final List<Object> results = associationQueryExecutor.query(id);
- if(!results.isEmpty()) {
+ if (!results.isEmpty()) {
entityAccess.setPropertyNoConversion(propertyName, results.get(0));
}
}
- }
- else if(association instanceof ToMany) {
+ } else if (association instanceof ToMany) {
Collection values;
final Class type = association.getType();
- if(List.class.isAssignableFrom(type)) {
+ if (List.class.isAssignableFrom(type)) {
values = new Neo4jPersistentList(id, session, entityAccess, (ToMany) association);
- }
- else if(SortedSet.class.isAssignableFrom(type)) {
+ } else if (SortedSet.class.isAssignableFrom(type)) {
values = new Neo4jPersistentSortedSet(id, session, entityAccess, (ToMany) association);
- }
- else {
+ } else {
values = new Neo4jPersistentSet(id, session, entityAccess, (ToMany) association);
}
entityAccess.setPropertyNoConversion(propertyName, values);
}
}
-
} else {
throw new IllegalArgumentException("property " + property.getName() + " is of type " + property.getClass().getSuperclass().getName());
}
}
- Map<String,Object> undeclared = new LinkedHashMap<>();
+ Map<String, Object> undeclared = new LinkedHashMap<>();
if (!nodeProperties.isEmpty()) {
for (String nodeProperty : nodeProperties) {
- if(!nodeProperty.equals(CypherBuilder.IDENTIFIER)) {
+ if (!nodeProperty.equals(CypherBuilder.IDENTIFIER)) {
undeclared.put(nodeProperty, node.get(nodeProperty).asObject());
}
}
}
final Object obj = entity;
- if(!undeclared.isEmpty()) {
- if(obj instanceof DynamicAttributes) {
- ((DynamicAttributes)obj).attributes(undeclared);
+ if (!undeclared.isEmpty()) {
+ if (obj instanceof DynamicAttributes) {
+ ((DynamicAttributes) obj).attributes(undeclared);
}
}
@@ -629,10 +655,10 @@ public class Neo4jEntityPersister extends EntityPersister {
private void handleRelationshipSide(PersistentEntity persistentEntity, Map<String, Object> resultData, Object entity, String associationNodesKey, Neo4jResultList resultSet, Association association) {
if (persistentEntity.equals(association.getAssociatedEntity())) {
resultSet.setInitializedAssociations(Collections.singletonMap(
- association, entity
+ association, entity
));
// the associated nodes are the inverse nodes, pass those through to avoid additional queries
- if(resultData.containsKey(associationNodesKey)) {
+ if (resultData.containsKey(associationNodesKey)) {
Collection<Node> nodes = (Collection<Node>) resultData.get(associationNodesKey);
for (Node n : nodes) {
resultSet.addInitializedNode(n);
@@ -646,42 +672,39 @@ public class Neo4jEntityPersister extends EntityPersister {
}
private Collection createDirtyCheckableAwareCollection(EntityAccess entityAccess, Association association, Collection delegate) {
- if (delegate==null) {
+ if (delegate == null) {
delegate = createCollection(association);
}
- if( !(delegate instanceof DirtyCheckableCollection)) {
+ if (!(delegate instanceof DirtyCheckableCollection dirtyCheckableCollection)) {
final Object entity = entityAccess.getEntity();
- if(entity instanceof DirtyCheckable) {
+ if (entity instanceof DirtyCheckable) {
final Neo4jSession session = getSession();
- for( Object o : delegate ) {
+ for (Object o : delegate) {
final EntityAccess associationAccess = getSession().createEntityAccess(association.getAssociatedEntity(), o);
Serializable associationId = (Serializable) associationAccess.getIdentifier();
- if(associationId != null) {
+ if (associationId != null) {
session.addPendingRelationshipInsert((Serializable) entityAccess.getIdentifier(), association, associationId);
}
}
delegate = association.isList() ?
- new Neo4jList(entityAccess, association, (List)delegate, session) :
- new Neo4jSet(entityAccess, association, (Set)delegate, session);
+ new Neo4jList(entityAccess, association, (List) delegate, session) :
+ new Neo4jSet(entityAccess, association, (Set) delegate, session);
}
- }
- else {
- final DirtyCheckableCollection dirtyCheckableCollection = (DirtyCheckableCollection) delegate;
+ } else {
final Neo4jSession session = getSession();
- if(dirtyCheckableCollection.hasChanged()) {
- for (Object o : ((Iterable)dirtyCheckableCollection)) {
+ if (dirtyCheckableCollection.hasChanged()) {
+ for (Object o : ((Iterable) dirtyCheckableCollection)) {
final EntityAccess associationAccess = getSession().createEntityAccess(association.getAssociatedEntity(), o);
- session.addPendingRelationshipInsert((Serializable) entityAccess.getIdentifier(),association, (Serializable) associationAccess.getIdentifier());
+ session.addPendingRelationshipInsert((Serializable) entityAccess.getIdentifier(), association, (Serializable) associationAccess.getIdentifier());
}
}
}
return delegate;
}
-
@Override
protected Serializable persistEntity(final PersistentEntity entity, Object obj, boolean isInsert) {
if (obj == null) {
@@ -701,14 +724,13 @@ public class Neo4jEntityPersister extends EntityPersister {
final EntityAccess entityAccess = createEntityAccess(entity, obj);
Object identifier = entityAccess.getIdentifier();
-
session.registerPending(obj);
// cancel operation if vetoed
boolean isUpdate = identifier != null && !isInsert;
GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) entity;
boolean assignedId = graphPersistentEntity.isAssignedId();
- if(assignedId && !session.contains(obj)) {
+ if (assignedId && !session.contains(obj)) {
isUpdate = false;
}
@@ -717,11 +739,11 @@ public class Neo4jEntityPersister extends EntityPersister {
} else {
boolean isNativeId = false;
- if(identifier == null) {
+ if (identifier == null) {
final IdGenerator idGenerator = graphPersistentEntity.getIdGenerator();
isNativeId = idGenerator == null;
- if(!isNativeId) {
+ if (!isNativeId) {
identifier = idGenerator.nextId();
entityAccess.setIdentifier(identifier);
@@ -748,7 +770,7 @@ public class Neo4jEntityPersister extends EntityPersister {
}
});
- if(isNativeId && !graphPersistentEntity.isRelationshipEntity()) {
+ if (isNativeId && !graphPersistentEntity.isRelationshipEntity()) {
// if we have a native identifier then we have to perform an insert to obtain the id
final List<PendingOperation<Object, Serializable>> preOperations = pendingInsert.getPreOperations();
for (PendingOperation preOperation : preOperations) {
@@ -758,7 +780,7 @@ public class Neo4jEntityPersister extends EntityPersister {
pendingInsert.run();
pendingInsert.setExecuted(true);
- if(pendingInsert.isVetoed()) {
+ if (pendingInsert.isVetoed()) {
return null;
}
@@ -766,41 +788,39 @@ public class Neo4jEntityPersister extends EntityPersister {
final String cypher = session.buildEntityCreateOperation(entity, pendingInsert, params, pendingInsert.getCascadeOperations());
Map<String, List<Object>> dynamicAssociations = null;
- if(graphPersistentEntity.hasDynamicAssociations()) {
+ if (graphPersistentEntity.hasDynamicAssociations()) {
dynamicAssociations = (Map<String, List<Object>>) params.remove(DYNAMIC_ASSOCIATION_PARAM);
}
final QueryRunner boltSession = session.hasTransaction() ? session.getTransaction().getNativeTransaction() : session.getNativeInterface();
final String finalCypher = cypher + graphPersistentEntity.formatReturnId();
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("CREATE Cypher [{}] for parameters [{}]", finalCypher, params);
}
final Result result = boltSession.run(finalCypher, params);
- if(!result.hasNext()) {
+ if (!result.hasNext()) {
throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + entityAccess.getEntity());
}
Record idMap = result.next();
- if(idMap != null) {
+ if (idMap != null) {
identifier = idMap.get(GormProperties.IDENTITY).asObject();
- if(identifier == null) {
+ if (identifier == null) {
throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + entityAccess.getEntity());
}
entityAccess.setIdentifier(identifier);
- if(obj instanceof DirtyCheckable) {
- ((DirtyCheckable)obj).trackChanges();
+ if (obj instanceof DirtyCheckable) {
+ ((DirtyCheckable) obj).trackChanges();
}
persistAssociationsOfEntity(graphPersistentEntity, entityAccess, false);
- if(dynamicAssociations != null) {
- processDynamicAssociations(graphPersistentEntity, entityAccess, (Neo4jMappingContext) getMappingContext(),dynamicAssociations, pendingInsert.getCascadeOperations(), false);
+ if (dynamicAssociations != null) {
+ processDynamicAssociations(graphPersistentEntity, entityAccess, (Neo4jMappingContext) getMappingContext(), dynamicAssociations, pendingInsert.getCascadeOperations(), false);
}
- }
- else {
+ } else {
throw new IdentityGenerationException("CREATE operation did not generate an identifier for entity " + entityAccess.getEntity());
}
session.addPendingInsert(pendingInsert);
- }
- else {
+ } else {
session.addPendingInsert(pendingInsert);
persistAssociationsOfEntity((GraphPersistentEntity) entity, entityAccess, false);
}
@@ -815,7 +835,6 @@ public class Neo4jEntityPersister extends EntityPersister {
return persistEntity(pe, obj, false);
}
-
private void registerPendingUpdate(Neo4jSession session, final PersistentEntity pe, final EntityAccess ea, final Object obj, final Serializable identifier) {
final Neo4jModificationTrackingEntityAccess entityAccess = new Neo4jModificationTrackingEntityAccess(ea);
final Object notEqualMarker = new Object();
@@ -826,9 +845,8 @@ public class Neo4jEntityPersister extends EntityPersister {
setVetoed(true);
} else {
Object entity = entityAccess.getEntity();
- if (entity instanceof DirtyCheckable) {
- DirtyCheckable dirtyCheckable = (DirtyCheckable) entity;
- for (Map.Entry<String, Object> entry: entityAccess.getModifiedProperties().entrySet()) {
+ if (entity instanceof DirtyCheckable dirtyCheckable) {
+ for (Map.Entry<String, Object> entry : entityAccess.getModifiedProperties().entrySet()) {
dirtyCheckable.markDirty(entry.getKey(), notEqualMarker, entry.getValue());
}
}
@@ -847,27 +865,27 @@ public class Neo4jEntityPersister extends EntityPersister {
}
private boolean shouldIgnore(Neo4jSession session, Object obj) {
- boolean isDirty = obj instanceof DirtyCheckable ? ((DirtyCheckable)obj).hasChanged() : true;
+ boolean isDirty = !(obj instanceof DirtyCheckable) || ((DirtyCheckable) obj).hasChanged();
return session.isPendingAlready(obj) || (!isDirty);
}
public void processDynamicAssociations(GraphPersistentEntity graphEntity, EntityAccess access, Neo4jMappingContext mappingContext, Map<String, List<Object>> dynamicRelProps, List<PendingOperation<Object, Serializable>> cascadingOperations, boolean isUpdate) {
- if(graphEntity.hasDynamicAssociations()) {
+ if (graphEntity.hasDynamicAssociations()) {
Serializable parentId = (Serializable) access.getIdentifier();
- for (final Map.Entry<String, List<Object>> e: dynamicRelProps.entrySet()) {
- for (final Object o : e.getValue()) {
+ for (final Map.Entry<String, List<Object>> e : dynamicRelProps.entrySet()) {
+ for (final Object o : e.getValue()) {
- if (((DirtyCheckable)access.getEntity()).hasChanged(e.getKey()) || !isUpdate) {
+ if (((DirtyCheckable) access.getEntity()).hasChanged(e.getKey()) || !isUpdate) {
final GraphPersistentEntity associated = (GraphPersistentEntity) mappingContext.getPersistentEntity(o.getClass().getName());
if (associated != null) {
Object childId = getSession().getEntityPersister(o).getObjectIdentifier(o);
if (childId == null) {
childId = persist(o);
}
- getSession().
- addPendingRelationshipInsert(parentId,
- new DynamicToOneAssociation(graphEntity, mappingContext, e.getKey(), associated),
- (Serializable) childId);
+ getSession()
+ .addPendingRelationshipInsert(parentId,
+ new DynamicToOneAssociation(graphEntity, mappingContext, e.getKey(), associated),
+ (Serializable) childId);
}
}
}
@@ -880,45 +898,41 @@ public class Neo4jEntityPersister extends EntityPersister {
Object obj = entityAccess.getEntity();
DirtyCheckable dirtyCheckable = null;
if (obj instanceof DirtyCheckable) {
- dirtyCheckable = (DirtyCheckable)obj;
+ dirtyCheckable = (DirtyCheckable) obj;
}
Neo4jSession neo4jSession = getSession();
- if(graphEntity.hasDynamicAssociations()) {
+ if (graphEntity.hasDynamicAssociations()) {
MappingContext mappingContext = graphEntity.getMappingContext();
DynamicAttributes dynamicAttributes = (DynamicAttributes) obj;
Map<String, Object> attributes = dynamicAttributes.attributes();
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
Object value = entry.getValue();
- if(value == null) {
+ if (value == null) {
String associationName = entry.getKey();
Object originalValue = ((DirtyCheckable) obj).getOriginalValue(associationName);
- if(originalValue != null && mappingContext.isPersistentEntity(originalValue)) {
+ if (originalValue != null && mappingContext.isPersistentEntity(originalValue)) {
processDynamicAssociationRemoval(graphEntity, entityAccess, neo4jSession, mappingContext, associationName, originalValue);
- }
- else if(originalValue instanceof Iterable) {
- Iterable i = (Iterable) originalValue;
+ } else if (originalValue instanceof Iterable i) {
for (Object o : i) {
processDynamicAssociationRemoval(graphEntity, entityAccess, neo4jSession, mappingContext, associationName, o);
}
}
- }
- else if(mappingContext.isPersistentEntity(value)) {
- if( ((DirtyCheckable)value).hasChanged() ) {
+ } else if (mappingContext.isPersistentEntity(value)) {
+ if (((DirtyCheckable) value).hasChanged()) {
neo4jSession.persist(value);
}
- }
- else if(value instanceof Iterable) {
+ } else if (value instanceof Iterable) {
boolean collectionChanged = false;
- for(Object o : ((Iterable)value)) {
- if(mappingContext.isPersistentEntity(o)) {
- collectionChanged = ((DirtyCheckable)o).hasChanged();
- if(collectionChanged) break;
+ for (Object o : ((Iterable) value)) {
+ if (mappingContext.isPersistentEntity(o)) {
+ collectionChanged = ((DirtyCheckable) o).hasChanged();
+ if (collectionChanged) break;
}
}
- if(collectionChanged) {
- neo4jSession.persist((Iterable)value);
+ if (collectionChanged) {
+ neo4jSession.persist((Iterable) value);
}
}
}
@@ -926,35 +940,33 @@ public class Neo4jEntityPersister extends EntityPersister {
for (PersistentProperty persistentProperty : graphEntity.getAssociations()) {
String propertyName = persistentProperty.getName();
- if(persistentProperty instanceof Basic) {
+ if (persistentProperty instanceof Basic) {
continue;
}
- if ((!isUpdate) || ((dirtyCheckable!=null) && dirtyCheckable.hasChanged(propertyName))) {
+ if ((!isUpdate) || ((dirtyCheckable != null) && dirtyCheckable.hasChanged(propertyName))) {
Object propertyValue = entityAccess.getProperty(propertyName);
if ((persistentProperty instanceof OneToMany) || (persistentProperty instanceof ManyToMany)) {
Association association = (Association) persistentProperty;
- if (propertyValue!= null) {
+ if (propertyValue != null) {
- if(propertyValue instanceof PersistentCollection) {
- PersistentCollection pc = (PersistentCollection) propertyValue;
- if(!pc.isInitialized()) continue;
+ if (propertyValue instanceof PersistentCollection pc) {
+ if (!pc.isInitialized()) continue;
}
if (association.isBidirectional()) {
// Populate other side of bidi
- for (Object associatedObject: (Iterable)propertyValue) {
+ for (Object associatedObject : (Iterable) propertyValue) {
EntityAccess assocEntityAccess = createEntityAccess(association.getAssociatedEntity(), associatedObject);
String referencedPropertyName = association.getReferencedPropertyName();
- if(association instanceof ManyToMany) {
- ((GormEntity)associatedObject).addTo(referencedPropertyName, obj);
- }
- else {
+ if (association instanceof ManyToMany) {
+ ((GormEntity) associatedObject).addTo(referencedPropertyName, obj);
+ } else {
assocEntityAccess.setPropertyNoConversion(referencedPropertyName, obj);
- ((DirtyCheckable)associatedObject).markDirty(referencedPropertyName);
+ ((DirtyCheckable) associatedObject).markDirty(referencedPropertyName);
}
}
}
@@ -979,22 +991,22 @@ public class Neo4jEntityPersister extends EntityPersister {
assocEntityAccess.setProperty(to.getReferencedPropertyName(), obj);
} else {
Collection collection = (Collection) assocEntityAccess.getProperty(to.getReferencedPropertyName());
- if (collection == null ) {
+ if (collection == null) {
collection = new ArrayList();
assocEntityAccess.setProperty(to.getReferencedPropertyName(), collection);
}
- if(proxyFactory.isInitialized(collection) && !collection.isEmpty()) {
+ if (proxyFactory.isInitialized(collection) && !collection.isEmpty()) {
boolean found = false;
for (Object o : collection) {
- if(o.equals(obj)) {
- found = true; break;
+ if (o.equals(obj)) {
+ found = true;
+ break;
}
}
if (!found) {
collection.add(obj);
}
- }
- else {
+ } else {
collection.add(obj);
}
}
@@ -1002,41 +1014,37 @@ public class Neo4jEntityPersister extends EntityPersister {
persistEntity(to.getAssociatedEntity(), propertyValue);
-
Serializable thisId = (Serializable) entityAccess.getIdentifier();
final EntityAccess associationAccess = neo4jSession.createEntityAccess(to.getAssociatedEntity(), propertyValue);
Serializable associationId = (Serializable) associationAccess.getIdentifier();
- if(graphEntity.isRelationshipEntity() && propertyName.equals(RelationshipPersistentEntity.FROM)) {
+ if (graphEntity.isRelationshipEntity() && propertyName.equals(RelationshipPersistentEntity.FROM)) {
RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) graphEntity;
// reverse the ids to correctly align from and to
thisId = associationId;
Object toValue = entityAccess.getProperty(RelationshipPersistentEntity.TO);
- if(toValue != null) {
+ if (toValue != null) {
GraphPersistentEntity toEntity = relEntity.getToEntity();
associationId = toEntity.getReflector().getIdentifier(toValue);
- if(associationId == null) {
- associationId = persistEntity(toEntity,toValue);
+ if (associationId == null) {
+ associationId = persistEntity(toEntity, toValue);
}
}
}
- if(thisId != null && associationId != null) {
+ if (thisId != null && associationId != null) {
boolean reversed = RelationshipUtils.useReversedMappingFor(to);
if (reversed) {
Association inverseSide = to.getInverseSide();
- if(inverseSide != null) {
+ if (inverseSide != null) {
neo4jSession.addPendingRelationshipInsert(associationId, inverseSide, thisId);
}
- }
- else {
+ } else {
neo4jSession.addPendingRelationshipInsert(thisId, to, associationId);
}
}
-
- }
- else if(isUpdate) {
+ } else if (isUpdate) {
Object previousValue = dirtyCheckable.getOriginalValue(propertyName);
if (previousValue != null) {
ToOne to = (ToOne) persistentProperty;
@@ -1047,11 +1055,10 @@ public class Neo4jEntityPersister extends EntityPersister {
}
}
} else {
- throw new IllegalArgumentException("GORM for Neo4j doesn't support properties of the given type " + persistentProperty + "(" + persistentProperty.getClass().getSuperclass() +")" );
+ throw new IllegalArgumentException("GORM for Neo4j doesn't support properties of the given type " + persistentProperty + "(" + persistentProperty.getClass().getSuperclass() + ")");
}
}
-
}
}
@@ -1060,9 +1067,9 @@ public class Neo4jEntityPersister extends EntityPersister {
if (associated != null) {
Object childId = getSession().getEntityPersister(originalValue).getObjectIdentifier(originalValue);
- if(childId != null) {
+ if (childId != null) {
Serializable parentId = (Serializable) entityAccess.getIdentifier();
- neo4jSession.addPendingRelationshipDelete(parentId,new DynamicToOneAssociation(graphEntity, mappingContext, associationName, associated), (Serializable)childId );
+ neo4jSession.addPendingRelationshipDelete(parentId, new DynamicToOneAssociation(graphEntity, mappingContext, associationName, associated), (Serializable) childId);
}
}
}
@@ -1071,7 +1078,6 @@ public class Neo4jEntityPersister extends EntityPersister {
protected void deleteEntity(final PersistentEntity pe, final Object obj) {
final EntityAccess entityAccess = createEntityAccess(pe, obj);
-
final Neo4jSession session = getSession();
session.clear(obj);
final PendingDeleteAdapter pendingDelete = createPendingDeleteOne(session, pe, entityAccess, obj);
@@ -1097,8 +1103,6 @@ public class Neo4jEntityPersister extends EntityPersister {
};
}
-
-
@Override
protected void deleteEntities(PersistentEntity pe, @SuppressWarnings("rawtypes") Iterable objects) {
for (Object object : objects) {
@@ -1115,14 +1119,4 @@ public class Neo4jEntityPersister extends EntityPersister {
public Serializable refresh(Object o) {
throw new UnsupportedOperationException();
}
-
- public static long countUpdates(Result execute) {
- ResultSummary resultSummary = execute.consume();
- SummaryCounters counters = resultSummary.counters();
- if (counters.containsUpdates()) {
- return counters.nodesCreated() + counters.nodesDeleted() + counters.propertiesSet() + counters.relationshipsCreated() + counters.relationshipsDeleted();
- } else {
- return 0;
- }
- }
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jModificationTrackingEntityAccess.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jModificationTrackingEntityAccess.groovy
index 5acd12c55f..ee0a97d46e 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jModificationTrackingEntityAccess.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jModificationTrackingEntityAccess.groovy
@@ -19,6 +19,7 @@
package org.grails.datastore.gorm.neo4j.engine
import groovy.transform.CompileStatic
+
import org.grails.datastore.mapping.engine.EntityAccess
import org.grails.datastore.mapping.engine.ModificationTrackingEntityAccess
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jQuery.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jQuery.groovy
index fe4806db62..1f745a0274 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jQuery.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jQuery.groovy
@@ -21,12 +21,25 @@ package org.grails.datastore.gorm.neo4j.engine
import groovy.transform.CompileStatic
import groovy.transform.EqualsAndHashCode
import groovy.util.logging.Slf4j
-import org.grails.datastore.gorm.neo4j.*
+
+import jakarta.persistence.FetchType
+
+import org.neo4j.driver.QueryRunner
+import org.neo4j.driver.Record
+import org.neo4j.driver.Result
+import org.neo4j.driver.Value
+import org.neo4j.driver.types.Node
+
+import org.grails.datastore.gorm.neo4j.CypherBuilder
+import org.grails.datastore.gorm.neo4j.GraphPersistentEntity
+import org.grails.datastore.gorm.neo4j.Neo4jMappingContext
+import org.grails.datastore.gorm.neo4j.Neo4jSession
+import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity
+import org.grails.datastore.gorm.neo4j.RelationshipUtils
import org.grails.datastore.gorm.neo4j.collection.Neo4jResultList
import org.grails.datastore.mapping.config.Property
import org.grails.datastore.mapping.model.PersistentEntity
import org.grails.datastore.mapping.model.PersistentProperty
-import org.grails.datastore.mapping.model.config.GormProperties
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.model.types.Basic
import org.grails.datastore.mapping.model.types.ManyToOne
@@ -35,14 +48,6 @@ import org.grails.datastore.mapping.model.types.ToOne
import org.grails.datastore.mapping.query.AssociationQuery
import org.grails.datastore.mapping.query.Query
import org.grails.datastore.mapping.query.QueryException
-import org.grails.datastore.mapping.reflect.EntityReflector
-import org.neo4j.driver.Record
-import org.neo4j.driver.Result
-import org.neo4j.driver.QueryRunner
-import org.neo4j.driver.Value
-import org.neo4j.driver.types.Node
-
-import jakarta.persistence.FetchType
/**
* perform criteria queries on a Neo4j backend
@@ -69,36 +74,38 @@ class Neo4jQuery extends Query {
private static Map<Class<? extends Query.PropertyComparisonCriterion>, String> COMPARISON_OPERATORS = [
(Query.GreaterThanEqualsProperty): CriterionHandler.OPERATOR_GREATER_THAN_EQUALS,
- (Query.EqualsProperty): CriterionHandler.OPERATOR_EQUALS,
- (Query.NotEqualsProperty): CriterionHandler.OPERATOR_NOT_EQUALS,
- (Query.LessThanEqualsProperty): CriterionHandler.OPERATOR_LESS_THAN_EQUALS,
- (Query.LessThanProperty): CriterionHandler.OPERATOR_LESS_THAN,
- (Query.GreaterThanProperty): CriterionHandler.OPERATOR_GREATER_THAN
+ (Query.EqualsProperty) : CriterionHandler.OPERATOR_EQUALS,
+ (Query.NotEqualsProperty) : CriterionHandler.OPERATOR_NOT_EQUALS,
+ (Query.LessThanEqualsProperty) : CriterionHandler.OPERATOR_LESS_THAN_EQUALS,
+ (Query.LessThanProperty) : CriterionHandler.OPERATOR_LESS_THAN,
+ (Query.GreaterThanProperty) : CriterionHandler.OPERATOR_GREATER_THAN
]
protected static Map<Class<? extends Query.Projection>, ProjectionHandler<? extends Projection>> PROJECT_HANDLERS = [
- (Query.CountProjection): new ProjectionHandler<Query.CountProjection>() {
+ (Query.CountProjection) : new ProjectionHandler<Query.CountProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.CountProjection projection, CypherBuilder builder) {
return ProjectionHandler.COUNT
}
},
- (Query.IdProjection): new ProjectionHandler<Query.IdProjection>() {
+ (Query.IdProjection) : new ProjectionHandler<Query.IdProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.IdProjection projection, CypherBuilder builder) {
GraphPersistentEntity graphEntity = (GraphPersistentEntity) entity
- if(graphEntity.isRelationshipEntity()) {
+ if (graphEntity.isRelationshipEntity()) {
return graphEntity.formatId(CypherBuilder.REL_VAR)
- }
- else {
+ } else {
return graphEntity.formatId(CypherBuilder.NODE_VAR)
}
}
},
(Query.CountDistinctProjection): new ProjectionHandler<Query.CountDistinctProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.CountDistinctProjection projection, CypherBuilder builder) {
@@ -107,7 +114,8 @@ class Neo4jQuery extends Query {
return "count( distinct ${var} )"
}
},
- (Query.MinProjection): new ProjectionHandler<Query.MinProjection>() {
+ (Query.MinProjection) : new ProjectionHandler<Query.MinProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.MinProjection projection, CypherBuilder builder) {
@@ -117,7 +125,8 @@ class Neo4jQuery extends Query {
return "min(${var})"
}
},
- (Query.MaxProjection): new ProjectionHandler<Query.MaxProjection>() {
+ (Query.MaxProjection) : new ProjectionHandler<Query.MaxProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.MaxProjection projection, CypherBuilder builder) {
@@ -127,7 +136,8 @@ class Neo4jQuery extends Query {
return "max(${var})"
}
},
- (Query.SumProjection): new ProjectionHandler<Query.SumProjection>() {
+ (Query.SumProjection) : new ProjectionHandler<Query.SumProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.SumProjection projection, CypherBuilder builder) {
@@ -136,7 +146,8 @@ class Neo4jQuery extends Query {
return "sum(${var})"
}
},
- (Query.AvgProjection): new ProjectionHandler<Query.AvgProjection>() {
+ (Query.AvgProjection) : new ProjectionHandler<Query.AvgProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.AvgProjection projection, CypherBuilder builder) {
@@ -145,7 +156,8 @@ class Neo4jQuery extends Query {
return "avg($var)"
}
},
- (Query.PropertyProjection): new ProjectionHandler<Query.PropertyProjection>() {
+ (Query.PropertyProjection) : new ProjectionHandler<Query.PropertyProjection>() {
+
@Override
@CompileStatic
String handle(PersistentEntity entity, Query.PropertyProjection projection, CypherBuilder builder) {
@@ -154,11 +166,11 @@ class Neo4jQuery extends Query {
GraphPersistentEntity graphEntity = (GraphPersistentEntity) entity
String var = graphEntity.variableName
if (association instanceof Association && !(association instanceof Basic)) {
- if(entity instanceof RelationshipPersistentEntity) {
+ if (entity instanceof RelationshipPersistentEntity) {
throw new QueryException("Cannot apply projection on property [$propertyName] of class [$entity.name]. Associations on relationships are not allowed")
}
def targetNodeName = "${association.name}_${builder.getNextMatchNumber()}"
- builder.addMatch("(n)${RelationshipUtils.matchForAssociation((Association)association)}(${targetNodeName})")
+ builder.addMatch("(n)${RelationshipUtils.matchForAssociation((Association) association)}(${targetNodeName})")
return targetNodeName
} else {
return graphEntity.formatProperty(var, propertyName)
@@ -170,27 +182,30 @@ class Neo4jQuery extends Query {
] as Map<Class<? extends Query.Projection>, ProjectionHandler<? extends Projection>>
public static Map<Class<? extends Query.Criterion>, CriterionHandler<? extends Criterion>> CRITERION_HANDLERS = [
- (Query.Conjunction): new CriterionHandler<Query.Conjunction>() {
+ (Query.Conjunction) : new CriterionHandler<Query.Conjunction>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.Conjunction criterion, CypherBuilder builder, String prefix) {
- def inner = ((Query.Junction)criterion).criteria
+ def inner = ((Query.Junction) criterion).criteria
.collect { Query.Criterion it -> dispatchCriterion(it, entity, builder, prefix).toString() }
- .join( CriterionHandler.OPERATOR_AND )
+ .join(CriterionHandler.OPERATOR_AND)
return new CypherExpression(inner ? "( $inner )" : inner)
}
},
- (Query.Disjunction): new CriterionHandler<Query.Disjunction>() {
+ (Query.Disjunction) : new CriterionHandler<Query.Disjunction>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.Disjunction criterion, CypherBuilder builder, String prefix) {
- def inner = ((Query.Junction)criterion).criteria
+ def inner = ((Query.Junction) criterion).criteria
.collect { Query.Criterion it -> dispatchCriterion(it, entity, builder, prefix).toString() }
- .join( CriterionHandler.OPERATOR_OR )
+ .join(CriterionHandler.OPERATOR_OR)
return new CypherExpression(inner ? "( $inner )" : inner)
}
},
- (Query.Negation): new CriterionHandler<Query.Negation>() {
+ (Query.Negation) : new CriterionHandler<Query.Negation>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.Negation criterion, CypherBuilder builder, String prefix) {
@@ -199,35 +214,34 @@ class Neo4jQuery extends Query {
new CypherExpression("NOT (${dispatchCriterion(disjunction, entity, builder, prefix)})")
}
},
- (Query.Equals): new CriterionHandler<Query.Equals>() {
+ (Query.Equals) : new CriterionHandler<Query.Equals>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity graphEntity, Query.Equals criterion, CypherBuilder builder, String prefix) {
- Neo4jMappingContext mappingContext = (Neo4jMappingContext)graphEntity.mappingContext
- int paramNumber = builder.addParam( mappingContext.convertToNative(criterion.value) )
+ Neo4jMappingContext mappingContext = (Neo4jMappingContext) graphEntity.mappingContext
+ int paramNumber = builder.addParam(mappingContext.convertToNative(criterion.value))
PersistentProperty association = graphEntity.getPropertyByName(criterion.property)
boolean isRelationshipEntity = graphEntity.isRelationshipEntity()
String lhs
if (association instanceof Association && !(association instanceof Basic)) {
- if(isRelationshipEntity && RelationshipPersistentEntity.isRelationshipAssociation((Association)association)) {
+ if (isRelationshipEntity && RelationshipPersistentEntity.isRelationshipAssociation((Association) association)) {
lhs = graphEntity.formatId(association.name)
- }
- else {
+ } else {
String targetNodeName = "m_${builder.getNextMatchNumber()}"
builder.addMatch(
- graphEntity.formatAssociationPatternFromExisting((Association)association, "", prefix, targetNodeName)
+ graphEntity.formatAssociationPatternFromExisting((Association) association, "", prefix, targetNodeName)
)
lhs = graphEntity.formatId(targetNodeName)
}
} else {
- if(isRelationshipEntity && criterion.property == RelationshipPersistentEntity.TYPE) {
- builder.replaceFirstRelationshipMatch( ((RelationshipPersistentEntity)graphEntity).buildRelationshipMatchTo(null, CypherBuilder.REL_VAR))
+ if (isRelationshipEntity && criterion.property == RelationshipPersistentEntity.TYPE) {
+ builder.replaceFirstRelationshipMatch(((RelationshipPersistentEntity) graphEntity).buildRelationshipMatchTo(null, CypherBuilder.REL_VAR))
lhs = "TYPE($CypherBuilder.REL_VAR)"
- }
- else {
+ } else {
lhs = graphEntity.formatProperty(prefix, criterion.property)
}
}
@@ -236,7 +250,8 @@ class Neo4jQuery extends Query {
}
},
- (Query.IdEquals): new CriterionHandler<Query.IdEquals>() {
+ (Query.IdEquals) : new CriterionHandler<Query.IdEquals>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.IdEquals criterion, CypherBuilder builder, String prefix) {
@@ -244,7 +259,8 @@ class Neo4jQuery extends Query {
return new CypherExpression(entity.formatId(prefix), "\$$paramNumber", CriterionHandler.OPERATOR_EQUALS)
}
},
- (Query.Like): new CriterionHandler<Query.Like>() {
+ (Query.Like) : new CriterionHandler<Query.Like>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.Like criterion, CypherBuilder builder, String prefix) {
@@ -253,7 +269,8 @@ class Neo4jQuery extends Query {
return new CypherExpression(entity.formatProperty(prefix, criterion.property), "\$$paramNumber", operator)
}
},
- (Query.ILike): new CriterionHandler<Query.ILike>() {
+ (Query.ILike) : new CriterionHandler<Query.ILike>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.ILike criterion, CypherBuilder builder, String prefix) {
@@ -261,14 +278,15 @@ class Neo4jQuery extends Query {
String operator = handleLike(criterion, builder, paramNumber, true)
String propertyRef = entity.formatProperty(prefix, criterion.property)
String parameterRef = "\$$paramNumber"
- if(operator != CriterionHandler.OPERATOR_LIKE) {
+ if (operator != CriterionHandler.OPERATOR_LIKE) {
propertyRef = "lower($propertyRef)"
parameterRef = "lower($parameterRef)"
}
return new CypherExpression(propertyRef, parameterRef, operator)
}
},
- (Query.RLike): new CriterionHandler<Query.RLike>() {
+ (Query.RLike) : new CriterionHandler<Query.RLike>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.RLike criterion, CypherBuilder builder, String prefix) {
@@ -276,94 +294,98 @@ class Neo4jQuery extends Query {
return new CypherExpression(entity.formatProperty(prefix, criterion.property), "\$$paramNumber", CriterionHandler.OPERATOR_LIKE)
}
},
- (Query.In): new CriterionHandler<Query.In>() {
+ (Query.In) : new CriterionHandler<Query.In>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.In criterion, CypherBuilder builder, String prefix) {
int paramNumber = addBuildParameterForCriterion(builder, entity, criterion)
- GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity)entity
+ GraphPersistentEntity graphPersistentEntity = (GraphPersistentEntity) entity
String lhs
Collection values = ((Query.In) criterion).values
- if(graphPersistentEntity.isRelationshipEntity()) {
+ if (graphPersistentEntity.isRelationshipEntity()) {
PersistentProperty persistentProperty = entity.getPropertyByName(criterion.property)
- if(RelationshipPersistentEntity.isRelationshipAssociation(persistentProperty)) {
- GraphPersistentEntity associatedEntity = (GraphPersistentEntity)((Association) persistentProperty).associatedEntity
+ if (RelationshipPersistentEntity.isRelationshipAssociation(persistentProperty)) {
+ GraphPersistentEntity associatedEntity = (GraphPersistentEntity) ((Association) persistentProperty).associatedEntity
lhs = associatedEntity.formatId(criterion.property)
def associatedReflector = associatedEntity.reflector
values = values?.collect {
associatedReflector.getIdentifier(it)
}
- }
- else {
+ } else {
lhs = graphPersistentEntity.formatProperty(prefix, criterion.property)
}
- }
- else {
+ } else {
lhs = graphPersistentEntity.formatProperty(prefix, criterion.property)
}
builder.replaceParamAt(paramNumber, convertEnumsInList(values))
return new CypherExpression(lhs, "\$$paramNumber", CriterionHandler.OPERATOR_IN)
}
},
- (Query.IsNull): new CriterionHandler<Query.IsNull>() {
+ (Query.IsNull) : new CriterionHandler<Query.IsNull>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.IsNull criterion, CypherBuilder builder, String prefix) {
return new CypherExpression("${entity.formatProperty(prefix, criterion.property)} IS NULL")
}
},
- (Query.IsEmpty): new CriterionHandler<Query.IsEmpty>() {
+ (Query.IsEmpty) : new CriterionHandler<Query.IsEmpty>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.IsEmpty criterion, CypherBuilder builder, String prefix) {
return new CypherExpression("length(${entity.formatProperty(prefix, criterion.property)}) = 0")
}
},
- (Query.IsNotEmpty): new CriterionHandler<Query.IsNotEmpty>() {
+ (Query.IsNotEmpty) : new CriterionHandler<Query.IsNotEmpty>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.IsNotEmpty criterion, CypherBuilder builder, String prefix) {
return new CypherExpression("length(${entity.formatProperty(prefix, criterion.property)}) > 0")
}
},
- (Query.IsNotNull): new CriterionHandler<Query.IsNotNull>() {
+ (Query.IsNotNull) : new CriterionHandler<Query.IsNotNull>() {
+
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.IsNotNull criterion, CypherBuilder builder, String prefix) {
return new CypherExpression("${entity.formatProperty(prefix, criterion.property)} IS NOT NULL")
}
},
- (AssociationQuery): new AssociationQueryHandler(),
- (Query.GreaterThan): ComparisonCriterionHandler.GREATER_THAN,
- (Query.GreaterThanEquals): ComparisonCriterionHandler.GREATER_THAN_EQUALS,
- (Query.LessThan): ComparisonCriterionHandler.LESS_THAN,
- (Query.LessThanEquals): ComparisonCriterionHandler.LESS_THAN_EQUALS,
- (Query.NotEquals): ComparisonCriterionHandler.NOT_EQUALS,
-
- (Query.GreaterThanProperty): PropertyComparisonCriterionHandler.GREATER_THAN,
+ (AssociationQuery) : new AssociationQueryHandler(),
+ (Query.GreaterThan) : ComparisonCriterionHandler.GREATER_THAN,
+ (Query.GreaterThanEquals) : ComparisonCriterionHandler.GREATER_THAN_EQUALS,
+ (Query.LessThan) : ComparisonCriterionHandler.LESS_THAN,
+ (Query.LessThanEquals) : ComparisonCriterionHandler.LESS_THAN_EQUALS,
+ (Query.NotEquals) : ComparisonCriterionHandler.NOT_EQUALS,
+
+ (Query.GreaterThanProperty) : PropertyComparisonCriterionHandler.GREATER_THAN,
(Query.GreaterThanEqualsProperty): PropertyComparisonCriterionHandler.GREATER_THAN_EQUALS,
- (Query.LessThanProperty): PropertyComparisonCriterionHandler.LESS_THAN,
- (Query.LessThanEqualsProperty): PropertyComparisonCriterionHandler.LESS_THAN_EQUALS,
- (Query.NotEqualsProperty): PropertyComparisonCriterionHandler.NOT_EQUALS,
- (Query.EqualsProperty): PropertyComparisonCriterionHandler.EQUALS,
+ (Query.LessThanProperty) : PropertyComparisonCriterionHandler.LESS_THAN,
+ (Query.LessThanEqualsProperty) : PropertyComparisonCriterionHandler.LESS_THAN_EQUALS,
+ (Query.NotEqualsProperty) : PropertyComparisonCriterionHandler.NOT_EQUALS,
+ (Query.EqualsProperty) : PropertyComparisonCriterionHandler.EQUALS,
+
+ (Query.Between) : new CriterionHandler<Query.Between>() {
- (Query.Between): new CriterionHandler<Query.Between>() {
@Override
@CompileStatic
CypherExpression handle(GraphPersistentEntity entity, Query.Between criterion, CypherBuilder builder, String prefix) {
int paramNumber = addBuildParameterForCriterion(builder, entity, criterion)
- Neo4jMappingContext mappingContext = (Neo4jMappingContext)entity.mappingContext
- int paramNumberFrom = builder.addParam( mappingContext.convertToNative(criterion.from) )
- int parmaNumberTo = builder.addParam( mappingContext.convertToNative(criterion.to) )
- new CypherExpression( "\$$paramNumberFrom<=${prefix}.$criterion.property and ${prefix}.$criterion.property<=\$$parmaNumberTo")
+ Neo4jMappingContext mappingContext = (Neo4jMappingContext) entity.mappingContext
+ int paramNumberFrom = builder.addParam(mappingContext.convertToNative(criterion.from))
+ int parmaNumberTo = builder.addParam(mappingContext.convertToNative(criterion.to))
+ new CypherExpression("\$$paramNumberFrom<=${prefix}.$criterion.property and ${prefix}.$criterion.property<=\$$parmaNumberTo")
}
},
- (Query.SizeLessThanEquals): SizeCriterionHandler.LESS_THAN_EQUALS,
- (Query.SizeLessThan): SizeCriterionHandler.LESS_THAN,
- (Query.SizeEquals): SizeCriterionHandler.EQUALS,
- (Query.SizeNotEquals): SizeCriterionHandler.NOT_EQUALS,
- (Query.SizeGreaterThan): SizeCriterionHandler.GREATER_THAN,
- (Query.SizeGreaterThanEquals): SizeCriterionHandler.GREATER_THAN_EQUALS
+ (Query.SizeLessThanEquals) : SizeCriterionHandler.LESS_THAN_EQUALS,
+ (Query.SizeLessThan) : SizeCriterionHandler.LESS_THAN,
+ (Query.SizeEquals) : SizeCriterionHandler.EQUALS,
+ (Query.SizeNotEquals) : SizeCriterionHandler.NOT_EQUALS,
+ (Query.SizeGreaterThan) : SizeCriterionHandler.GREATER_THAN,
+ (Query.SizeGreaterThanEquals) : SizeCriterionHandler.GREATER_THAN_EQUALS
] as Map<Class<? extends Query.Criterion>, CriterionHandler<? extends Criterion>>
@@ -415,105 +437,101 @@ class Neo4jQuery extends Query {
CypherBuilder cypherBuilder = buildBaseQuery(persistentEntity, criteria)
cypherBuilder.setOrderAndLimits(applyOrderAndLimits(cypherBuilder))
- GraphPersistentEntity graphEntity = (GraphPersistentEntity)persistentEntity
+ GraphPersistentEntity graphEntity = (GraphPersistentEntity) persistentEntity
def projectionList = projections.projectionList
- if(projectionList.isEmpty()) {
- if(isRelationshipEntity) {
- cypherBuilder.addReturnColumn(CypherBuilder.DEFAULT_REL_RETURN_STATEMENT)
- }
- else {
- Set<Association> associations = new TreeSet<Association>((Comparator<Association>){ Association a1, Association a2 -> a1.name <=> a2.name })
- Collection<PersistentEntity> childEntities = persistentEntity.mappingContext.getChildEntities(persistentEntity)
- if (!childEntities.empty) {
- for (PersistentEntity childEntity : childEntities) {
- associations.addAll(childEntity.associations)
- }
- }
- associations.addAll(persistentEntity.associations)
-
- if(associations.size() > 0) {
- int i = 0
- List previousAssociations = []
- cypherBuilder.addReturnColumn(CypherBuilder.DEFAULT_RETURN_TYPES)
-
- for(Association association in associations) {
- if(association.isBasic()) continue
-
- FetchType fetchType = fetchStrategy(association.name)
- boolean isEager = fetchType.is(fetchType.EAGER)
-
- String r = "r${i++}"
-
- String associationName = association.name
- GraphPersistentEntity associatedGraphEntity = (GraphPersistentEntity)association.associatedEntity
- boolean isAssociationRelationshipEntity = associatedGraphEntity.isRelationshipEntity()
- boolean isToMany = association instanceof ToMany
- boolean isToOne = association instanceof ToOne
-
- boolean lazy = false
- if(isToOne && !isEager) {
- Property propertyMapping = association.mapping.mappedForm
- Boolean isLazy = propertyMapping.getLazy()
- lazy = (isLazy != null ? isLazy : (association instanceof ManyToOne ? !association.isCircular() : true))
-
- }
- else if(isToMany) {
- lazy = ((ToMany)association).lazy
- }
-
- // if there are associations, add a join to get them
- String withMatch = "WITH n, ${previousAssociations.size() > 0 ? previousAssociations.join(", ") + ", " : ""}"
- String associationIdsRef = "${associationName}Ids"
- String associationNodeRef = "${associationName}Node"
- String associationNodesRef = "${associationName}Nodes"
-
- boolean addOptionalMatch = false
- // If it is a one-to-many and lazy=true
- // Or it is any non-eager to-one (regardless of nullability/laziness)
- // then just collect the identifiers and not the nodes.
- // A mandatory, lazy to-one (e.g. a required hasOne) must still have its id
- // collected here - otherwise the persister has no way to know the associated
- // entity's real identifier and falls back to an association-query-executor
- // proxy whose "key" is the *parent's* id, not the target's (see
- // AssociationQueryProxyHandler.getProxyKey()), corrupting things like
- // <property>Id lookups performed before the association is initialized.
- if((isToMany && lazy) || (isToOne && !isEager)) {
- withMatch += "collect(DISTINCT ${associatedGraphEntity.formatId(associationNodeRef)}) as ${associationIdsRef}"
- cypherBuilder.addReturnColumn(associationIdsRef)
- previousAssociations << associationIdsRef
- addOptionalMatch = true
- }
- else if(isEager) {
- withMatch += "collect(DISTINCT $associationNodeRef) as $associationNodesRef"
- cypherBuilder.addReturnColumn(associationNodesRef)
- if(isAssociationRelationshipEntity) {
- withMatch += ", collect($r) as ${associationName}Rels"
- cypherBuilder.addReturnColumn("${associationName}Rels")
- }
- previousAssociations << associationNodesRef
- addOptionalMatch = true
- }
-
- if(addOptionalMatch) {
-
- String relationshipPattern = graphEntity
- .formatAssociationPatternFromExisting(
- association,
- r,
- CypherBuilder.NODE_VAR,
- associationNodeRef
- )
- cypherBuilder.addOptionalMatch(
- "$relationshipPattern $withMatch"
- )
- }
-
- }
- }
- }
- }
- else {
+ if (projectionList.isEmpty()) {
+ if (isRelationshipEntity) {
+ cypherBuilder.addReturnColumn(CypherBuilder.DEFAULT_REL_RETURN_STATEMENT)
+ } else {
+ Set<Association> associations = new TreeSet<Association>((Comparator<Association>) { Association a1, Association a2 -> a1.name <=> a2.name })
+ Collection<PersistentEntity> childEntities = persistentEntity.mappingContext.getChildEntities(persistentEntity)
+ if (!childEntities.empty) {
+ for (PersistentEntity childEntity : childEntities) {
+ associations.addAll(childEntity.associations)
+ }
+ }
+ associations.addAll(persistentEntity.associations)
+
+ if (associations.size() > 0) {
+ int i = 0
+ List previousAssociations = []
+ cypherBuilder.addReturnColumn(CypherBuilder.DEFAULT_RETURN_TYPES)
+
+ for (Association association in associations) {
+ if (association.isBasic()) continue
+
+ FetchType fetchType = fetchStrategy(association.name)
+ boolean isEager = fetchType.is(fetchType.EAGER)
+
+ String r = "r${i++}"
+
+ String associationName = association.name
+ GraphPersistentEntity associatedGraphEntity = (GraphPersistentEntity) association.associatedEntity
+ boolean isAssociationRelationshipEntity = associatedGraphEntity.isRelationshipEntity()
+ boolean isToMany = association instanceof ToMany
+ boolean isToOne = association instanceof ToOne
+
+ boolean lazy = false
+ if (isToOne && !isEager) {
+ Property propertyMapping = association.mapping.mappedForm
+ Boolean isLazy = propertyMapping.getLazy()
+ lazy = (isLazy != null ? isLazy : (association instanceof ManyToOne ? !association.isCircular() : true))
+
+ } else if (isToMany) {
+ lazy = ((ToMany) association).lazy
+ }
+
+ // if there are associations, add a join to get them
+ String withMatch = "WITH n, ${previousAssociations.size() > 0 ? previousAssociations.join(", ") + ", " : ""}"
+ String associationIdsRef = "${associationName}Ids"
+ String associationNodeRef = "${associationName}Node"
+ String associationNodesRef = "${associationName}Nodes"
+
+ boolean addOptionalMatch = false
+ // If it is a one-to-many and lazy=true
+ // Or it is any non-eager to-one (regardless of nullability/laziness)
+ // then just collect the identifiers and not the nodes.
+ // A mandatory, lazy to-one (e.g. a required hasOne) must still have its id
+ // collected here - otherwise the persister has no way to know the associated
+ // entity's real identifier and falls back to an association-query-executor
+ // proxy whose "key" is the *parent's* id, not the target's (see
+ // AssociationQueryProxyHandler.getProxyKey()), corrupting things like
+ // <property>Id lookups performed before the association is initialized.
+ if ((isToMany && lazy) || (isToOne && !isEager)) {
+ withMatch += "collect(DISTINCT ${associatedGraphEntity.formatId(associationNodeRef)}) as ${associationIdsRef}"
+ cypherBuilder.addReturnColumn(associationIdsRef)
+ previousAssociations << associationIdsRef
+ addOptionalMatch = true
+ } else if (isEager) {
+ withMatch += "collect(DISTINCT $associationNodeRef) as $associationNodesRef"
+ cypherBuilder.addReturnColumn(associationNodesRef)
+ if (isAssociationRelationshipEntity) {
+ withMatch += ", collect($r) as ${associationName}Rels"
+ cypherBuilder.addReturnColumn("${associationName}Rels")
+ }
+ previousAssociations << associationNodesRef
+ addOptionalMatch = true
+ }
+
+ if (addOptionalMatch) {
+
+ String relationshipPattern = graphEntity
+ .formatAssociationPatternFromExisting(
+ association,
+ r,
+ CypherBuilder.NODE_VAR,
+ associationNodeRef
+ )
+ cypherBuilder.addOptionalMatch(
+ "$relationshipPattern $withMatch"
+ )
+ }
+
+ }
+ }
+ }
+ } else {
for (projection in projectionList) {
cypherBuilder.addReturnColumn(buildProjection(projection, cypherBuilder))
}
@@ -532,23 +550,23 @@ class Neo4jQuery extends Query {
} else {
List projectedResults = []
- while( executionResult.hasNext() ) {
+ while (executionResult.hasNext()) {
Record record = executionResult.next()
def columnNames = executionResult.keys()
projectedResults.add columnNames.collect { String columnName ->
Value value = record.get(columnName)
- if(value.type() == session.boltDriver.defaultTypeSystem().NODE()) {
+ if (value.type() == session.boltDriver.defaultTypeSystem().NODE()) {
// if a Node has been project then this is an association
def propName = columnName.substring(0, columnName.lastIndexOf('_'))
def prop = persistentEntity.getPropertyByName(propName)
- if(prop instanceof ToOne) {
- Association association = (Association)prop
+ if (prop instanceof ToOne) {
+ Association association = (Association) prop
Node childNode = value.asNode()
def persister = getSession().getEntityPersister(association.type)
- def data = Collections.<String,Object>singletonMap( CypherBuilder.NODE_DATA, childNode)
+ def data = Collections.<String, Object> singletonMap(CypherBuilder.NODE_DATA, childNode)
return persister.unmarshallOrFromCache(
association.associatedEntity, data)
}
@@ -557,10 +575,9 @@ class Neo4jQuery extends Query {
}
}
- if(projectionList.size() == 1 || projectedResults.size() == 1) {
+ if (projectionList.size() == 1 || projectedResults.size() == 1) {
return projectedResults.flatten()
- }
- else {
+ } else {
return projectedResults
}
}
@@ -579,14 +596,13 @@ class Neo4jQuery extends Query {
GraphPersistentEntity graphEntity = (GraphPersistentEntity) persistentEntity
CypherBuilder cypherBuilder
- if(isRelationshipEntity) {
- RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity)graphEntity
+ if (isRelationshipEntity) {
+ RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) graphEntity
GraphPersistentEntity fromEntity = relEntity.getFromEntity()
cypherBuilder = new CypherBuilder(fromEntity.labelsAsString)
cypherBuilder.setStartNode(RelationshipPersistentEntity.FROM)
cypherBuilder.addRelationshipMatch(relEntity.buildToMatch())
- }
- else {
+ } else {
cypherBuilder = new CypherBuilder(graphEntity.labelsAsString)
}
@@ -615,7 +631,7 @@ class Neo4jQuery extends Query {
}
String buildConditions(Query.Criterion criterion, CypherBuilder builder, String prefix) {
- return dispatchCriterion(criterion, (GraphPersistentEntity)entity, builder, prefix).toString()
+ return dispatchCriterion(criterion, (GraphPersistentEntity) entity, builder, prefix).toString()
}
private static Collection convertEnumsInList(Collection collection) {
@@ -630,17 +646,17 @@ class Neo4jQuery extends Query {
}
private static int addBuildParameterForCriterion(CypherBuilder builder, PersistentEntity entity, Query.PropertyCriterion criterion) {
- Neo4jMappingContext mappingContext = (Neo4jMappingContext)entity.mappingContext
- return builder.addParam( mappingContext.convertToNative(criterion.value) )
+ Neo4jMappingContext mappingContext = (Neo4jMappingContext) entity.mappingContext
+ return builder.addParam(mappingContext.convertToNative(criterion.value))
}
@Override
Neo4jSession getSession() {
- return (Neo4jSession)super.getSession()
+ return (Neo4jSession) super.getSession()
}
org.neo4j.driver.Session getBoltSession() {
- return (org.neo4j.driver.Session)getSession().getNativeInterface()
+ return (org.neo4j.driver.Session) getSession().getNativeInterface()
}
@@ -660,18 +676,16 @@ class Neo4jQuery extends Query {
} else if (left) {
operator = CriterionHandler.OPERATOR_ENDS_WITH
builder.replaceParamAt(paramNumber, value.substring(1, length))
- } else if(value.indexOf((int)CriterionHandler.PATTERN_CHAR) > -1) {
+ } else if (value.indexOf((int) CriterionHandler.PATTERN_CHAR) > -1) {
operator = CriterionHandler.OPERATOR_LIKE
String pattern = Query.patternToRegex(value)
- if(caseSensitive) {
+ if (caseSensitive) {
builder.replaceParamAt(paramNumber, "(?i)${pattern}".toString())
- }
- else {
+ } else {
builder.replaceParamAt(paramNumber, pattern)
}
- }
- else {
+ } else {
operator = CriterionHandler.OPERATOR_EQUALS
}
} else {
@@ -685,7 +699,9 @@ class Neo4jQuery extends Query {
* @param < T > The projection type
*/
static interface ProjectionHandler<T extends Query.Projection> {
+
String COUNT = "count(*)"
+
String handle(PersistentEntity entity, T projection, CypherBuilder builder)
}
@@ -695,6 +711,7 @@ class Neo4jQuery extends Query {
* @param < T > The criterion type
*/
static interface CriterionHandler<T extends Query.Criterion> {
+
char PATTERN_CHAR = '%'
String COUNT = "count"
String OPERATOR_EQUALS = '='
@@ -719,24 +736,24 @@ class Neo4jQuery extends Query {
*/
@CompileStatic
static class AssociationQueryHandler implements CriterionHandler<AssociationQuery> {
+
@Override
CypherExpression handle(GraphPersistentEntity entity, AssociationQuery criterion, CypherBuilder builder, String prefix) {
- AssociationQuery aq = (AssociationQuery)criterion
- if(entity.isRelationshipEntity()) {
+ AssociationQuery aq = (AssociationQuery) criterion
+ if (entity.isRelationshipEntity()) {
return dispatchCriterion(aq.criteria, entity, builder, aq.association.name)
- }
- else {
+ } else {
String targetNodeName = "m_${builder.getNextMatchNumber()}"
String nextPrefix = targetNodeName
String relationship = ""
- Association association = (Association)aq.association
+ Association association = (Association) aq.association
if (criterion.entity instanceof RelationshipPersistentEntity) {
String type = (criterion.entity as RelationshipPersistentEntity).type()
relationship = "$nextPrefix:$type"
targetNodeName = "m_${builder.getNextMatchNumber() + 1}"
}
builder.addMatch(
- entity.formatAssociationPatternFromExisting(association, relationship, prefix, targetNodeName)
+ entity.formatAssociationPatternFromExisting(association, relationship, prefix, targetNodeName)
)
return dispatchCriterion(aq.criteria, entity, builder, nextPrefix)
}
@@ -751,6 +768,7 @@ class Neo4jQuery extends Query {
*/
@CompileStatic
static class ComparisonCriterionHandler<T extends Query.PropertyCriterion> implements CriterionHandler<T> {
+
public static final ComparisonCriterionHandler<Query.GreaterThanEquals> GREATER_THAN_EQUALS = new ComparisonCriterionHandler<Query.GreaterThanEquals>(CriterionHandler.OPERATOR_GREATER_THAN_EQUALS)
public static final ComparisonCriterionHandler<Query.GreaterThan> GREATER_THAN = new ComparisonCriterionHandler<Query.GreaterThan>(CriterionHandler.OPERATOR_GREATER_THAN)
public static final ComparisonCriterionHandler<Query.LessThan> LESS_THAN = new ComparisonCriterionHandler<Query.LessThan>(CriterionHandler.OPERATOR_LESS_THAN)
@@ -771,24 +789,21 @@ class Neo4jQuery extends Query {
PersistentProperty association = graphEntity.getPropertyByName(criterion.property)
if (association instanceof Association && !(association instanceof Basic)) {
GraphPersistentEntity associatedGraphEntity = (GraphPersistentEntity) ((Association) association).associatedEntity
- if(graphEntity.isRelationshipEntity() && RelationshipPersistentEntity.isRelationshipAssociation((Association)association)) {
+ if (graphEntity.isRelationshipEntity() && RelationshipPersistentEntity.isRelationshipAssociation((Association) association)) {
lhs = associatedGraphEntity.formatId(association.name)
- }
- else {
+ } else {
String targetNodeName = "m_${builder.getNextMatchNumber()}"
builder.addMatch(
- graphEntity.formatAssociationPatternFromExisting((Association)association, "", prefix, targetNodeName)
+ graphEntity.formatAssociationPatternFromExisting((Association) association, "", prefix, targetNodeName)
)
lhs = graphEntity.formatId(targetNodeName)
}
- }
- else {
- if(graphEntity.isRelationshipEntity() && criterion.property == RelationshipPersistentEntity.TYPE) {
- builder.replaceFirstRelationshipMatch( ((RelationshipPersistentEntity)graphEntity).buildRelationshipMatchTo(null, CypherBuilder.REL_VAR))
+ } else {
+ if (graphEntity.isRelationshipEntity() && criterion.property == RelationshipPersistentEntity.TYPE) {
+ builder.replaceFirstRelationshipMatch(((RelationshipPersistentEntity) graphEntity).buildRelationshipMatchTo(null, CypherBuilder.REL_VAR))
lhs = "TYPE(r)"
- }
- else {
+ } else {
lhs = graphEntity.formatProperty(prefix, criterion.property)
}
@@ -818,6 +833,7 @@ class Neo4jQuery extends Query {
*/
@CompileStatic
static class PropertyComparisonCriterionHandler<T extends Query.PropertyComparisonCriterion> implements CriterionHandler<T> {
+
public static final PropertyComparisonCriterionHandler<Query.GreaterThanEqualsProperty> GREATER_THAN_EQUALS = new PropertyComparisonCriterionHandler<Query.GreaterThanEqualsProperty>(CriterionHandler.OPERATOR_GREATER_THAN_EQUALS)
public static final PropertyComparisonCriterionHandler<Query.GreaterThanProperty> GREATER_THAN = new PropertyComparisonCriterionHandler<Query.GreaterThanProperty>(CriterionHandler.OPERATOR_GREATER_THAN)
public static final PropertyComparisonCriterionHandler<Query.LessThanProperty> LESS_THAN = new PropertyComparisonCriterionHandler<Query.LessThanProperty>(CriterionHandler.OPERATOR_LESS_THAN)
@@ -834,7 +850,7 @@ class Neo4jQuery extends Query {
@Override
CypherExpression handle(GraphPersistentEntity entity, T criterion, CypherBuilder builder, String prefix) {
def operator = COMPARISON_OPERATORS.get(criterion.getClass())
- if(operator == null) {
+ if (operator == null) {
throw new UnsupportedOperationException("Unsupported Neo4j property comparison: ${criterion}")
}
return new CypherExpression("$prefix.${criterion.property}${operator}n.${criterion.otherProperty}")
@@ -850,7 +866,7 @@ class Neo4jQuery extends Query {
public static final SizeCriterionHandler<Query.SizeEquals> EQUALS = new SizeCriterionHandler<Query.SizeEquals>(CriterionHandler.OPERATOR_EQUALS)
public static final SizeCriterionHandler<Query.SizeNotEquals> NOT_EQUALS = new SizeCriterionHandler<Query.SizeNotEquals>(CriterionHandler.OPERATOR_NOT_EQUALS)
- public static final SizeCriterionHandler<Query.SizeGreaterThan> GREATER_THAN= new SizeCriterionHandler<Query.SizeGreaterThan>(CriterionHandler.OPERATOR_GREATER_THAN)
+ public static final SizeCriterionHandler<Query.SizeGreaterThan> GREATER_THAN = new SizeCriterionHandler<Query.SizeGreaterThan>(CriterionHandler.OPERATOR_GREATER_THAN)
public static final SizeCriterionHandler<Query.SizeGreaterThanEquals> GREATER_THAN_EQUALS = new SizeCriterionHandler<Query.SizeGreaterThanEquals>(CriterionHandler.OPERATOR_GREATER_THAN_EQUALS)
public static final SizeCriterionHandler<Query.SizeLessThan> LESS_THAN = new SizeCriterionHandler<Query.SizeLessThan>(CriterionHandler.OPERATOR_LESS_THAN)
public static final SizeCriterionHandler<Query.SizeLessThanEquals> LESS_THAN_EQUALS = new SizeCriterionHandler<Query.SizeLessThanEquals>(CriterionHandler.OPERATOR_LESS_THAN_EQUALS)
@@ -874,7 +890,8 @@ class Neo4jQuery extends Query {
@EqualsAndHashCode
static class CypherExpression {
- @Delegate final CharSequence expression
+ @Delegate
+ final CharSequence expression
CypherExpression(String lhs, String rhs, String operator) {
this.expression = "$lhs$operator$rhs".toString()
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingDelete.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingDelete.java
index c0d0478a84..39652b69d8 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingDelete.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingDelete.java
@@ -18,6 +18,15 @@
*/
package org.grails.datastore.gorm.neo4j.engine;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.neo4j.driver.Transaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.grails.datastore.gorm.neo4j.CypherBuilder;
import org.grails.datastore.gorm.neo4j.GraphPersistentEntity;
import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity;
@@ -26,14 +35,6 @@ import org.grails.datastore.mapping.core.impl.PendingOperationAdapter;
import org.grails.datastore.mapping.engine.EntityAccess;
import org.grails.datastore.mapping.model.config.GormProperties;
import org.grails.datastore.mapping.model.types.Association;
-import org.neo4j.driver.Transaction;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.Map;
import static org.grails.datastore.gorm.neo4j.engine.RelationshipPendingInsert.FROM;
import static org.grails.datastore.gorm.neo4j.engine.RelationshipPendingInsert.TO;
@@ -46,14 +47,13 @@ import static org.grails.datastore.gorm.neo4j.engine.RelationshipPendingInsert.T
*/
public class RelationshipPendingDelete extends PendingOperationAdapter<Object, Serializable> {
- private static Logger log = LoggerFactory.getLogger(RelationshipPendingDelete.class);
+ private static final Logger log = LoggerFactory.getLogger(RelationshipPendingDelete.class);
private final Transaction boltTransaction;
private final Association association;
private final Collection<Serializable> targetIdentifiers;
private final EntityAccess entityAccess;
-
public RelationshipPendingDelete(EntityAccess parent, Association association, Collection<Serializable> pendingInserts, Transaction boltTransaction) {
super(parent.getPersistentEntity(), (Serializable) parent.getIdentifier(), parent.getEntity());
this.targetIdentifiers = pendingInserts;
@@ -68,8 +68,8 @@ public class RelationshipPendingDelete extends PendingOperationAdapter<Object, S
Serializable parentId = getNativeKey();
final boolean isRelationshipAssociation = graphParent.isRelationshipEntity();
- if(isRelationshipAssociation) {
- if(association.getName().equals(FROM)) {
+ if (isRelationshipAssociation) {
+ if (association.getName().equals(FROM)) {
RelationshipPersistentEntity relEntity = (RelationshipPersistentEntity) graphParent;
GraphPersistentEntity graphChild = relEntity.getToEntity();
graphParent = relEntity.getFromEntity();
@@ -78,9 +78,8 @@ public class RelationshipPendingDelete extends PendingOperationAdapter<Object, S
Object startEntity = entityAccess.getProperty(FROM);
parentId = graphParent.getReflector().getIdentifier(startEntity);
this.targetIdentifiers.clear();
- this.targetIdentifiers.add( graphChild.getReflector().getIdentifier(endEntity) );
- }
- else {
+ this.targetIdentifiers.add(graphChild.getReflector().getIdentifier(endEntity));
+ } else {
// don't do anything for the 'to' end
return;
}
@@ -88,17 +87,15 @@ public class RelationshipPendingDelete extends PendingOperationAdapter<Object, S
final Map<String, Object> params = new LinkedHashMap<>(2);
- if(RelationshipUtils.useReversedMappingFor(association)) {
+ if (RelationshipUtils.useReversedMappingFor(association)) {
params.put(GormProperties.IDENTITY, parentId);
- }
- else {
+ } else {
params.put(CypherBuilder.START, parentId);
params.put(CypherBuilder.END, targetIdentifiers);
}
-
String cypher = graphParent.formatAssociationDelete(association, entityAccess.getEntity());
- if(cypher != null) {
+ if (cypher != null) {
if (log.isDebugEnabled()) {
log.debug("DELETE Cypher [{}] for parameters [{}]", cypher, params);
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingInsert.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingInsert.java
index bea372782c..7099c4e1c3 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingInsert.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingInsert.java
@@ -18,22 +18,35 @@
*/
package org.grails.datastore.gorm.neo4j.engine;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.neo4j.driver.Transaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import grails.neo4j.Relationship;
-import org.grails.datastore.gorm.neo4j.*;
+import org.grails.datastore.gorm.neo4j.CypherBuilder;
+import org.grails.datastore.gorm.neo4j.GraphPersistentEntity;
+import org.grails.datastore.gorm.neo4j.Neo4jMappingContext;
+import org.grails.datastore.gorm.neo4j.Neo4jSession;
+import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity;
+import org.grails.datastore.gorm.neo4j.RelationshipUtils;
import org.grails.datastore.gorm.neo4j.mapping.config.DynamicAssociation;
import org.grails.datastore.gorm.neo4j.mapping.config.DynamicToOneAssociation;
import org.grails.datastore.mapping.core.impl.PendingInsertAdapter;
import org.grails.datastore.mapping.engine.EntityAccess;
import org.grails.datastore.mapping.model.PersistentProperty;
-import org.grails.datastore.mapping.model.types.*;
+import org.grails.datastore.mapping.model.types.Association;
+import org.grails.datastore.mapping.model.types.Basic;
+import org.grails.datastore.mapping.model.types.OneToMany;
+import org.grails.datastore.mapping.model.types.OneToOne;
+import org.grails.datastore.mapping.model.types.Simple;
+import org.grails.datastore.mapping.model.types.TenantId;
import org.grails.datastore.mapping.reflect.EntityReflector;
-import org.neo4j.driver.Session;
-import org.neo4j.driver.Transaction;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.util.*;
/**
* Represents a pending relationship insert
@@ -43,6 +56,7 @@ import java.util.*;
*
*/
public class RelationshipPendingInsert extends PendingInsertAdapter<Object, Serializable> {
+
/**
* The name of the from property
*/
@@ -54,7 +68,7 @@ public class RelationshipPendingInsert extends PendingInsertAdapter<Object, Seri
public static final String SOURCE_TYPE = "sourceType";
public static final String TARGET_TYPE = "targetType";
- private static Logger log = LoggerFactory.getLogger(RelationshipPendingInsert.class);
+ private static final Logger log = LoggerFactory.getLogger(RelationshipPendingInsert.class);
private final Transaction boltTransaction;
private final Association association;
private final Collection<Serializable> targetIdentifiers;
@@ -74,16 +88,15 @@ public class RelationshipPendingInsert extends PendingInsertAdapter<Object, Seri
@Override
public void run() {
-
GraphPersistentEntity graphParent = (GraphPersistentEntity) getEntity();
GraphPersistentEntity graphChild = (GraphPersistentEntity) association.getAssociatedEntity();
- Map<String,Object> params = new LinkedHashMap<>(2);
+ Map<String, Object> params = new LinkedHashMap<>(2);
EntityAccess entityAccess = getEntityAccess();
Object parentId = entityAccess.getIdentifier();
final boolean isRelationshipAssociation = Relationship.class.isAssignableFrom(graphParent.getJavaClass());
- if(isRelationshipAssociation) {
- if(association.getName().equals(FROM)) {
+ if (isRelationshipAssociation) {
+ if (association.getName().equals(FROM)) {
Association endProperty = (Association) graphParent.getPropertyByName(TO);
Association startProperty = (Association) graphParent.getPropertyByName(FROM);
@@ -94,9 +107,8 @@ public class RelationshipPendingInsert extends PendingInsertAdapter<Object, Seri
Object startEntity = entityAccess.getProperty(FROM);
parentId = graphParent.getReflector().getIdentifier(startEntity);
this.targetIdentifiers.clear();
- this.targetIdentifiers.add( graphChild.getReflector().getIdentifier(endEntity) );
- }
- else {
+ this.targetIdentifiers.add(graphChild.getReflector().getIdentifier(endEntity));
+ } else {
// don't do anything for the 'to' end
return;
}
@@ -110,65 +122,62 @@ public class RelationshipPendingInsert extends PendingInsertAdapter<Object, Seri
final String relMatch;
- if(association instanceof DynamicToOneAssociation) {
+ if (association instanceof DynamicToOneAssociation) {
LinkedHashMap<String, String> attrs = new LinkedHashMap<String, String>();
attrs.put(SOURCE_TYPE, graphParent.getJavaClass().getSimpleName());
attrs.put(TARGET_TYPE, graphChild.getJavaClass().getSimpleName());
relMatch = RelationshipUtils.matchForAssociation(association, "r", attrs);
- }
- else if(isRelationshipAssociation) {
+ } else if (isRelationshipAssociation) {
LinkedHashMap<String, Object> attrs = new LinkedHashMap<>();
GraphPersistentEntity relEntity = (GraphPersistentEntity) getEntity();
EntityReflector reflector = relEntity.getReflector();
- Neo4jMappingContext mappingContext = (Neo4jMappingContext)relEntity.getMappingContext();
+ Neo4jMappingContext mappingContext = (Neo4jMappingContext) relEntity.getMappingContext();
Neo4jEntityPersister entityPersister = session.getEntityPersister(getEntityAccess().getEntity());
- if(entityPersister.cancelInsert(entity, getEntityAccess())) {
+ if (entityPersister.cancelInsert(entity, getEntityAccess())) {
// operation cancelled, return
return;
}
for (PersistentProperty pp : relEntity.getPersistentProperties()) {
- if(pp instanceof Simple || pp instanceof Basic || pp instanceof TenantId) {
+ if (pp instanceof Simple || pp instanceof Basic || pp instanceof TenantId) {
String propertyName = pp.getName();
- if(RelationshipPersistentEntity.TYPE.equals(propertyName)) {
+ if (RelationshipPersistentEntity.TYPE.equals(propertyName)) {
continue;
}
Object v = reflector.getProperty(getNativeEntry(), propertyName);
- if(v != null) {
+ if (v != null) {
attrs.put(propertyName, mappingContext.convertToNative(v));
}
}
}
Relationship relationship = (Relationship) getEntityAccess().getEntity();
- attrs.putAll( relationship.attributes() );
+ attrs.putAll(relationship.attributes());
params.put("rProps", attrs);
relMatch = RelationshipUtils.toMatch(association, relationship);
- }
- else {
+ } else {
relMatch = RelationshipUtils.matchForAssociation(association, "r");
}
- if(isUpdate &&
- (association instanceof DynamicAssociation ||
- ((association.isBidirectional() && (association instanceof OneToMany)) || (association instanceof OneToOne)) &&
- !RelationshipUtils.useReversedMappingFor(association))) {
+ if (isUpdate &&
+ (association instanceof DynamicAssociation ||
+ ((association.isBidirectional() && (association instanceof OneToMany)) || (association instanceof OneToOne)) &&
+ !RelationshipUtils.useReversedMappingFor(association))) {
// delete any previous
StringBuilder cypher = new StringBuilder(CypherBuilder.buildRelationshipMatch(labelsFrom, relMatch, labelsTo));
Map<String, Object> deleteParams;
- if(association instanceof DynamicToOneAssociation || association instanceof OneToOne) {
+ if (association instanceof DynamicToOneAssociation || association instanceof OneToOne) {
cypher.append(graphChild.formatId(FROM));
- deleteParams = Collections.<String, Object>singletonMap(CypherBuilder.START, Collections.singletonList(parentId));
- }
- else {
+ deleteParams = Collections.singletonMap(CypherBuilder.START, Collections.singletonList(parentId));
+ } else {
cypher.append(graphChild.formatId(TO));
- deleteParams = Collections.<String, Object>singletonMap(CypherBuilder.START, targetIdentifiers);
+ deleteParams = Collections.singletonMap(CypherBuilder.START, targetIdentifiers);
}
cypher.append(" IN $").append(CypherBuilder.START).append(" DELETE r");
- if(log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("DELETE Cypher [{}] for parameters [{}]", cypher, deleteParams);
}
boltTransaction.run(cypher.toString(), deleteParams);
@@ -177,16 +186,16 @@ public class RelationshipPendingInsert extends PendingInsertAdapter<Object, Seri
StringBuilder cypherQuery = new StringBuilder(String.format(CypherBuilder.CYPHER_FROM_TO_NODES_MATCH, labelsFrom, labelsTo));
cypherQuery.append(graphParent.formatId(RelationshipPersistentEntity.FROM))
- .append(" = $")
- .append(CypherBuilder.START)
- .append(" AND ")
- .append(graphChild.formatId(RelationshipPersistentEntity.TO))
- .append(" IN $")
- .append(CypherBuilder.END)
- .append(" MERGE (from)")
- .append(relMatch)
- .append("(to)");
- if(isRelationshipAssociation) {
+ .append(" = $")
+ .append(CypherBuilder.START)
+ .append(" AND ")
+ .append(graphChild.formatId(RelationshipPersistentEntity.TO))
+ .append(" IN $")
+ .append(CypherBuilder.END)
+ .append(" MERGE (from)")
+ .append(relMatch)
+ .append("(to)");
+ if (isRelationshipAssociation) {
cypherQuery.append(" ON CREATE SET r=$rProps");
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/extensions/Neo4jExtensions.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/extensions/Neo4jExtensions.groovy
index fdb281e69e..83ba1116b3 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/extensions/Neo4jExtensions.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/extensions/Neo4jExtensions.groovy
@@ -20,18 +20,20 @@ package org.grails.datastore.gorm.neo4j.extensions
import groovy.transform.CompileStatic
import org.codehaus.groovy.runtime.typehandling.GroovyCastException
-import org.grails.datastore.gorm.neo4j.Neo4jDatastore
-import org.grails.datastore.gorm.neo4j.Neo4jSession
-import org.grails.datastore.gorm.neo4j.collection.Neo4jPath
-import org.grails.datastore.gorm.neo4j.collection.Neo4jResultList
-import org.grails.datastore.mapping.core.AbstractDatastore
-import org.neo4j.driver.Result
+
import org.neo4j.driver.QueryRunner
+import org.neo4j.driver.Result
import org.neo4j.driver.types.MapAccessor
import org.neo4j.driver.types.Node
import org.neo4j.driver.types.Path
import org.neo4j.driver.types.Relationship
+import org.grails.datastore.gorm.neo4j.Neo4jDatastore
+import org.grails.datastore.gorm.neo4j.Neo4jSession
+import org.grails.datastore.gorm.neo4j.collection.Neo4jPath
+import org.grails.datastore.gorm.neo4j.collection.Neo4jResultList
+import org.grails.datastore.mapping.core.AbstractDatastore
+
/**
* Extension methods to improve the Neo4j experience in Groovy.
*
@@ -72,16 +74,14 @@ class Neo4jExtensions {
*/
static <N> N asType(Node node, Class<N> c) {
//TODO: Remove explicit typecast to Class<?> once GROOVY-9460 is resolved
- if(Map.isAssignableFrom((Class<?>) c)) {
- return (N)node.asMap()
- }
- else {
- Neo4jSession session = (Neo4jSession)AbstractDatastore.retrieveSession(Neo4jDatastore)
+ if (Map.isAssignableFrom((Class<?>) c)) {
+ return (N) node.asMap()
+ } else {
+ Neo4jSession session = (Neo4jSession) AbstractDatastore.retrieveSession(Neo4jDatastore)
def entityPersister = session.getEntityPersister(c)
- if(entityPersister != null) {
- return (N)entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), node)
- }
- else {
+ if (entityPersister != null) {
+ return (N) entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), node)
+ } else {
throw new ClassCastException("Class [$c.name] is not a GORM entity")
}
}
@@ -96,12 +96,11 @@ class Neo4jExtensions {
* @return The domain instance
*/
static <N> N asType(Relationship rel, Class<N> c) {
- Neo4jSession session = (Neo4jSession)AbstractDatastore.retrieveSession(Neo4jDatastore)
+ Neo4jSession session = (Neo4jSession) AbstractDatastore.retrieveSession(Neo4jDatastore)
def entityPersister = session.getEntityPersister(c)
- if(entityPersister != null) {
- return (N)entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), rel, Collections.emptyMap(), Collections.emptyMap())
- }
- else {
+ if (entityPersister != null) {
+ return (N) entityPersister.unmarshallOrFromCache(entityPersister.getPersistentEntity(), rel, Collections.emptyMap(), Collections.emptyMap())
+ } else {
throw new ClassCastException("Class [$c.name] is not a GORM relationship entity")
}
}
@@ -115,11 +114,10 @@ class Neo4jExtensions {
* @return The domain instance
*/
static grails.neo4j.Path asType(Path path, Class<grails.neo4j.Path> c) {
- if(grails.neo4j.Path.isAssignableFrom(c)) {
- Neo4jSession session = (Neo4jSession)AbstractDatastore.retrieveSession(Neo4jDatastore)
+ if (grails.neo4j.Path.isAssignableFrom(c)) {
+ Neo4jSession session = (Neo4jSession) AbstractDatastore.retrieveSession(Neo4jDatastore)
return new Neo4jPath<>(session.datastore, path)
- }
- else {
+ } else {
throw new GroovyCastException(path, c)
}
}
@@ -133,18 +131,16 @@ class Neo4jExtensions {
* @return The domain instance
*/
static <N> N asType(Result result, Class<N> c) {
- Neo4jSession session = (Neo4jSession)AbstractDatastore.retrieveSession(Neo4jDatastore)
+ Neo4jSession session = (Neo4jSession) AbstractDatastore.retrieveSession(Neo4jDatastore)
def entityPersister = session.getEntityPersister(c)
- if(entityPersister != null) {
+ if (entityPersister != null) {
def resultList = new Neo4jResultList(0, result, entityPersister)
- if(!resultList.isEmpty()) {
- return (N)resultList.get(0)
- }
- else {
+ if (!resultList.isEmpty()) {
+ return (N) resultList.get(0)
+ } else {
return null
}
- }
- else {
+ } else {
throw new ClassCastException("Class [$c.name] is not a GORM entity")
}
}
@@ -158,12 +154,11 @@ class Neo4jExtensions {
* @return The domain instance
*/
static <N> List<N> toList(Result result, Class<N> c) {
- Neo4jSession session = (Neo4jSession)AbstractDatastore.retrieveSession(Neo4jDatastore)
+ Neo4jSession session = (Neo4jSession) AbstractDatastore.retrieveSession(Neo4jDatastore)
def entityPersister = session.getEntityPersister(c)
- if(entityPersister != null) {
+ if (entityPersister != null) {
return new Neo4jResultList(0, result, entityPersister)
- }
- else {
+ } else {
throw new ClassCastException("Class [$c.name] is not a GORM entity")
}
}
@@ -177,9 +172,9 @@ class Neo4jExtensions {
* @return The query result
*/
static Result execute(QueryRunner session, String cypher, List<Object> positionalParameters) {
- Map<String,Object> params = new LinkedHashMap<>()
- int i = 0;
- for(p in positionalParameters) {
+ Map<String, Object> params = new LinkedHashMap<>()
+ int i = 0
+ for (p in positionalParameters) {
params.put(String.valueOf(++i), p)
}
session.run(cypher, params)
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/identity/SnowflakeIdGenerator.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/identity/SnowflakeIdGenerator.java
index 14c6527096..54ff48929d 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/identity/SnowflakeIdGenerator.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/identity/SnowflakeIdGenerator.java
@@ -18,16 +18,17 @@
*/
package org.grails.datastore.gorm.neo4j.identity;
-import org.grails.datastore.gorm.neo4j.IdGenerator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.Serializable;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Random;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.grails.datastore.gorm.neo4j.IdGenerator;
+
/**
*
* Generate unique IDs using the Twitter Snowflake algorithm (see https://github.com/twitter/snowflake). Snowflake IDs are 64 bit positive longs composed of: - 41 bits time stamp - 10 bits machine id - 12 bits sequence number
@@ -37,7 +38,7 @@ import java.util.Random;
public class SnowflakeIdGenerator implements IdGenerator {
- private static Logger log = LoggerFactory.getLogger(SnowflakeIdGenerator.class);
+ private static final Logger log = LoggerFactory.getLogger(SnowflakeIdGenerator.class);
private final long datacenterIdBits = 10L;
private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
@@ -64,7 +65,7 @@ public class SnowflakeIdGenerator implements IdGenerator {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new IllegalArgumentException("Clock moved backwards. Refusing to generate id for " + (
- lastTimestamp - timestamp) + " milliseconds.");
+ lastTimestamp - timestamp) + " milliseconds.");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) % sequenceMax;
@@ -76,8 +77,8 @@ public class SnowflakeIdGenerator implements IdGenerator {
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) |
- (datacenterId << datacenterIdShift) |
- sequence;
+ (datacenterId << datacenterIdShift) |
+ sequence;
}
protected long tilNextMillis(long lastTimestamp) {
@@ -110,7 +111,7 @@ public class SnowflakeIdGenerator implements IdGenerator {
}
private boolean isInvalidHardwareAddress(byte[] hardwareAddress) {
- return ((hardwareAddress == null) || (hardwareAddress.length<6));
+ return ((hardwareAddress == null) || (hardwareAddress.length < 6));
}
-}
\ No newline at end of file
+}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/Attribute.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/Attribute.groovy
index 9b0626e68b..f0e107834b 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/Attribute.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/Attribute.groovy
@@ -19,10 +19,11 @@
package org.grails.datastore.gorm.neo4j.mapping.config
-import grails.neo4j.Direction
import groovy.transform.CompileStatic
import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy
+
+import grails.neo4j.Direction
import org.grails.datastore.mapping.config.Property
/**
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicAssociation.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicAssociation.java
index 374757cb33..dc590eb2eb 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicAssociation.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicAssociation.java
@@ -28,4 +28,5 @@ import org.grails.datastore.mapping.model.PersistentProperty;
* @since 5.0
*/
public interface DynamicAssociation<T extends Property> extends PersistentProperty<T> {
+
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToManyAssociation.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToManyAssociation.java
index 1c1ba2aeb6..fc450f8f4c 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToManyAssociation.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToManyAssociation.java
@@ -29,7 +29,7 @@ import org.grails.datastore.mapping.model.types.ToMany;
* @author Graeme Rocher
* @since 5.0
*/
-public class DynamicToManyAssociation extends ToMany implements DynamicAssociation{
+public class DynamicToManyAssociation extends ToMany implements DynamicAssociation {
public DynamicToManyAssociation(PersistentEntity owner, MappingContext context, String name, PersistentEntity associatedType) {
super(owner, context, name, associatedType.getJavaClass());
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToOneAssociation.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToOneAssociation.java
index 670592080a..fe63d08bb1 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToOneAssociation.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/DynamicToOneAssociation.java
@@ -29,7 +29,7 @@ import org.grails.datastore.mapping.model.types.ToOne;
* @author Graeme Rocher
* @since 5.0
*/
-public class DynamicToOneAssociation extends ToOne implements DynamicAssociation{
+public class DynamicToOneAssociation extends ToOne implements DynamicAssociation {
public DynamicToOneAssociation(PersistentEntity owner, MappingContext context, String name, PersistentEntity associatedType) {
super(owner, context, name, associatedType.getJavaClass());
@@ -44,8 +44,7 @@ public class DynamicToOneAssociation extends ToOne implements DynamicAssociation
@Override
public boolean equals(Object obj) {
- if(obj instanceof DynamicToOneAssociation) {
- DynamicToOneAssociation other = (DynamicToOneAssociation) obj;
+ if (obj instanceof DynamicToOneAssociation other) {
return other.getName().equals(name) && other.getOwner().getJavaClass().equals(getOwner().getJavaClass());
}
return false;
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/NodeConfig.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/NodeConfig.groovy
index 84f7a50c21..ee2aa3004a 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/NodeConfig.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/NodeConfig.groovy
@@ -20,8 +20,9 @@ package org.grails.datastore.gorm.neo4j.mapping.config
import groovy.transform.CompileStatic
import groovy.transform.builder.Builder
-import groovy.transform.builder.SimpleStrategy;
-import org.grails.datastore.mapping.config.Entity;
+import groovy.transform.builder.SimpleStrategy
+
+import org.grails.datastore.mapping.config.Entity
/**
* Extends the default {@link Entity} configuration adding the ability to assign labels
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/RelationshipConfig.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/RelationshipConfig.groovy
index 571bb77c7f..46562c5521 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/RelationshipConfig.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/config/RelationshipConfig.groovy
@@ -19,11 +19,11 @@
package org.grails.datastore.gorm.neo4j.mapping.config
-import grails.neo4j.Direction
import groovy.transform.CompileStatic
import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy
-import org.grails.datastore.mapping.config.Entity
+
+import grails.neo4j.Direction
/**
* Config for a relationship
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/reflect/Neo4jNameUtils.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/reflect/Neo4jNameUtils.groovy
index 8268cee5f4..5f9ae81c64 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/reflect/Neo4jNameUtils.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/mapping/reflect/Neo4jNameUtils.groovy
@@ -19,10 +19,10 @@
package org.grails.datastore.gorm.neo4j.mapping.reflect
import groovy.transform.CompileStatic
+
import org.grails.datastore.gorm.neo4j.parsers.PlingStemmer
import org.grails.datastore.mapping.reflect.NameUtils
-
/**
* Utilities for Neo4j naming conventions
*
@@ -36,7 +36,7 @@ class Neo4jNameUtils extends NameUtils {
* @param word The word
* @return Whether the given word is plural
*/
- static boolean isPlural( String word ) {
+ static boolean isPlural(String word) {
PlingStemmer.isPlural(word)
}
@@ -44,7 +44,7 @@ class Neo4jNameUtils extends NameUtils {
* @param word The word
* @return Whether the given word is singular
*/
- static boolean isSingular( String word ) {
- PlingStemmer.isSingular( word )
+ static boolean isSingular(String word) {
+ PlingStemmer.isSingular(word)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/parsers/PlingStemmer.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/parsers/PlingStemmer.java
index 3f88b17e10..1554810f19 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/parsers/PlingStemmer.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/parsers/PlingStemmer.java
@@ -18,8 +18,12 @@
*/
package org.grails.datastore.gorm.neo4j.parsers;
-import java.util.*;
-
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
/**
* <p>
@@ -69,6 +73,717 @@ import java.util.*;
*/
public class PlingStemmer {
+ /**
+ * Words that end in "-se" in their plural forms (like "nurse" etc.)
+ */
+ private static final Set<String> categorySE_SES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "nurses",
+ "cruises",
+ "premises",
+ "houses",
+ "courses",
+ "cases"
+ )));
+ /**
+ * Words that do not have a distinct plural form (like "atlas" etc.)
+ */
+ private static final Set<String> category00 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "alias",
+ "asbestos",
+ "atlas",
+ "barracks",
+ "bathos",
+ "bias",
+ "breeches",
+ "britches",
+ "canvas",
+ "chaos",
+ "clippers",
+ "contretemps",
+ "corps",
+ "cosmos",
+ "crossroads",
+ "diabetes",
+ "ethos",
+ "gallows",
+ "gas",
+ "graffiti",
+ "headquarters",
+ "herpes",
+ "high-jinks",
+ "innings",
+ "jackanapes",
+ "lens",
+ "means",
+ "measles",
+ "mews",
+ "mumps",
+ "news",
+ "pathos",
+ "pincers",
+ "pliers",
+ "proceedings",
+ "rabies",
+ "rhinoceros",
+ "sassafras",
+ "scissors",
+ "series",
+ "shears",
+ "species",
+ "tuna"
+ )));
+ /**
+ * Words that change from "-um" to "-a" (like "curriculum" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryUM_A = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "addenda",
+ "agenda",
+ "aquaria",
+ "bacteria",
+ "candelabra",
+ "compendia",
+ "consortia",
+ "crania",
+ "curricula",
+ "data",
+ "desiderata",
+ "dicta",
+ "emporia",
+ "enconia",
+ "errata",
+ "extrema",
+ "gymnasia",
+ "honoraria",
+ "interregna",
+ "lustra",
+ "maxima",
+ "media",
+ "memoranda",
+ "millenia",
+ "minima",
+ "momenta",
+ "optima",
+ "ova",
+ "phyla",
+ "quanta",
+ "rostra",
+ "spectra",
+ "specula",
+ "stadia",
+ "strata",
+ "symposia",
+ "trapezia",
+ "ultimata",
+ "vacua",
+ "vela"
+ )));
+ /**
+ * Words that change from "-on" to "-a" (like "phenomenon" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryON_A = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "aphelia",
+ "asyndeta",
+ "automata",
+ "criteria",
+ "hyperbata",
+ "noumena",
+ "organa",
+ "perihelia",
+ "phenomena",
+ "prolegomena"
+ )));
+ /**
+ * Words that change from "-o" to "-i" (like "libretto" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryO_I = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "alti",
+ "bassi",
+ "canti",
+ "contralti",
+ "crescendi",
+ "libretti",
+ "soli",
+ "soprani",
+ "tempi",
+ "virtuosi"
+ )));
+ /**
+ * Words that change from "-us" to "-i" (like "fungus" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryUS_I = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "alumni",
+ "bacilli",
+ "cacti",
+ "foci",
+ "fungi",
+ "genii",
+ "hippopotami",
+ "incubi",
+ "nimbi",
+ "nuclei",
+ "nucleoli",
+ "octopi",
+ "radii",
+ "stimuli",
+ "styli",
+ "succubi",
+ "syllabi",
+ "termini",
+ "tori",
+ "umbilici",
+ "uteri"
+ )));
+ /**
+ * Words that change from "-ix" to "-ices" (like "appendix" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryIX_ICES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "appendices",
+ "cervices"
+ )));
+ /**
+ * Words that change from "-is" to "-es" (like "axis" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryIS_ES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ // plus everybody ending in theses
+ "analyses",
+ "axes",
+ "bases",
+ "crises",
+ "diagnoses",
+ "ellipses",
+ "emphases",
+ "neuroses",
+ "oases",
+ "paralyses",
+ "synopses"
+ )));
+ /**
+ * Words that change from "-oe" to "-oes" (like "toe" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryOE_OES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "aloes",
+ "backhoes",
+ "beroes",
+ "canoes",
+ "chigoes",
+ "cohoes",
+ "does",
+ "felloes",
+ "floes",
+ "foes",
+ "gumshoes",
+ "hammertoes",
+ "hoes",
+ "hoopoes",
+ "horseshoes",
+ "leucothoes",
+ "mahoes",
+ "mistletoes",
+ "oboes",
+ "overshoes",
+ "pahoehoes",
+ "pekoes",
+ "roes",
+ "shoes",
+ "sloes",
+ "snowshoes",
+ "throes",
+ "tic-tac-toes",
+ "tick-tack-toes",
+ "ticktacktoes",
+ "tiptoes",
+ "tit-tat-toes",
+ "toes",
+ "toetoes",
+ "tuckahoes",
+ "woes"
+ )));
+ /**
+ * Words that change from "-ex" to "-ices" (like "index" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryEX_ICES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "apices",
+ "codices",
+ "cortices",
+ "indices",
+ "latices",
+ "murices",
+ "pontifices",
+ "silices",
+ "simplices",
+ "vertices",
+ "vortices"
+ )));
+ /**
+ * Words that change from "-u" to "-us" (like "emu" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryU_US = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "apercus",
+ "barbus",
+ "cornus",
+ "ecrus",
+ "emus",
+ "fondus",
+ "gnus",
+ "iglus",
+ "mus",
+ "nandus",
+ "napus",
+ "poilus",
+ "quipus",
+ "snafus",
+ "tabus",
+ "tamandus",
+ "tatus",
+ "timucus",
+ "tiramisus",
+ "tofus",
+ "tutus"
+ )));
+ /**
+ * Words that change from "-sse" to "-sses" (like "finesse" etc.), listed in their plural forms
+ */
+ private static final Set<String> categorySSE_SSES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ //plus those ending in mousse
+ "bouillabaisses",
+ "coulisses",
+ "crevasses",
+ "crosses",
+ "cuisses",
+ "demitasses",
+ "ecrevisses",
+ "fesses",
+ "finesses",
+ "fosses",
+ "impasses",
+ "lacrosses",
+ "largesses",
+ "masses",
+ "noblesses",
+ "palliasses",
+ "pelisses",
+ "politesses",
+ "posses",
+ "tasses",
+ "wrasses"
+ )));
+ /**
+ * Words that change from "-che" to "-ches" (like "brioche" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryCHE_CHES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "adrenarches",
+ "attaches",
+ "avalanches",
+ "barouches",
+ "brioches",
+ "caches",
+ "caleches",
+ "caroches",
+ "cartouches",
+ "cliches",
+ "cloches",
+ "creches",
+ "demarches",
+ "douches",
+ "gouaches",
+ "guilloches",
+ "headaches",
+ "heartaches",
+ "huaraches",
+ "menarches",
+ "microfiches",
+ "moustaches",
+ "mustaches",
+ "niches",
+ "panaches",
+ "panoches",
+ "pastiches",
+ "penuches",
+ "pinches",
+ "postiches",
+ "psyches",
+ "quiches",
+ "schottisches",
+ "seiches",
+ "soutaches",
+ "synecdoches",
+ "thelarches",
+ "troches"
+ )));
+ /**
+ * Words that end with "-ics" and do not exist as nouns without the 's' (like "aerobics" etc.)
+ */
+ private static final Set<String> categoryICS = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "aerobatics",
+ "aerobics",
+ "aerodynamics",
+ "aeromechanics",
+ "aeronautics",
+ "alphanumerics",
+ "animatronics",
+ "apologetics",
+ "architectonics",
+ "astrodynamics",
+ "astronautics",
+ "astrophysics",
+ "athletics",
+ "atmospherics",
+ "autogenics",
+ "avionics",
+ "ballistics",
+ "bibliotics",
+ "bioethics",
+ "biometrics",
+ "bionics",
+ "bionomics",
+ "biophysics",
+ "biosystematics",
+ "cacogenics",
+ "calisthenics",
+ "callisthenics",
+ "catoptrics",
+ "civics",
+ "cladistics",
+ "cryogenics",
+ "cryonics",
+ "cryptanalytics",
+ "cybernetics",
+ "cytoarchitectonics",
+ "cytogenetics",
+ "diagnostics",
+ "dietetics",
+ "dramatics",
+ "dysgenics",
+ "econometrics",
+ "economics",
+ "electromagnetics",
+ "electronics",
+ "electrostatics",
+ "endodontics",
+ "enterics",
+ "ergonomics",
+ "eugenics",
+ "eurhythmics",
+ "eurythmics",
+ "exodontics",
+ "fibreoptics",
+ "futuristics",
+ "genetics",
+ "genomics",
+ "geographics",
+ "geophysics",
+ "geopolitics",
+ "geriatrics",
+ "glyptics",
+ "graphics",
+ "gymnastics",
+ "hermeneutics",
+ "histrionics",
+ "homiletics",
+ "hydraulics",
+ "hydrodynamics",
+ "hydrokinetics",
+ "hydroponics",
+ "hydrostatics",
+ "hygienics",
+ "informatics",
+ "kinematics",
+ "kinesthetics",
+ "kinetics",
+ "lexicostatistics",
+ "linguistics",
+ "lithoglyptics",
+ "liturgics",
+ "logistics",
+ "macrobiotics",
+ "macroeconomics",
+ "magnetics",
+ "magnetohydrodynamics",
+ "mathematics",
+ "metamathematics",
+ "metaphysics",
+ "microeconomics",
+ "microelectronics",
+ "mnemonics",
+ "morphophonemics",
+ "neuroethics",
+ "neurolinguistics",
+ "nucleonics",
+ "numismatics",
+ "obstetrics",
+ "onomastics",
+ "orthodontics",
+ "orthopaedics",
+ "orthopedics",
+ "orthoptics",
+ "paediatrics",
+ "patristics",
+ "patristics",
+ "pedagogics",
+ "pediatrics",
+ "periodontics",
+ "pharmaceutics",
+ "pharmacogenetics",
+ "pharmacokinetics",
+ "phonemics",
+ "phonetics",
+ "phonics",
+ "photomechanics",
+ "physiatrics",
+ "pneumatics",
+ "poetics",
+ "politics",
+ "pragmatics",
+ "prosthetics",
+ "prosthodontics",
+ "proteomics",
+ "proxemics",
+ "psycholinguistics",
+ "psychometrics",
+ "psychonomics",
+ "psychophysics",
+ "psychotherapeutics",
+ "robotics",
+ "semantics",
+ "semiotics",
+ "semitropics",
+ "sociolinguistics",
+ "stemmatics",
+ "strategics",
+ "subtropics",
+ "systematics",
+ "tectonics",
+ "telerobotics",
+ "therapeutics",
+ "thermionics",
+ "thermodynamics",
+ "thermostatics"
+ )));
+ /**
+ * Words that change from "-ie" to "-ies" (like "auntie" etc.), listed in their plural forms
+ */
+ private static final Set<String> categoryIE_IES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "aeries",
+ "anomies",
+ "aunties",
+ "baddies",
+ "beanies",
+ "birdies",
+ "boccies",
+ "bogies",
+ "bolshies",
+ "bombies",
+ "bonhomies",
+ "bonxies",
+ "booboisies",
+ "boogies",
+ "boogie-woogies",
+ "bookies",
+ "booties",
+ "bosies",
+ "bourgeoisies",
+ "brasseries",
+ "brassies",
+ "brownies",
+ "budgies",
+ "byrnies",
+ "caddies",
+ "calories",
+ "camaraderies",
+ "capercaillies",
+ "capercailzies",
+ "cassies",
+ "catties",
+ "causeries",
+ "charcuteries",
+ "chinoiseries",
+ "collies",
+ "commies",
+ "cookies",
+ "coolies",
+ "coonties",
+ "cooties",
+ "corries",
+ "coteries",
+ "cowpies",
+ "cowries",
+ "cozies",
+ "crappies",
+ "crossties",
+ "curies",
+ "dachsies",
+ "darkies",
+ "dassies",
+ "dearies",
+ "dickies",
+ "dies",
+ "dixies",
+ "doggies",
+ "dogies",
+ "dominies",
+ "dovekies",
+ "eyries",
+ "faeries",
+ "falsies",
+ "floozies",
+ "folies",
+ "foodies",
+ "freebies",
+ "gaucheries",
+ "gendarmeries",
+ "genies",
+ "ghillies",
+ "gillies",
+ "goalies",
+ "goonies",
+ "grannies",
+ "grotesqueries",
+ "groupies",
+ "hankies",
+ "hippies",
+ "hoagies",
+ "honkies",
+ "hymies",
+ "indies",
+ "junkies",
+ "kelpies",
+ "kilocalories",
+ "knobkerries",
+ "koppies",
+ "kylies",
+ "laddies",
+ "lassies",
+ "lies",
+ "lingeries",
+ "magpies",
+ "magpies",
+ "marqueteries",
+ "mashies",
+ "mealies",
+ "meanies",
+ "menageries",
+ "millicuries",
+ "mollies",
+ "facts1",
+ "moxies",
+ "neckties",
+ "newbies",
+ "nighties",
+ "nookies",
+ "oldies",
+ "organdies",
+ "panties",
+ "parqueteries",
+ "passementeries",
+ "patisseries",
+ "pies",
+ "pinkies",
+ "pixies",
+ "porkpies",
+ "potpies",
+ "prairies",
+ "preemies",
+ "premies",
+ "punkies",
+ "pyxies",
+ "quickies",
+ "ramies",
+ "reveries",
+ "rookies",
+ "rotisseries",
+ "scrapies",
+ "sharpies",
+ "smoothies",
+ "softies",
+ "stoolies",
+ "stymies",
+ "swaggies",
+ "sweeties",
+ "talkies",
+ "techies",
+ "ties",
+ "tooshies",
+ "toughies",
+ "townies",
+ "veggies",
+ "walkie-talkies",
+ "wedgies",
+ "weenies",
+ "weirdies",
+ "yardies",
+ "yuppies",
+ "zombies"
+ )));
+ /**
+ * Maps irregular Germanic English plural nouns to their singular form
+ */
+ private static final Map<String, String> irregular = Collections.unmodifiableMap(new HashMap<String, String>() {
+ {
+ put("beefs", "beef");
+ put("beeves", "beef");
+ put("brethren", "brother");
+ put("busses", "bus");
+ put("cattle", "cattlebeast");
+ put("children", "child");
+ put("corpora", "corpus");
+ put("ephemerides", "ephemeris");
+ put("firemen", "fireman");
+ put("genera", "genus");
+ put("genies", "genie");
+ put("genii", "genie");
+ put("kine", "cow");
+ put("lice", "louse");
+ put("men", "man");
+ put("mice", "mouse");
+ put("mongooses", "mongoose");
+ put("monies", "money");
+ put("mythoi", "mythos");
+ put("octopodes", "octopus");
+ put("octopuses", "octopus");
+ put("oxen", "ox");
+ put("people", "person");
+ put("soliloquies", "soliloquy");
+ put("throes", "throes");
+ put("trilbys", "trilby");
+ put("women", "woman");
+ }
+ });
+ /**
+ * Contains word forms that can either be plural or singular
+ */
+ private static final Set<String> singAndPlur = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+ "acoustics",
+ "aestetics",
+ "aquatics",
+ "basics",
+ "ceramics",
+ "classics",
+ "cosmetics",
+ "dermatoglyphics",
+ "dialectics",
+ "dynamics",
+ "esthetics",
+ "ethics",
+ "harmonics",
+ "heroics",
+ "isometrics",
+ "mechanics",
+ "metrics",
+ "statistics",
+ "optic",
+ "people",
+ "physics",
+ "polemics",
+ "premises",
+ "propaedeutics",
+ "pyrotechnics",
+ "quadratics",
+ "quarters",
+ "statistics",
+ "tactics",
+ "tropics"
+ )));
+
/**
* Tells whether a word form is plural. This method just checks whether the
* stem method alters the word
@@ -124,7 +839,7 @@ public class PlingStemmer {
if (categoryUS_I.contains(s)) return (stem = cut(s, "i") + "us");
//Wrong plural
if (s.endsWith("uses") && (categoryUS_I.contains(cut(s, "uses") + "i") ||
- s.equals("genuses") || s.equals("corpuses"))) return (stem = cut(s, "es"));
+ s.equals("genuses") || s.equals("corpuses"))) return (stem = cut(s, "es"));
// -ex to -ices
if (categoryEX_ICES.contains(s)) return (stem = cut(s, "ices") + "ex");
@@ -152,8 +867,8 @@ public class PlingStemmer {
// -us to -us
//No other common word ends in -us, except for false plurals of French words
//Catch words that are not latin or known to end in -u
- if (s.endsWith("us") && !s.endsWith("eaus") && !s.endsWith("ieus") && !noLatin(s)
- && !categoryU_US.contains(s)) return (stem = s);
+ if (s.endsWith("us") && !s.endsWith("eaus") && !s.endsWith("ieus") && !noLatin(s) &&
+ !categoryU_US.contains(s)) return (stem = s);
// -tooth to -teeth
// -goose to -geese
@@ -195,15 +910,15 @@ public class PlingStemmer {
// -[nlw]ife to -[nlw]ives
//No other common word ends with "[nlw]ive(s)" except for olive
if (s.endsWith("nives") || s.endsWith("lives") && !s.endsWith("olives") ||
- s.endsWith("wives")) return (stem = cut(s, "ves") + "fe");
+ s.endsWith("wives")) return (stem = cut(s, "ves") + "fe");
// -[aeo]lf to -ves exceptions: valve, solve
// -[^d]eaf to -ves exceptions: heave, weave
// -arf to -ves no exception
if (s.endsWith("alves") && !s.endsWith("valves") ||
- s.endsWith("olves") && !s.endsWith("solves") ||
- s.endsWith("eaves") && !s.endsWith("heaves") && !s.endsWith("weaves") ||
- s.endsWith("arves")) return (stem = cut(s, "ves") + "f");
+ s.endsWith("olves") && !s.endsWith("solves") ||
+ s.endsWith("eaves") && !s.endsWith("heaves") && !s.endsWith("weaves") ||
+ s.endsWith("arves")) return (stem = cut(s, "ves") + "f");
// -y to -ies
// -ies is very uncommon as a singular suffix
@@ -244,736 +959,8 @@ public class PlingStemmer {
*/
private static boolean noLatin(String s) {
return (s.indexOf('h') > 0 || s.indexOf('j') > 0 || s.indexOf('k') > 0 ||
- s.indexOf('w') > 0 || s.indexOf('y') > 0 || s.indexOf('z') > 0 ||
- s.indexOf("ou") > 0 || s.indexOf("sh") > 0 || s.indexOf("ch") > 0 ||
- s.endsWith("aus"));
+ s.indexOf('w') > 0 || s.indexOf('y') > 0 || s.indexOf('z') > 0 ||
+ s.indexOf("ou") > 0 || s.indexOf("sh") > 0 || s.indexOf("ch") > 0 ||
+ s.endsWith("aus"));
}
-
- /**
- * Words that end in "-se" in their plural forms (like "nurse" etc.)
- */
- private static Set<String> categorySE_SES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "nurses",
- "cruises",
- "premises",
- "houses",
- "courses",
- "cases"
- )));
-
- /**
- * Words that do not have a distinct plural form (like "atlas" etc.)
- */
- private static Set<String> category00 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "alias",
- "asbestos",
- "atlas",
- "barracks",
- "bathos",
- "bias",
- "breeches",
- "britches",
- "canvas",
- "chaos",
- "clippers",
- "contretemps",
- "corps",
- "cosmos",
- "crossroads",
- "diabetes",
- "ethos",
- "gallows",
- "gas",
- "graffiti",
- "headquarters",
- "herpes",
- "high-jinks",
- "innings",
- "jackanapes",
- "lens",
- "means",
- "measles",
- "mews",
- "mumps",
- "news",
- "pathos",
- "pincers",
- "pliers",
- "proceedings",
- "rabies",
- "rhinoceros",
- "sassafras",
- "scissors",
- "series",
- "shears",
- "species",
- "tuna"
- )));
-
- /**
- * Words that change from "-um" to "-a" (like "curriculum" etc.), listed in their plural forms
- */
- private static Set<String> categoryUM_A = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "addenda",
- "agenda",
- "aquaria",
- "bacteria",
- "candelabra",
- "compendia",
- "consortia",
- "crania",
- "curricula",
- "data",
- "desiderata",
- "dicta",
- "emporia",
- "enconia",
- "errata",
- "extrema",
- "gymnasia",
- "honoraria",
- "interregna",
- "lustra",
- "maxima",
- "media",
- "memoranda",
- "millenia",
- "minima",
- "momenta",
- "optima",
- "ova",
- "phyla",
- "quanta",
- "rostra",
- "spectra",
- "specula",
- "stadia",
- "strata",
- "symposia",
- "trapezia",
- "ultimata",
- "vacua",
- "vela"
- )));
-
- /**
- * Words that change from "-on" to "-a" (like "phenomenon" etc.), listed in their plural forms
- */
- private static Set<String> categoryON_A = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "aphelia",
- "asyndeta",
- "automata",
- "criteria",
- "hyperbata",
- "noumena",
- "organa",
- "perihelia",
- "phenomena",
- "prolegomena"
- )));
-
- /**
- * Words that change from "-o" to "-i" (like "libretto" etc.), listed in their plural forms
- */
- private static Set<String> categoryO_I = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "alti",
- "bassi",
- "canti",
- "contralti",
- "crescendi",
- "libretti",
- "soli",
- "soprani",
- "tempi",
- "virtuosi"
- )));
-
- /**
- * Words that change from "-us" to "-i" (like "fungus" etc.), listed in their plural forms
- */
- private static Set<String> categoryUS_I = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "alumni",
- "bacilli",
- "cacti",
- "foci",
- "fungi",
- "genii",
- "hippopotami",
- "incubi",
- "nimbi",
- "nuclei",
- "nucleoli",
- "octopi",
- "radii",
- "stimuli",
- "styli",
- "succubi",
- "syllabi",
- "termini",
- "tori",
- "umbilici",
- "uteri"
- )));
-
- /**
- * Words that change from "-ix" to "-ices" (like "appendix" etc.), listed in their plural forms
- */
- private static Set<String> categoryIX_ICES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "appendices",
- "cervices"
- )));
-
- /**
- * Words that change from "-is" to "-es" (like "axis" etc.), listed in their plural forms
- */
- private static Set<String> categoryIS_ES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- // plus everybody ending in theses
- "analyses",
- "axes",
- "bases",
- "crises",
- "diagnoses",
- "ellipses",
- "emphases",
- "neuroses",
- "oases",
- "paralyses",
- "synopses"
- )));
-
- /**
- * Words that change from "-oe" to "-oes" (like "toe" etc.), listed in their plural forms
- */
- private static Set<String> categoryOE_OES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "aloes",
- "backhoes",
- "beroes",
- "canoes",
- "chigoes",
- "cohoes",
- "does",
- "felloes",
- "floes",
- "foes",
- "gumshoes",
- "hammertoes",
- "hoes",
- "hoopoes",
- "horseshoes",
- "leucothoes",
- "mahoes",
- "mistletoes",
- "oboes",
- "overshoes",
- "pahoehoes",
- "pekoes",
- "roes",
- "shoes",
- "sloes",
- "snowshoes",
- "throes",
- "tic-tac-toes",
- "tick-tack-toes",
- "ticktacktoes",
- "tiptoes",
- "tit-tat-toes",
- "toes",
- "toetoes",
- "tuckahoes",
- "woes"
- )));
-
- /**
- * Words that change from "-ex" to "-ices" (like "index" etc.), listed in their plural forms
- */
- private static Set<String> categoryEX_ICES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "apices",
- "codices",
- "cortices",
- "indices",
- "latices",
- "murices",
- "pontifices",
- "silices",
- "simplices",
- "vertices",
- "vortices"
- )));
-
- /**
- * Words that change from "-u" to "-us" (like "emu" etc.), listed in their plural forms
- */
- private static Set<String> categoryU_US = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "apercus",
- "barbus",
- "cornus",
- "ecrus",
- "emus",
- "fondus",
- "gnus",
- "iglus",
- "mus",
- "nandus",
- "napus",
- "poilus",
- "quipus",
- "snafus",
- "tabus",
- "tamandus",
- "tatus",
- "timucus",
- "tiramisus",
- "tofus",
- "tutus"
- )));
-
- /**
- * Words that change from "-sse" to "-sses" (like "finesse" etc.), listed in their plural forms
- */
- private static Set<String> categorySSE_SSES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- //plus those ending in mousse
- "bouillabaisses",
- "coulisses",
- "crevasses",
- "crosses",
- "cuisses",
- "demitasses",
- "ecrevisses",
- "fesses",
- "finesses",
- "fosses",
- "impasses",
- "lacrosses",
- "largesses",
- "masses",
- "noblesses",
- "palliasses",
- "pelisses",
- "politesses",
- "posses",
- "tasses",
- "wrasses"
- )));
-
- /**
- * Words that change from "-che" to "-ches" (like "brioche" etc.), listed in their plural forms
- */
- private static Set<String> categoryCHE_CHES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "adrenarches",
- "attaches",
- "avalanches",
- "barouches",
- "brioches",
- "caches",
- "caleches",
- "caroches",
- "cartouches",
- "cliches",
- "cloches",
- "creches",
- "demarches",
- "douches",
- "gouaches",
- "guilloches",
- "headaches",
- "heartaches",
- "huaraches",
- "menarches",
- "microfiches",
- "moustaches",
- "mustaches",
- "niches",
- "panaches",
- "panoches",
- "pastiches",
- "penuches",
- "pinches",
- "postiches",
- "psyches",
- "quiches",
- "schottisches",
- "seiches",
- "soutaches",
- "synecdoches",
- "thelarches",
- "troches"
- )));
-
- /**
- * Words that end with "-ics" and do not exist as nouns without the 's' (like "aerobics" etc.)
- */
- private static Set<String> categoryICS = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "aerobatics",
- "aerobics",
- "aerodynamics",
- "aeromechanics",
- "aeronautics",
- "alphanumerics",
- "animatronics",
- "apologetics",
- "architectonics",
- "astrodynamics",
- "astronautics",
- "astrophysics",
- "athletics",
- "atmospherics",
- "autogenics",
- "avionics",
- "ballistics",
- "bibliotics",
- "bioethics",
- "biometrics",
- "bionics",
- "bionomics",
- "biophysics",
- "biosystematics",
- "cacogenics",
- "calisthenics",
- "callisthenics",
- "catoptrics",
- "civics",
- "cladistics",
- "cryogenics",
- "cryonics",
- "cryptanalytics",
- "cybernetics",
- "cytoarchitectonics",
- "cytogenetics",
- "diagnostics",
- "dietetics",
- "dramatics",
- "dysgenics",
- "econometrics",
- "economics",
- "electromagnetics",
- "electronics",
- "electrostatics",
- "endodontics",
- "enterics",
- "ergonomics",
- "eugenics",
- "eurhythmics",
- "eurythmics",
- "exodontics",
- "fibreoptics",
- "futuristics",
- "genetics",
- "genomics",
- "geographics",
- "geophysics",
- "geopolitics",
- "geriatrics",
- "glyptics",
- "graphics",
- "gymnastics",
- "hermeneutics",
- "histrionics",
- "homiletics",
- "hydraulics",
- "hydrodynamics",
- "hydrokinetics",
- "hydroponics",
- "hydrostatics",
- "hygienics",
- "informatics",
- "kinematics",
- "kinesthetics",
- "kinetics",
- "lexicostatistics",
- "linguistics",
- "lithoglyptics",
- "liturgics",
- "logistics",
- "macrobiotics",
- "macroeconomics",
- "magnetics",
- "magnetohydrodynamics",
- "mathematics",
- "metamathematics",
- "metaphysics",
- "microeconomics",
- "microelectronics",
- "mnemonics",
- "morphophonemics",
- "neuroethics",
- "neurolinguistics",
- "nucleonics",
- "numismatics",
- "obstetrics",
- "onomastics",
- "orthodontics",
- "orthopaedics",
- "orthopedics",
- "orthoptics",
- "paediatrics",
- "patristics",
- "patristics",
- "pedagogics",
- "pediatrics",
- "periodontics",
- "pharmaceutics",
- "pharmacogenetics",
- "pharmacokinetics",
- "phonemics",
- "phonetics",
- "phonics",
- "photomechanics",
- "physiatrics",
- "pneumatics",
- "poetics",
- "politics",
- "pragmatics",
- "prosthetics",
- "prosthodontics",
- "proteomics",
- "proxemics",
- "psycholinguistics",
- "psychometrics",
- "psychonomics",
- "psychophysics",
- "psychotherapeutics",
- "robotics",
- "semantics",
- "semiotics",
- "semitropics",
- "sociolinguistics",
- "stemmatics",
- "strategics",
- "subtropics",
- "systematics",
- "tectonics",
- "telerobotics",
- "therapeutics",
- "thermionics",
- "thermodynamics",
- "thermostatics"
- )));
-
- /**
- * Words that change from "-ie" to "-ies" (like "auntie" etc.), listed in their plural forms
- */
- private static Set<String> categoryIE_IES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "aeries",
- "anomies",
- "aunties",
- "baddies",
- "beanies",
- "birdies",
- "boccies",
- "bogies",
- "bolshies",
- "bombies",
- "bonhomies",
- "bonxies",
- "booboisies",
- "boogies",
- "boogie-woogies",
- "bookies",
- "booties",
- "bosies",
- "bourgeoisies",
- "brasseries",
- "brassies",
- "brownies",
- "budgies",
- "byrnies",
- "caddies",
- "calories",
- "camaraderies",
- "capercaillies",
- "capercailzies",
- "cassies",
- "catties",
- "causeries",
- "charcuteries",
- "chinoiseries",
- "collies",
- "commies",
- "cookies",
- "coolies",
- "coonties",
- "cooties",
- "corries",
- "coteries",
- "cowpies",
- "cowries",
- "cozies",
- "crappies",
- "crossties",
- "curies",
- "dachsies",
- "darkies",
- "dassies",
- "dearies",
- "dickies",
- "dies",
- "dixies",
- "doggies",
- "dogies",
- "dominies",
- "dovekies",
- "eyries",
- "faeries",
- "falsies",
- "floozies",
- "folies",
- "foodies",
- "freebies",
- "gaucheries",
- "gendarmeries",
- "genies",
- "ghillies",
- "gillies",
- "goalies",
- "goonies",
- "grannies",
- "grotesqueries",
- "groupies",
- "hankies",
- "hippies",
- "hoagies",
- "honkies",
- "hymies",
- "indies",
- "junkies",
- "kelpies",
- "kilocalories",
- "knobkerries",
- "koppies",
- "kylies",
- "laddies",
- "lassies",
- "lies",
- "lingeries",
- "magpies",
- "magpies",
- "marqueteries",
- "mashies",
- "mealies",
- "meanies",
- "menageries",
- "millicuries",
- "mollies",
- "facts1",
- "moxies",
- "neckties",
- "newbies",
- "nighties",
- "nookies",
- "oldies",
- "organdies",
- "panties",
- "parqueteries",
- "passementeries",
- "patisseries",
- "pies",
- "pinkies",
- "pixies",
- "porkpies",
- "potpies",
- "prairies",
- "preemies",
- "premies",
- "punkies",
- "pyxies",
- "quickies",
- "ramies",
- "reveries",
- "rookies",
- "rotisseries",
- "scrapies",
- "sharpies",
- "smoothies",
- "softies",
- "stoolies",
- "stymies",
- "swaggies",
- "sweeties",
- "talkies",
- "techies",
- "ties",
- "tooshies",
- "toughies",
- "townies",
- "veggies",
- "walkie-talkies",
- "wedgies",
- "weenies",
- "weirdies",
- "yardies",
- "yuppies",
- "zombies"
- )));
-
- /**
- * Maps irregular Germanic English plural nouns to their singular form
- */
- private static Map<String, String> irregular = Collections.unmodifiableMap(new HashMap<String, String>() {
- {
- put("beefs", "beef");
- put("beeves", "beef");
- put("brethren", "brother");
- put("busses", "bus");
- put("cattle", "cattlebeast");
- put("children", "child");
- put("corpora", "corpus");
- put("ephemerides", "ephemeris");
- put("firemen", "fireman");
- put("genera", "genus");
- put("genies", "genie");
- put("genii", "genie");
- put("kine", "cow");
- put("lice", "louse");
- put("men", "man");
- put("mice", "mouse");
- put("mongooses", "mongoose");
- put("monies", "money");
- put("mythoi", "mythos");
- put("octopodes", "octopus");
- put("octopuses", "octopus");
- put("oxen", "ox");
- put("people", "person");
- put("soliloquies", "soliloquy");
- put("throes", "throes");
- put("trilbys", "trilby");
- put("women", "woman");
- }
- }
- );
-
- /**
- * Contains word forms that can either be plural or singular
- */
- private static Set<String> singAndPlur = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "acoustics",
- "aestetics",
- "aquatics",
- "basics",
- "ceramics",
- "classics",
- "cosmetics",
- "dermatoglyphics",
- "dialectics",
- "dynamics",
- "esthetics",
- "ethics",
- "harmonics",
- "heroics",
- "isometrics",
- "mechanics",
- "metrics",
- "statistics",
- "optic",
- "people",
- "physics",
- "polemics",
- "premises",
- "propaedeutics",
- "pyrotechnics",
- "quadratics",
- "quarters",
- "statistics",
- "tactics",
- "tropics"
- )));
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/HashcodeEqualsAwareProxyFactory.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/HashcodeEqualsAwareProxyFactory.java
index ec7f5f54ad..f444a60245 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/HashcodeEqualsAwareProxyFactory.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/HashcodeEqualsAwareProxyFactory.java
@@ -18,18 +18,19 @@
*/
package org.grails.datastore.gorm.neo4j.proxy;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyObject;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.ReflectionUtils;
+
import org.grails.datastore.mapping.core.Session;
import org.grails.datastore.mapping.proxy.EntityProxy;
import org.grails.datastore.mapping.proxy.GroovyObjectMethodHandler;
import org.grails.datastore.mapping.proxy.JavassistProxyFactory;
-import org.grails.datastore.mapping.proxy.SessionEntityProxyMethodHandler;
-import org.springframework.beans.BeanUtils;
-import org.springframework.util.ReflectionUtils;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
/**
* extends {@link org.grails.datastore.mapping.proxy.JavassistProxyFactory} to capture method calls `hashCode` and `equals`
@@ -40,79 +41,78 @@ public class HashcodeEqualsAwareProxyFactory extends JavassistProxyFactory {
@Override
protected Object createProxiedInstance(final Session session, final Class cls, Class proxyClass, final Serializable id) {
- MethodHandler mi = new GroovyObjectMethodHandler(proxyClass) {
- private Object target;
+ MethodHandler mi = new GroovyObjectMethodHandler(proxyClass) {
+ private Object target;
- @Override
- protected Object resolveDelegate(Object self) {
- return target;
- }
+ @Override
+ protected Object resolveDelegate(Object self) {
+ return target;
+ }
- public Object invoke(Object proxy, Method method, Method proceed, Object[] args) throws Throwable {
- final String methodName = method.getName();
- if (args.length == 0) {
- if (methodName.equals("getId") || methodName.equals("getProxyKey")) {
- return id;
- }
- if (methodName.equals("initialize")) {
- initialize();
- return null;
- }
- if (methodName.equals("isInitialized")) {
- return target != null;
- }
- if (methodName.equals("getTarget")) {
- initialize();
- return target;
- }
- if (methodName.equals("hashCode")) {
- return ((Long)id).intValue();
- }
+ public Object invoke(Object proxy, Method method, Method proceed, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if (args.length == 0) {
+ if (methodName.equals("getId") || methodName.equals("getProxyKey")) {
+ return id;
}
- else if(args.length == 1) {
- if (methodName.equals("equals")) {
- final Method getIdMethod = ReflectionUtils.findMethod(cls, "getId");
- Object other = args[0];
- if(other == null) {
- return false;
- }
- if(other == proxy) {
- return true;
- }
- if(other.getClass() == proxyClass && other instanceof EntityProxy && id.equals(((EntityProxy)other).getProxyKey())) {
- return true;
- }
- if(other.getClass() == cls && id.equals(ReflectionUtils.invokeMethod(getIdMethod, other))) {
- return true;
- }
- return false;
- }
+ if (methodName.equals("initialize")) {
+ initialize();
+ return null;
}
- if (target == null) {
+ if (methodName.equals("isInitialized")) {
+ return target != null;
+ }
+ if (methodName.equals("getTarget")) {
initialize();
-
- // This tends to happen during unit testing if the proxy class is not properly mocked
- // and therefore can't be found in the session.
- if( target == null ) {
- throw new IllegalStateException("Proxy for ["+cls.getName()+":"+id+"] could not be initialized");
+ return target;
+ }
+ if (methodName.equals("hashCode")) {
+ return ((Long) id).intValue();
+ }
+ } else if (args.length == 1) {
+ if (methodName.equals("equals")) {
+ final Method getIdMethod = ReflectionUtils.findMethod(cls, "getId");
+ Object other = args[0];
+ if (other == null) {
+ return false;
+ }
+ if (other == proxy) {
+ return true;
+ }
+ if (other.getClass() == proxyClass && other instanceof EntityProxy && id.equals(((EntityProxy) other).getProxyKey())) {
+ return true;
}
+ if (other.getClass() == cls && id.equals(ReflectionUtils.invokeMethod(getIdMethod, other))) {
+ return true;
+ }
+ return false;
}
+ }
+ if (target == null) {
+ initialize();
- Object result = handleInvocation(target, method, args);
- if(!wasHandled(result)) {
- return org.springframework.util.ReflectionUtils.invokeMethod(method, target, args);
- } else {
- return result;
+ // This tends to happen during unit testing if the proxy class is not properly mocked
+ // and therefore can't be found in the session.
+ if (target == null) {
+ throw new IllegalStateException("Proxy for [" + cls.getName() + ":" + id + "] could not be initialized");
}
}
- public void initialize() {
- target = session.retrieve(cls, id);
+ Object result = handleInvocation(target, method, args);
+ if (!wasHandled(result)) {
+ return org.springframework.util.ReflectionUtils.invokeMethod(method, target, args);
+ } else {
+ return result;
}
- };
- Object proxy = BeanUtils.instantiateClass(proxyClass);
- ((ProxyObject)proxy).setHandler(mi);
- return proxy;
- }
+ }
+
+ public void initialize() {
+ target = session.retrieve(cls, id);
+ }
+ };
+ Object proxy = BeanUtils.instantiateClass(proxyClass);
+ ((ProxyObject) proxy).setHandler(mi);
+ return proxy;
+ }
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jAssociationQueryProxyHandler.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jAssociationQueryProxyHandler.java
index 5655faa96e..d919849eec 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jAssociationQueryProxyHandler.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jAssociationQueryProxyHandler.java
@@ -18,13 +18,13 @@
*/
package org.grails.datastore.gorm.neo4j.proxy;
+import java.io.Serializable;
+
import org.grails.datastore.mapping.core.Session;
import org.grails.datastore.mapping.engine.AssociationQueryExecutor;
import org.grails.datastore.mapping.model.config.GormProperties;
import org.grails.datastore.mapping.proxy.AssociationQueryProxyHandler;
-import java.io.Serializable;
-
public class Neo4jAssociationQueryProxyHandler extends AssociationQueryProxyHandler {
public Neo4jAssociationQueryProxyHandler(Session session, AssociationQueryExecutor executor, Serializable associationKey) {
@@ -40,7 +40,6 @@ public class Neo4jAssociationQueryProxyHandler extends AssociationQueryProxyHand
}
}
-
@Override
protected Object getPropertyBeforeResolving(Object self, String property) {
if (property.equals(GormProperties.IDENTITY)) {
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jProxyFactory.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jProxyFactory.java
index dce9570daa..00498fb33b 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jProxyFactory.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/proxy/Neo4jProxyFactory.java
@@ -18,13 +18,14 @@
*/
package org.grails.datastore.gorm.neo4j.proxy;
+import java.io.Serializable;
+
import javassist.util.proxy.MethodHandler;
+
import org.grails.datastore.mapping.core.Session;
import org.grails.datastore.mapping.engine.AssociationQueryExecutor;
import org.grails.datastore.mapping.proxy.JavassistProxyFactory;
-import java.io.Serializable;
-
/**
* extends {@link org.grails.datastore.mapping.proxy.JavassistProxyFactory} to capture method calls `hashCode` and `equals`
* without expanding the proxy
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindAllCypherQueryImplementer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindAllCypherQueryImplementer.groovy
index bdf45683b9..0aa280906a 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindAllCypherQueryImplementer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindAllCypherQueryImplementer.groovy
@@ -19,18 +19,19 @@
package org.grails.datastore.gorm.neo4j.services.implementers
-import grails.neo4j.services.Cypher
+import java.lang.annotation.Annotation
+
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.VariableScope
import org.codehaus.groovy.control.SourceUnit
+
+import grails.neo4j.services.Cypher
import org.grails.datastore.gorm.neo4j.services.transform.CypherQueryStringTransformer
import org.grails.datastore.gorm.services.implementers.FindAllStringQueryImplementer
import org.grails.datastore.gorm.services.transform.QueryStringTransformer
-import java.lang.annotation.Annotation
-
/**
* A cypher query implementer
*
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindOneCypherQueryImplementer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindOneCypherQueryImplementer.groovy
index d910638ece..6256aeb20c 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindOneCypherQueryImplementer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindOneCypherQueryImplementer.groovy
@@ -19,16 +19,17 @@
package org.grails.datastore.gorm.neo4j.services.implementers
-import grails.neo4j.services.Cypher
+import java.lang.annotation.Annotation
+
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.VariableScope
import org.codehaus.groovy.control.SourceUnit
+
+import grails.neo4j.services.Cypher
import org.grails.datastore.gorm.neo4j.services.transform.CypherQueryStringTransformer
import org.grails.datastore.gorm.services.implementers.FindOneStringQueryImplementer
import org.grails.datastore.gorm.services.transform.QueryStringTransformer
-import java.lang.annotation.Annotation
-
/**
* A cypher query implementer
*
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindPathCypherQueryImplementer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindPathCypherQueryImplementer.groovy
index cbd46f072d..8a90004176 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindPathCypherQueryImplementer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindPathCypherQueryImplementer.groovy
@@ -19,13 +19,13 @@
package org.grails.datastore.gorm.neo4j.services.implementers
-import grails.neo4j.Path
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.expr.Expression
import org.codehaus.groovy.ast.stmt.Statement
-import org.grails.datastore.mapping.core.Ordered
+
+import grails.neo4j.Path
import org.grails.datastore.mapping.reflect.AstUtils
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindShortestPathImplementer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindShortestPathImplementer.groovy
index a94cde3719..88c6705c98 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindShortestPathImplementer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/FindShortestPathImplementer.groovy
@@ -19,19 +19,23 @@
package org.grails.datastore.gorm.neo4j.services.implementers
-import grails.neo4j.Path
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.Parameter
import org.codehaus.groovy.ast.expr.Expression
import org.codehaus.groovy.ast.stmt.BlockStatement
+
+import grails.neo4j.Path
import org.grails.datastore.gorm.services.implementers.AbstractReadOperationImplementer
import org.grails.datastore.gorm.services.implementers.FindOneByImplementer
import org.grails.datastore.gorm.services.implementers.SingleResultServiceImplementer
import org.grails.datastore.mapping.reflect.AstUtils
-import static org.codehaus.groovy.ast.tools.GeneralUtils.*
+import static org.codehaus.groovy.ast.tools.GeneralUtils.args
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX
+import static org.codehaus.groovy.ast.tools.GeneralUtils.castX
+import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS
/**
* Service implementer for findShortestPath
@@ -41,6 +45,7 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.*
*/
@CompileStatic
class FindShortestPathImplementer extends AbstractReadOperationImplementer implements SingleResultServiceImplementer<Path> {
+
@Override
int getOrder() {
return FindOneByImplementer.POSITION - 100
@@ -52,9 +57,9 @@ class FindShortestPathImplementer extends AbstractReadOperationImplementer imple
Expression methodCall = callX(domainClassNode, "findShortestPath", args(newMethodNode.parameters))
methodCall = castX(returnType.plainNodeReference, methodCall)
- BlockStatement bs = (BlockStatement)newMethodNode.code
+ BlockStatement bs = (BlockStatement) newMethodNode.code
bs.addStatement(
- returnS(methodCall)
+ returnS(methodCall)
)
}
@@ -63,14 +68,13 @@ class FindShortestPathImplementer extends AbstractReadOperationImplementer imple
def alreadyImplemented = methodNode.getNodeMetaData(IMPLEMENTED)
Parameter[] parameters = methodNode.parameters
int paramCount = parameters.length
- if(!alreadyImplemented && AstUtils.implementsInterface(methodNode.returnType, Path.name) && paramCount > 1 && paramCount < 4) {
- if(AstUtils.isDomainClass(parameters[0].type) && AstUtils.isDomainClass(parameters[1].type)) {
- if(paramCount == 3) {
- if(AstUtils.implementsInterface(parameters[2].type, "java.lang.Number")) {
+ if (!alreadyImplemented && AstUtils.implementsInterface(methodNode.returnType, Path.name) && paramCount > 1 && paramCount < 4) {
+ if (AstUtils.isDomainClass(parameters[0].type) && AstUtils.isDomainClass(parameters[1].type)) {
+ if (paramCount == 3) {
+ if (AstUtils.implementsInterface(parameters[2].type, "java.lang.Number")) {
return true
}
- }
- else {
+ } else {
return true
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/StatementResultCypherQueryImplementer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/StatementResultCypherQueryImplementer.groovy
index 1cb59171f7..fdee190d5c 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/StatementResultCypherQueryImplementer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/StatementResultCypherQueryImplementer.groovy
@@ -24,9 +24,11 @@ import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.expr.Expression
import org.codehaus.groovy.ast.stmt.Statement
-import org.grails.datastore.mapping.reflect.AstUtils
+
import org.neo4j.driver.Result
+import org.grails.datastore.mapping.reflect.AstUtils
+
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX
import static org.codehaus.groovy.ast.tools.GeneralUtils.castX
import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/UpdateCypherQueryImplementer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/UpdateCypherQueryImplementer.groovy
index 2efb984242..e6eec44d65 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/UpdateCypherQueryImplementer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/implementers/UpdateCypherQueryImplementer.groovy
@@ -19,8 +19,6 @@
package org.grails.datastore.gorm.neo4j.services.implementers
-import grails.gorm.services.Query
-import grails.neo4j.services.Cypher
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.AnnotationNode
import org.codehaus.groovy.ast.ClassHelper
@@ -30,6 +28,8 @@ import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.Expression
import org.codehaus.groovy.ast.expr.GStringExpression
import org.codehaus.groovy.ast.stmt.Statement
+
+import grails.neo4j.services.Cypher
import org.grails.datastore.gorm.transactions.transform.TransactionalTransform
import org.grails.datastore.mapping.reflect.AstUtils
@@ -55,21 +55,20 @@ class UpdateCypherQueryImplementer extends FindAllCypherQueryImplementer {
@Override
boolean doesImplement(ClassNode domainClass, MethodNode methodNode) {
AnnotationNode ann = AstUtils.findAnnotation(methodNode, Cypher)
- if( ann != null) {
+ if (ann != null) {
Expression expr = ann.getMember("value")
- if(expr instanceof GStringExpression) {
- GStringExpression gstring = (GStringExpression)expr
- for(ConstantExpression ce in gstring.strings) {
+ if (expr instanceof GStringExpression) {
+ GStringExpression gstring = (GStringExpression) expr
+ for (ConstantExpression ce in gstring.strings) {
String queryStem = ce.text
- if(isWriteOperation(queryStem)) {
+ if (isWriteOperation(queryStem)) {
return isCompatibleReturnType(domainClass, methodNode, methodNode.returnType, methodNode.name)
}
}
- }
- else if(expr instanceof ConstantExpression) {
- String queryStem = ((ConstantExpression)expr).text
- if(isWriteOperation(queryStem)) {
+ } else if (expr instanceof ConstantExpression) {
+ String queryStem = ((ConstantExpression) expr).text
+ if (isWriteOperation(queryStem)) {
return isCompatibleReturnType(domainClass, methodNode, methodNode.returnType, methodNode.name)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/transform/CypherQueryStringTransformer.groovy b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/transform/CypherQueryStringTransformer.groovy
index 832a8f98ac..c61cfff43e 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/transform/CypherQueryStringTransformer.groovy
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/services/transform/CypherQueryStringTransformer.groovy
@@ -19,11 +19,12 @@
package org.grails.datastore.gorm.neo4j.services.transform
-import grails.neo4j.Relationship
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.VariableScope
import org.codehaus.groovy.control.SourceUnit
+
+import grails.neo4j.Relationship
import org.grails.datastore.gorm.neo4j.RelationshipPersistentEntity
import org.grails.datastore.gorm.services.transform.QueryStringTransformer
import org.grails.datastore.mapping.reflect.AstUtils
@@ -36,21 +37,21 @@ import org.grails.datastore.mapping.reflect.AstUtils
*/
@CompileStatic
class CypherQueryStringTransformer extends QueryStringTransformer {
+
CypherQueryStringTransformer(SourceUnit sourceUnit, VariableScope variableScope) {
super(sourceUnit, variableScope)
}
@Override
protected String formatDomainClassVariable(ClassNode domainType, String variableName) {
- if(AstUtils.implementsInterface(domainType, Relationship.name)) {
+ if (AstUtils.implementsInterface(domainType, Relationship.name)) {
ClassNode relInterface = domainType.getInterfaces().find() { ClassNode ifce -> ifce.name == Relationship.name }
ClassNode from = relInterface.genericsTypes[0].type.plainNodeReference
ClassNode to = relInterface.genericsTypes[1].type.plainNodeReference
declaredQueryTargets.put(RelationshipPersistentEntity.FROM, from)
declaredQueryTargets.put(RelationshipPersistentEntity.TO, to)
return "${formatNodeVariable(RelationshipPersistentEntity.FROM, from)}-[$variableName]->${formatNodeVariable(RelationshipPersistentEntity.TO, to)}"
- }
- else {
+ } else {
return formatNodeVariable(variableName, domainType)
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/EmbeddedNeo4jServer.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/EmbeddedNeo4jServer.java
index ffa096fe0d..ced9c00943 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/EmbeddedNeo4jServer.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/EmbeddedNeo4jServer.java
@@ -18,8 +18,13 @@
*/
package org.grails.datastore.gorm.neo4j.util;
-import org.grails.datastore.mapping.reflect.ClassUtils;
-import org.neo4j.graphdb.factory.GraphDatabaseSettings;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+
import org.neo4j.harness.ServerControls;
import org.neo4j.harness.TestServerBuilder;
import org.neo4j.harness.TestServerBuilders;
@@ -27,15 +32,10 @@ import org.neo4j.kernel.configuration.BoltConnector;
import org.neo4j.kernel.configuration.Connector;
import org.neo4j.server.ServerStartupException;
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.util.Collections;
-import java.util.Map;
+import org.grails.datastore.mapping.reflect.ClassUtils;
-import static org.neo4j.kernel.configuration.BoltConnector.EncryptionLevel.DISABLED;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.data_directory;
+import static org.neo4j.kernel.configuration.BoltConnector.EncryptionLevel.DISABLED;
/**
* Helper class for starting a Neo4j 3.x embedded server
@@ -59,7 +59,7 @@ public class EmbeddedNeo4jServer {
* @param dataLocation The data location
*/
public static ServerControls start(File dataLocation) throws IOException {
- return attemptStartServer(0, dataLocation, Collections.<String, Object>emptyMap());
+ return attemptStartServer(0, dataLocation, Collections.emptyMap());
}
/**
@@ -72,8 +72,6 @@ public class EmbeddedNeo4jServer {
return attemptStartServer(0, dataLocation, options);
}
-
-
/**
* Start a server on the given address
*
@@ -82,7 +80,7 @@ public class EmbeddedNeo4jServer {
* @return The {@link ServerControls}
*/
public static ServerControls start(InetSocketAddress inetAddr) {
- return start(inetAddr.getHostName(),inetAddr.getPort(), null);
+ return start(inetAddr.getHostName(), inetAddr.getPort(), null);
}
/**
@@ -93,7 +91,7 @@ public class EmbeddedNeo4jServer {
* @return The {@link ServerControls}
*/
public static ServerControls start(InetSocketAddress inetAddr, File dataLocation) {
- return start(inetAddr.getHostName(),inetAddr.getPort(), dataLocation);
+ return start(inetAddr.getHostName(), inetAddr.getPort(), dataLocation);
}
/**
@@ -104,7 +102,7 @@ public class EmbeddedNeo4jServer {
* @return The {@link ServerControls}
*/
public static ServerControls start(InetSocketAddress inetAddr, File dataLocation, Map<String, Object> options) {
- return start(inetAddr.getHostName(),inetAddr.getPort(), dataLocation,options);
+ return start(inetAddr.getHostName(), inetAddr.getPort(), dataLocation, options);
}
/**
@@ -131,7 +129,6 @@ public class EmbeddedNeo4jServer {
return start(uri.getHost(), uri.getPort(), dataLocation);
}
-
/**
* Start a server on the given address
*
@@ -139,7 +136,7 @@ public class EmbeddedNeo4jServer {
*
* @return The {@link ServerControls}
*/
- public static ServerControls start(String address, File dataLocation,Map<String, Object> options) {
+ public static ServerControls start(String address, File dataLocation, Map<String, Object> options) {
URI uri = URI.create(address);
return start(uri.getHost(), uri.getPort(), dataLocation, options);
}
@@ -153,8 +150,9 @@ public class EmbeddedNeo4jServer {
* @return The {@link ServerControls}
*/
public static ServerControls start(String host, int port) {
- return start(host, port, null);
+ return start(host, port, null);
}
+
/**
* Start a server on the given address
*
@@ -164,7 +162,7 @@ public class EmbeddedNeo4jServer {
* @return The {@link ServerControls}
*/
public static ServerControls start(String host, int port, File dataLocation) {
- return start(host, port, dataLocation, Collections.<String, Object>emptyMap());
+ return start(host, port, dataLocation, Collections.emptyMap());
}
/**
@@ -179,12 +177,12 @@ public class EmbeddedNeo4jServer {
String myBoltAddress = String.format("%s:%d", host, port);
TestServerBuilder serverBuilder = TestServerBuilders.newInProcessBuilder()
- .withConfig(new BoltConnector("0").enabled, "true")
- .withConfig(new BoltConnector("0").type, Connector.ConnectorType.BOLT.name())
- .withConfig(new BoltConnector("0").encryption_level, DISABLED.name())
- .withConfig(new BoltConnector("0").listen_address, myBoltAddress);
- if(dataLocation != null) {
- serverBuilder = serverBuilder.withConfig(data_directory, dataLocation.getPath());
+ .withConfig(new BoltConnector("0").enabled, "true")
+ .withConfig(new BoltConnector("0").type, Connector.ConnectorType.BOLT.name())
+ .withConfig(new BoltConnector("0").encryption_level, DISABLED.name())
+ .withConfig(new BoltConnector("0").listen_address, myBoltAddress);
+ if (dataLocation != null) {
+ serverBuilder = serverBuilder.withConfig(data_directory, dataLocation.getPath());
}
for (String name : options.keySet()) {
@@ -192,7 +190,7 @@ public class EmbeddedNeo4jServer {
}
return serverBuilder
- .newServer();
+ .newServer();
}
private static ServerControls attemptStartServer(int retryCount, File dataLocation, Map<String, Object> options) throws IOException {
@@ -201,10 +199,9 @@ public class EmbeddedNeo4jServer {
//In the new driver 0 implicitly means a random port
return start("localhost", 0, dataLocation, options);
} catch (ServerStartupException sse) {
- if(retryCount < 4) {
+ if (retryCount < 4) {
return attemptStartServer(++retryCount, dataLocation, options);
- }
- else {
+ } else {
throw sse;
}
}
diff --git a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/IteratorUtil.java b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/IteratorUtil.java
index eefe2337b7..a043353e83 100644
--- a/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/IteratorUtil.java
+++ b/grails-data-neo4j/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/util/IteratorUtil.java
@@ -28,7 +28,6 @@ import java.util.Iterator;
*/
public class IteratorUtil {
-
/**
* A single item or null
*
@@ -38,7 +37,7 @@ public class IteratorUtil {
*/
public static <T> T singleOrNull(Iterable<T> iterable) {
Iterator<T> i = iterable.iterator();
- if(i.hasNext()) {
+ if (i.hasNext()) {
return i.next();
}
return null;
@@ -57,7 +56,7 @@ public class IteratorUtil {
}
public static <T> T single(Iterator<T> i) {
- if(i.hasNext()) {
+ if (i.hasNext()) {
return i.next();
}
return null;
@@ -73,7 +72,7 @@ public class IteratorUtil {
public static int count(Iterator i) {
int count = 0;
- while(i.hasNext()) {
+ while (i.hasNext()) {
count++;
i.next();
}