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 2012/12/05 09:07:35 UTC

[10/11] ISIS-188: more refactoring of artifacts

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java
new file mode 100644
index 0000000..1ef61ab
--- /dev/null
+++ b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java
@@ -0,0 +1,407 @@
+/*
+ *  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.runtimes.dflt.webapp;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.factory.InstanceUtil;
+import org.apache.isis.core.commons.lang.PathUtils;
+import org.apache.isis.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.core.webapp.content.ResourceCachingFilter;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.runtimes.dflt.webapp.auth.AuthenticationSessionStrategy;
+import org.apache.isis.runtimes.dflt.webapp.auth.AuthenticationSessionStrategyDefault;
+
+public class IsisSessionFilter implements Filter {
+
+    /**
+     * Recommended standard init parameter key for filters and servlets to
+     * lookup an implementation of {@link AuthenticationSessionStrategy}.
+     */
+    public static final String AUTHENTICATION_SESSION_STRATEGY_KEY = "authenticationSessionStrategy";
+
+    /**
+     * Default value for
+     * {@link AuthenticationSessionLookupStrategyConstants#AUTHENTICATION_SESSION_STRATEGY_KEY}
+     * if not specified.
+     */
+    public static final String AUTHENTICATION_SESSION_STRATEGY_DEFAULT = AuthenticationSessionStrategyDefault.class.getName();
+
+    /**
+     * Init parameter key for backward compatibility; if logonPage set then
+     * assume 'restricted' handling.
+     */
+    public static final String LOGON_PAGE_KEY = "logonPage";
+
+    /**
+     * Init parameter key for what should be done if no session was found.
+     * 
+     * <p>
+     * Valid values are:
+     * <ul>
+     * <li>unauthorized - issue a 401 response.
+     * <li>basicAuthChallenge - issue a basic auth 401 challenge. The idea here
+     * is that the configured logon strategy should handle the next request
+     * <li>restricted - allow access but only to a restricted (comma-separated)
+     * list of paths. Access elsewhere should be redirected to the first of
+     * these paths
+     * <li>continue - allow the request to continue (eg if there is no security
+     * requirements)
+     * </ul>
+     */
+    public static final String WHEN_NO_SESSION_KEY = "whenNoSession";
+
+    /**
+     * Init parameter key to read the restricted list of paths (if
+     * {@link #WHEN_NO_SESSION_KEY} is for {@link WhenNoSession#RESTRICTED}).
+     * 
+     * <p>
+     * The servlets mapped to these paths are expected to be able to deal with
+     * there being no session. Typically they will be logon pages.
+     */
+    public static final String RESTRICTED_KEY = "restricted";
+
+    /**
+     * Init parameter key to redirect to if an exception occurs.
+     */
+    public static final String REDIRECT_TO_ON_EXCEPTION_KEY = "redirectToOnException";
+
+    /**
+     * Init parameter key for which extensions should be ignored (typically,
+     * mappings for other viewers within the webapp context).
+     * 
+     * <p>
+     * It can also be used to specify ignored static resources (though putting
+     * the {@link ResourceCachingFilter} first in the <tt>web.xml</tt>
+     * accomplishes the same thing).
+     * 
+     * <p>
+     * The value is expected as a comma separated list, for example:
+     * 
+     * <pre>
+     * htmlviewer
+     * </pre>
+     */
+    public static final String IGNORE_EXTENSIONS_KEY = "ignoreExtensions";
+
+    private static final Function<String, Pattern> STRING_TO_PATTERN = new Function<String, Pattern>() {
+        @Override
+        public Pattern apply(final String input) {
+            return Pattern.compile(".*\\." + input);
+        }
+
+    };
+
+    static void redirect(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final String redirectTo) throws IOException {
+        httpResponse.sendRedirect(PathUtils.combine(httpRequest.getContextPath(), redirectTo));
+    }
+
+    public enum WhenNoSession {
+        UNAUTHORIZED("unauthorized") {
+            @Override
+            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+                httpResponse.sendError(401);
+            }
+        },
+        BASIC_AUTH_CHALLENGE("basicAuthChallenge") {
+            @Override
+            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+                httpResponse.setHeader("WWW-Authenticate", "Basic realm=\"Apache Isis\"");
+                httpResponse.sendError(401);
+            }
+        },
+        /**
+         * the destination servlet is expected to know that there will be no
+         * open context
+         */
+        CONTINUE("continue") {
+            @Override
+            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+                chain.doFilter(httpRequest, httpResponse);
+            }
+        },
+        /**
+         * Allow access to a restricted list of URLs (else redirect to the first
+         * of that list of URLs)
+         */
+        RESTRICTED("restricted") {
+            @Override
+            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+
+                if (filter.restrictedPaths.contains(httpRequest.getServletPath())) {
+                    chain.doFilter(httpRequest, httpResponse);
+                    return;
+                }
+                redirect(httpRequest, httpResponse, filter.restrictedPaths.get(0));
+            }
+
+        };
+        private final String initParamValue;
+
+        private WhenNoSession(final String initParamValue) {
+            this.initParamValue = initParamValue;
+        }
+
+        public static WhenNoSession lookup(final String whenNoSessionStr) {
+            for (final WhenNoSession wns : values()) {
+                if (wns.initParamValue.equals(whenNoSessionStr)) {
+                    return wns;
+                }
+            }
+            throw new IllegalStateException("require an init-param of '" + WHEN_NO_SESSION_KEY + "', taking a value of " + WhenNoSession.values());
+        }
+
+        public abstract void handle(IsisSessionFilter filter, HttpServletRequest httpRequest, HttpServletResponse httpResponse, FilterChain chain) throws IOException, ServletException;
+    }
+
+    /**
+     * Used as a flag on {@link HttpServletRequest} so that if there are two
+     * {@link IsisSessionFilter}s in a request pipeline, then the second can
+     * determine what processing has already been done (and is usually then just
+     * a no-op).
+     */
+    private static final String SESSION_STATE_KEY = IsisSessionFilter.SessionState.class.getName();
+
+    private AuthenticationSessionStrategy authSessionStrategy;
+    private List<String> restrictedPaths;
+    private WhenNoSession whenNoSession;
+    private String redirectToOnException;
+    private Collection<Pattern> ignoreExtensions;
+
+    // /////////////////////////////////////////////////////////////////
+    // init, destroy
+    // /////////////////////////////////////////////////////////////////
+
+    @Override
+    public void init(final FilterConfig config) throws ServletException {
+        authSessionStrategy = lookup(config.getInitParameter(AUTHENTICATION_SESSION_STRATEGY_KEY));
+        lookupWhenNoSession(config);
+        lookupRedirectToOnException(config);
+        lookupIgnoreExtensions(config);
+    }
+
+    /**
+     * Public visibility so can also be used by servlets.
+     */
+    public static AuthenticationSessionStrategy lookup(String authLookupStrategyClassName) {
+        if (authLookupStrategyClassName == null) {
+            authLookupStrategyClassName = AUTHENTICATION_SESSION_STRATEGY_DEFAULT;
+        }
+        return (AuthenticationSessionStrategy) InstanceUtil.createInstance(authLookupStrategyClassName);
+    }
+
+    private void lookupWhenNoSession(final FilterConfig config) {
+
+        final String whenNoSessionStr = config.getInitParameter(WHEN_NO_SESSION_KEY);
+
+        // backward compatibility
+        final String logonPage = config.getInitParameter(LOGON_PAGE_KEY);
+        if (logonPage != null) {
+            if (whenNoSessionStr != null) {
+                throw new IllegalStateException("The init-param '" + LOGON_PAGE_KEY + "' is only provided for backwards compatibility; remove if the init-param '" + WHEN_NO_SESSION_KEY + "' has been specified");
+            }
+            whenNoSession = WhenNoSession.RESTRICTED;
+            this.restrictedPaths = Lists.newArrayList(logonPage);
+            return;
+        }
+
+        whenNoSession = WhenNoSession.lookup(whenNoSessionStr);
+        if (whenNoSession == WhenNoSession.RESTRICTED) {
+            final String restrictedPathsStr = config.getInitParameter(RESTRICTED_KEY);
+            if (restrictedPathsStr == null) {
+                throw new IllegalStateException("Require an init-param of '" + RESTRICTED_KEY + "' key to be set.");
+            }
+            this.restrictedPaths = Lists.newArrayList(Splitter.on(",").split(restrictedPathsStr));
+        }
+
+    }
+
+    private void lookupRedirectToOnException(final FilterConfig config) {
+        redirectToOnException = config.getInitParameter(REDIRECT_TO_ON_EXCEPTION_KEY);
+    }
+
+    private void lookupIgnoreExtensions(final FilterConfig config) {
+        ignoreExtensions = Collections.unmodifiableCollection(parseIgnorePatterns(config));
+    }
+
+    private Collection<Pattern> parseIgnorePatterns(final FilterConfig config) {
+        final String ignoreExtensionsStr = config.getInitParameter(IGNORE_EXTENSIONS_KEY);
+        if (ignoreExtensionsStr != null) {
+            final List<String> ignoreExtensions = Lists.newArrayList(Splitter.on(",").split(ignoreExtensionsStr));
+            return Collections2.transform(ignoreExtensions, STRING_TO_PATTERN);
+        }
+        return Lists.newArrayList();
+    }
+
+    @Override
+    public void destroy() {
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // doFilter
+    // /////////////////////////////////////////////////////////////////
+
+    public enum SessionState {
+
+        UNDEFINED {
+            @Override
+            public void handle(final IsisSessionFilter filter, final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+
+                final HttpServletRequest httpRequest = (HttpServletRequest) request;
+                final HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+                if (requestIsIgnoreExtension(filter, httpRequest)) {
+                    try {
+                        chain.doFilter(request, response);
+                        return;
+                    } finally {
+                        closeSession();
+                    }
+                }
+
+                if (ResourceCachingFilter.isCachedResource(httpRequest)) {
+                    try {
+                        chain.doFilter(request, response);
+                        return;
+                    } finally {
+                        closeSession();
+                    }
+                }
+
+                // authenticate
+                final AuthenticationSession validSession = filter.authSessionStrategy.lookupValid(request, response);
+                if (validSession != null) {
+                    filter.authSessionStrategy.bind(request, response, validSession);
+
+                    openSession(validSession);
+                    SESSION_IN_PROGRESS.setOn(request);
+                    try {
+                        chain.doFilter(request, response);
+                    } finally {
+                        UNDEFINED.setOn(request);
+                        closeSession();
+                    }
+                    return;
+                }
+
+                try {
+                    NO_SESSION_SINCE_NOT_AUTHENTICATED.setOn(request);
+                    filter.whenNoSession.handle(filter, httpRequest, httpResponse, chain);
+                } catch (final RuntimeException ex) {
+                    // in case the destination servlet cannot cope, but we've
+                    // been told
+                    // to redirect elsewhere
+                    if (filter.redirectToOnException != null) {
+                        redirect(httpRequest, httpResponse, filter.redirectToOnException);
+                        return;
+                    }
+                    throw ex;
+                } catch (final IOException ex) {
+                    if (filter.redirectToOnException != null) {
+                        redirect(httpRequest, httpResponse, filter.redirectToOnException);
+                        return;
+                    }
+                    throw ex;
+                } catch (final ServletException ex) {
+                    // in case the destination servlet cannot cope, but we've
+                    // been told
+                    // to redirect elsewhere
+                    if (filter.redirectToOnException != null) {
+                        redirect(httpRequest, httpResponse, filter.redirectToOnException);
+                        return;
+                    }
+                    throw ex;
+                } finally {
+                    UNDEFINED.setOn(request);
+                    // nothing to do
+                }
+
+            }
+
+            private boolean requestIsIgnoreExtension(final IsisSessionFilter filter, final HttpServletRequest httpRequest) {
+                final String servletPath = httpRequest.getServletPath();
+                for (final Pattern extension : filter.ignoreExtensions) {
+                    if (extension.matcher(servletPath).matches()) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        },
+        NO_SESSION_SINCE_REDIRECTING_TO_LOGON_PAGE, NO_SESSION_SINCE_NOT_AUTHENTICATED, SESSION_IN_PROGRESS;
+
+        static SessionState lookup(final ServletRequest request) {
+            final Object state = request.getAttribute(SESSION_STATE_KEY);
+            return state != null ? (SessionState) state : SessionState.UNDEFINED;
+        }
+
+        boolean isValid(final AuthenticationSession authSession) {
+            return authSession != null && getAuthenticationManager().isSessionValid(authSession);
+        }
+
+        void setOn(final ServletRequest request) {
+            request.setAttribute(SESSION_STATE_KEY, this);
+        }
+
+        public void handle(final IsisSessionFilter filter, final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+            chain.doFilter(request, response);
+        }
+
+        AuthenticationManager getAuthenticationManager() {
+            return IsisContext.getAuthenticationManager();
+        }
+
+        void openSession(final AuthenticationSession authSession) {
+            IsisContext.openSession(authSession);
+        }
+
+        void closeSession() {
+            IsisContext.closeSession();
+        }
+
+    }
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+
+        final SessionState sessionState = SessionState.lookup(request);
+        sessionState.handle(this, request, response, chain);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java
new file mode 100644
index 0000000..ebcbc82
--- /dev/null
+++ b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java
@@ -0,0 +1,217 @@
+/*
+ *  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.runtimes.dflt.webapp;
+
+import java.util.List;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.config.IsisConfigurationBuilder;
+import org.apache.isis.core.commons.config.IsisConfigurationBuilderPrimer;
+import org.apache.isis.core.commons.config.IsisConfigurationBuilderResourceStreams;
+import org.apache.isis.core.commons.config.NotFoundPolicy;
+import org.apache.isis.core.commons.resource.ResourceStreamSource;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceComposite;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceFileSystem;
+import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer;
+import org.apache.isis.core.webapp.config.ResourceStreamSourceForWebInf;
+import org.apache.isis.runtimes.dflt.runtime.installerregistry.InstallerLookup;
+import org.apache.isis.runtimes.dflt.runtime.installers.InstallerLookupDefault;
+import org.apache.isis.runtimes.dflt.runtime.runner.IsisModule;
+import org.apache.isis.runtimes.dflt.runtime.system.DeploymentType;
+import org.apache.isis.runtimes.dflt.runtime.system.IsisSystem;
+import org.apache.isis.runtimes.dflt.runtime.system.SystemConstants;
+
+/**
+ * Initialize the {@link IsisSystem} when the web application starts, and
+ * destroys it when it ends.
+ * <p>
+ * Implementation note: we use a number of helper builders to keep this class as
+ * small and focused as possible. The builders are available for reuse by other
+ * bootstrappers.
+ */
+public class IsisWebAppBootstrapper implements ServletContextListener {
+
+    private static final Logger LOG = Logger.getLogger(IsisWebAppBootstrapper.class);
+    private final IsisLoggingConfigurer loggingConfigurer = new IsisLoggingConfigurer();
+    private Injector injector;
+
+    /**
+     * Convenience for servlets that need to obtain the {@link IsisSystem}.
+     */
+    public static IsisSystem getSystemBoundTo(final ServletContext servletContext) {
+        final Object system = servletContext.getAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
+        return (IsisSystem) system;
+    }
+
+    // /////////////////////////////////////////////////////
+    // Initialization
+    // /////////////////////////////////////////////////////
+
+    @Override
+    public void contextInitialized(final ServletContextEvent servletContextEvent) {
+        try {
+            final ServletContext servletContext = servletContextEvent.getServletContext();
+
+            final String webappDir = servletContext.getRealPath("/");
+            final String webInfDir = servletContext.getRealPath("/WEB-INF");
+            loggingConfigurer.configureLogging(webInfDir, new String[0]);
+
+            String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM);
+            ResourceStreamSourceComposite compositeSource = null;
+            if ( configLocation == null ) {
+              LOG.info( "Config override location: No override location configured!" );
+              compositeSource = new ResourceStreamSourceComposite(ResourceStreamSourceContextLoaderClassPath.create(), new ResourceStreamSourceForWebInf(servletContext));
+            } else {
+              LOG.info( "Config override location: " + configLocation );
+              ResourceStreamSource configSourceStream = ResourceStreamSourceFileSystem.create(configLocation);
+              compositeSource = new ResourceStreamSourceComposite(ResourceStreamSourceContextLoaderClassPath.create(), new ResourceStreamSourceForWebInf(servletContext), configSourceStream);
+            }
+            // will load either from WEB-INF, from the classpath or from config directory.
+            final IsisConfigurationBuilder isisConfigurationBuilder = new IsisConfigurationBuilderResourceStreams(compositeSource);
+
+            primeConfigurationBuilder(isisConfigurationBuilder, servletContext);
+
+            final DeploymentType deploymentType = determineDeploymentType(isisConfigurationBuilder, servletContext);
+
+            addConfigurationResourcesForWebApps(isisConfigurationBuilder);
+            addConfigurationResourcesForDeploymentType(isisConfigurationBuilder, deploymentType);
+            addConfigurationResourcesForViewers(isisConfigurationBuilder, servletContext);
+
+            isisConfigurationBuilder.add(WebAppConstants.WEB_APP_DIR, webappDir);
+            isisConfigurationBuilder.add(SystemConstants.NOSPLASH_KEY, "true");
+
+            final InstallerLookup installerLookup = new InstallerLookupDefault();
+
+            injector = createGuiceInjector(isisConfigurationBuilder, deploymentType, installerLookup);
+
+            final IsisSystem system = injector.getInstance(IsisSystem.class);
+            
+            isisConfigurationBuilder.dumpResourcesToLog();
+
+            servletContext.setAttribute(WebAppConstants.ISIS_SYSTEM_KEY, system);
+        } catch (final RuntimeException e) {
+            LOG.error("startup failed", e);
+            throw e;
+        }
+        LOG.info("server started");
+    }
+
+    private Injector createGuiceInjector(final IsisConfigurationBuilder isisConfigurationBuilder, final DeploymentType deploymentType, final InstallerLookup installerLookup) {
+        final IsisModule isisModule = new IsisModule(deploymentType, isisConfigurationBuilder, installerLookup);
+        return Guice.createInjector(isisModule);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void primeConfigurationBuilder(final IsisConfigurationBuilder isisConfigurationBuilder, final ServletContext servletContext) {
+        final List<IsisConfigurationBuilderPrimer> isisConfigurationBuilderPrimers = (List<IsisConfigurationBuilderPrimer>) servletContext.getAttribute(WebAppConstants.CONFIGURATION_PRIMERS_KEY);
+        if (isisConfigurationBuilderPrimers == null) {
+            return;
+        }
+        for (final IsisConfigurationBuilderPrimer isisConfigurationBuilderPrimer : isisConfigurationBuilderPrimers) {
+            isisConfigurationBuilderPrimer.primeConfigurationBuilder(isisConfigurationBuilder);
+        }
+    }
+
+    /**
+     * Checks {@link IsisConfigurationBuilder configuration} for
+     * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}, (that is, from the command
+     * line), but otherwise searches in the {@link ServletContext}, first for
+     * {@value WebAppConstants#DEPLOYMENT_TYPE_KEY} and also
+     * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}.
+     * <p>
+     * If no setting is found, defaults to
+     * {@value WebAppConstants#DEPLOYMENT_TYPE_DEFAULT}.
+     */
+    private DeploymentType determineDeploymentType(final IsisConfigurationBuilder isisConfigurationBuilder, final ServletContext servletContext) {
+        String deploymentTypeStr = null;
+        if (deploymentTypeStr == null) {
+            deploymentTypeStr = servletContext.getInitParameter(WebAppConstants.DEPLOYMENT_TYPE_KEY);
+        }
+        if (deploymentTypeStr == null) {
+            deploymentTypeStr = servletContext.getInitParameter(SystemConstants.DEPLOYMENT_TYPE_KEY);
+        }
+        if (deploymentTypeStr == null) {
+            deploymentTypeStr = isisConfigurationBuilder.getConfiguration().getString(SystemConstants.DEPLOYMENT_TYPE_KEY);
+        }
+        if (deploymentTypeStr == null) {
+            deploymentTypeStr = WebAppConstants.DEPLOYMENT_TYPE_DEFAULT;
+        }
+        return DeploymentType.lookup(deploymentTypeStr);
+    }
+
+    private void addConfigurationResourcesForDeploymentType(final IsisConfigurationBuilder configurationLoader, final DeploymentType deploymentType) {
+        final String type = deploymentType.name().toLowerCase();
+        configurationLoader.addConfigurationResource(type + ".properties", NotFoundPolicy.CONTINUE);
+    }
+
+    private void addConfigurationResourcesForWebApps(final IsisConfigurationBuilder configurationLoader) {
+        for (final String config : (new String[] { "web.properties", "war.properties" })) {
+            if (config != null) {
+                configurationLoader.addConfigurationResource(config, NotFoundPolicy.CONTINUE);
+            }
+        }
+    }
+
+    private void addConfigurationResourcesForViewers(final IsisConfigurationBuilder configurationLoader, final ServletContext servletContext) {
+        addConfigurationResourcesForContextParam(configurationLoader, servletContext, "isis.viewers");
+        addConfigurationResourcesForContextParam(configurationLoader, servletContext, "isis.viewer");
+    }
+
+    private void addConfigurationResourcesForContextParam(final IsisConfigurationBuilder configurationLoader, final ServletContext servletContext, final String name) {
+        final String viewers = servletContext.getInitParameter(name);
+        if (viewers == null) {
+            return;
+        }
+        for (final String viewer : viewers.split(",")) {
+            configurationLoader.addConfigurationResource("viewer_" + viewer + ".properties", NotFoundPolicy.CONTINUE);
+        }
+    }
+
+    // /////////////////////////////////////////////////////
+    // Destroy
+    // /////////////////////////////////////////////////////
+
+    @Override
+    public void contextDestroyed(final ServletContextEvent ev) {
+        LOG.info("server shutting down");
+        final ServletContext servletContext = ev.getServletContext();
+
+        try {
+            final IsisSystem system = (IsisSystem) servletContext.getAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
+            if (system != null) {
+                LOG.info("calling system shutdown");
+                system.shutdown();
+            }
+        } finally {
+            servletContext.removeAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
+            LOG.info("server shut down");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java
new file mode 100644
index 0000000..0cb07ce
--- /dev/null
+++ b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java
@@ -0,0 +1,85 @@
+/*
+ *  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.runtimes.dflt.webapp;
+
+import org.apache.isis.applib.fixtures.LogonFixture;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.config.IsisConfigurationBuilderPrimer;
+import org.apache.isis.runtimes.dflt.runtime.system.DeploymentType;
+import org.apache.isis.runtimes.dflt.runtime.system.IsisSystem;
+
+public final class WebAppConstants {
+
+    /**
+     * Name of context-param (<tt>ServletContext#getInitParameter(String)</tt>)
+     * to specify the deployment type.
+     */
+    public static final String DEPLOYMENT_TYPE_KEY = "deploymentType";
+    /**
+     * Deployment type to use if there is none {@link DEPLOYMENT_TYPE_KEY
+     * specified}.
+     */
+    public static final String DEPLOYMENT_TYPE_DEFAULT = DeploymentType.SERVER.name();
+
+    /**
+     * Key under which the list of {@link IsisConfigurationBuilderPrimer}s is
+     * bound as a servlet context attribute (
+     * <tt>ServletContext#getAttribute(String)</tt>); used to pass from the
+     * <tt>webserver</tt> module to this.
+     */
+    public static final String CONFIGURATION_PRIMERS_KEY = "isis.configurationPrimers";
+
+    /**
+     * Key under which the {@link IsisSystem} is bound as a servlet context
+     * attribute ( <tt>ServletContext#getAttribute(String)</tt>).
+     */
+    public final static String ISIS_SYSTEM_KEY = WebAppConstants.class.getPackage().getName() + ".isisSystem";
+
+    /**
+     * Key under which the {@link AuthenticationSession} is bound as a session
+     * attribute ( <tt>HttpSession#getAttribute(String)</tt>).
+     */
+    public final static String HTTP_SESSION_AUTHENTICATION_SESSION_KEY = WebAppConstants.class.getPackage().getName() + ".authenticationSession";
+
+    /**
+     * Key used to determine if a logon has already been performed implicitly
+     * using the {@link LogonFixture}, meaning that a Logout should be followed
+     * by the Logon page.
+     */
+    public final static String HTTP_SESSION_LOGGED_ON_PREVIOUSLY_USING_LOGON_FIXTURE_KEY = WebAppConstants.class.getPackage().getName() + ".loggedOnPreviouslyUsingLogonFixture";
+
+    /**
+     * Property name given to the web app directory.
+     */
+    public static final String WEB_APP_DIR = "application.webapp.dir";
+
+    /**
+     * Servlet context parameter name used to specify the location for property file 
+     * overloads. Property files in this location take precendence over property files 
+     * in other locations. Since the ResourceStreamSourceComposite is being used
+     * property files from various locations are merged together. So only overloaded
+     * properties (entries in the file) need to present.
+     */
+    public static final String CONFIG_DIR_PARAM = "isis.config.dir";
+
+    private WebAppConstants() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java
new file mode 100644
index 0000000..9719c92
--- /dev/null
+++ b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java
@@ -0,0 +1,43 @@
+/*
+ *  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.runtimes.dflt.webapp.auth;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.runtimes.dflt.webapp.IsisSessionFilter;
+
+/**
+ * Decouples the {@link IsisSessionFilter} from the mechanism of obtaining the
+ * {@link AuthenticationSession}.
+ */
+public interface AuthenticationSessionStrategy {
+
+    /**
+     * Returns a
+     * {@link AuthenticationManager#isSessionValid(AuthenticationSession)
+     * still-valid} {@link AuthenticationSession}.
+     */
+    AuthenticationSession lookupValid(ServletRequest servletRequest, ServletResponse servletResponse);
+
+    void bind(ServletRequest servletRequest, ServletResponse servletResponse, AuthenticationSession authSession);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java
new file mode 100644
index 0000000..4d68958
--- /dev/null
+++ b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java
@@ -0,0 +1,46 @@
+/*
+ *  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.runtimes.dflt.webapp.auth;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+
+public abstract class AuthenticationSessionStrategyAbstract implements AuthenticationSessionStrategy {
+
+    protected HttpSession getHttpSession(final ServletRequest servletRequest) {
+        final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+        return httpServletRequest.getSession();
+    }
+
+    protected ServletContext getServletContext(final ServletRequest servletRequest) {
+        final HttpSession httpSession = getHttpSession(servletRequest);
+        return httpSession.getServletContext();
+    }
+
+    @Override
+    public void bind(final ServletRequest servletRequest, final ServletResponse servletResponse, final AuthenticationSession authSession) {
+        // no-op
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyDefault.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyDefault.java b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyDefault.java
new file mode 100644
index 0000000..e0f1c1d
--- /dev/null
+++ b/framework/runtimes/dflt/runtime/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyDefault.java
@@ -0,0 +1,113 @@
+/*
+ *  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.runtimes.dflt.webapp.auth;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.isis.applib.fixtures.LogonFixture;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.runtimes.dflt.runtime.authentication.exploration.AuthenticationRequestExploration;
+import org.apache.isis.runtimes.dflt.runtime.fixtures.authentication.AuthenticationRequestLogonFixture;
+import org.apache.isis.runtimes.dflt.runtime.system.IsisSystem;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.runtimes.dflt.webapp.WebAppConstants;
+
+/**
+ * Returns a valid {@link AuthenticationSession} through a number of mechanisms;
+ * supports caching of the {@link AuthenticationSession} onto the
+ * {@link HttpSession}.
+ * 
+ * <p>
+ * The session is looked-up as follows:
+ * <ul>
+ * <li>it looks up from the {@link HttpSession} using the value
+ * {@value WebAppConstants#HTTP_SESSION_AUTHENTICATION_SESSION_KEY}</li>
+ * <li>failing that, if in exploration mode, then returns an exploration session
+ * </li>
+ * <li>failing that, if a {@link LogonFixture} has been provided and not already
+ * used, will provide an session for that fixture. The {@link HttpSession} also
+ * stores the value
+ * {@value WebAppConstants#HTTP_SESSION_LOGGED_ON_PREVIOUSLY_USING_LOGON_FIXTURE_KEY}
+ * in the session to track whether this has been done</li>
+ * </ul>
+ * <p>
+ */
+public class AuthenticationSessionStrategyDefault extends AuthenticationSessionStrategyAbstract {
+
+    @Override
+    public AuthenticationSession lookupValid(final ServletRequest servletRequest, final ServletResponse servletResponse) {
+
+        final AuthenticationManager authenticationManager = getAuthenticationManager();
+        final HttpSession httpSession = getHttpSession(servletRequest);
+
+        // use previously authenticated session if available
+        AuthenticationSession authSession = (AuthenticationSession) httpSession.getAttribute(WebAppConstants.HTTP_SESSION_AUTHENTICATION_SESSION_KEY);
+        if (authSession != null) {
+            final boolean sessionValid = authenticationManager.isSessionValid(authSession);
+            if (sessionValid) {
+                return authSession;
+            }
+        }
+
+        // otherwise, look for LogonFixture and try to authenticate
+        final ServletContext servletContext = getServletContext(servletRequest);
+        final IsisSystem system = (IsisSystem) servletContext.getAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
+        if (system == null) {
+            // not expected to happen...
+            return null;
+        }
+        final LogonFixture logonFixture = system.getLogonFixture();
+
+        // see if exploration is supported
+        if (system.getDeploymentType().isExploring()) {
+            authSession = authenticationManager.authenticate(new AuthenticationRequestExploration(logonFixture));
+            if (authSession != null) {
+                return authSession;
+            }
+        }
+
+        final boolean loggedInUsingLogonFixture = httpSession.getAttribute(WebAppConstants.HTTP_SESSION_LOGGED_ON_PREVIOUSLY_USING_LOGON_FIXTURE_KEY) != null;
+        if (logonFixture != null && !loggedInUsingLogonFixture) {
+            httpSession.setAttribute(WebAppConstants.HTTP_SESSION_LOGGED_ON_PREVIOUSLY_USING_LOGON_FIXTURE_KEY, true);
+            return authenticationManager.authenticate(new AuthenticationRequestLogonFixture(logonFixture));
+        }
+
+        return null;
+    }
+
+    @Override
+    public void bind(final ServletRequest servletRequest, final ServletResponse servletResponse, final AuthenticationSession authSession) {
+        final HttpSession httpSession = getHttpSession(servletRequest);
+        httpSession.setAttribute(WebAppConstants.HTTP_SESSION_AUTHENTICATION_SESSION_KEY, authSession);
+    }
+
+    // //////////////////////////////////////////////////////////
+    // Dependencies (from context)
+    // //////////////////////////////////////////////////////////
+
+    protected AuthenticationManager getAuthenticationManager() {
+        return IsisContext.getAuthenticationManager();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/runtime/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/runtime/src/site/apt/index.apt b/framework/runtimes/dflt/runtime/src/site/apt/index.apt
index 6f34b9d..05d2fd0 100644
--- a/framework/runtimes/dflt/runtime/src/site/apt/index.apt
+++ b/framework/runtimes/dflt/runtime/src/site/apt/index.apt
@@ -39,6 +39,35 @@ Runtime
  bootstrapper, making it easy to bootstrap <Apache Isis> from a main() or a 
  JUnit test case.
 
+
+WebApp Support
+ 
+ The <webapp> module is a small module that provides reusable servlet context 
+ listeners and filters to webapp viewers.  They include:
+ 
+ * <<<IsisWebAppBootstrapper>>> which is a servlet context listener to bootstrap
+   an Isis runtime and bind to the servlet context
+
+ * <<<IsisSessionFilter>>> which is a filter used to
+   creating an <<<IsisSession>>> for each request (the 
+   {{{http://community.jboss.org/wiki/OpenSessioninView}Open session in View}}
+    pattern)
+
+ []
+ 
+ Not every webapp-based viewer is required to use these classes; refer to their
+ documentation for exact details of what should reside in the <<<web.xml>>>.
+ 
+
+
+Identity Bytecode
+ 
+ The <identity> bytecode module is a no-op implementation of the bytecode
+ APIs.  It is provided for those object stores that do not need the use of 
+ bytecode enhancement, typically because they hook into the lazy loading 
+ of the underlying ORM.
+
+
 Documentation
 
  See the {{{../index.html}core}} documentation 

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/testsupport/pom.xml
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/testsupport/pom.xml b/framework/runtimes/dflt/testsupport/pom.xml
index 879b37c..e421112 100644
--- a/framework/runtimes/dflt/testsupport/pom.xml
+++ b/framework/runtimes/dflt/testsupport/pom.xml
@@ -102,12 +102,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.isis.progmodels</groupId>
-            <artifactId>dflt</artifactId>
-            <version>0.3.1-SNAPSHOT</version>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.isis.runtimes.dflt.bytecode</groupId>
             <artifactId>dflt</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/webapp/pom.xml b/framework/runtimes/dflt/webapp/pom.xml
index 341e03d..66d0ee6 100644
--- a/framework/runtimes/dflt/webapp/pom.xml
+++ b/framework/runtimes/dflt/webapp/pom.xml
@@ -97,7 +97,7 @@
 
 		<dependency>
 			<groupId>org.apache.isis.core</groupId>
-            <artifactId>webapp</artifactId>
+            <artifactId>isis-metamodel</artifactId>
 		</dependency>
 
 	    <dependency>

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java b/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java
deleted file mode 100644
index 1ef61ab..0000000
--- a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisSessionFilter.java
+++ /dev/null
@@ -1,407 +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.runtimes.dflt.webapp;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.google.common.base.Function;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.factory.InstanceUtil;
-import org.apache.isis.core.commons.lang.PathUtils;
-import org.apache.isis.core.runtime.authentication.AuthenticationManager;
-import org.apache.isis.core.webapp.content.ResourceCachingFilter;
-import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
-import org.apache.isis.runtimes.dflt.webapp.auth.AuthenticationSessionStrategy;
-import org.apache.isis.runtimes.dflt.webapp.auth.AuthenticationSessionStrategyDefault;
-
-public class IsisSessionFilter implements Filter {
-
-    /**
-     * Recommended standard init parameter key for filters and servlets to
-     * lookup an implementation of {@link AuthenticationSessionStrategy}.
-     */
-    public static final String AUTHENTICATION_SESSION_STRATEGY_KEY = "authenticationSessionStrategy";
-
-    /**
-     * Default value for
-     * {@link AuthenticationSessionLookupStrategyConstants#AUTHENTICATION_SESSION_STRATEGY_KEY}
-     * if not specified.
-     */
-    public static final String AUTHENTICATION_SESSION_STRATEGY_DEFAULT = AuthenticationSessionStrategyDefault.class.getName();
-
-    /**
-     * Init parameter key for backward compatibility; if logonPage set then
-     * assume 'restricted' handling.
-     */
-    public static final String LOGON_PAGE_KEY = "logonPage";
-
-    /**
-     * Init parameter key for what should be done if no session was found.
-     * 
-     * <p>
-     * Valid values are:
-     * <ul>
-     * <li>unauthorized - issue a 401 response.
-     * <li>basicAuthChallenge - issue a basic auth 401 challenge. The idea here
-     * is that the configured logon strategy should handle the next request
-     * <li>restricted - allow access but only to a restricted (comma-separated)
-     * list of paths. Access elsewhere should be redirected to the first of
-     * these paths
-     * <li>continue - allow the request to continue (eg if there is no security
-     * requirements)
-     * </ul>
-     */
-    public static final String WHEN_NO_SESSION_KEY = "whenNoSession";
-
-    /**
-     * Init parameter key to read the restricted list of paths (if
-     * {@link #WHEN_NO_SESSION_KEY} is for {@link WhenNoSession#RESTRICTED}).
-     * 
-     * <p>
-     * The servlets mapped to these paths are expected to be able to deal with
-     * there being no session. Typically they will be logon pages.
-     */
-    public static final String RESTRICTED_KEY = "restricted";
-
-    /**
-     * Init parameter key to redirect to if an exception occurs.
-     */
-    public static final String REDIRECT_TO_ON_EXCEPTION_KEY = "redirectToOnException";
-
-    /**
-     * Init parameter key for which extensions should be ignored (typically,
-     * mappings for other viewers within the webapp context).
-     * 
-     * <p>
-     * It can also be used to specify ignored static resources (though putting
-     * the {@link ResourceCachingFilter} first in the <tt>web.xml</tt>
-     * accomplishes the same thing).
-     * 
-     * <p>
-     * The value is expected as a comma separated list, for example:
-     * 
-     * <pre>
-     * htmlviewer
-     * </pre>
-     */
-    public static final String IGNORE_EXTENSIONS_KEY = "ignoreExtensions";
-
-    private static final Function<String, Pattern> STRING_TO_PATTERN = new Function<String, Pattern>() {
-        @Override
-        public Pattern apply(final String input) {
-            return Pattern.compile(".*\\." + input);
-        }
-
-    };
-
-    static void redirect(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final String redirectTo) throws IOException {
-        httpResponse.sendRedirect(PathUtils.combine(httpRequest.getContextPath(), redirectTo));
-    }
-
-    public enum WhenNoSession {
-        UNAUTHORIZED("unauthorized") {
-            @Override
-            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
-                httpResponse.sendError(401);
-            }
-        },
-        BASIC_AUTH_CHALLENGE("basicAuthChallenge") {
-            @Override
-            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
-                httpResponse.setHeader("WWW-Authenticate", "Basic realm=\"Apache Isis\"");
-                httpResponse.sendError(401);
-            }
-        },
-        /**
-         * the destination servlet is expected to know that there will be no
-         * open context
-         */
-        CONTINUE("continue") {
-            @Override
-            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
-                chain.doFilter(httpRequest, httpResponse);
-            }
-        },
-        /**
-         * Allow access to a restricted list of URLs (else redirect to the first
-         * of that list of URLs)
-         */
-        RESTRICTED("restricted") {
-            @Override
-            public void handle(final IsisSessionFilter filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
-
-                if (filter.restrictedPaths.contains(httpRequest.getServletPath())) {
-                    chain.doFilter(httpRequest, httpResponse);
-                    return;
-                }
-                redirect(httpRequest, httpResponse, filter.restrictedPaths.get(0));
-            }
-
-        };
-        private final String initParamValue;
-
-        private WhenNoSession(final String initParamValue) {
-            this.initParamValue = initParamValue;
-        }
-
-        public static WhenNoSession lookup(final String whenNoSessionStr) {
-            for (final WhenNoSession wns : values()) {
-                if (wns.initParamValue.equals(whenNoSessionStr)) {
-                    return wns;
-                }
-            }
-            throw new IllegalStateException("require an init-param of '" + WHEN_NO_SESSION_KEY + "', taking a value of " + WhenNoSession.values());
-        }
-
-        public abstract void handle(IsisSessionFilter filter, HttpServletRequest httpRequest, HttpServletResponse httpResponse, FilterChain chain) throws IOException, ServletException;
-    }
-
-    /**
-     * Used as a flag on {@link HttpServletRequest} so that if there are two
-     * {@link IsisSessionFilter}s in a request pipeline, then the second can
-     * determine what processing has already been done (and is usually then just
-     * a no-op).
-     */
-    private static final String SESSION_STATE_KEY = IsisSessionFilter.SessionState.class.getName();
-
-    private AuthenticationSessionStrategy authSessionStrategy;
-    private List<String> restrictedPaths;
-    private WhenNoSession whenNoSession;
-    private String redirectToOnException;
-    private Collection<Pattern> ignoreExtensions;
-
-    // /////////////////////////////////////////////////////////////////
-    // init, destroy
-    // /////////////////////////////////////////////////////////////////
-
-    @Override
-    public void init(final FilterConfig config) throws ServletException {
-        authSessionStrategy = lookup(config.getInitParameter(AUTHENTICATION_SESSION_STRATEGY_KEY));
-        lookupWhenNoSession(config);
-        lookupRedirectToOnException(config);
-        lookupIgnoreExtensions(config);
-    }
-
-    /**
-     * Public visibility so can also be used by servlets.
-     */
-    public static AuthenticationSessionStrategy lookup(String authLookupStrategyClassName) {
-        if (authLookupStrategyClassName == null) {
-            authLookupStrategyClassName = AUTHENTICATION_SESSION_STRATEGY_DEFAULT;
-        }
-        return (AuthenticationSessionStrategy) InstanceUtil.createInstance(authLookupStrategyClassName);
-    }
-
-    private void lookupWhenNoSession(final FilterConfig config) {
-
-        final String whenNoSessionStr = config.getInitParameter(WHEN_NO_SESSION_KEY);
-
-        // backward compatibility
-        final String logonPage = config.getInitParameter(LOGON_PAGE_KEY);
-        if (logonPage != null) {
-            if (whenNoSessionStr != null) {
-                throw new IllegalStateException("The init-param '" + LOGON_PAGE_KEY + "' is only provided for backwards compatibility; remove if the init-param '" + WHEN_NO_SESSION_KEY + "' has been specified");
-            }
-            whenNoSession = WhenNoSession.RESTRICTED;
-            this.restrictedPaths = Lists.newArrayList(logonPage);
-            return;
-        }
-
-        whenNoSession = WhenNoSession.lookup(whenNoSessionStr);
-        if (whenNoSession == WhenNoSession.RESTRICTED) {
-            final String restrictedPathsStr = config.getInitParameter(RESTRICTED_KEY);
-            if (restrictedPathsStr == null) {
-                throw new IllegalStateException("Require an init-param of '" + RESTRICTED_KEY + "' key to be set.");
-            }
-            this.restrictedPaths = Lists.newArrayList(Splitter.on(",").split(restrictedPathsStr));
-        }
-
-    }
-
-    private void lookupRedirectToOnException(final FilterConfig config) {
-        redirectToOnException = config.getInitParameter(REDIRECT_TO_ON_EXCEPTION_KEY);
-    }
-
-    private void lookupIgnoreExtensions(final FilterConfig config) {
-        ignoreExtensions = Collections.unmodifiableCollection(parseIgnorePatterns(config));
-    }
-
-    private Collection<Pattern> parseIgnorePatterns(final FilterConfig config) {
-        final String ignoreExtensionsStr = config.getInitParameter(IGNORE_EXTENSIONS_KEY);
-        if (ignoreExtensionsStr != null) {
-            final List<String> ignoreExtensions = Lists.newArrayList(Splitter.on(",").split(ignoreExtensionsStr));
-            return Collections2.transform(ignoreExtensions, STRING_TO_PATTERN);
-        }
-        return Lists.newArrayList();
-    }
-
-    @Override
-    public void destroy() {
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // doFilter
-    // /////////////////////////////////////////////////////////////////
-
-    public enum SessionState {
-
-        UNDEFINED {
-            @Override
-            public void handle(final IsisSessionFilter filter, final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
-
-                final HttpServletRequest httpRequest = (HttpServletRequest) request;
-                final HttpServletResponse httpResponse = (HttpServletResponse) response;
-
-                if (requestIsIgnoreExtension(filter, httpRequest)) {
-                    try {
-                        chain.doFilter(request, response);
-                        return;
-                    } finally {
-                        closeSession();
-                    }
-                }
-
-                if (ResourceCachingFilter.isCachedResource(httpRequest)) {
-                    try {
-                        chain.doFilter(request, response);
-                        return;
-                    } finally {
-                        closeSession();
-                    }
-                }
-
-                // authenticate
-                final AuthenticationSession validSession = filter.authSessionStrategy.lookupValid(request, response);
-                if (validSession != null) {
-                    filter.authSessionStrategy.bind(request, response, validSession);
-
-                    openSession(validSession);
-                    SESSION_IN_PROGRESS.setOn(request);
-                    try {
-                        chain.doFilter(request, response);
-                    } finally {
-                        UNDEFINED.setOn(request);
-                        closeSession();
-                    }
-                    return;
-                }
-
-                try {
-                    NO_SESSION_SINCE_NOT_AUTHENTICATED.setOn(request);
-                    filter.whenNoSession.handle(filter, httpRequest, httpResponse, chain);
-                } catch (final RuntimeException ex) {
-                    // in case the destination servlet cannot cope, but we've
-                    // been told
-                    // to redirect elsewhere
-                    if (filter.redirectToOnException != null) {
-                        redirect(httpRequest, httpResponse, filter.redirectToOnException);
-                        return;
-                    }
-                    throw ex;
-                } catch (final IOException ex) {
-                    if (filter.redirectToOnException != null) {
-                        redirect(httpRequest, httpResponse, filter.redirectToOnException);
-                        return;
-                    }
-                    throw ex;
-                } catch (final ServletException ex) {
-                    // in case the destination servlet cannot cope, but we've
-                    // been told
-                    // to redirect elsewhere
-                    if (filter.redirectToOnException != null) {
-                        redirect(httpRequest, httpResponse, filter.redirectToOnException);
-                        return;
-                    }
-                    throw ex;
-                } finally {
-                    UNDEFINED.setOn(request);
-                    // nothing to do
-                }
-
-            }
-
-            private boolean requestIsIgnoreExtension(final IsisSessionFilter filter, final HttpServletRequest httpRequest) {
-                final String servletPath = httpRequest.getServletPath();
-                for (final Pattern extension : filter.ignoreExtensions) {
-                    if (extension.matcher(servletPath).matches()) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        },
-        NO_SESSION_SINCE_REDIRECTING_TO_LOGON_PAGE, NO_SESSION_SINCE_NOT_AUTHENTICATED, SESSION_IN_PROGRESS;
-
-        static SessionState lookup(final ServletRequest request) {
-            final Object state = request.getAttribute(SESSION_STATE_KEY);
-            return state != null ? (SessionState) state : SessionState.UNDEFINED;
-        }
-
-        boolean isValid(final AuthenticationSession authSession) {
-            return authSession != null && getAuthenticationManager().isSessionValid(authSession);
-        }
-
-        void setOn(final ServletRequest request) {
-            request.setAttribute(SESSION_STATE_KEY, this);
-        }
-
-        public void handle(final IsisSessionFilter filter, final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
-            chain.doFilter(request, response);
-        }
-
-        AuthenticationManager getAuthenticationManager() {
-            return IsisContext.getAuthenticationManager();
-        }
-
-        void openSession(final AuthenticationSession authSession) {
-            IsisContext.openSession(authSession);
-        }
-
-        void closeSession() {
-            IsisContext.closeSession();
-        }
-
-    }
-
-    @Override
-    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
-
-        final SessionState sessionState = SessionState.lookup(request);
-        sessionState.handle(this, request, response, chain);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java b/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java
deleted file mode 100644
index ebcbc82..0000000
--- a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/IsisWebAppBootstrapper.java
+++ /dev/null
@@ -1,217 +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.runtimes.dflt.webapp;
-
-import java.util.List;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-import org.apache.log4j.Logger;
-
-import org.apache.isis.core.commons.config.IsisConfigurationBuilder;
-import org.apache.isis.core.commons.config.IsisConfigurationBuilderPrimer;
-import org.apache.isis.core.commons.config.IsisConfigurationBuilderResourceStreams;
-import org.apache.isis.core.commons.config.NotFoundPolicy;
-import org.apache.isis.core.commons.resource.ResourceStreamSource;
-import org.apache.isis.core.commons.resource.ResourceStreamSourceComposite;
-import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
-import org.apache.isis.core.commons.resource.ResourceStreamSourceFileSystem;
-import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer;
-import org.apache.isis.core.webapp.config.ResourceStreamSourceForWebInf;
-import org.apache.isis.runtimes.dflt.runtime.installerregistry.InstallerLookup;
-import org.apache.isis.runtimes.dflt.runtime.installers.InstallerLookupDefault;
-import org.apache.isis.runtimes.dflt.runtime.runner.IsisModule;
-import org.apache.isis.runtimes.dflt.runtime.system.DeploymentType;
-import org.apache.isis.runtimes.dflt.runtime.system.IsisSystem;
-import org.apache.isis.runtimes.dflt.runtime.system.SystemConstants;
-
-/**
- * Initialize the {@link IsisSystem} when the web application starts, and
- * destroys it when it ends.
- * <p>
- * Implementation note: we use a number of helper builders to keep this class as
- * small and focused as possible. The builders are available for reuse by other
- * bootstrappers.
- */
-public class IsisWebAppBootstrapper implements ServletContextListener {
-
-    private static final Logger LOG = Logger.getLogger(IsisWebAppBootstrapper.class);
-    private final IsisLoggingConfigurer loggingConfigurer = new IsisLoggingConfigurer();
-    private Injector injector;
-
-    /**
-     * Convenience for servlets that need to obtain the {@link IsisSystem}.
-     */
-    public static IsisSystem getSystemBoundTo(final ServletContext servletContext) {
-        final Object system = servletContext.getAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
-        return (IsisSystem) system;
-    }
-
-    // /////////////////////////////////////////////////////
-    // Initialization
-    // /////////////////////////////////////////////////////
-
-    @Override
-    public void contextInitialized(final ServletContextEvent servletContextEvent) {
-        try {
-            final ServletContext servletContext = servletContextEvent.getServletContext();
-
-            final String webappDir = servletContext.getRealPath("/");
-            final String webInfDir = servletContext.getRealPath("/WEB-INF");
-            loggingConfigurer.configureLogging(webInfDir, new String[0]);
-
-            String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM);
-            ResourceStreamSourceComposite compositeSource = null;
-            if ( configLocation == null ) {
-              LOG.info( "Config override location: No override location configured!" );
-              compositeSource = new ResourceStreamSourceComposite(ResourceStreamSourceContextLoaderClassPath.create(), new ResourceStreamSourceForWebInf(servletContext));
-            } else {
-              LOG.info( "Config override location: " + configLocation );
-              ResourceStreamSource configSourceStream = ResourceStreamSourceFileSystem.create(configLocation);
-              compositeSource = new ResourceStreamSourceComposite(ResourceStreamSourceContextLoaderClassPath.create(), new ResourceStreamSourceForWebInf(servletContext), configSourceStream);
-            }
-            // will load either from WEB-INF, from the classpath or from config directory.
-            final IsisConfigurationBuilder isisConfigurationBuilder = new IsisConfigurationBuilderResourceStreams(compositeSource);
-
-            primeConfigurationBuilder(isisConfigurationBuilder, servletContext);
-
-            final DeploymentType deploymentType = determineDeploymentType(isisConfigurationBuilder, servletContext);
-
-            addConfigurationResourcesForWebApps(isisConfigurationBuilder);
-            addConfigurationResourcesForDeploymentType(isisConfigurationBuilder, deploymentType);
-            addConfigurationResourcesForViewers(isisConfigurationBuilder, servletContext);
-
-            isisConfigurationBuilder.add(WebAppConstants.WEB_APP_DIR, webappDir);
-            isisConfigurationBuilder.add(SystemConstants.NOSPLASH_KEY, "true");
-
-            final InstallerLookup installerLookup = new InstallerLookupDefault();
-
-            injector = createGuiceInjector(isisConfigurationBuilder, deploymentType, installerLookup);
-
-            final IsisSystem system = injector.getInstance(IsisSystem.class);
-            
-            isisConfigurationBuilder.dumpResourcesToLog();
-
-            servletContext.setAttribute(WebAppConstants.ISIS_SYSTEM_KEY, system);
-        } catch (final RuntimeException e) {
-            LOG.error("startup failed", e);
-            throw e;
-        }
-        LOG.info("server started");
-    }
-
-    private Injector createGuiceInjector(final IsisConfigurationBuilder isisConfigurationBuilder, final DeploymentType deploymentType, final InstallerLookup installerLookup) {
-        final IsisModule isisModule = new IsisModule(deploymentType, isisConfigurationBuilder, installerLookup);
-        return Guice.createInjector(isisModule);
-    }
-
-    @SuppressWarnings("unchecked")
-    private void primeConfigurationBuilder(final IsisConfigurationBuilder isisConfigurationBuilder, final ServletContext servletContext) {
-        final List<IsisConfigurationBuilderPrimer> isisConfigurationBuilderPrimers = (List<IsisConfigurationBuilderPrimer>) servletContext.getAttribute(WebAppConstants.CONFIGURATION_PRIMERS_KEY);
-        if (isisConfigurationBuilderPrimers == null) {
-            return;
-        }
-        for (final IsisConfigurationBuilderPrimer isisConfigurationBuilderPrimer : isisConfigurationBuilderPrimers) {
-            isisConfigurationBuilderPrimer.primeConfigurationBuilder(isisConfigurationBuilder);
-        }
-    }
-
-    /**
-     * Checks {@link IsisConfigurationBuilder configuration} for
-     * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}, (that is, from the command
-     * line), but otherwise searches in the {@link ServletContext}, first for
-     * {@value WebAppConstants#DEPLOYMENT_TYPE_KEY} and also
-     * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}.
-     * <p>
-     * If no setting is found, defaults to
-     * {@value WebAppConstants#DEPLOYMENT_TYPE_DEFAULT}.
-     */
-    private DeploymentType determineDeploymentType(final IsisConfigurationBuilder isisConfigurationBuilder, final ServletContext servletContext) {
-        String deploymentTypeStr = null;
-        if (deploymentTypeStr == null) {
-            deploymentTypeStr = servletContext.getInitParameter(WebAppConstants.DEPLOYMENT_TYPE_KEY);
-        }
-        if (deploymentTypeStr == null) {
-            deploymentTypeStr = servletContext.getInitParameter(SystemConstants.DEPLOYMENT_TYPE_KEY);
-        }
-        if (deploymentTypeStr == null) {
-            deploymentTypeStr = isisConfigurationBuilder.getConfiguration().getString(SystemConstants.DEPLOYMENT_TYPE_KEY);
-        }
-        if (deploymentTypeStr == null) {
-            deploymentTypeStr = WebAppConstants.DEPLOYMENT_TYPE_DEFAULT;
-        }
-        return DeploymentType.lookup(deploymentTypeStr);
-    }
-
-    private void addConfigurationResourcesForDeploymentType(final IsisConfigurationBuilder configurationLoader, final DeploymentType deploymentType) {
-        final String type = deploymentType.name().toLowerCase();
-        configurationLoader.addConfigurationResource(type + ".properties", NotFoundPolicy.CONTINUE);
-    }
-
-    private void addConfigurationResourcesForWebApps(final IsisConfigurationBuilder configurationLoader) {
-        for (final String config : (new String[] { "web.properties", "war.properties" })) {
-            if (config != null) {
-                configurationLoader.addConfigurationResource(config, NotFoundPolicy.CONTINUE);
-            }
-        }
-    }
-
-    private void addConfigurationResourcesForViewers(final IsisConfigurationBuilder configurationLoader, final ServletContext servletContext) {
-        addConfigurationResourcesForContextParam(configurationLoader, servletContext, "isis.viewers");
-        addConfigurationResourcesForContextParam(configurationLoader, servletContext, "isis.viewer");
-    }
-
-    private void addConfigurationResourcesForContextParam(final IsisConfigurationBuilder configurationLoader, final ServletContext servletContext, final String name) {
-        final String viewers = servletContext.getInitParameter(name);
-        if (viewers == null) {
-            return;
-        }
-        for (final String viewer : viewers.split(",")) {
-            configurationLoader.addConfigurationResource("viewer_" + viewer + ".properties", NotFoundPolicy.CONTINUE);
-        }
-    }
-
-    // /////////////////////////////////////////////////////
-    // Destroy
-    // /////////////////////////////////////////////////////
-
-    @Override
-    public void contextDestroyed(final ServletContextEvent ev) {
-        LOG.info("server shutting down");
-        final ServletContext servletContext = ev.getServletContext();
-
-        try {
-            final IsisSystem system = (IsisSystem) servletContext.getAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
-            if (system != null) {
-                LOG.info("calling system shutdown");
-                system.shutdown();
-            }
-        } finally {
-            servletContext.removeAttribute(WebAppConstants.ISIS_SYSTEM_KEY);
-            LOG.info("server shut down");
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java b/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java
deleted file mode 100644
index 0cb07ce..0000000
--- a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/WebAppConstants.java
+++ /dev/null
@@ -1,85 +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.runtimes.dflt.webapp;
-
-import org.apache.isis.applib.fixtures.LogonFixture;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.config.IsisConfigurationBuilderPrimer;
-import org.apache.isis.runtimes.dflt.runtime.system.DeploymentType;
-import org.apache.isis.runtimes.dflt.runtime.system.IsisSystem;
-
-public final class WebAppConstants {
-
-    /**
-     * Name of context-param (<tt>ServletContext#getInitParameter(String)</tt>)
-     * to specify the deployment type.
-     */
-    public static final String DEPLOYMENT_TYPE_KEY = "deploymentType";
-    /**
-     * Deployment type to use if there is none {@link DEPLOYMENT_TYPE_KEY
-     * specified}.
-     */
-    public static final String DEPLOYMENT_TYPE_DEFAULT = DeploymentType.SERVER.name();
-
-    /**
-     * Key under which the list of {@link IsisConfigurationBuilderPrimer}s is
-     * bound as a servlet context attribute (
-     * <tt>ServletContext#getAttribute(String)</tt>); used to pass from the
-     * <tt>webserver</tt> module to this.
-     */
-    public static final String CONFIGURATION_PRIMERS_KEY = "isis.configurationPrimers";
-
-    /**
-     * Key under which the {@link IsisSystem} is bound as a servlet context
-     * attribute ( <tt>ServletContext#getAttribute(String)</tt>).
-     */
-    public final static String ISIS_SYSTEM_KEY = WebAppConstants.class.getPackage().getName() + ".isisSystem";
-
-    /**
-     * Key under which the {@link AuthenticationSession} is bound as a session
-     * attribute ( <tt>HttpSession#getAttribute(String)</tt>).
-     */
-    public final static String HTTP_SESSION_AUTHENTICATION_SESSION_KEY = WebAppConstants.class.getPackage().getName() + ".authenticationSession";
-
-    /**
-     * Key used to determine if a logon has already been performed implicitly
-     * using the {@link LogonFixture}, meaning that a Logout should be followed
-     * by the Logon page.
-     */
-    public final static String HTTP_SESSION_LOGGED_ON_PREVIOUSLY_USING_LOGON_FIXTURE_KEY = WebAppConstants.class.getPackage().getName() + ".loggedOnPreviouslyUsingLogonFixture";
-
-    /**
-     * Property name given to the web app directory.
-     */
-    public static final String WEB_APP_DIR = "application.webapp.dir";
-
-    /**
-     * Servlet context parameter name used to specify the location for property file 
-     * overloads. Property files in this location take precendence over property files 
-     * in other locations. Since the ResourceStreamSourceComposite is being used
-     * property files from various locations are merged together. So only overloaded
-     * properties (entries in the file) need to present.
-     */
-    public static final String CONFIG_DIR_PARAM = "isis.config.dir";
-
-    private WebAppConstants() {
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java b/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java
deleted file mode 100644
index 9719c92..0000000
--- a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategy.java
+++ /dev/null
@@ -1,43 +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.runtimes.dflt.webapp.auth;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.runtime.authentication.AuthenticationManager;
-import org.apache.isis.runtimes.dflt.webapp.IsisSessionFilter;
-
-/**
- * Decouples the {@link IsisSessionFilter} from the mechanism of obtaining the
- * {@link AuthenticationSession}.
- */
-public interface AuthenticationSessionStrategy {
-
-    /**
-     * Returns a
-     * {@link AuthenticationManager#isSessionValid(AuthenticationSession)
-     * still-valid} {@link AuthenticationSession}.
-     */
-    AuthenticationSession lookupValid(ServletRequest servletRequest, ServletResponse servletResponse);
-
-    void bind(ServletRequest servletRequest, ServletResponse servletResponse, AuthenticationSession authSession);
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6de87443/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java
----------------------------------------------------------------------
diff --git a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java b/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java
deleted file mode 100644
index 4d68958..0000000
--- a/framework/runtimes/dflt/webapp/src/main/java/org/apache/isis/runtimes/dflt/webapp/auth/AuthenticationSessionStrategyAbstract.java
+++ /dev/null
@@ -1,46 +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.runtimes.dflt.webapp.auth;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-
-public abstract class AuthenticationSessionStrategyAbstract implements AuthenticationSessionStrategy {
-
-    protected HttpSession getHttpSession(final ServletRequest servletRequest) {
-        final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
-        return httpServletRequest.getSession();
-    }
-
-    protected ServletContext getServletContext(final ServletRequest servletRequest) {
-        final HttpSession httpSession = getHttpSession(servletRequest);
-        return httpSession.getServletContext();
-    }
-
-    @Override
-    public void bind(final ServletRequest servletRequest, final ServletResponse servletResponse, final AuthenticationSession authSession) {
-        // no-op
-    }
-
-}