This commit is contained in:
Phillip Webb
2016-03-25 11:51:42 -07:00
parent c68e5f12ff
commit 609704a3bf
12 changed files with 87 additions and 63 deletions

View File

@@ -50,6 +50,7 @@ class Neo4jRepositoriesAutoConfigureRegistrar
@EnableNeo4jRepositories
private static class EnableNeo4jRepositoriesConfiguration {
}
}

View File

@@ -72,8 +72,7 @@ public class Neo4jAutoConfiguration {
@Override
public SessionFactory getSessionFactory() {
SessionFactoryProvider provider = this.sessionFactoryProvider.getObject();
return provider.getSessionFactory();
return this.sessionFactoryProvider.getObject().getSessionFactory();
}
@Bean

View File

@@ -20,6 +20,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.config.DriverConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -115,31 +116,31 @@ public class Neo4jProperties implements ApplicationContextAware {
*/
public Configuration createConfiguration() {
Configuration configuration = new Configuration();
if (this.uri == null) {
if (getEmbedded().isEnabled()
&& ClassUtils.isPresent(EMBEDDED_DRIVER, this.classLoader)) {
configuration.driverConfiguration().setDriverClassName(EMBEDDED_DRIVER);
}
else {
configuration.driverConfiguration().setDriverClassName(HTTP_DRIVER);
configuration.driverConfiguration().setURI(DEFAULT_HTTP_URI);
}
}
else {
configuration.driverConfiguration().setDriverClassName(deduceDriverFromUri());
configuration.driverConfiguration().setURI(this.uri);
}
if (this.username != null && this.password != null) {
configuration.driverConfiguration().setCredentials(this.username,
this.password);
}
configureDriver(configuration.driverConfiguration());
if (this.compiler != null) {
configuration.compilerConfiguration().setCompilerClassName(this.compiler);
}
return configuration;
}
private void configureDriver(DriverConfiguration driverConfiguration) {
if (this.uri != null) {
configureDriverFromUri(driverConfiguration, this.uri);
}
else {
configureDriverWithDefaults(driverConfiguration);
}
if (this.username != null && this.password != null) {
driverConfiguration.setCredentials(this.username, this.password);
}
}
private void configureDriverFromUri(DriverConfiguration driverConfiguration,
String uri) {
driverConfiguration.setDriverClassName(deduceDriverFromUri());
driverConfiguration.setURI(uri);
}
private String deduceDriverFromUri() {
try {
URI uri = new URI(this.uri);
@@ -147,13 +148,11 @@ public class Neo4jProperties implements ApplicationContextAware {
if (scheme == null || scheme.equals("file")) {
return EMBEDDED_DRIVER;
}
else if ("http".equals(scheme)) {
if ("http".equals(scheme)) {
return HTTP_DRIVER;
}
else {
throw new IllegalArgumentException(
"Could not deduce driver to use based on URI '" + uri + "'");
}
throw new IllegalArgumentException(
"Could not deduce driver to use based on URI '" + uri + "'");
}
catch (URISyntaxException ex) {
throw new IllegalArgumentException(
@@ -161,6 +160,16 @@ public class Neo4jProperties implements ApplicationContextAware {
}
}
private void configureDriverWithDefaults(DriverConfiguration driverConfiguration) {
if (getEmbedded().isEnabled()
&& ClassUtils.isPresent(EMBEDDED_DRIVER, this.classLoader)) {
driverConfiguration.setDriverClassName(EMBEDDED_DRIVER);
return;
}
driverConfiguration.setDriverClassName(HTTP_DRIVER);
driverConfiguration.setURI(DEFAULT_HTTP_URI);
}
public static class Embedded {
/**

View File

@@ -127,7 +127,7 @@ public class Neo4jPropertiesTests {
private static void assertCredentials(Configuration actual, String username,
String password) {
Credentials credentials = actual.driverConfiguration().getCredentials();
Credentials<?> credentials = actual.driverConfiguration().getCredentials();
if (username == null & password == null) {
assertThat(credentials).isNull();
}

View File

@@ -21,15 +21,18 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
/**
* A base {@link BeanPostProcessor} implementation that holds the packages to
* use for a given component. An implementation must implement
* {@link #postProcessBeforeInitialization(Object, String)} and update the
* component responsible to manage the packages to scan.
* A base {@link BeanPostProcessor} implementation that holds the packages to use for a
* given component. An implementation must implement
* {@link #postProcessBeforeInitialization(Object, String)} and update the component
* responsible to manage the packages to scan.
*
* @author Phillip Webb
* @author Oliver Gierke
* @author Stephane Nicoll
* @since 1.4.0
*/
public abstract class AbstractEntityScanBeanPostProcessor implements BeanPostProcessor, Ordered {
public abstract class AbstractEntityScanBeanPostProcessor
implements BeanPostProcessor, Ordered {
private final String[] packagesToScan;

View File

@@ -34,22 +34,24 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* A base {@link ImportBeanDefinitionRegistrar} used to collect the packages to
* scan for a given component.
* A base {@link ImportBeanDefinitionRegistrar} used to collect the packages to scan for a
* given component.
* <p>
* Expect to process an annotation type that defines a {@code basePackage} and
* {@code basePackageClasses} attributes as well as a {@code value} alias of
* {@code basePackage}.
* <p>
* The {@link ImportBeanDefinitionRegistrar} registers a single
* {@link AbstractEntityScanBeanPostProcessor} implementation with the packages
* to use.
* {@link AbstractEntityScanBeanPostProcessor} implementation with the packages to use.
*
* @author Phillip Webb
* @author Oliver Gierke
* @author Stephane Nicoll
* @since 1.4.0
* @see AbstractEntityScanBeanPostProcessor
*/
public abstract class AbstractEntityScanRegistrar implements ImportBeanDefinitionRegistrar {
public abstract class AbstractEntityScanRegistrar
implements ImportBeanDefinitionRegistrar {
private final Class<? extends Annotation> annotationType;
@@ -71,7 +73,6 @@ public abstract class AbstractEntityScanRegistrar implements ImportBeanDefinitio
this.beanPostProcessorType = beanPostProcessorType;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
@@ -91,9 +92,10 @@ public abstract class AbstractEntityScanRegistrar implements ImportBeanDefinitio
String[] basePackages = attributes.getStringArray("basePackages");
Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses");
if (!ObjectUtils.isEmpty(value)) {
Assert.state(ObjectUtils.isEmpty(basePackages), String.format(
"@%s basePackages and value attributes are mutually exclusive",
this.annotationType.getSimpleName()));
Assert.state(ObjectUtils.isEmpty(basePackages),
String.format(
"@%s basePackages and value attributes are mutually exclusive",
this.annotationType.getSimpleName()));
}
Set<String> packagesToScan = new LinkedHashSet<String>();
packagesToScan.addAll(Arrays.asList(value));
@@ -123,9 +125,10 @@ public abstract class AbstractEntityScanRegistrar implements ImportBeanDefinitio
private void updateEntityScanBeanPostProcessor(BeanDefinitionRegistry registry,
Set<String> packagesToScan) {
BeanDefinition definition = registry.getBeanDefinition(this.beanPostProcessorName);
ConstructorArgumentValues.ValueHolder constructorArguments = definition.getConstructorArgumentValues()
.getGenericArgumentValue(String[].class);
BeanDefinition definition = registry
.getBeanDefinition(this.beanPostProcessorName);
ConstructorArgumentValues.ValueHolder constructorArguments = definition
.getConstructorArgumentValues().getGenericArgumentValue(String[].class);
Set<String> mergedPackages = new LinkedHashSet<String>();
mergedPackages.addAll(Arrays.asList((String[]) constructorArguments.getValue()));
mergedPackages.addAll(packagesToScan);

View File

@@ -22,16 +22,17 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Import;
/**
* Configures the {@link SessionFactory} to scan for node entity
* classes in the classpath. This annotation provides an alternative to manually setting
* {@link SessionFactoryProvider#setPackagesToScan(String...)} and is
* particularly useful if you want to configure entity scanning in a type-safe way, or if
* your {@link SessionFactory} is auto-configured.
* Configures the {@link SessionFactory} to scan for Neo4J {@link NodeEntity} classes in
* the classpath. This annotation provides an alternative to manually setting
* {@link SessionFactoryProvider#setPackagesToScan(String...)} and is particularly useful
* if you want to configure entity scanning in a type-safe way, or if your
* {@link SessionFactory} is auto-configured.
* <p>
* A {@link SessionFactoryProvider} must be configured within your Spring
* ApplicationContext in order to use entity scanning. Furthermore, any existing
@@ -42,7 +43,6 @@ import org.springframework.context.annotation.Import;
* packages are not defined scanning will occur from the package of the class with this
* annotation.
*
* @author Phillip Webb
* @author Stephane Nicoll
* @since 1.4.0
*/

View File

@@ -32,16 +32,17 @@ import org.springframework.util.Assert;
class NodeEntityScanRegistrar extends AbstractEntityScanRegistrar {
NodeEntityScanRegistrar() {
super(NodeEntityScan.class, "nodeEntityScanBeanPostProcessor", NodeEntityScanBeanPostProcessor.class);
super(NodeEntityScan.class, "nodeEntityScanBeanPostProcessor",
NodeEntityScanBeanPostProcessor.class);
}
/**
* {@link BeanPostProcessor} to set
* {@link SessionFactoryProvider#setPackagesToScan(String...)} based
* on an {@link NodeEntityScan} annotation.
* {@link SessionFactoryProvider#setPackagesToScan(String...)} based on an
* {@link NodeEntityScan} annotation.
*/
static class NodeEntityScanBeanPostProcessor extends AbstractEntityScanBeanPostProcessor
implements SmartInitializingSingleton {
static class NodeEntityScanBeanPostProcessor extends
AbstractEntityScanBeanPostProcessor implements SmartInitializingSingleton {
private boolean processed;

View File

@@ -177,7 +177,6 @@ public class EntityManagerFactoryBuilder {
else {
entityManagerFactoryBean.setDataSource(this.dataSource);
}
entityManagerFactoryBean.setPackagesToScan(this.packagesToScan);
entityManagerFactoryBean.getJpaPropertyMap()
.putAll(EntityManagerFactoryBuilder.this.jpaProperties);

View File

@@ -34,7 +34,8 @@ import org.springframework.util.Assert;
class JpaEntityScanRegistrar extends AbstractEntityScanRegistrar {
JpaEntityScanRegistrar() {
super(EntityScan.class, "entityScanBeanPostProcessor", JpaEntityScanBeanPostProcessor.class);
super(EntityScan.class, "entityScanBeanPostProcessor",
JpaEntityScanBeanPostProcessor.class);
}
/**
@@ -42,8 +43,8 @@ class JpaEntityScanRegistrar extends AbstractEntityScanRegistrar {
* {@link LocalContainerEntityManagerFactoryBean#setPackagesToScan(String...)} based
* on an {@link EntityScan} annotation.
*/
static class JpaEntityScanBeanPostProcessor extends AbstractEntityScanBeanPostProcessor
implements SmartInitializingSingleton {
static class JpaEntityScanBeanPostProcessor extends
AbstractEntityScanBeanPostProcessor implements SmartInitializingSingleton {
private boolean processed;

View File

@@ -44,7 +44,8 @@ class TestEntityScanRegistrar extends AbstractEntityScanRegistrar {
}
static class TestEntityScanBeanPostProcessor extends AbstractEntityScanBeanPostProcessor {
static class TestEntityScanBeanPostProcessor
extends AbstractEntityScanBeanPostProcessor {
TestEntityScanBeanPostProcessor(String[] packagesToScan) {
super(packagesToScan);

View File

@@ -103,9 +103,7 @@ public class TestEntityScanTests {
}
private void assertSetPackagesToScan(String... expected) {
String[] actual = this.context
.getBean(TestFactoryBean.class)
.getPackagesToScan();
String[] actual = this.context.getBean(TestFactoryBean.class).getPackagesToScan();
assertThat(actual).isEqualTo(expected);
}
@@ -121,38 +119,47 @@ public class TestEntityScanTests {
@TestEntityScan("com.mycorp.entity")
static class ValueConfig extends BaseConfig {
}
@TestEntityScan(basePackages = "com.mycorp.entity2")
static class BasePackagesConfig extends BaseConfig {
}
@TestEntityScan(basePackageClasses = TestEntityScanTests.class)
static class BasePackageClassesConfig extends BaseConfig {
}
@TestEntityScan
static class FromConfigConfig extends BaseConfig {
}
@TestEntityScan(value = "com.mycorp.entity", basePackages = "com.mycorp")
static class ValueAndBasePackages extends BaseConfig {
}
@TestEntityScan(value = "com.mycorp.entity", basePackageClasses = TestEntityScanTests.class)
static class ValueAndBasePackageClasses extends BaseConfig {
}
@TestEntityScan(basePackages = "com.mycorp.entity2", basePackageClasses = TestEntityScanTests.class)
static class BasePackagesAndBasePackageClasses extends BaseConfig {
}
@TestEntityScan(basePackages = "foo")
static class MultiScanFirst extends BaseConfig {
}
@TestEntityScan(basePackages = "bar")
static class MultiScanSecond extends BaseConfig {
}
}