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/08/30 14:29:29 UTC

[isis] branch master updated: ISIS-1895: extract config loading responsibility into a singleton

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new d094d06  ISIS-1895: extract config loading responsibility into a singleton
d094d06 is described below

commit d094d0613f601fab779471e680a0253ac2ba4a0b
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Aug 30 16:29:23 2018 +0200

    ISIS-1895: extract config loading responsibility into a singleton
    
    introduces IsisWebAppConfigProvider
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1895
---
 .../isis/core/webapp/IsisWebAppBootstrapper.java   |  53 +--------
 .../isis/core/webapp/IsisWebAppConfigProvider.java | 131 +++++++++++++++++++++
 .../core/webapp/IsisWebAppContextListener.java     |  14 ++-
 .../apache/isis/core/webapp/modules/WebModule.java |  11 +-
 .../wicket/viewer/IsisWicketApplication.java       |   5 +-
 5 files changed, 151 insertions(+), 63 deletions(-)

diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppBootstrapper.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppBootstrapper.java
index 838496f..bce7206 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppBootstrapper.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppBootstrapper.java
@@ -32,18 +32,13 @@ import org.slf4j.LoggerFactory;
 import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.commons.config.NotFoundPolicy;
 import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder;
-import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
-import org.apache.isis.core.commons.resource.ResourceStreamSourceCurrentClassClassPath;
-import org.apache.isis.core.commons.resource.ResourceStreamSourceFileSystem;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
 import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer;
 import org.apache.isis.core.runtime.runner.IsisInjectModule;
-import org.apache.isis.core.runtime.runner.opts.OptionHandlerInitParameters;
 import org.apache.isis.core.runtime.system.DeploymentType;
 import org.apache.isis.core.runtime.system.SystemConstants;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactoryBuilder;
-import org.apache.isis.core.webapp.config.ResourceStreamSourceForWebInf;
 
 /**
  * Initialize the {@link IsisSessionFactoryBuilder} when the web application starts, and
@@ -83,7 +78,8 @@ public class IsisWebAppBootstrapper implements ServletContextListener {
             final String webInfDir = servletContext.getRealPath("/WEB-INF");
             loggingConfigurer.configureLogging(webInfDir, new String[0]);
 
-            final IsisConfigurationBuilder isisConfigurationBuilder = obtainIsisConfigurationBuilder(servletContext);
+            final IsisConfigurationBuilder isisConfigurationBuilder = 
+                    IsisWebAppConfigProvider.getInstance().getConfigurationBuilder(servletContext);
             isisConfigurationBuilder.addDefaultConfigurationResourcesAndPrimers();
 
             final DeploymentType deploymentType = determineDeploymentType(servletContext, isisConfigurationBuilder);
@@ -107,51 +103,6 @@ public class IsisWebAppBootstrapper implements ServletContextListener {
         LOG.info("server started");
     }
 
-    protected IsisConfigurationBuilder obtainIsisConfigurationBuilder(final ServletContext servletContext) {
-        return obtainConfigBuilderFrom(servletContext);
-    }
-
-    /**
-     * public so can also be used by Wicket viewer.
-     */
-    public static IsisConfigurationBuilder obtainConfigBuilderFrom(final ServletContext servletContext) {
-        final IsisConfigurationBuilder isisConfigurationBuilder = lookupIsisConfigurationBuilder(servletContext);
-        isisConfigurationBuilder.primeWith(new OptionHandlerInitParameters(servletContext));
-
-        addResourceStreamSources(servletContext, isisConfigurationBuilder);
-        return isisConfigurationBuilder;
-    }
-
-    public static IsisConfigurationBuilder lookupIsisConfigurationBuilder(final ServletContext servletContext) {
-        IsisConfigurationBuilder isisConfigurationBuilder =
-                (IsisConfigurationBuilder) servletContext.getAttribute(WebAppConstants.CONFIGURATION_BUILDER_KEY);
-        if(isisConfigurationBuilder == null) {
-            isisConfigurationBuilder = new IsisConfigurationBuilder();
-        }
-        return isisConfigurationBuilder;
-    }
-
-    private static void addResourceStreamSources(
-            final ServletContext servletContext,
-            final IsisConfigurationBuilder isisConfigurationBuilder) {
-
-
-        // will load either from WEB-INF, from the classpath or from config directory.
-        final String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM);
-        if ( configLocation != null ) {
-            LOG.info("Config override location: {}", configLocation );
-            isisConfigurationBuilder.addResourceStreamSource(ResourceStreamSourceFileSystem.create(configLocation));
-        } else {
-            LOG.info("Config override location: No override location configured" );
-
-            isisConfigurationBuilder.addResourceStreamSource(ResourceStreamSourceContextLoaderClassPath.create());
-            isisConfigurationBuilder.addResourceStreamSource(new ResourceStreamSourceCurrentClassClassPath());
-            isisConfigurationBuilder.addResourceStreamSource(new ResourceStreamSourceForWebInf(servletContext));
-        }
-
-
-    }
-
     /**
      * Checks {@link IsisConfigurationBuilder configuration} for
      * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}, (that is, from the command
diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppConfigProvider.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppConfigProvider.java
new file mode 100644
index 0000000..c36a9ae
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppConfigProvider.java
@@ -0,0 +1,131 @@
+/*
+ *  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.core.webapp;
+
+import static org.apache.isis.commons.internal.context._Context.getOrThrow;
+import static org.apache.isis.commons.internal.context._Context.putSingleton;
+
+import javax.servlet.ServletContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceCurrentClassClassPath;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceFileSystem;
+import org.apache.isis.core.runtime.runner.opts.OptionHandlerInitParameters;
+import org.apache.isis.core.webapp.config.ResourceStreamSourceForWebInf;
+
+/**
+ * Provides IsisConfigurationBuilder instances.
+ *  
+ * @since 2.0.0
+ */
+public class IsisWebAppConfigProvider {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(IsisWebAppConfigProvider.class);
+    
+    /**
+     * Removes any cashed IsisConfigurationBuilder instance from the ServletContext.
+     * @param servletContext
+     */
+    public void invalidate(final ServletContext servletContext) {
+        servletContext.setAttribute(WebAppConstants.CONFIGURATION_BUILDER_KEY, null);
+    }
+    
+    /**
+     * If available reuses the IsisConfigurationBuilder instance that is already on the ServletContext or
+     * creates a new one. 
+     * 
+     * @param servletContext
+     * @return
+     */
+    public IsisConfigurationBuilder getConfigurationBuilder(final ServletContext servletContext) {
+        IsisConfigurationBuilder isisConfigurationBuilder =
+                (IsisConfigurationBuilder) servletContext.getAttribute(WebAppConstants.CONFIGURATION_BUILDER_KEY);
+        if(isisConfigurationBuilder == null) {
+            isisConfigurationBuilder = newIsisConfigurationBuilder(servletContext);
+        }
+        return isisConfigurationBuilder;
+    }
+    
+    /**
+     * Shortcut for {@code getConfigurationBuilder(servletContext).peekConfiguration()}
+     * @param servletContext
+     * @return a configuration copy
+     */
+    public IsisConfiguration peekConfiguration(final ServletContext servletContext) {
+        return getConfigurationBuilder(servletContext).peekConfiguration();
+    }
+
+    /**
+     * Returns a new IsisConfigurationBuilder populated with all currently available configuration values. 
+     * @param servletContext
+     * @return
+     */
+    protected IsisConfigurationBuilder newIsisConfigurationBuilder(final ServletContext servletContext) {
+        IsisConfigurationBuilder isisConfigurationBuilder = new IsisConfigurationBuilder();
+        isisConfigurationBuilder.primeWith(new OptionHandlerInitParameters(servletContext));
+        addResourceStreamSources(servletContext, isisConfigurationBuilder);
+        return isisConfigurationBuilder;
+    }
+    
+    // -- LOOKUP
+    
+    /**
+     * Register an instance of IsisWebAppConfigProvider as an application-scoped singleton.
+     * @param configProvider
+     */
+    public static void register(IsisWebAppConfigProvider configProvider) {
+        putSingleton(IsisWebAppConfigProvider.class, configProvider);
+    }
+    
+    /**
+     * @return the application-scoped singleton instance of IsisWebAppConfigProvider
+     * @throws IllegalStateException if no such singleton was registered
+     */
+    public static IsisWebAppConfigProvider getInstance() {
+        return getOrThrow(IsisWebAppConfigProvider.class, 
+                ()->new IllegalStateException("No config provider registered on this context."));
+    }
+    
+    // -- HELPER
+
+    private static void addResourceStreamSources(
+            final ServletContext servletContext,
+            final IsisConfigurationBuilder isisConfigurationBuilder) {
+
+
+        // will load either from WEB-INF, from the class-path or from config directory.
+        final String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM);
+        if ( configLocation != null ) {
+            LOG.info("Config override location: {}", configLocation );
+            isisConfigurationBuilder.addResourceStreamSource(ResourceStreamSourceFileSystem.create(configLocation));
+        } else {
+            LOG.info("Config override location: No override location configured" );
+
+            isisConfigurationBuilder.addResourceStreamSource(ResourceStreamSourceContextLoaderClassPath.create());
+            isisConfigurationBuilder.addResourceStreamSource(new ResourceStreamSourceCurrentClassClassPath());
+            isisConfigurationBuilder.addResourceStreamSource(new ResourceStreamSourceForWebInf(servletContext));
+        }
+    }
+    
+}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppContextListener.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppContextListener.java
index 54808ae..8856bc6 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppContextListener.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/IsisWebAppContextListener.java
@@ -66,19 +66,25 @@ public class IsisWebAppContextListener implements ServletContextListener {
         
         setDefaultClassLoader(this.getClass().getClassLoader(), true);
         
-        // setting up context specific properties before bootstrapping
+        final IsisWebAppConfigProvider configProvider = new IsisWebAppConfigProvider();
+        IsisWebAppConfigProvider.register(configProvider);
+        
+        // phase 1 - setting up context specific properties before bootstrapping
+        
         putContextPathIfPresent(servletContext.getContextPath());
 
-        // phase 1
         final List<WebModule> webModules =
                  WebModule.discoverWebModules()
                  .peek(module->module.prepare(servletContext)) // prepare context
                  .collect(Collectors.toList());
 
         // put the list of viewer names "isis.viewers" into a context parameter
-        WebModule.ContextUtil.commitViewers(servletContext); 
+        WebModule.ContextUtil.commitViewers(servletContext);
+        // invalidate config such that next IsisConfigurationBuilder that gets obtained is reinitialized
+        configProvider.invalidate(servletContext);  
+        
+        // phase 2 - initializing the ServletContext
         
-        // phase 2
         webModules.stream()
         .filter(module->module.isApplicable(servletContext)) // filter those WebModules that are applicable
         .forEach(module->addListener(servletContext, module));
diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java
index 3f4178e..a837fe4 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java
@@ -32,8 +32,8 @@ import javax.servlet.ServletException;
 import javax.servlet.annotation.WebListener;
 
 import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.core.commons.config.IsisConfigurationDefault;
-import org.apache.isis.core.webapp.IsisWebAppBootstrapper;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.webapp.IsisWebAppConfigProvider;
 import org.apache.isis.core.webapp.IsisWebAppContextListener;
 
 /**
@@ -181,11 +181,10 @@ public interface WebModule {
             requires(key, "key");
             requires(defaultValue, "defaultValue");
             
-            final IsisConfigurationDefault webXmlConfig = 
-                    IsisWebAppBootstrapper.lookupIsisConfigurationBuilder(ctx)
-                    .getConfiguration();
+            final IsisConfiguration webXmlConfig = 
+                    IsisWebAppConfigProvider.getInstance().peekConfiguration(ctx);
             
-            return ifPresentElse(webXmlConfig.getProperty(key), defaultValue);
+            return ifPresentElse(webXmlConfig.getString(key), defaultValue);
         }
         
         
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
index ec1d105..69c8ecf 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
@@ -90,7 +90,7 @@ import org.apache.isis.core.runtime.system.DeploymentType;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.runtime.threadpool.ThreadPoolSupport;
-import org.apache.isis.core.webapp.IsisWebAppBootstrapper;
+import org.apache.isis.core.webapp.IsisWebAppConfigProvider;
 import org.apache.isis.core.webapp.WebAppConstants;
 import org.apache.isis.schema.utils.ChangesDtoUtils;
 import org.apache.isis.schema.utils.CommandDtoUtils;
@@ -631,7 +631,8 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
     protected IsisConfigurationBuilder obtainConfigBuilder() {
         return isisConfigurationBuilder != null
                 ? isisConfigurationBuilder
-                        : (isisConfigurationBuilder = IsisWebAppBootstrapper.obtainConfigBuilderFrom(getServletContext()));
+                        : (isisConfigurationBuilder = IsisWebAppConfigProvider.getInstance()
+                            .getConfigurationBuilder(getServletContext()));
     }
 
     // //////////////////////////////////////