Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

made IndexProvider configurable as a Spring bean #15

Merged
merged 1 commit into from
Nov 30, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package org.springframework.data.neo4j.config;

import static java.util.Arrays.*;

import javax.validation.Validator;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
Expand All @@ -41,7 +45,13 @@
import org.springframework.data.neo4j.support.MappingInfrastructure;
import org.springframework.data.neo4j.support.Neo4jExceptionTranslator;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.mapping.*;
import org.springframework.data.neo4j.support.index.IndexProvider;
import org.springframework.data.neo4j.support.index.IndexProviderImpl;
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
import org.springframework.data.neo4j.support.mapping.Neo4jEntityFetchHandler;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.mapping.SourceStateTransmitter;
import org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
Expand All @@ -52,10 +62,6 @@
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.transaction.jta.UserTransactionAdapter;

import javax.validation.Validator;

import static java.util.Arrays.asList;

/**
* Abstract base class for code based configuration of Spring managed Neo4j infrastructure.
* <p>Subclasses are required to provide an implementation of graphDbService ....
Expand Down Expand Up @@ -105,6 +111,8 @@ public MappingInfrastructure mappingInfrastructure() throws Exception {

infrastructure.setTransactionManager(neo4jTransactionManager());
infrastructure.setGraphDatabase(graphDatabase());

infrastructure.setIndexProvider(indexProvider());

if (validator!=null) {
infrastructure.setValidator(validator);
Expand Down Expand Up @@ -251,4 +259,9 @@ public ConfigurationCheck configurationCheck() throws Exception {
public PersistenceExceptionTranslator persistenceExceptionTranslator() {
return new Neo4jExceptionTranslator();
}

@Bean
public IndexProvider indexProvider() throws Exception {
return new IndexProviderImpl(mappingContext(), graphDatabase());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.springframework.data.neo4j.support;

import javax.validation.Validator;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
Expand All @@ -26,7 +28,12 @@
import org.springframework.data.neo4j.mapping.EntityInstantiator;
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
import org.springframework.data.neo4j.support.index.IndexProvider;
import org.springframework.data.neo4j.support.mapping.*;
import org.springframework.data.neo4j.support.index.IndexProviderImpl;
import org.springframework.data.neo4j.support.mapping.EntityRemover;
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
import org.springframework.data.neo4j.support.mapping.EntityTools;
import org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.node.EntityStateFactory;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
Expand All @@ -35,8 +42,6 @@
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
import org.springframework.transaction.PlatformTransactionManager;

import javax.validation.Validator;

/**
* @author mh
* @since 17.10.11
Expand Down Expand Up @@ -102,12 +107,14 @@ public void postConstruct() {
EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator);
this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
this.entityRemover = new EntityRemover(this.entityStateHandler, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy, graphDatabase);
this.indexProvider = new IndexProvider(mappingContext, graphDatabase);
if (this.resultConverter==null) {
this.resultConverter = new EntityResultConverter<Object, Object>(conversionService,entityPersister);
}
this.graphDatabase.setResultConverter(resultConverter);
this.cypherQueryExecutor = new CypherQueryExecutor(graphDatabase.queryEngineFor(QueryType.Cypher, resultConverter));
if (this.indexProvider == null) {
this.indexProvider = new IndexProviderImpl(this.mappingContext, graphDatabase);
}
}


Expand Down Expand Up @@ -229,4 +236,8 @@ public Neo4jMappingContext getMappingContext() {
public void setTypeRepresentationStrategyFactory(TypeRepresentationStrategyFactory typeRepresentationStrategyFactory) {
this.typeRepresentationStrategyFactory = typeRepresentationStrategyFactory;
}

public void setIndexProvider(IndexProvider indexProvider) {
this.indexProvider = indexProvider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,22 @@

package org.springframework.data.neo4j.support;

import static org.springframework.data.neo4j.support.ParameterCheck.*;

import java.util.Map;

import javax.annotation.PostConstruct;
import javax.validation.Validator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.helpers.collection.ClosableIterable;
Expand Down Expand Up @@ -57,12 +70,6 @@
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.PostConstruct;
import javax.validation.Validator;
import java.util.Map;

import static org.springframework.data.neo4j.support.ParameterCheck.notNull;

/**
* Mediator class for the graph related services like the {@link GraphDatabaseService}, the used
* {@link org.springframework.data.neo4j.core.TypeRepresentationStrategy}, entity instantiators for nodes and relationships as well as a spring conversion service.
Expand Down Expand Up @@ -546,10 +553,12 @@ public <T extends PropertyContainer> Result<T> lookup(final Class<?> indexedType
}
}

@Override
public <T extends PropertyContainer> Index<T> getIndex(String indexName, Class<?> indexedType) {
return getIndexProvider().getIndex(indexedType, indexName);
}

@Override
public <T extends PropertyContainer> Index<T> getIndex(Class<?> indexedType, String propertyName) {
final Neo4jPersistentEntityImpl<?> persistentEntity = getPersistentEntity(indexedType);
final Neo4jPersistentProperty property = persistentEntity.getPersistentProperty(propertyName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,90 +15,31 @@
*/
package org.springframework.data.neo4j.support.index;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.index.Index;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.mapping.Neo4jPersistentEntityImpl;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;

import static org.springframework.data.neo4j.support.ParameterCheck.notNull;
public interface IndexProvider {

/**
* @author mh
* @since 17.10.11
*/
public class IndexProvider {
private Neo4jMappingContext mappingContext;
private final GraphDatabase graphDatabase;

public IndexProvider(Neo4jMappingContext mappingContext, GraphDatabase graphDatabase) {
this.mappingContext = mappingContext;
this.graphDatabase = graphDatabase;
}

public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
return getIndex(type, null);
}
public abstract <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type);

public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName) {
return getIndex(type, indexName, null);
}
public abstract <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName);

@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName, IndexType indexType) {
if (type == null) {
notNull(indexName, "indexName");
return getIndex(indexName);
}

final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
if (indexName == null) indexName = Indexed.Name.get(type);
final boolean useExistingIndex = indexType == null;

if (useExistingIndex) {
if (persistentEntity.isNodeEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
if (persistentEntity.isRelationshipEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}

if (persistentEntity.isNodeEntity()) return (Index<S>) createIndex(Node.class, indexName, indexType);
if (persistentEntity.isRelationshipEntity())
return (Index<S>) createIndex(Relationship.class, indexName, indexType);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}
public abstract <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName,
IndexType indexType);

@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> getIndex(String indexName) {
return graphDatabase.getIndex(indexName);
}
public abstract <T extends PropertyContainer> Index<T> getIndex(String indexName);

public boolean isNode(Class<? extends PropertyContainer> type) {
if (type.equals(Node.class)) return true;
if (type.equals(Relationship.class)) return false;
throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship" + type);
}
public abstract boolean isNode(Class<? extends PropertyContainer> type);

// TODO handle existing indexes
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName, IndexType fullText) {
return graphDatabase.createIndex(type, indexName, fullText);
}
public abstract <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName,
IndexType fullText);

public abstract <S extends PropertyContainer> Index<S> getIndex(Neo4jPersistentProperty property,
final Class<?> instanceType);

public <S extends PropertyContainer> Index<S> getIndex(Neo4jPersistentProperty property, final Class<?> instanceType) {
final Indexed indexedAnnotation = property.getAnnotation(Indexed.class);
final Class<?> declaringType = property.getOwner().getType();
final String providedIndexName = indexedAnnotation==null || indexedAnnotation.indexName().isEmpty() ? null : indexedAnnotation.indexName();
final Indexed.Level level = indexedAnnotation == null ? Indexed.Level.CLASS : indexedAnnotation.level();
String indexName = Indexed.Name.get(level, declaringType, providedIndexName, instanceType);
if (!property.isIndexed() || property.getIndexInfo().getIndexType() == IndexType.SIMPLE) {
return getIndex(declaringType, indexName, IndexType.SIMPLE);
}
String defaultIndexName = Indexed.Name.get(level, declaringType, null, instanceType.getClass());
if (providedIndexName==null || providedIndexName.equals(defaultIndexName)) throw new IllegalStateException("Index name for "+property+" must differ from the default name: "+defaultIndexName);
return getIndex(declaringType, indexName, property.getIndexInfo().getIndexType());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.neo4j.support.index;

import static org.springframework.data.neo4j.support.ParameterCheck.*;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.index.Index;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.mapping.Neo4jPersistentEntityImpl;

/**
* @author mh
* @since 17.10.11
*/
public class IndexProviderImpl implements IndexProvider {
private final Neo4jMappingContext mappingContext;
private final GraphDatabase graphDatabase;

public IndexProviderImpl(Neo4jMappingContext mappingContext, GraphDatabase graphDatabase) {
this.mappingContext = mappingContext;
this.graphDatabase = graphDatabase;
}

@Override
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
return getIndex(type, null);
}

@Override
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName) {
return getIndex(type, indexName, null);
}
@Override
@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName, IndexType indexType) {
if (type == null) {
notNull(indexName, "indexName");
return getIndex(indexName);
}

final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
if (indexName == null) indexName = Indexed.Name.get(type);
final boolean useExistingIndex = indexType == null;

if (useExistingIndex) {
if (persistentEntity.isNodeEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
if (persistentEntity.isRelationshipEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}

if (persistentEntity.isNodeEntity()) return (Index<S>) createIndex(Node.class, indexName, indexType);
if (persistentEntity.isRelationshipEntity())
return (Index<S>) createIndex(Relationship.class, indexName, indexType);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}

@Override
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> getIndex(String indexName) {
return graphDatabase.getIndex(indexName);
}

@Override
public boolean isNode(Class<? extends PropertyContainer> type) {
if (type.equals(Node.class)) return true;
if (type.equals(Relationship.class)) return false;
throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship" + type);
}

// TODO handle existing indexes
@Override
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName, IndexType fullText) {
return graphDatabase.createIndex(type, indexName, fullText);
}

@Override
public <S extends PropertyContainer> Index<S> getIndex(Neo4jPersistentProperty property, final Class<?> instanceType) {
final Indexed indexedAnnotation = property.getAnnotation(Indexed.class);
final Class<?> declaringType = property.getOwner().getType();
final String providedIndexName = indexedAnnotation==null || indexedAnnotation.indexName().isEmpty() ? null : indexedAnnotation.indexName();
final Indexed.Level level = indexedAnnotation == null ? Indexed.Level.CLASS : indexedAnnotation.level();
String indexName = Indexed.Name.get(level, declaringType, providedIndexName, instanceType);
if (!property.isIndexed() || property.getIndexInfo().getIndexType() == IndexType.SIMPLE) {
return getIndex(declaringType, indexName, IndexType.SIMPLE);
}
String defaultIndexName = Indexed.Name.get(level, declaringType, null, instanceType.getClass());
if (providedIndexName==null || providedIndexName.equals(defaultIndexName)) throw new IllegalStateException("Index name for "+property+" must differ from the default name: "+defaultIndexName);
return getIndex(declaringType, indexName, property.getIndexInfo().getIndexType());
}
}