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

commit 51ab3e1e28faf8d63d4a8dcf9285309f677f6595
Author: Andi Huber <ahu...@apache.org>
AuthorDate: Fri Aug 31 14:37:46 2018 +0200

    ISIS-1895: optimizations and cleanup
    
    cleaning up IsisWicketApplication
    
    reuse configuration instances when applicable
    
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1895
---
 .../configbuilder/IsisConfigurationBuilder.java    |   6 +-
 .../isis/core/webapp/IsisWebAppConfigProvider.java |  35 +-
 .../core/webapp/IsisWebAppContextListener.java     |  12 +-
 .../apache/isis/core/webapp/modules/WebModule.java |  21 -
 .../core/webapp/modules/WebModule_RestEasy.java    |   4 +-
 .../isis/core/webapp/modules/WebModule_Wicket.java |  11 +-
 .../wicket/viewer/IsisWicketApplication.java       | 635 +++++++++------------
 .../viewer/IsisWicketApplication_Experimental.java | 107 ++++
 8 files changed, 427 insertions(+), 404 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
index 9b3e5c2..a8790a0 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
@@ -366,7 +366,9 @@ public final class IsisConfigurationBuilder {
         }
     }
 
-
+    public String peekAt(String key) {
+        return configuration.getString(key);
+    }
 
     // -- dumpResourcesToLog, toString
 
@@ -397,6 +399,4 @@ public final class IsisConfigurationBuilder {
         return toString.toString(this);
     }
 
-
-
 }
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
index c36a9ae..5b22087 100644
--- 
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
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.core.webapp;
 
+import static org.apache.isis.commons.internal.base._With.ifPresentElse;
+import static org.apache.isis.commons.internal.base._With.requires;
 import static org.apache.isis.commons.internal.context._Context.getOrThrow;
 import static org.apache.isis.commons.internal.context._Context.putSingleton;
 
@@ -26,7 +28,6 @@ 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;
@@ -53,28 +54,20 @@ public class IsisWebAppConfigProvider {
     
     /**
      * If available reuses the IsisConfigurationBuilder instance that is 
already on the ServletContext or
-     * creates a new one. 
+     * creates a new one and puts it on the ServletContext.
      * 
      * @param servletContext
      * @return
      */
-    public IsisConfigurationBuilder getConfigurationBuilder(final 
ServletContext servletContext) {
+    public synchronized IsisConfigurationBuilder getConfigurationBuilder(final 
ServletContext servletContext) {
         IsisConfigurationBuilder isisConfigurationBuilder =
                 (IsisConfigurationBuilder) 
servletContext.getAttribute(WebAppConstants.CONFIGURATION_BUILDER_KEY);
         if(isisConfigurationBuilder == null) {
             isisConfigurationBuilder = 
newIsisConfigurationBuilder(servletContext);
+            
servletContext.setAttribute(WebAppConstants.CONFIGURATION_BUILDER_KEY, 
isisConfigurationBuilder);
         }
         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. 
@@ -88,6 +81,24 @@ public class IsisWebAppConfigProvider {
         return isisConfigurationBuilder;
     }
     
+    // -- PEEKING
+    
+    /**
+     * Try to fetch the value from config stored under {@code key} else 
fallback to {@code defaultValue}
+     * @param servletContext
+     * @param key
+     * @param defaultValue
+     * @return non-null
+     */
+    public String peekAtOrDefault(ServletContext servletContext, String key, 
String defaultValue) {
+        requires(servletContext, "servletContext");
+        requires(key, "key");
+        requires(defaultValue, "defaultValue");
+        
+        final String configValue = 
getConfigurationBuilder(servletContext).peekAt(key);
+        return ifPresentElse(configValue, defaultValue);
+    }
+    
     // -- LOOKUP
     
     /**
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 0f41369..a0bc0ee 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
@@ -61,16 +61,16 @@ public class IsisWebAppContextListener implements 
ServletContextListener {
     
     @Override
     public void contextInitialized(ServletContextEvent event) {
-        
+
         final ServletContext servletContext = event.getServletContext();
         
+        LOG.info("=== PHASE 1 === Setting up ServletContext parameters");
+        
         setDefaultClassLoader(this.getClass().getClassLoader(), true);
+        putContextPathIfPresent(servletContext.getContextPath());
         
         final IsisWebAppConfigProvider configProvider = new 
IsisWebAppConfigProvider();
         IsisWebAppConfigProvider.register(configProvider);
-        
-        // phase 1 - setting up context specific properties before 
bootstrapping
-        putContextPathIfPresent(servletContext.getContextPath());
 
         final List<WebModule> webModules =
                  WebModule.discoverWebModules()
@@ -82,13 +82,15 @@ public class IsisWebAppContextListener implements 
ServletContextListener {
         // invalidate config such that next IsisConfigurationBuilder that gets 
obtained is reinitialized
         configProvider.invalidate(servletContext);  
         
-        // phase 2 - initializing the ServletContext
+        LOG.info("=== PHASE 2 === Initializing the ServletContext");
         
         webModules.stream()
         .filter(module->module.isApplicable(servletContext)) // filter those 
WebModules that are applicable
         .forEach(module->addListener(servletContext, module));
         
         activeListeners.forEach(listener->listener.contextInitialized(event));
+        
+        LOG.info("=== DONE === ServletContext initialized.");
     }
 
     @Override
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 a837fe4..eab3bbd 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
@@ -19,8 +19,6 @@
 package org.apache.isis.core.webapp.modules;
 
 import static org.apache.isis.commons.internal.base._Strings.isEmpty;
-import static org.apache.isis.commons.internal.base._With.ifPresentElse;
-import static org.apache.isis.commons.internal.base._With.requires;
 
 import java.util.stream.Stream;
 
@@ -32,8 +30,6 @@ import javax.servlet.ServletException;
 import javax.servlet.annotation.WebListener;
 
 import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.core.commons.config.IsisConfiguration;
-import org.apache.isis.core.webapp.IsisWebAppConfigProvider;
 import org.apache.isis.core.webapp.IsisWebAppContextListener;
 
 /**
@@ -169,23 +165,6 @@ public interface WebModule {
             final String list = (String) ctx.getAttribute("isis.protected");
             return _Strings.splitThenStream(list, ",");
         }
-
-        /**
-         * Try to fetch the value from config stored under {@code key} else 
fallback to {@code defaultValue}
-         * @param ctx
-         * @param key
-         * @param defaultValue
-         * @return non-null
-         */
-        public static String getConfigOrDefault(ServletContext ctx, String 
key, String defaultValue) {
-            requires(key, "key");
-            requires(defaultValue, "defaultValue");
-            
-            final IsisConfiguration webXmlConfig = 
-                    
IsisWebAppConfigProvider.getInstance().peekConfiguration(ctx);
-            
-            return ifPresentElse(webXmlConfig.getString(key), defaultValue);
-        }
         
         
     }
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
 
b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
index 462b6ad..de06abd 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
@@ -32,6 +32,7 @@ import javax.servlet.ServletContextListener;
 import javax.servlet.ServletException;
 
 import org.apache.isis.core.webapp.IsisSessionFilter;
+import org.apache.isis.core.webapp.IsisWebAppConfigProvider;
 
 /**
  * Package private mixin for WebModule implementing WebModule.
@@ -64,7 +65,8 @@ final class WebModule_RestEasy implements WebModule  {
         
         // try to fetch restfulPath from config else fallback to default
         final String restfulPath = 
-                ContextUtil.getConfigOrDefault(ctx, KEY_RESTFUL_BASE_PATH, 
KEY_RESTFUL_BASE_PATH_DEFAULT); 
+                IsisWebAppConfigProvider.getInstance()
+                .peekAtOrDefault(ctx, KEY_RESTFUL_BASE_PATH, 
KEY_RESTFUL_BASE_PATH_DEFAULT);
                 
         putRestfulPath(restfulPath);
         
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_Wicket.java
 
b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_Wicket.java
index b2076b5..3e5b2ad 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_Wicket.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_Wicket.java
@@ -27,6 +27,9 @@ import static 
org.apache.isis.commons.internal.exceptions._Exceptions.unexpected
 
 import javax.servlet.Filter;
 import javax.servlet.FilterRegistration.Dynamic;
+
+import org.apache.isis.core.webapp.IsisWebAppConfigProvider;
+
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextListener;
 import javax.servlet.ServletException;
@@ -58,14 +61,16 @@ final class WebModule_Wicket implements WebModule  {
             return;
         }
         
+        final IsisWebAppConfigProvider configProvider = 
IsisWebAppConfigProvider.getInstance();
+        
         pathConfigValue = 
-                ContextUtil.getConfigOrDefault(ctx, 
"isis.viewer.wicket.basePath", "/wicket");
+                configProvider.peekAtOrDefault(ctx, 
"isis.viewer.wicket.basePath", "/wicket");
         
         modeConfigValue = 
-                ContextUtil.getConfigOrDefault(ctx, "isis.viewer.wicket.mode", 
"deployment");
+                configProvider.peekAtOrDefault(ctx, "isis.viewer.wicket.mode", 
"deployment");
         
         appConfigValue = 
-                ContextUtil.getConfigOrDefault(ctx, "isis.viewer.wicket.app", 
+                configProvider.peekAtOrDefault(ctx, "isis.viewer.wicket.app", 
                         
"org.apache.isis.viewer.wicket.viewer.IsisWicketApplication");
         
         ContextUtil.registerBootstrapper(ctx, this);
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 69c8ecf..8a0c9a0 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
@@ -19,11 +19,12 @@
 
 package org.apache.isis.viewer.wicket.viewer;
 
+import static java.util.Objects.requireNonNull;
+
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.UUID;
@@ -33,21 +34,18 @@ import java.util.concurrent.Future;
 import java.util.function.Function;
 
 import com.google.common.base.Joiner;
-import com.google.common.collect.Sets;
 import com.google.common.io.Resources;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Module;
 
 import org.apache.wicket.Application;
-import org.apache.wicket.Component;
 import org.apache.wicket.ConverterLocator;
 import org.apache.wicket.IConverterLocator;
 import org.apache.wicket.Page;
 import org.apache.wicket.RuntimeConfigurationType;
 import org.apache.wicket.SharedResources;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.AjaxRequestTarget.IListener;
 import org.apache.wicket.authentication.IAuthenticationStrategy;
 import org.apache.wicket.authentication.strategy.DefaultAuthenticationStrategy;
 import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
@@ -187,7 +185,7 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
     private final IsisLoggingConfigurer loggingConfigurer = new 
IsisLoggingConfigurer();
 
     /**
-     * Convenience locator, downcasts inherited functionality.
+     * Convenience locator, down-casts inherited functionality.
      */
     public static IsisWicketApplication get() {
         return (IsisWicketApplication) AuthenticatedWebApplication.get();
@@ -229,20 +227,13 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
      * {@link com.google.inject.Inject Inject}ed when {@link #init() 
initialized}.
      */
     @com.google.inject.Inject
-    private IsisConfiguration configuration;
-
-    /**
-     * {@link com.google.inject.Inject Inject}ed when {@link #init() 
initialized}.
-     */
-    @com.google.inject.Inject
     private DeploymentCategory deploymentCategory;
 
     @com.google.inject.Inject
     private WicketViewerSettings settings;
 
-
-    private boolean determiningConfigurationType;
-    private DeploymentTypeWicketAbstract deploymentType;
+    private IsisConfigurationDefault isisConfiguration;
+    private final IsisWicketApplication_Experimental experimental;
 
 
     // /////////////////////////////////////////////////
@@ -250,6 +241,7 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
     // /////////////////////////////////////////////////
 
     public IsisWicketApplication() {
+        experimental = new IsisWicketApplication_Experimental(this);
     }
 
 
@@ -266,11 +258,30 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
         setResourceSettings(new IsisResourceSettings(this));
 
         // this doesn't seem to accomplish anything
-        // addListenerToStripRemovedComponentsFromAjaxTargetResponse();
+        // 
experimental.addListenerToStripRemovedComponentsFromAjaxTargetResponse();
 
+        // --- prepare the configuration prior to init()
+        
+        isisConfiguration = prepareConfiguration();
+        deploymentType = determineDeploymentType(isisConfiguration);
+        
         super.internalInit();
 
     }
+    
+    private IsisConfigurationDefault prepareConfiguration() {
+        
+        final String isisConfigDir = 
getServletContext().getInitParameter("isis.config.dir");
+        configureLogging(isisConfigDir);
+        
+        final IsisConfigurationBuilder isisConfigurationBuilder = 
IsisWebAppConfigProvider.getInstance()
+                .getConfigurationBuilder(getServletContext());
+        isisConfigurationBuilder.addDefaultConfigurationResourcesAndPrimers();
+
+        final IsisConfigurationDefault configuration = 
isisConfigurationBuilder.getConfiguration();
+        
+        return configuration;
+    }
 
     private static AjaxRequestTarget decorate(final AjaxRequestTarget 
ajaxRequestTarget) {
         ajaxRequestTarget.registerRespondListener( new 
TargetRespondListenerToResetQueryResultCache() );
@@ -285,44 +296,6 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
         return application;
     }
 
-    // idea here is to avoid XmlPartialPageUpdate spitting out warnings, eg:
-    //
-    // 13:08:36,642  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxLink [Component id = copyLink]]' with markupid: 'copyLink94c' not 
rendered because it was already removed from page
-    //  13:08:36,642  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[SimpleClipboardModalWindow [Component id = simpleClipboardModalWindow]]' with 
markupid: 'simpleClipboardModalWindow94e' not rendered because it was already 
removed from page
-    // 13:08:36,643  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxFallbackLink [Component id = link]]' with markupid: 'link951' not 
rendered because it was already removed from page
-    // 13:08:36,643  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxFallbackLink [Component id = link]]' with markupid: 'link952' not 
rendered because it was already removed from page
-    // 13:08:36,655  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxLink [Component id = clearBookmarkLink]]' with markupid: 
'clearBookmarkLink953' not rendered because it was already removed from page
-    //
-    // however, doesn't seem to work (even though the provided map is mutable).
-    // must be some other sort of side-effect which causes the enqueued 
component(s) to be removed from page between
-    // this listener firing and XmlPartialPageUpdate actually attempting to 
render the change components
-    //
-    private boolean 
addListenerToStripRemovedComponentsFromAjaxTargetResponse() {
-        return getAjaxRequestTargetListeners().add(new IListener(){
-
-            @Override
-            public void onBeforeRespond(Map<String, Component> map, 
AjaxRequestTarget target) {
-
-                System.out.println("=====================================");
-                System.out.println("=== on before respond");
-                System.out.println("map="+map);
-                System.out.println("=====================================");
-                System.out.println("=== removals");
-                map.entrySet().removeIf(entry->{
-                    final Component component = entry.getValue();
-                    final Page page = component.findParent(Page.class);
-                    if(page==null) {
-                        System.out.println("id: "+entry.getKey()+": 
page="+page);
-                    }
-                    return page==null;
-                });
-
-                System.out.println("=====================================");
-
-            }
-        });
-    }
-
     /**
      * Initializes the application; in particular, bootstrapping the Isis
      * backend, and initializing the {@link ComponentFactoryRegistry} to be 
used
@@ -336,22 +309,12 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
 
             futures = startBackgroundInitializationThreads();
 
-            String isisConfigDir = 
getServletContext().getInitParameter("isis.config.dir");
-
-            configureLogging(isisConfigDir);
+            final IsisConfigurationDefault configuration = 
requireNonNull(isisConfiguration, 
+                    "Configuration must be prepared prior to init().");
 
             
getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.REDIRECT_TO_RENDER);
-
             getResourceSettings().setParentFolderPlaceholder("$up$");
 
-            final IsisConfigurationBuilder isisConfigurationBuilder = 
obtainConfigBuilder();
-            
isisConfigurationBuilder.addDefaultConfigurationResourcesAndPrimers();
-
-            final IsisConfigurationDefault configuration = 
isisConfigurationBuilder.getConfiguration();
-
-            DeploymentTypeWicketAbstract deploymentType =
-                    
determineDeploymentType(configuration.getString("isis.deploymentType"));
-
             RequestCycleListenerCollection requestCycleListeners = 
getRequestCycleListeners();
             IRequestCycleListener requestCycleListenerForIsis = 
newWebRequestCycleForIsis();
             requestCycleListeners.add(requestCycleListenerForIsis);
@@ -387,7 +350,7 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
             filterJavascriptContributions();
 
             configureWicketSourcePluginIfNecessary();
-
+            
             // TODO ISIS-987 Either make the API better (no direct access to 
the map) or use DB records
             int maxEntries = 1000;
             setMetaData(AccountConfirmationMap.KEY, new 
AccountConfirmationMap(maxEntries, Duration.days(1)));
@@ -439,7 +402,7 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
             ThreadPoolSupport.join(futures);
         }
     }
-
+    
     protected List<Future<Object>> startBackgroundInitializationThreads() {
         return 
ThreadPoolSupport.getInstance().invokeAll(_Lists.<Callable<Object>>of(
 
@@ -501,7 +464,9 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
     }
 
     protected void configureWicketSourcePluginIfNecessary() {
-        if(isWicketSourcePluginEnabled(this.configuration)) {
+        final IsisConfigurationDefault configuration = 
requireNonNull(isisConfiguration, 
+                "Configuration must be prepared prior to init().");
+        if(isWicketSourcePluginEnabled(configuration)) {
             configureWicketSourcePlugin();
         }
     }
@@ -587,52 +552,25 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
     /**
      * Made protected visibility for easy (informal) pluggability.
      */
-    protected void determineDeploymentTypeIfRequired() {
-        if(deploymentType != null) {
-            return;
-        }
-
-        determiningConfigurationType = true;
-        try {
-            final IsisConfigurationBuilder isisConfigurationBuilder = 
obtainConfigBuilder();
-
-            final IsisConfiguration configuration = 
isisConfigurationBuilder.peekConfiguration();
-            String deploymentTypeFromConfig = 
configuration.getString("isis.deploymentType");
-            deploymentType = determineDeploymentType(deploymentTypeFromConfig);
-        } finally {
-            determiningConfigurationType = false;
-        }
-    }
-
-    /**
-     * Made protected visibility for easy (informal) pluggability.
-     */
-    protected DeploymentTypeWicketAbstract determineDeploymentType(String 
deploymentTypeFromConfig) {
-        final DeploymentTypeWicketAbstract prototype = new 
WicketServerPrototype();
-        final DeploymentTypeWicketAbstract deployment = new WicketServer();
-
-        if(deploymentTypeFromConfig != null) {
-            final DeploymentType deploymentType = 
DeploymentType.lookup(deploymentTypeFromConfig);
-            return !deploymentType.getDeploymentCategory().isProduction()
-                    ? prototype
-                            : deployment;
+    protected DeploymentTypeWicketAbstract 
determineDeploymentType(IsisConfigurationDefault configuration) {
+        
+        //TODO[ahuber] we need to get rid of this static processing, 
+        // once wicket is only one of multiple viewer options 
+        final String deploymentTypeConfigValue = 
configuration.getString("isis.deploymentType");
+        final String wicketModeConfigValue = 
configuration.getString("isis.viewer.wicket.mode");
+        
+        final boolean isPrototype;
+        
+        if(wicketModeConfigValue!=null) {
+            isPrototype = 
"development".equalsIgnoreCase(wicketModeConfigValue);
+        } else if(deploymentTypeConfigValue!=null) {
+            final DeploymentType deploymentType = 
DeploymentType.lookup(deploymentTypeConfigValue);
+            isPrototype = 
!deploymentType.getDeploymentCategory().isProduction();
         } else {
-            return usesDevelopmentConfig()
-                    ? prototype
-                            : deployment;
+            isPrototype = false; // defaulting to production
         }
-    }
-
-
-    // //////////////////////////////////////
-
-    private IsisConfigurationBuilder isisConfigurationBuilder;
-
-    protected IsisConfigurationBuilder obtainConfigBuilder() {
-        return isisConfigurationBuilder != null
-                ? isisConfigurationBuilder
-                        : (isisConfigurationBuilder = 
IsisWebAppConfigProvider.getInstance()
-                            .getConfigurationBuilder(getServletContext()));
+        
+        return isPrototype ? new WicketServerPrototype() : new WicketServer();
     }
 
     // //////////////////////////////////////
@@ -650,16 +588,7 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
      * Made protected visibility for easy (informal) pluggability.
      */
     protected void buildCssBundle() {
-        // get the css for all components built by component factories
-        final Set<CssResourceReference> references = 
cssResourceReferencesForAllComponents();
-
-        // some additional special cases.
-        addSpecialCasesToCssBundle(references);
-
-        // create the bundle
-        getResourceBundles().addCssBundle(
-                IsisWicketApplication.class, "isis-wicket-viewer-bundle.css",
-                references.toArray(new CssResourceReference[]{}));
+        experimental.buildCssBundle();
     }
 
     /**
@@ -698,280 +627,268 @@ implements ComponentFactoryRegistryAccessor, 
PageClassRegistryAccessor, WicketVi
                             Collections.<CssResourceReference>emptyList();
             };
 
+    // //////////////////////////////////////
 
-            protected Set<CssResourceReference> 
cssResourceReferencesForAllComponents() {
-                // TODO mgrigorov: ISIS-537 temporary disabled to not mess up 
with Bootstrap styles
-                //        Collection<ComponentFactory> componentFactories = 
getComponentFactoryRegistry().listComponentFactories();
-                return Sets.newLinkedHashSet(
-                        //                Iterables.concat(
-                        //                        Iterables.transform(
-                        //                                componentFactories,
-                        //                                
getCssResourceReferences))
-                        );
-            }
+    /**
+     * filters Javascript header contributions so rendered to bottom of page.
+     *
+     * <p>
+     * Factored out for easy (informal) pluggability.
+     * </p>
+     */
+    protected void filterJavascriptContributions() {
 
-            // //////////////////////////////////////
-
-            /**
-             * filters Javascript header contributions so rendered to bottom 
of page.
-             *
-             * <p>
-             * Factored out for easy (informal) pluggability.
-             * </p>
-             */
-            protected void filterJavascriptContributions() {
-
-                setHeaderResponseDecorator(response -> {
-                    return new ResourceAggregator(new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
-                });
-
-                //[ahuber] no longer supported since wicket 8
-                //             setHeaderResponseDecorator(new 
IHeaderResponseDecorator()
-                //             {
-                //                     @Override
-                //                     public IHeaderResponse 
decorate(IHeaderResponse response)
-                //                     {
-                //                             // use this header resource 
decorator to load all JavaScript resources in the page
-                //                             // footer (after </body>)
-                //                             return new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS");
-                //                     }
-                //             });
-            }
+        setHeaderResponseDecorator(response -> {
+            return new ResourceAggregator(new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
+        });
 
-            // //////////////////////////////////////
+        //[ahuber] no longer supported since wicket 8
+        //             setHeaderResponseDecorator(new 
IHeaderResponseDecorator()
+        //             {
+        //                     @Override
+        //                     public IHeaderResponse decorate(IHeaderResponse 
response)
+        //                     {
+        //                             // use this header resource decorator 
to load all JavaScript resources in the page
+        //                             // footer (after </body>)
+        //                             return new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS");
+        //                     }
+        //             });
+    }
 
-            /**
-             * Map entity and action to provide prettier URLs.
-             *
-             * <p>
-             * Factored out for easy (informal) pluggability.
-             * </p>
-             */
-            protected void mountPages() {
+    // //////////////////////////////////////
 
-                mountPage("/signin", PageType.SIGN_IN);
-                mountPage("/signup", PageType.SIGN_UP);
-                mountPage("/signup/verify", PageType.SIGN_UP_VERIFY);
-                mountPage("/password/reset", PageType.PASSWORD_RESET);
+    /**
+     * Map entity and action to provide prettier URLs.
+     *
+     * <p>
+     * Factored out for easy (informal) pluggability.
+     * </p>
+     */
+    protected void mountPages() {
 
-                mountPage("/entity/#{objectOid}", PageType.ENTITY);
+        mountPage("/signin", PageType.SIGN_IN);
+        mountPage("/signup", PageType.SIGN_UP);
+        mountPage("/signup/verify", PageType.SIGN_UP_VERIFY);
+        mountPage("/password/reset", PageType.PASSWORD_RESET);
 
-                // nb: action mount cannot contain {actionArgs}, because the 
default
-                // parameters encoder doesn't seem to be able to handle 
multiple args
-                
mountPage("/action/${objectOid}/${actionOwningSpec}/${actionId}/${actionType}", 
PageType.ACTION_PROMPT);
+        mountPage("/entity/#{objectOid}", PageType.ENTITY);
 
-                mountPage("/logout", WicketLogoutPage.class);
-            }
+        // nb: action mount cannot contain {actionArgs}, because the default
+        // parameters encoder doesn't seem to be able to handle multiple args
+        
mountPage("/action/${objectOid}/${actionOwningSpec}/${actionId}/${actionType}", 
PageType.ACTION_PROMPT);
 
-            protected void mountPage(final String mountPath, final PageType 
pageType) {
-                final Class<? extends Page> pageClass = 
this.pageClassRegistry.getPageClass(pageType);
-                mount(new MountedMapper(mountPath, pageClass));
-            }
+        mountPage("/logout", WicketLogoutPage.class);
+    }
 
+    protected void mountPage(final String mountPath, final PageType pageType) {
+        final Class<? extends Page> pageClass = 
this.pageClassRegistry.getPageClass(pageType);
+        mount(new MountedMapper(mountPath, pageClass));
+    }
 
-            // //////////////////////////////////////
 
-            private void logError(String validationError) {
-                log(validationError);
-            }
+    // //////////////////////////////////////
 
-            private static void logBanner() {
-                String msg = "################################################ 
ISIS METAMODEL VALIDATION ERRORS 
################################################################";
-                log(msg);
-            }
+    private void logError(String validationError) {
+        log(validationError);
+    }
 
-            private static void log(String msg) {
-                System.err.println(msg);
-                LOG.error(msg);
-            }
+    private static void logBanner() {
+        String msg = "################################################ ISIS 
METAMODEL VALIDATION ERRORS 
################################################################";
+        log(msg);
+    }
 
-            // //////////////////////////////////////
-
-            /**
-             * Whether Wicket tags should be stripped from the markup, as 
specified by configuration settings..
-             *
-             * <p>
-             * If the <tt>isis.viewer.wicket.stripWicketTags</tt> is set, then 
this is used, otherwise the default is to strip
-             * the tags because they may break some CSS rules.
-             */
-            private boolean determineStripWicketTags(IsisConfiguration 
configuration) {
-                final boolean strip = 
configuration.getBoolean(STRIP_WICKET_TAGS_KEY, STRIP_WICKET_TAGS_DEFAULT);
-                return strip;
-            }
+    private static void log(String msg) {
+        System.err.println(msg);
+        LOG.error(msg);
+    }
 
-            // //////////////////////////////////////
-
-            /**
-             * Whether the Ajax debug should be shown, as specified by 
configuration settings.
-             *
-             * <p>
-             * If the <tt>isis.viewer.wicket.ajaxDebugMode</tt> is set, then 
this is used, otherwise the default is to disable.
-             */
-            private boolean determineAjaxDebugModeEnabled(IsisConfiguration 
configuration) {
-                final boolean debugModeEnabled = 
configuration.getBoolean(AJAX_DEBUG_MODE_KEY, AJAX_DEBUG_MODE_DEFAULT);
-                return debugModeEnabled;
-            }
+    // //////////////////////////////////////
 
-            /**
-             * Whether the Wicket source plugin should be enabled, as 
specified by configuration settings.
-             *
-             * <p>
-             * If the <tt>isis.viewer.wicket.wicketSourcePlugin</tt> is set, 
then this is used, otherwise the default is to disable.
-             */
-            private boolean isWicketSourcePluginEnabled(IsisConfiguration 
configuration) {
-                final boolean pluginEnabled = 
configuration.getBoolean(WICKET_SOURCE_PLUGIN_KEY, 
WICKET_SOURCE_PLUGIN_DEFAULT);
-                return pluginEnabled;
-            }
+    /**
+     * Whether Wicket tags should be stripped from the markup, as specified by 
configuration settings..
+     *
+     * <p>
+     * If the <tt>isis.viewer.wicket.stripWicketTags</tt> is set, then this is 
used, otherwise the default is to strip
+     * the tags because they may break some CSS rules.
+     */
+    private boolean determineStripWicketTags(IsisConfiguration configuration) {
+        final boolean strip = configuration.getBoolean(STRIP_WICKET_TAGS_KEY, 
STRIP_WICKET_TAGS_DEFAULT);
+        return strip;
+    }
 
-            // //////////////////////////////////////
+    // //////////////////////////////////////
 
-            @Override
-            protected void onDestroy() {
-                try {
-                    if (isisSessionFactory != null) {
-                        isisSessionFactory.destroyServicesAndShutdown();
-                    }
-                    
getServletContext().setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, null);
-                    super.onDestroy();
-                    IsisContext.clear();
-                } catch(final RuntimeException ex) {
-                    // symmetry with #init()
-                    LOG.error("Failed to destroy", ex);
-                    throw ex;
-                }
-            }
+    /**
+     * Whether the Ajax debug should be shown, as specified by configuration 
settings.
+     *
+     * <p>
+     * If the <tt>isis.viewer.wicket.ajaxDebugMode</tt> is set, then this is 
used, otherwise the default is to disable.
+     */
+    private boolean determineAjaxDebugModeEnabled(IsisConfiguration 
configuration) {
+        final boolean debugModeEnabled = 
configuration.getBoolean(AJAX_DEBUG_MODE_KEY, AJAX_DEBUG_MODE_DEFAULT);
+        return debugModeEnabled;
+    }
 
-            // //////////////////////////////////////
+    /**
+     * Whether the Wicket source plugin should be enabled, as specified by 
configuration settings.
+     *
+     * <p>
+     * If the <tt>isis.viewer.wicket.wicketSourcePlugin</tt> is set, then this 
is used, otherwise the default is to disable.
+     */
+    private boolean isWicketSourcePluginEnabled(IsisConfiguration 
configuration) {
+        final boolean pluginEnabled = 
configuration.getBoolean(WICKET_SOURCE_PLUGIN_KEY, 
WICKET_SOURCE_PLUGIN_DEFAULT);
+        return pluginEnabled;
+    }
 
-            @Override
-            public RuntimeConfigurationType getConfigurationType() {
-                if(determiningConfigurationType) {
-                    // avoiding an infinite loop; have already passed through 
here once before
-                    // this time around, just delegate to web-inf
-                    return super.getConfigurationType();
-                }
-                determineDeploymentTypeIfRequired();
-                return deploymentType.getConfigurationType();
-            }
+    // //////////////////////////////////////
 
-            protected IsisInjectModule newIsisModule(
-                    final DeploymentCategory deploymentCategory,
-                    final IsisConfigurationDefault isisConfiguration) {
-                return new IsisInjectModule(deploymentCategory, 
isisConfiguration);
-            }
-            
-            // //////////////////////////////////////
+    @Override
+    protected void onDestroy() {
+        try {
+            if (isisSessionFactory != null) {
+                isisSessionFactory.destroyServicesAndShutdown();
+            }
+            
getServletContext().setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, null);
+            super.onDestroy();
+            IsisContext.clear();
+        } catch(final RuntimeException ex) {
+            // symmetry with #init()
+            LOG.error("Failed to destroy", ex);
+            throw ex;
+        }
+    }
 
+    // //////////////////////////////////////
 
-            protected void initWicketComponentInjection(final Injector 
injector) {
-                getComponentInstantiationListeners().add(new 
GuiceComponentInjector(this, injector, false));
-            }
+    private DeploymentTypeWicketAbstract deploymentType;
+    
+    @Override
+    public RuntimeConfigurationType getConfigurationType() {
+        requireNonNull(deploymentType, 
+                "Applications needs to be prepared before accessing this 
field.");
+        return deploymentType.getConfigurationType();
+    }
+    
+    // //////////////////////////////////////
 
-            // /////////////////////////////////////////////////
-            // Wicket Hooks
-            // /////////////////////////////////////////////////
-
-            /**
-             * Installs a {@link AuthenticatedWebSessionForIsis custom 
implementation}
-             * of Wicket's own {@link AuthenticatedWebSession}, effectively 
associating
-             * the Wicket session with the Isis's equivalent session object.
-             *
-             * <p>
-             * In general, it shouldn't be necessary to override this method.
-             */
-            @Override
-            protected Class<? extends AuthenticatedWebSession> 
getWebSessionClass() {
-                return AuthenticatedWebSessionForIsis.class;
-            }
+    protected IsisInjectModule newIsisModule(
+            final DeploymentCategory deploymentCategory,
+            final IsisConfigurationDefault isisConfiguration) {
+        return new IsisInjectModule(deploymentCategory, isisConfiguration);
+    }
 
-            /**
-             * Installs a {@link ConverterLocator} preconfigured with a number 
of
-             * implementations to support Isis specific objects.
-             */
-            @Override
-            protected IConverterLocator newConverterLocator() {
-                final ConverterLocator converterLocator = new 
ConverterLocator();
-                converterLocator.set(ObjectAdapter.class, new 
ConverterForObjectAdapter());
-                converterLocator.set(ObjectAdapterMemento.class, new 
ConverterForObjectAdapterMemento());
-                return converterLocator;
-            }
+    // //////////////////////////////////////
 
-            // /////////////////////////////////////////////////
-            // Component Factories
-            // /////////////////////////////////////////////////
 
-            @Override
-            public final ComponentFactoryRegistry 
getComponentFactoryRegistry() {
-                return componentFactoryRegistry;
-            }
+    protected void initWicketComponentInjection(final Injector injector) {
+        getComponentInstantiationListeners().add(new 
GuiceComponentInjector(this, injector, false));
+    }
 
-            // /////////////////////////////////////////////////
-            // Page Registry
-            // /////////////////////////////////////////////////
+    // /////////////////////////////////////////////////
+    // Wicket Hooks
+    // /////////////////////////////////////////////////
 
-            /**
-             * Access to other page types.
-             *
-             * <p>
-             * Non-final only for testing purposes; should not typically be 
overridden.
-             */
-            @Override
-            public PageClassRegistry getPageClassRegistry() {
-                return pageClassRegistry;
-            }
+    /**
+     * Installs a {@link AuthenticatedWebSessionForIsis custom implementation}
+     * of Wicket's own {@link AuthenticatedWebSession}, effectively associating
+     * the Wicket session with the Isis's equivalent session object.
+     *
+     * <p>
+     * In general, it shouldn't be necessary to override this method.
+     */
+    @Override
+    protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
+        return AuthenticatedWebSessionForIsis.class;
+    }
 
-            /**
-             * Delegates to the {@link #getPageClassRegistry() 
PageClassRegistry}.
-             */
-            @Override
-            public Class<? extends Page> getHomePage() {
-                return getPageClassRegistry().getPageClass(PageType.HOME);
-            }
+    /**
+     * Installs a {@link ConverterLocator} preconfigured with a number of
+     * implementations to support Isis specific objects.
+     */
+    @Override
+    protected IConverterLocator newConverterLocator() {
+        final ConverterLocator converterLocator = new ConverterLocator();
+        converterLocator.set(ObjectAdapter.class, new 
ConverterForObjectAdapter());
+        converterLocator.set(ObjectAdapterMemento.class, new 
ConverterForObjectAdapterMemento());
+        return converterLocator;
+    }
 
-            /**
-             * Delegates to the {@link #getPageClassRegistry() 
PageClassRegistry}.
-             */
-            @SuppressWarnings("unchecked")
-            @Override
-            public Class<? extends WebPage> getSignInPageClass() {
-                return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.SIGN_IN);
-            }
+    // /////////////////////////////////////////////////
+    // Component Factories
+    // /////////////////////////////////////////////////
 
-            /**
-             * Delegates to the {@link #getPageClassRegistry() 
PageClassRegistry}.
-             */
-            @SuppressWarnings("unchecked")
-            public Class<? extends WebPage> getSignUpPageClass() {
-                return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.SIGN_UP);
-            }
+    @Override
+    public final ComponentFactoryRegistry getComponentFactoryRegistry() {
+        return componentFactoryRegistry;
+    }
 
-            /**
-             * Delegates to the {@link #getPageClassRegistry() 
PageClassRegistry}.
-             */
-            @SuppressWarnings("unchecked")
-            public Class<? extends WebPage> getSignUpVerifyPageClass() {
-                return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.SIGN_UP_VERIFY);
-            }
+    // /////////////////////////////////////////////////
+    // Page Registry
+    // /////////////////////////////////////////////////
 
-            /**
-             * Delegates to the {@link #getPageClassRegistry() 
PageClassRegistry}.
-             */
-            @SuppressWarnings("unchecked")
-            public Class<? extends WebPage> getForgotPasswordPageClass() {
-                return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.PASSWORD_RESET);
-            }
+    /**
+     * Access to other page types.
+     *
+     * <p>
+     * Non-final only for testing purposes; should not typically be overridden.
+     */
+    @Override
+    public PageClassRegistry getPageClassRegistry() {
+        return pageClassRegistry;
+    }
 
-            public AuthenticationSession getAuthenticationSession() {
-                return 
isisSessionFactory.getCurrentSession().getAuthenticationSession();
-            }
+    /**
+     * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+     */
+    @Override
+    public Class<? extends Page> getHomePage() {
+        return getPageClassRegistry().getPageClass(PageType.HOME);
+    }
 
-            public DeploymentCategory getDeploymentCategory() {
-                return deploymentCategory;
-            }
+    /**
+     * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Class<? extends WebPage> getSignInPageClass() {
+        return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.SIGN_IN);
+    }
 
-            @Override
-            public WicketViewerSettings getSettings() {
-                return settings;
-            }
+    /**
+     * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+     */
+    @SuppressWarnings("unchecked")
+    public Class<? extends WebPage> getSignUpPageClass() {
+        return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.SIGN_UP);
+    }
+
+    /**
+     * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+     */
+    @SuppressWarnings("unchecked")
+    public Class<? extends WebPage> getSignUpVerifyPageClass() {
+        return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.SIGN_UP_VERIFY);
+    }
+
+    /**
+     * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+     */
+    @SuppressWarnings("unchecked")
+    public Class<? extends WebPage> getForgotPasswordPageClass() {
+        return (Class<? extends WebPage>) 
getPageClassRegistry().getPageClass(PageType.PASSWORD_RESET);
+    }
+
+    public AuthenticationSession getAuthenticationSession() {
+        return 
isisSessionFactory.getCurrentSession().getAuthenticationSession();
+    }
+
+    public DeploymentCategory getDeploymentCategory() {
+        return deploymentCategory;
+    }
+
+    @Override
+    public WicketViewerSettings getSettings() {
+        return settings;
+    }
 
 }
diff --git 
a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Experimental.java
 
b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Experimental.java
new file mode 100644
index 0000000..c0f0449
--- /dev/null
+++ 
b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Experimental.java
@@ -0,0 +1,107 @@
+/*
+ *  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.viewer.wicket.viewer;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.AjaxRequestTarget.IListener;
+import org.apache.wicket.request.resource.CssResourceReference;
+
+/**
+ * package private mixin for IsisWicketApplication;
+ * to move experimental code out of IsisWicketApplication
+ */
+final class IsisWicketApplication_Experimental {
+    
+    private final IsisWicketApplication holder;
+    
+    IsisWicketApplication_Experimental(IsisWicketApplication holder) {
+        this.holder = holder;
+    }
+
+    // idea here is to avoid XmlPartialPageUpdate spitting out warnings, eg:
+    //
+    // 13:08:36,642  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxLink [Component id = copyLink]]' with markupid: 'copyLink94c' not 
rendered because it was already removed from page
+    //  13:08:36,642  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[SimpleClipboardModalWindow [Component id = simpleClipboardModalWindow]]' with 
markupid: 'simpleClipboardModalWindow94e' not rendered because it was already 
removed from page
+    // 13:08:36,643  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxFallbackLink [Component id = link]]' with markupid: 'link951' not 
rendered because it was already removed from page
+    // 13:08:36,643  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxFallbackLink [Component id = link]]' with markupid: 'link952' not 
rendered because it was already removed from page
+    // 13:08:36,655  [XmlPartialPageUpdate qtp1988859660-18 WARN ]  Component 
'[AjaxLink [Component id = clearBookmarkLink]]' with markupid: 
'clearBookmarkLink953' not rendered because it was already removed from page
+    //
+    // however, doesn't seem to work (even though the provided map is mutable).
+    // must be some other sort of side-effect which causes the enqueued 
component(s) to be removed from page between
+    // this listener firing and XmlPartialPageUpdate actually attempting to 
render the change components
+    //
+    boolean addListenerToStripRemovedComponentsFromAjaxTargetResponse() {
+        
+        return holder.getAjaxRequestTargetListeners().add(new IListener(){
+
+            @Override
+            public void onBeforeRespond(Map<String, Component> map, 
AjaxRequestTarget target) {
+
+                System.out.println("=====================================");
+                System.out.println("=== on before respond");
+                System.out.println("map="+map);
+                System.out.println("=====================================");
+                System.out.println("=== removals");
+                map.entrySet().removeIf(entry->{
+                    final Component component = entry.getValue();
+                    final Page page = component.findParent(Page.class);
+                    if(page==null) {
+                        System.out.println("id: "+entry.getKey()+": 
page="+page);
+                    }
+                    return page==null;
+                });
+
+                System.out.println("=====================================");
+
+            }
+        });
+    }
+    
+    private Set<CssResourceReference> cssResourceReferencesForAllComponents() {
+        // TODO mgrigorov: ISIS-537 temporary disabled to not mess up with 
Bootstrap styles
+        //        Collection<ComponentFactory> componentFactories = 
getComponentFactoryRegistry().listComponentFactories();
+        return Sets.newLinkedHashSet(
+                //                Iterables.concat(
+                //                        Iterables.transform(
+                //                                componentFactories,
+                //                                getCssResourceReferences))
+                );
+    }
+
+    void buildCssBundle() {
+        // get the css for all components built by component factories
+        final Set<CssResourceReference> references = 
cssResourceReferencesForAllComponents();
+
+        // some additional special cases.
+        holder.addSpecialCasesToCssBundle(references);
+
+        // create the bundle
+        holder.getResourceBundles().addCssBundle(
+                IsisWicketApplication.class, "isis-wicket-viewer-bundle.css",
+                references.toArray(new CssResourceReference[]{}));
+    }
+    
+}

Reply via email to