You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2014/09/25 15:35:30 UTC
git commit: ISIS-866: @PostConstruct and @PreDestroy now honoured for
request-scope services.
Repository: isis
Updated Branches:
refs/heads/master 790e70df1 -> ad79a943c
ISIS-866: @PostConstruct and @PreDestroy now honoured for request-scope services.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/ad79a943
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/ad79a943
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/ad79a943
Branch: refs/heads/master
Commit: ad79a943c51473f81b33bc0f84b17fc2819d0ea6
Parents: 790e70d
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Sep 25 14:35:06 2014 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Sep 25 14:35:06 2014 +0100
----------------------------------------------------------------------
.../org/apache/isis/applib/annotation/Bulk.java | 7 +-
.../applib/services/scratchpad/Scratchpad.java | 3 -
.../integtestsupport/IsisSystemForTest.java | 3 +
.../config/IsisConfigurationDefault.java | 32 ++--
.../specloader/ObjectReflectorDefault.java | 33 +---
.../specloader/ServiceInitializer.java | 9 +-
.../specloader/ServiceInitializerTest.java | 14 +-
.../runtime/services/ServiceInstantiator.java | 160 ++++++++++++++++++-
.../ServicesInstallerFromAnnotation.java | 20 ++-
.../ServicesInstallerFromConfiguration.java | 24 +++
.../system/IsisSystemFixturesHookAbstract.java | 22 ++-
.../services/ServiceInstantiatorTest.java | 16 +-
12 files changed, 249 insertions(+), 94 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
index 84cff20..f97790a 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
@@ -19,15 +19,10 @@
package org.apache.isis.applib.annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import java.lang.annotation.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-
import javax.enterprise.context.RequestScoped;
/**
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/applib/src/main/java/org/apache/isis/applib/services/scratchpad/Scratchpad.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/scratchpad/Scratchpad.java b/core/applib/src/main/java/org/apache/isis/applib/services/scratchpad/Scratchpad.java
index 24c84d7..7c3af84 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/scratchpad/Scratchpad.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/scratchpad/Scratchpad.java
@@ -19,11 +19,8 @@
package org.apache.isis.applib.services.scratchpad;
import java.util.Map;
-
import javax.enterprise.context.RequestScoped;
-
import com.google.common.collect.Maps;
-
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.Programmatic;
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
----------------------------------------------------------------------
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
index b3a1692..08cae1e 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
@@ -199,9 +199,12 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
throw new IllegalArgumentException("Specify packagePrefixes to search for @DomainService-annotated services");
}
final ServicesInstallerFromAnnotation installer = new ServicesInstallerFromAnnotation();
+ installer.setConfiguration(configuration);
installer.withPackagePrefixes(packagePrefixes);
final List<Object> serviceList = installer.getServices(null);
this.services.addAll(serviceList);
+
+ installer.init();
return this;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/metamodel/src/main/java/org/apache/isis/core/commons/config/IsisConfigurationDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/config/IsisConfigurationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/config/IsisConfigurationDefault.java
index a6bd278..07ff90d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/config/IsisConfigurationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/config/IsisConfigurationDefault.java
@@ -92,35 +92,35 @@ public class IsisConfigurationDefault implements IsisConfiguration {
/**
* Add the properties from an existing Properties object; if the key exists in the configuration then will be ignored.
- *
- * @see #add(Properties, ContainsPolicy)
+ *
+ * @see #addPerPolicy(Properties, ContainsPolicy)
* @see #put(Properties)
*/
public void add(final Properties properties) {
- add(properties, ContainsPolicy.IGNORE);
+ addPerPolicy(properties, ContainsPolicy.IGNORE);
}
-
+
/**
* Add the properties from an existing Properties object; if the key exists in the configuration then will be overwritten.
- *
+ *
* @see #add(Properties)
- * @see #add(Properties, ContainsPolicy)
+ * @see #addPerPolicy(Properties, ContainsPolicy)
*/
public void put(final Properties properties) {
- add(properties, ContainsPolicy.OVERWRITE);
+ addPerPolicy(properties, ContainsPolicy.OVERWRITE);
}
-
+
/**
* Add the properties from an existing Properties object; if the key exists in the configuration then the
* {@link ContainsPolicy} will be applied.
- *
+ *
* @see #add(Properties)
* @see #put(Properties)
*/
- public void add(final Properties properties, final ContainsPolicy policy) {
+ private void addPerPolicy(final Properties properties, final ContainsPolicy policy) {
for(Object key: properties.keySet()) {
Object value = properties.get(key);
- add((String)key, (String)value);
+ addPerPolicy((String) key, (String) value, policy);
}
}
@@ -128,11 +128,11 @@ public class IsisConfigurationDefault implements IsisConfiguration {
* Adds a key-value pair to this set of properties; if the key exists in the configuration then will be ignored.
*
* <p>
- * @see #add(String, String, ContainsPolicy)
+ * @see #addPerPolicy(String, String, ContainsPolicy)
* @see #put(String, String)
*/
public void add(final String key, final String value) {
- add(key, value, ContainsPolicy.IGNORE);
+ addPerPolicy(key, value, ContainsPolicy.IGNORE);
}
/**
@@ -140,10 +140,10 @@ public class IsisConfigurationDefault implements IsisConfiguration {
*
* <p>
* @see #add(String, String)
- * @see #add(String, String, ContainsPolicy)
+ * @see #addPerPolicy(String, String, ContainsPolicy)
*/
public void put(final String key, final String value) {
- add(key, value, ContainsPolicy.OVERWRITE);
+ addPerPolicy(key, value, ContainsPolicy.OVERWRITE);
}
/**
@@ -153,7 +153,7 @@ public class IsisConfigurationDefault implements IsisConfiguration {
* @see #add(String, String)
* @see #put(String, String)
*/
- public void add(final String key, final String value, final ContainsPolicy policy) {
+ private void addPerPolicy(final String key, final String value, final ContainsPolicy policy) {
if (value == null) {
LOG.debug("ignoring " + key + " as value is null");
return;
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
index a56b9d3..3d2400e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
@@ -19,24 +19,12 @@
package org.apache.isis.core.metamodel.specloader;
-import static org.apache.isis.core.commons.ensure.Ensure.ensureThatArg;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import java.util.*;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
import org.apache.isis.core.commons.components.ApplicationScopedComponent;
@@ -60,15 +48,7 @@ import org.apache.isis.core.metamodel.runtimecontext.RuntimeContext;
import org.apache.isis.core.metamodel.runtimecontext.RuntimeContextAware;
import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
import org.apache.isis.core.metamodel.runtimecontext.noruntime.RuntimeContextNoRuntime;
-import org.apache.isis.core.metamodel.spec.FreeStandingList;
-import org.apache.isis.core.metamodel.spec.ObjectInstantiator;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.SpecificationContext;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpiAware;
+import org.apache.isis.core.metamodel.spec.*;
import org.apache.isis.core.metamodel.spec.feature.ObjectMemberContext;
import org.apache.isis.core.metamodel.specloader.classsubstitutor.ClassSubstitutor;
import org.apache.isis.core.metamodel.specloader.collectiontyperegistry.CollectionTypeRegistry;
@@ -86,6 +66,10 @@ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
+import static org.apache.isis.core.commons.ensure.Ensure.ensureThatArg;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+
/**
* Builds the meta-model.
*
@@ -148,9 +132,7 @@ public final class ObjectReflectorDefault implements SpecificationLoaderSpi, App
private final FacetProcessor facetProcessor;
/**
- * Defaulted in the constructor, so can be added to via
- * {@link #setFacetDecorators(FacetDecoratorSet)} or
- * {@link #addFacetDecorator(FacetDecorator)}.
+ * Initialized in the constructor.
*
* <p>
* {@link FacetDecorator}s must be added prior to {@link #init()
@@ -182,7 +164,6 @@ public final class ObjectReflectorDefault implements SpecificationLoaderSpi, App
private final MetaModelValidator metaModelValidator;
private final SpecificationCacheDefault cache = new SpecificationCacheDefault();
- private final ServiceInitializer serviceInitializer = new ServiceInitializer();
private boolean initialized = false;
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ServiceInitializer.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ServiceInitializer.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ServiceInitializer.java
index 367e99e..65404ab 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ServiceInitializer.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ServiceInitializer.java
@@ -19,16 +19,11 @@ package org.apache.isis.core.metamodel.specloader;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
-
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
-
import com.google.common.collect.Maps;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.lang.MethodExtensions;
@@ -44,7 +39,7 @@ public class ServiceInitializer {
// //////////////////////////////////////
- public void validate(final IsisConfiguration configuration, DomainObjectContainer container, final List<Object> services) {
+ public void validate(final IsisConfiguration configuration, final List<Object> services) {
this.props = configuration.asMap();
@@ -111,7 +106,7 @@ public class ServiceInitializer {
for (final Map.Entry<Object, Method> entry : postConstructMethodsByService.entrySet()) {
final Object service = entry.getKey();
final Method method = entry.getValue();
-
+
LOG.info("... calling @PostConstruct method: " + service.getClass().getName() + ": " + method.getName());
final int numParams = method.getParameterTypes().length;
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/ServiceInitializerTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/ServiceInitializerTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/ServiceInitializerTest.java
index a1940a4..81c83aa 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/ServiceInitializerTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/ServiceInitializerTest.java
@@ -102,7 +102,7 @@ public class ServiceInitializerTest {
public void postConstruct() {
final DomainServiceWithPostConstruct d1 = new DomainServiceWithPostConstruct();
final DomainServiceWithPostConstructWithProperties d2 = new DomainServiceWithPostConstructWithProperties();
- serviceInitializer.validate(configuration, container, listOf(d1, d2));
+ serviceInitializer.validate(configuration, listOf(d1, d2));
serviceInitializer.postConstruct();
assertThat(d1.called, is(true));
assertThat(d2.called, is(true));
@@ -122,7 +122,7 @@ public class ServiceInitializerTest {
public void preDestroy() {
final DomainServiceWithPreDestroy d1 = new DomainServiceWithPreDestroy();
final DomainServiceWithPreDestroy d2 = new DomainServiceWithPreDestroy();
- serviceInitializer.validate(configuration, container, listOf(d1, d2));
+ serviceInitializer.validate(configuration, listOf(d1, d2));
serviceInitializer.preDestroy();
assertThat(d1.called, is(true));
assertThat(d2.called, is(true));
@@ -146,7 +146,7 @@ public class ServiceInitializerTest {
expectedException.expectMessage(
containsString(
"Found more than one @PostConstruct method; service is: org.apache.isis.core.metamodel.specloader.ServiceInitializerTest$DomainServiceWithMultiplePostConstruct, found"));
- serviceInitializer.validate(configuration, container, listOf(d1));
+ serviceInitializer.validate(configuration, listOf(d1));
}
public static class DomainServiceWithMultiplePreDestroy {
@@ -167,7 +167,7 @@ public class ServiceInitializerTest {
expectedException.expectMessage(
containsString(
"Found more than one @PreDestroy method; service is: org.apache.isis.core.metamodel.specloader.ServiceInitializerTest$DomainServiceWithMultiplePreDestroy, found"));
- serviceInitializer.validate(configuration, container, listOf(d1));
+ serviceInitializer.validate(configuration, listOf(d1));
}
public static class DomainServiceWithPostConstructOneArgWrongType {
@@ -183,7 +183,7 @@ public class ServiceInitializerTest {
final DomainServiceWithPostConstructOneArgWrongType d1 = new DomainServiceWithPostConstructOneArgWrongType();
expectedException.expectMessage(
"@PostConstruct method must be no-arg or 1-arg accepting java.util.Map; method is: org.apache.isis.core.metamodel.specloader.ServiceInitializerTest$DomainServiceWithPostConstructOneArgWrongType#y");
- serviceInitializer.validate(configuration, container, listOf(d1));
+ serviceInitializer.validate(configuration, listOf(d1));
}
public static class DomainServiceWithPostConstructTwoArgs {
@@ -199,7 +199,7 @@ public class ServiceInitializerTest {
final DomainServiceWithPostConstructTwoArgs d1 = new DomainServiceWithPostConstructTwoArgs();
expectedException.expectMessage(
"@PostConstruct method must be no-arg or 1-arg accepting java.util.Map; method is: org.apache.isis.core.metamodel.specloader.ServiceInitializerTest$DomainServiceWithPostConstructTwoArgs#y");
- serviceInitializer.validate(configuration, container, listOf(d1));
+ serviceInitializer.validate(configuration, listOf(d1));
}
public static class DomainServiceWithPreDestroyOneArgs {
@@ -216,7 +216,7 @@ public class ServiceInitializerTest {
final DomainServiceWithPreDestroyOneArgs d1 = new DomainServiceWithPreDestroyOneArgs();
expectedException.expectMessage(
"@PreDestroy method must be no-arg; method is: org.apache.isis.core.metamodel.specloader.ServiceInitializerTest$DomainServiceWithPreDestroyOneArgs#y");
- serviceInitializer.validate(configuration, container, listOf(d1));
+ serviceInitializer.validate(configuration, listOf(d1));
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
index f2458ad..b87c4db 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
@@ -19,19 +19,28 @@
package org.apache.isis.core.runtime.services;
-import java.lang.reflect.Method;
-
import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import javax.enterprise.context.RequestScoped;
-
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.commons.factory.InstanceCreationClassException;
import org.apache.isis.core.commons.factory.InstanceCreationException;
import org.apache.isis.core.commons.lang.ArrayExtensions;
+import org.apache.isis.core.commons.lang.MethodExtensions;
import org.apache.isis.core.metamodel.specloader.classsubstitutor.JavassistEnhanced;
/**
@@ -58,12 +67,34 @@ import org.apache.isis.core.metamodel.specloader.classsubstitutor.JavassistEnhan
*/
public final class ServiceInstantiator {
+ private final static Logger LOG = LoggerFactory.getLogger(ServiceInstantiator.class);
+
+
public ServiceInstantiator() {
}
// //////////////////////////////////////
+
+ /**
+ * initially null, but checked before first use that has been set (through {@link #setConfiguration(org.apache.isis.core.commons.config.IsisConfiguration)}).
+ */
+ private Map<String, String> props;
+
+ public void setConfiguration(IsisConfiguration configuration) {
+ this.props = configuration.asMap();
+ }
+
+ private void ensureInitialized() {
+ if(props == null) {
+ throw new IllegalStateException("IsisConfiguration properties not set on ServiceInstantiator prior to first-use");
+ }
+ }
+
+
+ // //////////////////////////////////////
public <T> T createInstance(final Class<T> cls) {
+ ensureInitialized();
if(cls.isAnnotationPresent(RequestScoped.class)) {
return instantiateRequestScopedProxy(cls);
} else {
@@ -104,11 +135,22 @@ public final class ServiceInstantiator {
@Override
public Object invoke(final Object proxied, final Method proxyMethod, final Method proxiedMethod, final Object[] args) throws Throwable {
+
+ cacheMethodsIfNecessary(cls);
+
if(proxyMethod.getName().equals("__isis_startRequest")) {
T service = instantiate(cls);
+
+ callPostConstructIfPresent(service);
+
serviceByThread.set(service);
return null;
} else if(proxyMethod.getName().equals("__isis_endRequest")) {
+
+ final T service = serviceByThread.get();
+
+ callPreDestroyIfPresent(service);
+
serviceByThread.set(null);
return null;
} else {
@@ -130,6 +172,118 @@ public final class ServiceInstantiator {
}
}
+ private Set<Class<?>> cached = Sets.newHashSet();
+ private Map<Class<?>, Method> postConstructMethodsByServiceClass = Maps.newLinkedHashMap();
+ private Map<Class<?>, Method> preDestroyMethodsByServiceClass = Maps.newLinkedHashMap();
+
+ <T> void callPostConstructIfPresent(T service) {
+
+ final Class<?> serviceClass = service.getClass();
+ final Method postConstructMethod = postConstructMethodsByServiceClass.get(serviceClass);
+ if(postConstructMethod == null) {
+ return;
+ }
+ final int numParams = postConstructMethod.getParameterTypes().length;
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("... calling @PostConstruct method: " + serviceClass.getName() + ": " + postConstructMethod.getName());
+ }
+ // unlike shutdown, we don't swallow exceptions; would rather fail early
+ if(numParams == 0) {
+ MethodExtensions.invoke(postConstructMethod, service);
+ } else {
+ MethodExtensions.invoke(postConstructMethod, service, new Object[]{props});
+ }
+ }
+
+ <T> void callPreDestroyIfPresent(T service) throws InvocationTargetException, IllegalAccessException {
+
+ final Class<?> serviceClass = service.getClass();
+ final Method preDestroyMethod = preDestroyMethodsByServiceClass.get(serviceClass);
+ if(preDestroyMethod == null) {
+ return;
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("... calling @PreDestroy method: " + serviceClass.getName() + ": " + preDestroyMethod.getName());
+ }
+ try {
+ MethodExtensions.invoke(preDestroyMethod, service);
+ } catch(Exception ex) {
+ // do nothing
+ LOG.warn("... @PreDestroy method threw exception - continuing anyway", ex);
+ }
+ }
+
+
+ private void cacheMethodsIfNecessary(Class<?> serviceClass) {
+ if(cached.contains(serviceClass)) {
+ return;
+ }
+ cacheMethods(serviceClass);
+ cached.add(serviceClass);
+ }
+
+ private void cacheMethods(Class<?> serviceClass) {
+ final Method[] methods = serviceClass.getMethods();
+
+ // @PostConstruct
+ Method postConstructMethod = null;
+ for (final Method method : methods) {
+
+ final PostConstruct postConstructAnnotation = method.getAnnotation(PostConstruct.class);
+ if (postConstructAnnotation == null) {
+ continue;
+ }
+ if (postConstructMethod != null) {
+ throw new RuntimeException("Found more than one @PostConstruct method; service is: " + serviceClass.getName() + ", found " + postConstructMethod.getName() + " and " + method.getName());
+ }
+
+ final Class<?>[] parameterTypes = method.getParameterTypes();
+ switch (parameterTypes.length) {
+ case 0:
+ break;
+ case 1:
+ if (Map.class != parameterTypes[0]) {
+ throw new RuntimeException("@PostConstruct method must be no-arg or 1-arg accepting java.util.Map; method is: " + serviceClass.getName() + "#" + method.getName());
+ }
+ break;
+ default:
+ throw new RuntimeException("@PostConstruct method must be no-arg or 1-arg accepting java.util.Map; method is: " + serviceClass.getName() + "#" + method.getName());
+ }
+ postConstructMethod = method;
+ }
+
+ // @PreDestroy
+ Method preDestroyMethod = null;
+ for (final Method method : methods) {
+
+ final PreDestroy preDestroyAnnotation = method.getAnnotation(PreDestroy.class);
+ if(preDestroyAnnotation == null) {
+ continue;
+ }
+ if(preDestroyMethod != null) {
+ throw new RuntimeException("Found more than one @PreDestroy method; service is: " + serviceClass.getName() + ", found " + preDestroyMethod.getName() + " and " + method.getName());
+ }
+
+ final Class<?>[] parameterTypes = method.getParameterTypes();
+ switch(parameterTypes.length) {
+ case 0:
+ break;
+ default:
+ throw new RuntimeException("@PreDestroy method must be no-arg; method is: " + serviceClass.getName() + "#" + method.getName());
+ }
+ preDestroyMethod = method;
+ }
+
+ if(postConstructMethod != null) {
+ postConstructMethodsByServiceClass.put(serviceClass, postConstructMethod);
+ }
+ if(preDestroyMethod != null) {
+ preDestroyMethodsByServiceClass.put(serviceClass, preDestroyMethod);
+ }
+ }
+
// //////////////////////////////////////
private static <T> T instantiate(final Class<T> cls) {
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
index 68c187b..e706692 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
@@ -99,16 +99,22 @@ public class ServicesInstallerFromAnnotation extends InstallerAbstract implement
if(initialized) {
return;
}
- if(packagePrefixes != null) {
- return;
- }
+ if(getConfiguration() == null) {
+ throw new IllegalStateException("No IsisConfiguration injected - aborting");
+ }
try {
- String packagePrefixes = getConfiguration().getString(PACKAGE_PREFIX_KEY);
- if(Strings.isNullOrEmpty(packagePrefixes)) {
- throw new IllegalStateException("Could not locate '" + PACKAGE_PREFIX_KEY + "' key in property files - aborting");
+
+ // lazily copy over the configuration to the instantiator
+ serviceInstantiator.setConfiguration(getConfiguration());
+
+ if(packagePrefixes == null) {
+ String packagePrefixes = getConfiguration().getString(PACKAGE_PREFIX_KEY);
+ if(Strings.isNullOrEmpty(packagePrefixes)) {
+ throw new IllegalStateException("Could not locate '" + PACKAGE_PREFIX_KEY + "' key in property files - aborting");
+ }
+ this.packagePrefixes = packagePrefixes + PACKAGE_PREFIX_STANDARD;
}
- this.packagePrefixes = packagePrefixes + PACKAGE_PREFIX_STANDARD;
} finally {
initialized = true;
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromConfiguration.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromConfiguration.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromConfiguration.java
index c8f43ec..06f530b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromConfiguration.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromConfiguration.java
@@ -56,11 +56,35 @@ public class ServicesInstallerFromConfiguration extends InstallerAbstract implem
private Map<DeploymentType, List<Object>> servicesByDeploymentType = Maps.newHashMap();
+ public void init() {
+ initIfRequired();
+ }
+
+ private boolean initialized = false;
+
+ protected void initIfRequired() {
+ if(initialized) {
+ return;
+ }
+
+ try {
+ // lazily copy over the configuration to the instantiator
+ serviceInstantiator.setConfiguration(getConfiguration());
+
+ } finally {
+ initialized = true;
+ }
+ }
+
+
@Override
public List<Object> getServices(final DeploymentType deploymentType) {
LOG.info("installing " + this.getClass().getName());
+ // rather nasty, lazily copy over the configuration to the instantiator
+ serviceInstantiator.setConfiguration(getConfiguration());
+
List<Object> serviceList = servicesByDeploymentType.get(deploymentType);
if(serviceList == null) {
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/runtime/src/main/java/org/apache/isis/core/runtime/system/IsisSystemFixturesHookAbstract.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/IsisSystemFixturesHookAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/IsisSystemFixturesHookAbstract.java
index a3aebc9..be43af1 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/IsisSystemFixturesHookAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/IsisSystemFixturesHookAbstract.java
@@ -54,6 +54,7 @@ import org.apache.isis.core.runtime.system.internal.SplashWindow;
import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
import org.apache.isis.core.runtime.system.session.IsisSession;
import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManagerException;
import org.apache.isis.core.runtime.userprofile.UserProfileStore;
@@ -171,22 +172,22 @@ public abstract class IsisSystemFixturesHookAbstract implements IsisSystem {
// validate
final ServiceInitializer serviceInitializer = new ServiceInitializer();
- serviceInitializer.validate(getConfiguration(), container, services);
+ serviceInitializer.validate(getConfiguration(), services);
// call @PostConstruct (in a session)
IsisContext.openSession(new InitialisationSession());
try {
- IsisContext.getTransactionManager().startTransaction();
+ getTransactionManager().startTransaction();
try {
serviceInitializer.postConstruct();
return serviceInitializer;
} catch(RuntimeException ex) {
- IsisContext.getTransactionManager().getTransaction().setAbortCause(new IsisTransactionManagerException(ex));
+ getTransactionManager().getTransaction().setAbortCause(new IsisTransactionManagerException(ex));
return serviceInitializer;
} finally {
// will commit or abort
- IsisContext.getTransactionManager().endTransaction();
+ getTransactionManager().endTransaction();
}
} finally {
IsisContext.closeSession();
@@ -211,15 +212,15 @@ public abstract class IsisSystemFixturesHookAbstract implements IsisSystem {
// call @PostDestroy (in a session)
IsisContext.openSession(new InitialisationSession());
try {
- IsisContext.getTransactionManager().startTransaction();
+ getTransactionManager().startTransaction();
try {
serviceInitializer.preDestroy();
} catch(RuntimeException ex) {
- IsisContext.getTransactionManager().getTransaction().setAbortCause(new IsisTransactionManagerException(ex));
+ getTransactionManager().getTransaction().setAbortCause(new IsisTransactionManagerException(ex));
} finally {
// will commit or abort
- IsisContext.getTransactionManager().endTransaction();
+ getTransactionManager().endTransaction();
}
} finally {
IsisContext.closeSession();
@@ -360,7 +361,7 @@ public abstract class IsisSystemFixturesHookAbstract implements IsisSystem {
* {@link IsisConfiguration} using
* {@link PersistenceConstants#DOMAIN_OBJECT_CONTAINER_CLASS_NAME}. If no
* implementation is specified, then defaults to
- * {@value PersistenceConstants#DOMAIN_OBJECT_CONTAINER_NAME_DEFAULT}.
+ * {@link PersistenceConstants#DOMAIN_OBJECT_CONTAINER_NAME_DEFAULT}.
*/
protected DomainObjectContainer obtainContainer() {
return createContainer(getConfiguration());
@@ -496,4 +497,9 @@ public abstract class IsisSystemFixturesHookAbstract implements IsisSystem {
}
}
+ IsisTransactionManager getTransactionManager() {
+ return IsisContext.getTransactionManager();
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad79a943/core/runtime/src/test/java/org/apache/isis/core/runtime/services/ServiceInstantiatorTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/services/ServiceInstantiatorTest.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/services/ServiceInstantiatorTest.java
index 8d0203d..049d2d3 100644
--- a/core/runtime/src/test/java/org/apache/isis/core/runtime/services/ServiceInstantiatorTest.java
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/services/ServiceInstantiatorTest.java
@@ -16,23 +16,16 @@
*/
package org.apache.isis.core.runtime.services;
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.assertThat;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
-
import javax.enterprise.context.RequestScoped;
-
-import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
-import org.apache.isis.applib.services.memento.MementoService.Memento;
-import org.apache.isis.core.commons.matchers.IsisMatchers;
-import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
public class ServiceInstantiatorTest {
@@ -41,6 +34,7 @@ public class ServiceInstantiatorTest {
@Before
public void setUp() throws Exception {
serviceInstantiator = new ServiceInstantiator();
+ serviceInstantiator.setConfiguration(new IsisConfigurationDefault());
}
@Test