You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/01/23 18:52:17 UTC
[isis] branch ISIS-1846_internal_utils updated: ISIS-1846 minor
refactoring: introduces _Context (internal API)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch ISIS-1846_internal_utils
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/ISIS-1846_internal_utils by this push:
new da7b587 ISIS-1846 minor refactoring: introduces _Context (internal API)
da7b587 is described below
commit da7b58731073f96958807c50722cba309623fe72
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Jan 23 19:51:46 2018 +0100
ISIS-1846 minor refactoring: introduces _Context (internal API)
IsisContext is no longer a concrete class, but instead an interface,
that has only static methods and can not hold any state itself.
Singletons are now internal API via _Context. _Context also provides the
framework's internal single entry-point for requesting the framework's
default class-loader. (The public entry-point is via IsisContext.)
---
.../isis/applib/internal/context/_Context.java | 136 +++++++++++++++++++++
.../isis/applib/internal/context/_Contexts.java | 72 -----------
.../applib/internal/exceptions/_Exceptions.java | 4 +-
.../isis/applib/internal/reflection/_Reflect.java | 4 +-
.../isis/core/runtime/headless/IsisSystem.java | 2 +-
.../core/runtime/system/context/IsisContext.java | 102 +++++++---------
.../system/session/IsisSessionFactoryBuilder.java | 8 +-
7 files changed, 187 insertions(+), 141 deletions(-)
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Context.java b/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Context.java
new file mode 100644
index 0000000..ab7b256
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Context.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.isis.applib.internal.context;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Supplier;
+
+import org.apache.isis.applib.internal.base._Casts;
+
+/**
+ * <h1>- internal use only -</h1>
+ * <p>
+ * Provides a context for storing and retrieving singletons (usually application scoped).
+ * </p>
+ * <p>
+ * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
+ * These may be changed or removed without notice!
+ * </p>
+ * @since 2.0.0
+ */
+public final class _Context {
+
+ private _Context(){}
+
+ private final static Map<String, Object> singletonMap = new HashMap<>();
+
+ /**
+ * Puts a singleton instance onto the current context.
+ * @param type non-null
+ * @param singleton non-null
+ * @throws IllegalStateException if there is already an instance of same type on the current context.
+ */
+ public static void putSingleton(Class<?> type, Object singleton) {
+ Objects.requireNonNull(type);
+ Objects.requireNonNull(singleton);
+
+ if(singletonMap.containsKey(toKey(type)))
+ throw new IllegalStateException("there is already a singleton of type '"+type+"' on this context.");
+
+ singletonMap.put(toKey(type), singleton);
+ }
+
+ /**
+ * Gets a singleton instance of {@code type} if there is any, null otherwise.
+ * @param type non-null
+ * @return null, if there is no such instance
+ */
+ public static <T> T getIfAny(Class<? super T> type) {
+ return _Casts.uncheckedCast(singletonMap.get(toKey(type)));
+ }
+
+ /**
+ * Gets a singleton instance of {@code type} if there is any,
+ * otherwise returns the {@code fallback}'s result,
+ * which could be null.
+ * @param type non-null
+ * @param fallback non-null
+ * @return
+ */
+ public static <T> T getOrElse(Class<? super T> type, Supplier<T> fallback) {
+ Objects.requireNonNull(fallback);
+ final T singleton = getIfAny(type);
+ if(singleton!=null) {
+ return singleton;
+ }
+ return fallback.get();
+ }
+
+ /**
+ * Gets a singleton instance of {@code type} if there is any,
+ * otherwise throws the {@code onNotFound}'s result,
+ * which could be null.
+ * @param type non-null
+ * @param onNotFound non-null
+ * @return
+ * @throws Exception
+ */
+ public static <T, E extends Exception> T getOrThrow(
+ Class<? super T> type,
+ Supplier<E> onNotFound)
+ throws E {
+ Objects.requireNonNull(onNotFound);
+ final T singleton = getIfAny(type);
+ if(singleton!=null) {
+ return singleton;
+ }
+ throw onNotFound.get();
+ }
+
+ /**
+ * Removes any singleton references from the current context.
+ */
+ public static void clear() {
+ singletonMap.clear();
+ }
+
+ // -- DEFAULT CLASSLOADER
+
+ private final static Supplier<ClassLoader> FALLBACK_CLASSLOADER =
+ Thread.currentThread()::getContextClassLoader;
+
+ /**
+ * Will be set by the framework's bootstrapping mechanism if required.
+ * @return the default class loader
+ */
+ public static ClassLoader getDefaultClassLoader() {
+ return getOrElse(ClassLoader.class, FALLBACK_CLASSLOADER);
+ }
+
+ // -- HELPER
+
+ private static String toKey(Class<?> type) {
+ return type.getName();
+ }
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Contexts.java b/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Contexts.java
deleted file mode 100644
index 72c75ed..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Contexts.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.isis.applib.internal.context;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * <h1>- internal use only -</h1>
- * <p>
- * Entry point for providing application scoped contexts.
- * </p>
- * <p>
- * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
- * These may be changed or removed without notice!
- * </p>
- * @since 2.0.0
- */
-public final class _Contexts {
-
- private _Contexts(){}
-
- public interface Context {
- public ClassLoader getDefaultClassLoader();
- }
-
- private final static Map<Long, Context> contextMap = new HashMap<Long, _Contexts.Context>();
-
- /**
- * TODO this is just a stub yet
- * @return the current context
- *
- * @throws IllegalStateException if there is more than one context available,
- * use {@link #get(long)} instead
- */
- public static Context current() {
- return new Context() {
- @Override
- public ClassLoader getDefaultClassLoader() {
- return Thread.currentThread().getContextClassLoader();
- }
- };
- }
-
- /**
- * Get a context by id
- * @param contextId
- * @return
- */
- public static Context get(long contextId) {
- return contextMap.get(contextId);
- }
-
-
-}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java b/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java
index b503853..f3af4b8 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java
@@ -64,8 +64,8 @@ public final class _Exceptions {
return new IllegalArgumentException(String.format(format, _case));
}
- public static final RuntimeException unexpectedCodeReach() {
- return new RuntimeException("internal error: code was reached, that is expected unreachable");
+ public static final IllegalStateException unexpectedCodeReach() {
+ return new IllegalStateException("internal error: code was reached, that is expected unreachable");
}
// -- STACKTRACE UTILITITIES
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java
index 01b6fd6..fcffa73 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java
@@ -23,7 +23,7 @@ import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Set;
-import org.apache.isis.applib.internal.context._Contexts;
+import org.apache.isis.applib.internal.context._Context;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
@@ -62,7 +62,7 @@ public final class _Reflect {
public static Discovery discoverFullscan(String packageNamePrefix) {
_Reflect_Manifest.prepareDiscovery();
return _Reflect_Discovery.of(
- ClasspathHelper.forClassLoader(_Contexts.current().getDefaultClassLoader()),
+ ClasspathHelper.forClassLoader(_Context.getDefaultClassLoader()),
ClasspathHelper.forClass(Object.class),
ClasspathHelper.forPackage(packageNamePrefix),
new SubTypesScanner(false)
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
index b57e97b..f6c8142 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
@@ -245,7 +245,7 @@ public class IsisSystem {
// for subsequent tests; the attempt to bootstrap the framework will leave
// the IsisContext singleton as set.
- IsisContext.testReset();
+ IsisContext.clear();
final Set<String> validationErrors = ex.getValidationErrors();
final StringBuilder buf = new StringBuilder();
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/IsisContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/IsisContext.java
index dd63f0f..ee1cc1c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/IsisContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/IsisContext.java
@@ -19,80 +19,64 @@
package org.apache.isis.core.runtime.system.context;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.applib.internal.context._Context;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelInvalidException;
-import org.apache.isis.core.runtime.system.session.IsisSessionFactoryBuilder;
-import org.apache.isis.core.runtime.system.session.IsisSession;
import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
/**
- * Simply a static field holding the {@link IsisSessionFactory} singleton, and conveneince methods to obtain the
- * current {@link IsisSession}, along with application-scoped components and also any transaction-scoped components.
+ * Provides static access to current context's singletons
+ * {@link MetaModelInvalidException} and {@link IsisSessionFactory}.
*/
-public final class IsisContext {
-
- private static final Logger LOG = LoggerFactory.getLogger(IsisContext.class);
-
- private IsisContext(){
- throw new IllegalStateException("Never instantiated");
- }
-
- //region > metaModelInvalidExceptionIfAny (static)
- /**
- * Populated only if the metamodel was found to be invalid
- */
- private static MetaModelInvalidException metamodelInvalidException;
-
- public static MetaModelInvalidException getMetaModelInvalidExceptionIfAny() {
- return IsisContext.metamodelInvalidException;
- }
- public static void setMetaModelInvalidException(final MetaModelInvalidException metaModelInvalid) {
- IsisContext.metamodelInvalidException = metaModelInvalid;
- }
- //endregion
-
- //region > sessionFactory (static)
-
- private static IsisSessionFactory sessionFactory;
-
- public static IsisSessionFactory getSessionFactory() {
- return sessionFactory;
- }
-
-
+public interface IsisContext {
+
+ /**
+ * Populated only if the meta-model was found to be invalid.
+ * @return null, if there is none
+ */
+ public static MetaModelInvalidException getMetaModelInvalidExceptionIfAny() {
+ return _Context.getIfAny(MetaModelInvalidException.class);
+ }
+
+ /**
+ *
+ * @return Isis's session factory
+ */
+ // Implementation Note: Populated only by {@link IsisSessionFactoryBuilder}.
+ public static IsisSessionFactory getSessionFactory() {
+ return _Context.getOrThrow(
+ IsisSessionFactory.class,
+ ()->new IllegalStateException(
+ "internal error: should have been populated by IsisSessionFactoryBuilder") );
+ }
+
+ /**
+ *
+ * @return Isis's default class loader
+ */
+ public static ClassLoader getClassLoader() {
+ return _Context.getDefaultClassLoader();
+ }
+
+ // -- LIFE-CYCLING
+
/**
- * Intended to be called only by {@link IsisSessionFactoryBuilder}.
+ * Destroys this context and clears any state associated with it.
+ * It marks the end of IsisContext's life-cycle. Subsequent calls have no effect.
*/
- public static void setSessionFactory(final IsisSessionFactory sessionFactory) {
- if (IsisContext.sessionFactory != null) {
- throw new IsisException("SessionFactory already set up");
- }
- IsisContext.sessionFactory = sessionFactory;
+ public static void clear() {
+ _Context.clear();
}
+ // -- DEPRECATIONS
+
/**
* Resets
- * @deprecated replaced by {@link #destroy()}
+ * @deprecated replaced by {@link #clear()}
*
*/
@Deprecated
public static void testReset() {
- destroy();
+ clear();
}
-
- /**
- * Destroys this context and clears any state associated with it.
- * It marks the end of IsisContext's lifecycle. Subsequent calls have no effect.
- */
- public static void destroy() {
- sessionFactory = null;
- metamodelInvalidException = null;
- }
-
- //endregion
-
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
index 1ddcaf7..bb08a05 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
@@ -30,6 +30,7 @@ import org.apache.isis.applib.AppManifest;
import org.apache.isis.applib.clock.Clock;
import org.apache.isis.applib.fixtures.FixtureClock;
import org.apache.isis.applib.fixturescripts.FixtureScripts;
+import org.apache.isis.applib.internal.context._Context;
import org.apache.isis.applib.services.fixturespec.FixtureScriptsDefault;
import org.apache.isis.core.commons.config.IsisConfigurationDefault;
import org.apache.isis.core.commons.lang.ListExtensions;
@@ -173,12 +174,9 @@ public class IsisSessionFactoryBuilder {
// finally, wire up components and components into services...
servicesInjector.autowire();
-
// ... and make IsisSessionFactory available via the IsisContext static for those places where we cannot
// yet inject.
- IsisContext.setSessionFactory(isisSessionFactory);
-
-
+ _Context.putSingleton(IsisSessionFactory.class, isisSessionFactory);
// time to initialize...
specificationLoader.init();
@@ -221,7 +219,7 @@ public class IsisSessionFactoryBuilder {
if(LOG.isDebugEnabled()) {
LOG.debug("Meta model invalid", ex);
}
- IsisContext.setMetaModelInvalidException(ex);
+ _Context.putSingleton(MetaModelInvalidException.class, ex);
}
}
--
To stop receiving notification emails like this one, please contact
ahuber@apache.org.