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 2015/09/03 14:32:40 UTC

[49/87] [abbrv] [partial] isis git commit: ISIS-1194: moving the wicket submodules to be direct children of core; removing the isis-viewer-wicket parent pom.

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
new file mode 100644
index 0000000..098efde
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
@@ -0,0 +1,274 @@
+/*
+ *  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.integration.wicket;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.IPageFactory;
+import org.apache.wicket.Page;
+import org.apache.wicket.RestartResponseException;
+import org.apache.wicket.Session;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
+import org.apache.wicket.core.request.handler.PageProvider;
+import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
+import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.protocol.http.PageExpiredException;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.component.IRequestablePage;
+import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.session.IsisSession;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.errors.ExceptionModel;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.ui.pages.error.ErrorPage;
+import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage;
+import org.apache.isis.viewer.wicket.ui.pages.mmverror.MmvErrorPage;
+import org.apache.isis.viewer.wicket.viewer.IsisWicketApplication;
+
+/**
+ * Isis-specific implementation of the Wicket's {@link RequestCycle},
+ * automatically opening a {@link IsisSession} at the beginning of the request
+ * and committing the transaction and closing the session at the end.
+ */
+public class WebRequestCycleForIsis extends AbstractRequestCycleListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(WebRequestCycleForIsis.class);
+
+    private PageClassRegistry pageClassRegistry;
+
+    @Override
+    public synchronized void onBeginRequest(RequestCycle requestCycle) {
+        
+        if (!Session.exists()) {
+            return;
+        }
+        final AuthenticatedWebSessionForIsis wicketSession = AuthenticatedWebSessionForIsis.get();
+        final AuthenticationSession authenticationSession = wicketSession.getAuthenticationSession();
+        if (authenticationSession == null) {
+            return;
+        }
+
+        getIsisContext().openSessionInstance(authenticationSession);
+        getTransactionManager().startTransaction();
+    }
+
+    
+    /**
+     * Is called prior to {@link #onEndRequest(RequestCycle)}, and offers the opportunity to
+     * throw an exception.
+     */
+    @Override
+    public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("onRequestHandlerExecuted: handler: " + handler);
+        }
+        
+        final IsisSession session = getIsisContext().getSessionInstance();
+        if (session != null) {
+            try {
+                // will commit (or abort) the transaction;
+                // an abort will cause the exception to be thrown.
+                getTransactionManager().endTransaction();
+            } catch(Exception ex) {
+                // will redirect to error page after this, 
+                // so make sure there is a new transaction ready to go.
+                if(getTransactionManager().getTransaction().getState().isComplete()) {
+                    getTransactionManager().startTransaction();
+                }
+                if(handler instanceof RenderPageRequestHandler) {
+                    RenderPageRequestHandler requestHandler = (RenderPageRequestHandler) handler;
+                    if(requestHandler.getPage() instanceof ErrorPage) {
+                        // do nothing
+                        return;
+                    }
+                }
+                
+                // shouldn't return null given that we're in a session ...
+                PageProvider errorPageProvider = errorPageProviderFor(ex);
+                throw new RestartResponseException(errorPageProvider, RedirectPolicy.ALWAYS_REDIRECT);
+            }
+        }
+    }
+
+    /**
+     * It is not possible to throw exceptions here, hence use of {@link #onRequestHandlerExecuted(RequestCycle, IRequestHandler)}.
+     */
+    @Override
+    public synchronized void onEndRequest(RequestCycle cycle) {
+        final IsisSession session = getIsisContext().getSessionInstance();
+        if (session != null) {
+            try {
+                // belt and braces
+                getTransactionManager().endTransaction();
+            } finally {
+                getIsisContext().closeSessionInstance();
+            }
+        }
+    }
+
+
+    @Override
+    public IRequestHandler onException(RequestCycle cycle, Exception ex) {
+        PageProvider errorPageProvider = errorPageProviderFor(ex);
+        // avoid infinite redirect loops
+        RedirectPolicy redirectPolicy = ex instanceof PageExpiredException? RedirectPolicy.NEVER_REDIRECT: RedirectPolicy.ALWAYS_REDIRECT;
+        return errorPageProvider != null 
+                ? new RenderPageRequestHandler(errorPageProvider, redirectPolicy)
+                : null;
+    }
+
+    protected PageProvider errorPageProviderFor(Exception ex) {
+        IRequestablePage errorPage = errorPageFor(ex);
+        return errorPage != null? new PageProvider(errorPage): null;
+    }
+
+    // special case handling for PageExpiredException, otherwise infinite loop
+    private final static ExceptionRecognizerForType pageExpiredExceptionRecognizer = 
+            new ExceptionRecognizerForType(PageExpiredException.class, new Function<String,String>(){
+                @Override
+                public String apply(String input) {
+                    return "Requested page is no longer available. Please navigate back to the home page or select an object from the bookmark bar.";
+                }
+            });
+
+    protected IRequestablePage errorPageFor(Exception ex) {
+        List<ExceptionRecognizer> exceptionRecognizers = Lists.newArrayList();
+        exceptionRecognizers.add(pageExpiredExceptionRecognizer);
+
+        if(inIsisSession()) {
+            exceptionRecognizers.addAll(getServicesInjector().lookupServices(ExceptionRecognizer.class));
+        } else {
+            List<String> validationErrors = IsisWicketApplication.get().getValidationErrors();
+            if(!validationErrors.isEmpty()) {
+                return new MmvErrorPage(Model.ofList(validationErrors));
+            }
+            // not sure whether this can ever happen now...
+            LOG.warn("Unable to obtain exceptionRecognizers (no session), will be treated as unrecognized exception");
+        }
+        String recognizedMessageIfAny = new ExceptionRecognizerComposite(exceptionRecognizers).recognize(ex);
+        ExceptionModel exceptionModel = ExceptionModel.create(recognizedMessageIfAny, ex);
+        
+        return isSignedIn() ? new ErrorPage(exceptionModel) : newSignInPage(exceptionModel);
+    }
+
+    /**
+     * Tries to instantiate the configured {@link PageType#SIGN_IN signin page} with the given exception model
+     *
+     * @param exceptionModel A model bringing the information about the occurred problem
+     * @return An instance of the configured signin page
+     */
+    private IRequestablePage newSignInPage(final ExceptionModel exceptionModel) {
+        Class<? extends Page> signInPageClass = null;
+        if (pageClassRegistry != null) {
+            signInPageClass = pageClassRegistry.getPageClass(PageType.SIGN_IN);
+        }
+        if (signInPageClass == null) {
+            signInPageClass = WicketSignInPage.class;
+        }
+        final PageParameters parameters = new PageParameters();
+        Page signInPage;
+        try {
+            Constructor<? extends Page> constructor = signInPageClass.getConstructor(PageParameters.class, ExceptionModel.class);
+            signInPage = constructor.newInstance(parameters, exceptionModel);
+        } catch (Exception _) {
+            try {
+                IPageFactory pageFactory = Application.get().getPageFactory();
+                signInPage = pageFactory.newPage(signInPageClass, parameters);
+            } catch (Exception x) {
+                throw new WicketRuntimeException("Cannot instantiate the configured sign in page", x);
+            }
+        }
+        return signInPage;
+    }
+
+    /**
+     * TODO: this is very hacky...
+     * 
+     * <p>
+     * Matters should improve once ISIS-299 gets implemented...
+     */
+    protected boolean isSignedIn() {
+        if(!inIsisSession()) {
+            return false;
+        }
+        if(getAuthenticationSession() == null) {
+            return false;
+        }
+        return getWicketAuthenticationSession().isSignedIn();
+    }
+
+
+    public void setPageClassRegistry(PageClassRegistry pageClassRegistry) {
+        this.pageClassRegistry = pageClassRegistry;
+    }
+    
+    ///////////////////////////////////////////////////////////////
+    // Dependencies (from isis' context)
+    ///////////////////////////////////////////////////////////////
+    
+    protected ServicesInjector getServicesInjector() {
+        return IsisContext.getPersistenceSession().getServicesInjector();
+    }
+    
+    protected IsisContext getIsisContext() {
+        return IsisContext.getInstance();
+    }
+
+    protected IsisTransactionManager getTransactionManager() {
+        return IsisContext.getTransactionManager();
+    }
+
+    protected boolean inIsisSession() {
+        return IsisContext.inSession();
+    }
+
+    protected AuthenticationSession getAuthenticationSession() {
+        return IsisContext.getAuthenticationSession();
+    }
+
+    ///////////////////////////////////////////////////////////////
+    // Dependencies (from wicket)
+    ///////////////////////////////////////////////////////////////
+
+    
+    protected AuthenticatedWebSession getWicketAuthenticationSession() {
+        return AuthenticatedWebSession.get();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
new file mode 100644
index 0000000..479b474
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -0,0 +1,267 @@
+/*
+ *  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.registries.components;
+
+import java.util.ServiceLoader;
+import com.google.inject.Singleton;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar;
+import org.apache.isis.viewer.wicket.ui.components.about.AboutPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actionlink.ActionLinkPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions.TertiaryMenuPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actions.ActionInfoPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actions.ActionParametersFormPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions.ServiceActionsPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.bookmarkedpages.BookmarkedPagesPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.multiple.CollectionContentsMultipleViewsPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.summary.CollectionContentsAsSummaryFactory;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.empty.EmptyCollectionPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.collections.EntityCollectionsPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.combined.EntityCombinedPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.header.EntityHeaderPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconAndTitlePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconTitleAndCopyLinkPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.properties.EntityPropertiesPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.selector.links.EntityLinksSelectorPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.footer.FooterPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.header.HeaderPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.*;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlDatePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimestampPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaUtilDatePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdkmath.JavaMathBigDecimalPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdkmath.JavaMathBigIntegerPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jodatime.JodaDateTimePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jodatime.JodaLocalDatePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jodatime.JodaLocalDateTimePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.primitive.*;
+import org.apache.isis.viewer.wicket.ui.components.scalars.reference.ReferencePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.string.StringPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.value.ValuePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.standalonecollection.StandaloneCollectionPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.unknown.UnknownModelPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.value.StandaloneValuePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.voidreturn.VoidReturnPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.welcome.WelcomePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.widgets.entitysimplelink.EntityLinkSimplePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.widgets.valuechoices.ValueChoicesSelect2PanelFactory;
+
+/**
+ * Default implementation of {@link ComponentFactoryRegistrar} that registers a
+ * hardcoded set of built-in {@link ComponentFactory}s, along with any
+ * implementations loaded using {@link ServiceLoader} (ie from
+ * <tt>META-INF/services</tt>).
+ */
+@Singleton
+public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistrar {
+
+    @Override
+    public void addComponentFactories(final ComponentFactoryList componentFactories) {
+
+        addComponentFactoriesActingAsSelectors(componentFactories);
+        
+        addComponentFactoriesUsingServiceLoader(componentFactories);
+
+        addBuiltInComponentFactories(componentFactories);
+    }
+
+    /**
+     * Any {@link ComponentFactory}s that act as selectors of other factories
+     * should be registered here; they will be loaded first, to ensure that they
+     * are found first.
+     */
+    protected void addComponentFactoriesActingAsSelectors(final ComponentFactoryList componentFactories) {
+        addLinksSelectorFactories(componentFactories);
+        componentFactories.add(new CollectionContentsAsUnresolvedPanelFactory()); // to prevent eager loading
+    }
+
+    protected void addLinksSelectorFactories(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new EntityLinksSelectorPanelFactory());
+        componentFactories.add(new CollectionContentsMultipleViewsPanelFactory());
+    }
+
+    protected void addComponentFactoriesUsingServiceLoader(final ComponentFactoryList componentFactories) {
+        final ServiceLoader<ComponentFactory> serviceLoader = ServiceLoader.load(ComponentFactory.class);
+
+        for (final ComponentFactory componentFactory : serviceLoader) {
+            componentFactories.add(componentFactory);
+        }
+    }
+
+    private void addBuiltInComponentFactories(final ComponentFactoryList componentFactories) {
+        addComponentFactoriesForWelcomeAndAbout(componentFactories);
+        addComponentFactoriesForApplicationActions(componentFactories);
+        addComponentFactoriesForEntity(componentFactories);
+        addComponentFactoriesForActionInfo(componentFactories);
+        addComponentFactoriesForAction(componentFactories);
+        addComponentFactoriesForActionLink(componentFactories);
+        addComponentFactoriesForEntityCollection(componentFactories);
+        addComponentFactoriesForEntityCollectionContents(componentFactories);
+        addComponentFactoriesForEmptyCollection(componentFactories);
+        addComponentFactoriesForScalar(componentFactories);
+        addComponentFactoriesForEntityLink(componentFactories);
+        addComponentFactoriesForVoidReturn(componentFactories);
+        addComponentFactoriesForValue(componentFactories);
+        addComponentFactoriesForParameters(componentFactories);
+        addComponentFactoriesForBreadcrumbs(componentFactories);
+        addComponentFactoriesForPageHeader(componentFactories);
+        addComponentFactoriesForPageFooter(componentFactories);
+        
+        addComponentFactoriesForUnknown(componentFactories);
+    }
+
+    protected void addComponentFactoriesForPageHeader(ComponentFactoryList componentFactories) {
+        componentFactories.add(new HeaderPanelFactory());
+    }
+
+    protected void addComponentFactoriesForPageFooter(ComponentFactoryList componentFactories) {
+        componentFactories.add(new FooterPanelFactory());
+    }
+
+    protected void addComponentFactoriesForWelcomeAndAbout(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new WelcomePanelFactory());
+        componentFactories.add(new AboutPanelFactory());
+    }
+
+    protected void addComponentFactoriesForEntity(final ComponentFactoryList componentFactories) {
+
+        // top-level
+        componentFactories.add(new EntityCombinedPanelFactory());
+        
+        // lower-level
+        componentFactories.add(new EntityIconAndTitlePanelFactory());
+        componentFactories.add(new EntityIconTitleAndCopyLinkPanelFactory());
+        componentFactories.add(new EntityHeaderPanelFactory());
+        componentFactories.add(new EntityPropertiesPanelFactory());
+        componentFactories.add(new EntityCollectionsPanelFactory());
+    }
+
+    protected void addComponentFactoriesForEntityCollectionContents(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new CollectionContentsAsAjaxTablePanelFactory());
+        
+        // // work-in-progress
+        // componentFactories.add(new CollectionContentsAsIconsPanelFactory());
+        
+        componentFactories.add(new CollectionContentsAsSummaryFactory());
+    }
+
+    protected void addComponentFactoriesForEntityCollection(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new CollectionPanelFactory());
+    }
+
+    protected void addComponentFactoriesForEmptyCollection(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new EmptyCollectionPanelFactory());
+    }
+
+    protected void addComponentFactoriesForValue(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new StandaloneValuePanelFactory());
+    }
+
+    protected void addComponentFactoriesForScalar(final ComponentFactoryList componentFactories) {
+
+        componentFactories.add(new ReferencePanelFactory());
+
+        componentFactories.add(new BooleanPanelFactory());
+        componentFactories.add(new BytePanelFactory());
+        componentFactories.add(new ShortPanelFactory());
+        componentFactories.add(new IntegerPanelFactory());
+        componentFactories.add(new LongPanelFactory());
+        componentFactories.add(new CharacterPanelFactory());
+        componentFactories.add(new FloatPanelFactory());
+        componentFactories.add(new DoublePanelFactory());
+
+        componentFactories.add(new StringPanelFactory());
+
+        // work-in-progress
+        // componentFactories.add(new JavaAwtImagePanelFactory()); 
+        componentFactories.add(new JavaUtilDatePanelFactory());
+        componentFactories.add(new JavaSqlTimestampPanelFactory());
+        componentFactories.add(new JavaSqlDatePanelFactory());
+        componentFactories.add(new JavaSqlTimePanelFactory());
+
+        componentFactories.add(new IsisMoneyPanelFactory());
+        componentFactories.add(new IsisDatePanelFactory());
+        componentFactories.add(new IsisDateTimePanelFactory());
+        componentFactories.add(new IsisTimePanelFactory());
+        componentFactories.add(new IsisTimeStampPanelFactory());
+        componentFactories.add(new IsisColorPanelFactory());
+        componentFactories.add(new IsisPercentagePanelFactory());
+        componentFactories.add(new IsisPasswordPanelFactory());
+
+        componentFactories.add(new IsisBlobPanelFactory()); 
+        componentFactories.add(new IsisClobPanelFactory()); 
+        
+        componentFactories.add(new JavaMathBigIntegerPanelFactory());
+        componentFactories.add(new JavaMathBigDecimalPanelFactory());
+
+        componentFactories.add(new JodaLocalDatePanelFactory());
+        componentFactories.add(new JodaLocalDateTimePanelFactory());
+        componentFactories.add(new JodaDateTimePanelFactory());
+
+        componentFactories.add(new ValuePanelFactory());
+
+        // or for choices
+        componentFactories.add(new ValueChoicesSelect2PanelFactory());
+    }
+
+    protected void addComponentFactoriesForEntityLink(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new EntityLinkSimplePanelFactory());
+    }
+
+    protected void addComponentFactoriesForVoidReturn(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new VoidReturnPanelFactory());
+    }
+
+    protected void addComponentFactoriesForActionInfo(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new ActionInfoPanelFactory());
+    }
+
+    protected void addComponentFactoriesForParameters(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new ActionParametersFormPanelFactory());
+    }
+
+    protected void addComponentFactoriesForAction(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new ActionPanelFactory());
+        componentFactories.add(new StandaloneCollectionPanelFactory());
+    }
+
+    protected void addComponentFactoriesForActionLink(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new ActionLinkPanelFactory());
+    }
+
+    protected void addComponentFactoriesForApplicationActions(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new ServiceActionsPanelFactory());
+        componentFactories.add(new TertiaryMenuPanelFactory());
+    }
+
+    protected void addComponentFactoriesForBreadcrumbs(ComponentFactoryList componentFactories) {
+        componentFactories.add(new BookmarkedPagesPanelFactory());
+    }
+
+    protected void addComponentFactoriesForUnknown(final ComponentFactoryList componentFactories) {
+        componentFactories.add(new UnknownModelPanelFactory());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java
new file mode 100644
index 0000000..00f7a4d
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java
@@ -0,0 +1,177 @@
+/*
+ *  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.registries.components;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.inject.Singleton;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory.ApplicationAdvice;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar.ComponentFactoryList;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
+
+/**
+ * Implementation of {@link ComponentFactoryRegistry} that delegates to a
+ * provided {@link ComponentFactoryRegistrar}.
+ */
+@Singleton
+public class ComponentFactoryRegistryDefault implements ComponentFactoryRegistry {
+
+    private final Multimap<ComponentType, ComponentFactory> componentFactoriesByType;
+
+    @Inject
+    public ComponentFactoryRegistryDefault(final ComponentFactoryRegistrar componentFactoryList) {
+        componentFactoriesByType = Multimaps.newListMultimap(new HashMap<ComponentType, Collection<ComponentFactory>>(), new Supplier<List<ComponentFactory>>() {
+            @Override
+            public List<ComponentFactory> get() {
+                return Lists.newArrayList();
+            }
+        });
+
+        registerComponentFactories(componentFactoryList);
+    }
+
+    // ///////////////////////////////////////////////////////
+    // Registration
+    // ///////////////////////////////////////////////////////
+
+    /**
+     * Registers the provided set of component factories.
+     */
+    protected void registerComponentFactories(final ComponentFactoryRegistrar componentFactoryRegistrar) {
+        
+        final ComponentFactoryList componentFactories = new ComponentFactoryList();
+        componentFactoryRegistrar.addComponentFactories(componentFactories);
+
+        for (final ComponentFactory componentFactory : componentFactories) {
+            registerComponentFactory(componentFactory);
+        }
+
+        ensureAllComponentTypesRegistered();
+    }
+
+    protected synchronized void registerComponentFactory(final ComponentFactory componentFactory) {
+        componentFactoriesByType.put(componentFactory.getComponentType(), componentFactory);
+    }
+
+    private void ensureAllComponentTypesRegistered() {
+        for (final ComponentType componentType : ComponentType.values()) {
+            final Collection<ComponentFactory> componentFactories = componentFactoriesByType.get(componentType);
+            if (componentFactories.isEmpty()) {
+                throw new IllegalStateException("No component factories registered for " + componentType);
+            }
+        }
+    }
+
+    // ///////////////////////////////////////////////////////
+    // Public API
+    // ///////////////////////////////////////////////////////
+
+    
+    @Override
+    public Component addOrReplaceComponent(final MarkupContainer markupContainer, final ComponentType componentType, final IModel<?> model) {
+        final Component component = createComponent(componentType, model);
+        markupContainer.addOrReplace(component);
+        return component;
+    }
+
+    @Override
+    public Component addOrReplaceComponent(final MarkupContainer markupContainer, final String id, final ComponentType componentType, final IModel<?> model) {
+        final Component component = createComponent(componentType, id, model);
+        markupContainer.addOrReplace(component);
+        return component;
+    }
+
+    @Override
+    public Component createComponent(final ComponentType componentType, final IModel<?> model) {
+        final ComponentFactory componentFactory = findComponentFactoryElseFailFast(componentType, model);
+        final Component component = componentFactory.createComponent(model);
+        return component;
+    }
+
+    @Override
+    public Component createComponent(final ComponentType componentType, final String id, final IModel<?> model) {
+        final ComponentFactory componentFactory = findComponentFactoryElseFailFast(componentType, model);
+        final Component component = componentFactory.createComponent(id, model);
+        return component;
+    }
+
+    @Override
+    public List<ComponentFactory> findComponentFactories(final ComponentType componentType, final IModel<?> model) {
+        final Collection<ComponentFactory> componentFactoryList = componentFactoriesByType.get(componentType);
+        final List<ComponentFactory> matching = Lists.newArrayList();
+        for (final ComponentFactory componentFactory : componentFactoryList) {
+            final ApplicationAdvice appliesTo = componentFactory.appliesTo(componentType, model);
+            if (appliesTo.applies()) {
+                matching.add(componentFactory);
+            }
+            if (appliesTo.exclusively()) {
+                break;
+            }
+        }
+        if (matching.isEmpty()) {
+            // will just be one
+            matching.addAll(componentFactoriesByType.get(ComponentType.UNKNOWN));
+        }
+        return matching;
+    }
+
+    @Override
+    public ComponentFactory findComponentFactory(final ComponentType componentType, final IModel<?> model) {
+        final Collection<ComponentFactory> componentFactories = findComponentFactories(componentType, model);
+        return firstOrNull(componentFactories);
+    }
+
+    @Override
+    public ComponentFactory findComponentFactoryElseFailFast(final ComponentType componentType, final IModel<?> model) {
+        final ComponentFactory componentFactory = findComponentFactory(componentType, model);
+        if (componentFactory == null) {
+            throw new RuntimeException(String.format("could not find component for componentType = '%s'; model object is of type %s", componentType, model.getClass().getName()));
+        }
+        return componentFactory;
+    }
+
+    private static <T> T firstOrNull(final Collection<T> collection) {
+        final Iterator<T> iterator = collection.iterator();
+        return iterator.hasNext() ? iterator.next() : null;
+    }
+
+    @Override
+    public Collection<ComponentFactory> listComponentFactories() {
+        return componentFactoriesByType.values();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
new file mode 100644
index 0000000..5d15946
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
@@ -0,0 +1,141 @@
+/*
+ *  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.registries.pages;
+
+import com.google.inject.Singleton;
+
+import org.apache.wicket.Page;
+
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassList;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistrySpi;
+import org.apache.isis.viewer.wicket.ui.pages.about.AboutPage;
+import org.apache.isis.viewer.wicket.ui.pages.actionprompt.ActionPromptPage;
+import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
+import org.apache.isis.viewer.wicket.ui.pages.home.HomePage;
+import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage;
+import org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage;
+import org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage;
+import org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage;
+import org.apache.isis.viewer.wicket.ui.pages.standalonecollection.StandaloneCollectionPage;
+import org.apache.isis.viewer.wicket.ui.pages.value.ValuePage;
+import org.apache.isis.viewer.wicket.ui.pages.voidreturn.VoidReturnPage;
+
+/**
+ * Default implementation of {@link PageClassList}, specifying the default pages
+ * for each of the {@link PageType}s.
+ */
+@Singleton
+public class PageClassListDefault implements PageClassList {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public void registerPages(final PageClassRegistrySpi pageRegistry) {
+        pageRegistry.registerPage(PageType.SIGN_IN, getSignInPageClass());
+        pageRegistry.registerPage(PageType.SIGN_UP, getSignUpPageClass());
+        pageRegistry.registerPage(PageType.SIGN_UP_VERIFY, getSignUpVerifyPageClass());
+        pageRegistry.registerPage(PageType.PASSWORD_RESET, getPasswordResetPageClass());
+        pageRegistry.registerPage(PageType.ABOUT, getAboutPageClass());
+        pageRegistry.registerPage(PageType.ENTITY, getEntityPageClass());
+        pageRegistry.registerPage(PageType.HOME, getHomePageClass());
+        pageRegistry.registerPage(PageType.ACTION_PROMPT, getActionPromptPageClass());
+        pageRegistry.registerPage(PageType.STANDALONE_COLLECTION, getStandaloneCollectionPageClass());
+        pageRegistry.registerPage(PageType.VALUE, getValuePageClass());
+        pageRegistry.registerPage(PageType.VOID_RETURN, getVoidReturnPageClass());
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getActionPromptPageClass() {
+        return ActionPromptPage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getEntityPageClass() {
+        return EntityPage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getStandaloneCollectionPageClass() {
+        return StandaloneCollectionPage.class;
+    }
+    
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getValuePageClass() {
+        return ValuePage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getVoidReturnPageClass() {
+        return VoidReturnPage.class;
+    }
+    
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getSignInPageClass() {
+        return WicketSignInPage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getSignUpPageClass() {
+        return RegistrationFormPage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getSignUpVerifyPageClass() {
+        return RegisterPage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getPasswordResetPageClass() {
+        return PasswordResetPage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getHomePageClass() {
+        return HomePage.class;
+    }
+
+    /**
+     * For subclassing if required.
+     */
+    protected Class<? extends Page> getAboutPageClass() {
+        return AboutPage.class;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java
new file mode 100644
index 0000000..56550c7
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.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.viewer.wicket.viewer.registries.pages;
+
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import org.apache.wicket.Page;
+
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassList;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistrySpi;
+
+/**
+ * Default implementation of {@link PageClassRegistry}; just delegates to an
+ * underlying {@link PageClassList}.
+ */
+@Singleton
+public class PageClassRegistryDefault implements PageClassRegistry, PageClassRegistrySpi {
+
+    private static final long serialVersionUID = 1L;
+
+    private final Map<PageType, Class<? extends Page>> pagesByType = Maps.newHashMap();
+
+    /**
+     * {@link Inject}ed in {@link #PageClassRegistryDefault(PageClassList)
+     * constructor}.
+     */
+    @SuppressWarnings("unused")
+    private final PageClassList pageClassList;
+
+    @Inject
+    public PageClassRegistryDefault(final PageClassList pageClassList) {
+        this.pageClassList = pageClassList;
+        pageClassList.registerPages(this);
+        ensureAllPageTypesRegistered();
+    }
+
+    private void ensureAllPageTypesRegistered() {
+        for (final PageType pageType : PageType.values()) {
+            if (getPageClass(pageType) == null) {
+                throw new IllegalStateException("No page registered for " + pageType);
+            }
+        }
+    }
+
+    // /////////////////////////////////////////////////////////
+    // API
+    // /////////////////////////////////////////////////////////
+
+    @Override
+    public final Class<? extends Page> getPageClass(final PageType pageType) {
+        return pagesByType.get(pageType);
+    }
+
+    // /////////////////////////////////////////////////////////
+    // API
+    // /////////////////////////////////////////////////////////
+
+    @Override
+    public final void registerPage(final PageType pageType, final Class<? extends Page> pageClass) {
+        pagesByType.put(pageType, pageClass);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java
new file mode 100644
index 0000000..ab45158
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java
@@ -0,0 +1,70 @@
+/*
+ *  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.registries.pages;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.wicket.Page;
+import org.apache.wicket.RestartResponseAtInterceptPageException;
+import org.apache.wicket.RestartResponseException;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.ui.pages.PageNavigationService;
+
+/**
+ * Default implementation of {@link org.apache.isis.viewer.wicket.ui.pages.PageNavigationService}
+ */
+@Singleton
+public class PageNavigationServiceDefault implements PageNavigationService {
+
+    private static final long serialVersionUID = 1L;
+
+    private final PageClassRegistry pageClassRegistry;
+
+    @Inject
+    public PageNavigationServiceDefault(final PageClassRegistry pageClassRegistry) {
+        this.pageClassRegistry = pageClassRegistry;
+    }
+
+    @Override
+    public void navigateTo(PageType pageType) {
+        navigateTo(pageType, new PageParameters());
+    }
+
+    @Override
+    public void navigateTo(PageType pageType, PageParameters parameters) {
+        Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType);
+        RequestCycle.get().setResponsePage(pageClass, parameters);
+    }
+
+    @Override
+    public void restartAt(PageType pageType) {
+        Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType);
+        throw new RestartResponseException(pageClass);
+    }
+
+    @Override
+    public void interceptAndRestartAt(PageType pageType) {
+        Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType);
+        throw new RestartResponseAtInterceptPageException(pageClass);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java
new file mode 100644
index 0000000..a665979
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java
@@ -0,0 +1,82 @@
+/*
+ *  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.services;
+
+import javax.inject.Inject;
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.apache.wicket.Page;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.guice.GuiceBeanProvider;
+import org.apache.isis.applib.services.linking.DeepLinkService;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.adaptermanager.AdapterManagerDefault;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault;
+
+/**
+ * An implementation of {@link org.apache.isis.applib.services.linking.DeepLinkService}
+ * for Wicket Viewer
+ */
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class DeepLinkServiceWicket implements DeepLinkService {
+
+    @Programmatic
+    @Override
+    public URI deepLinkFor(final Object domainObject) {
+
+        final AdapterManagerDefault adapterManager = getAdapterManager();
+        final ObjectAdapter objectAdapter = adapterManager.adapterFor(domainObject);
+        final PageParameters pageParameters = EntityModel.createPageParameters(objectAdapter);
+
+        PageClassRegistry pageClassRegistry = guiceBeanProvider.lookup(PageClassRegistry.class);
+        final Class<? extends Page> pageClass = pageClassRegistry.getPageClass(PageType.ENTITY);
+
+        final RequestCycle requestCycle = RequestCycle.get();
+        final CharSequence urlForPojo = requestCycle.urlFor(pageClass, pageParameters);
+        final String fullUrl = requestCycle.getUrlRenderer().renderFullUrl(Url.parse(urlForPojo));
+        try {
+            return new URI(fullUrl);
+        } catch (final URISyntaxException ex) {
+            throw new RuntimeException("Cannot create a deep link to domain object: " + domainObject, ex);
+        }
+    }
+
+    protected AdapterManagerDefault getAdapterManager() {
+        return getPersistenceSession().getAdapterManager();
+    }
+
+    protected PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+    @Inject
+    private GuiceBeanProvider guiceBeanProvider;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/GuiceBeanProviderWicket.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/GuiceBeanProviderWicket.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/GuiceBeanProviderWicket.java
new file mode 100644
index 0000000..f963ce8
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/GuiceBeanProviderWicket.java
@@ -0,0 +1,55 @@
+/**
+ *  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.services;
+
+import java.lang.annotation.Annotation;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import org.apache.wicket.Application;
+import org.apache.wicket.guice.GuiceInjectorHolder;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.guice.GuiceBeanProvider;
+
+/**
+ * An implementation of {@link org.apache.isis.applib.services.guice.GuiceBeanProvider}
+ * that uses the Injector configured for Wicket
+ */
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class GuiceBeanProviderWicket implements GuiceBeanProvider {
+
+    @Programmatic
+    @Override
+    public <T> T lookup(final Class<T> beanType) {
+        final Application application = Application.get();
+        final GuiceInjectorHolder injectorHolder = application.getMetaData(GuiceInjectorHolder.INJECTOR_KEY);
+        final Injector injector = injectorHolder.getInjector();
+        return injector.getInstance(beanType);
+    }
+
+    @Programmatic
+    @Override
+    public <T> T lookup(final Class<T> beanType, final Annotation qualifier) {
+        final Application application = Application.get();
+        final GuiceInjectorHolder injectorHolder = application.getMetaData(GuiceInjectorHolder.INJECTOR_KEY);
+        final Injector injector = injectorHolder.getInjector();
+        return injector.getInstance(Key.get(beanType, qualifier));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java
new file mode 100644
index 0000000..997a4ee
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java
@@ -0,0 +1,59 @@
+/*
+ *  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.services;
+
+import java.util.Locale;
+import org.apache.wicket.Application;
+import org.apache.wicket.Session;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.i18n.LocaleProvider;
+
+
+/**
+ * An implementation that provides the locale of the current session.
+ */
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class LocaleProviderWicket implements LocaleProvider {
+
+    public static final Logger LOG = LoggerFactory.getLogger(LocaleProviderWicket.class);
+
+    @Programmatic
+    @Override
+    public Locale getLocale() {
+        // Request Cycle can be null, e.g. during the start of an application
+        RequestCycle requestCycle = RequestCycle.get();
+
+        if (!Application.exists() || requestCycle == null) {
+            // eg if request from RO viewer
+            return null;
+        }
+        return RequestCycle.get().getRequest().getLocale();
+    }
+
+    protected Session getSession() {
+        return Session.get();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java
new file mode 100644
index 0000000..0cf5e5a
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java
@@ -0,0 +1,108 @@
+/*
+ *  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.services;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Pattern;
+import javax.servlet.ServletContext;
+import com.google.common.base.Charsets;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.io.CharSource;
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.i18n.TranslationsResolver;
+import org.apache.isis.core.webapp.WebAppConstants;
+import org.apache.isis.viewer.wicket.viewer.IsisWicketApplication;
+
+
+/**
+ * An implementation that reads from /WEB-INF/...
+ */
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class TranslationsResolverWicket implements TranslationsResolver {
+
+    public static Logger LOG = LoggerFactory.getLogger(TranslationsResolverWicket.class);
+
+    @Override
+    @Programmatic
+    public List<String> readLines(final String file) {
+        final ServletContext servletContext = getServletContext();
+
+        final String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM);
+        try {
+            if(configLocation != null) {
+                LOG.info( "Reading translations relative to config override location: " + configLocation );
+                return Files.readLines(newFile(configLocation, file), Charsets.UTF_8);
+            } else {
+                final URL url = servletContext.getResource("/WEB-INF/" + file);
+                return readLines(url);
+            }
+        } catch (final RuntimeException | IOException ignored) {
+            return null;
+        }
+    }
+
+    static File newFile(final String dir, final String file) {
+        final File base = new File(dir);
+        final Path path = base.toPath();
+        final Path resolve = path.resolve(file);
+        return resolve.toFile();
+    }
+
+    protected ServletContext getServletContext() {
+        return getIsisWicketApplication().getServletContext();
+    }
+
+    private static final Pattern nonEmpty = Pattern.compile("^(#:|msgid|msgstr).+$");
+    private static List<String> readLines(final URL url) throws IOException {
+        if(url == null) {
+            return null;
+        }
+        final CharSource charSource = Resources.asCharSource(url, Charsets.UTF_8);
+        final ImmutableList<String> strings = charSource.readLines();
+        return Collections.unmodifiableList(
+                Lists.newArrayList(
+                Iterables.filter(strings, new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String input) {
+                        return input != null && nonEmpty.matcher(input).matches();
+                    }
+                })));
+    }
+
+    protected IsisWicketApplication getIsisWicketApplication() {
+        return IsisWicketApplication.get();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java
new file mode 100644
index 0000000..ddb3da6
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java
@@ -0,0 +1,101 @@
+/*
+ *  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.settings;
+
+import java.util.List;
+import org.apache.wicket.Application;
+import org.apache.wicket.resource.loader.*;
+import org.apache.wicket.settings.def.ResourceSettings;
+import org.apache.wicket.util.lang.Generics;
+
+public class IsisResourceSettings extends ResourceSettings {
+
+    /** Chain of string resource loaders to use */
+    private final List<IStringResourceLoader> stringResourceLoaders = Generics.newArrayList(4);
+
+    /**
+     * Configures Wicket's default ResourceLoaders.
+     *
+     * <p>
+     * In contrast to the default lookup strategy, Isis' searches for application-specific properties first.
+     *
+     * </p>
+     * For an example in {@code FooApplication} let {@code bar.Foo} extend {@link org.apache.wicket.Component}, this
+     * results in the following ordering:
+     * <dl>
+     * <dt>application specific</dt>
+     * <dd>
+     * <ul>
+     * <li>FooApplication.properties</li>
+     * <li>Application.properties</li>
+     * </ul>
+     * </dd>
+     * <dt>component specific</dt>
+     * <dd>
+     * <ul>
+     * <li>bar/Foo.properties</li>
+     * <li>org/apache/wicket/Component.properties</li>
+     * </ul>
+     * </dd>
+     * <dt>package specific</dt>
+     * <dd>
+     * <ul>
+     * <li>bar/package.properties</li>
+     * <li>package.properties (on Foo's class loader)</li>
+     * <li>org/apache/wicket/package.properties</li>
+     * <li>org/apache/package.properties</li>
+     * <li>org/package.properties</li>
+     * <li>package.properties (on Component's class loader)</li>
+     * </ul>
+     * </dd>
+     * <dt>validator specific</dt>
+     * <dt>Initializer specific</dt>
+     * <dd>
+     * <ul>
+     * <li>bar.Foo.properties (Foo implementing IInitializer)</li>
+     * </ul>
+     * </dd>
+     * </dl>
+     *
+     * @param application
+     */
+    public IsisResourceSettings(Application application) {
+        super(application);
+
+        // consult first (the default implementation checks this only third)
+        stringResourceLoaders.add(new ClassStringResourceLoader(application.getClass()));
+
+        stringResourceLoaders.add(new ComponentStringResourceLoader());
+        stringResourceLoaders.add(new PackageStringResourceLoader());
+        // this is where the default implementation registered the search.
+        //stringResourceLoaders.add(new ClassStringResourceLoader(application.getClass()));
+        stringResourceLoaders.add(new ValidatorStringResourceLoader());
+        stringResourceLoaders.add(new InitializerStringResourceLoader(application.getInitializers()));
+    }
+
+    /**
+     * @see org.apache.wicket.settings.IResourceSettings#getStringResourceLoaders()
+     */
+    @Override
+    public List<IStringResourceLoader> getStringResourceLoaders()
+    {
+        return stringResourceLoaders;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java
new file mode 100644
index 0000000..5e01d0b
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java
@@ -0,0 +1,100 @@
+/*
+ *  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.settings;
+
+import com.google.inject.Singleton;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.datepicker.TextFieldWithDatePicker;
+
+@Singleton
+public class WicketViewerSettingsDefault implements WicketViewerSettings {
+
+    private static final long serialVersionUID = 1L;
+
+    IsisConfiguration getConfiguration() {
+        return IsisContext.getConfiguration();
+    }
+
+    /**
+     * The maximum length that a title of an object will be shown when rendered in a standalone table;
+     * will be truncated beyond this (with ellipses to indicate the truncation). 
+     */
+    @Override
+    public int getMaxTitleLengthInStandaloneTables() {
+        return getConfiguration().getInteger("isis.viewer.wicket.maxTitleLengthInStandaloneTables", getMaxTitleLengthInTables());
+    }
+
+    /**
+     * The maximum length that a title of an object will be shown when rendered in a parented table;
+     * will be truncated beyond this (with ellipses to indicate the truncation). 
+     */
+    @Override
+    public int getMaxTitleLengthInParentedTables() {
+        return getConfiguration().getInteger("isis.viewer.wicket.maxTitleLengthInParentedTables", getMaxTitleLengthInTables());
+    }
+
+    /**
+     * Fallback for either {@link #getMaxTitleLengthInParentedTables()} and {@link #getMaxTitleLengthInParentedTables()}
+     */
+    private int getMaxTitleLengthInTables() {
+        return getConfiguration().getInteger("isis.viewer.wicket.maxTitleLengthInTables", 12);
+    }
+
+    /**
+     * The pattern used for rendering and parsing dates.
+     */
+    @Override
+    public String getDatePattern() {
+        return getConfiguration().getString("isis.viewer.wicket.datePattern", "dd-MM-yyyy");
+    }
+
+    /**
+     * The pattern used for rendering and parsing date/times.
+     */
+    @Override
+    public String getDateTimePattern() {
+        return getConfiguration().getString("isis.viewer.wicket.dateTimePattern", "dd-MM-yyyy HH:mm");
+    }
+
+    /**
+     * The pattern used for rendering and parsing timestamps.
+     */
+    @Override
+    public String getTimestampPattern() {
+        return getConfiguration().getString("isis.viewer.wicket.timestampPattern", "yyyy-MM-dd HH:mm:ss.SSS");
+    }
+    
+    /**
+     * The pattern used for rendering dates chosen by the {@link TextFieldWithDatePicker}.
+     * 
+     * <p>
+     * This pattern is different from {@link #getDatePattern()} because it is interpreted by
+     * <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">Bootstrap Datetime Picker</a> component
+     * that uses <a href="http://momentjs.com/docs/#/parsing/string-format/">Moment.js formats</a>, rather
+     * than by Java code. 
+     */
+    @Override
+    public String getDatePickerPattern() {
+        return getConfiguration().getString("isis.viewer.wicket.datePickerPattern", "DD-MM-YYYY");
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/resources/log4j.properties b/core/viewer-wicket-impl/src/main/resources/log4j.properties
new file mode 100644
index 0000000..f275d06
--- /dev/null
+++ b/core/viewer-wicket-impl/src/main/resources/log4j.properties
@@ -0,0 +1,28 @@
+#  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.
+log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n
+
+log4j.rootLogger=INFO,Stdout
+
+log4j.logger.org.apache.wicket=INFO
+log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=INFO
+log4j.logger.org.apache.wicket.version=INFO
+log4j.logger.org.apache.wicket.RequestCycle=INFO
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java
new file mode 100644
index 0000000..904d74c
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java
@@ -0,0 +1,79 @@
+/*
+ *  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 static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.apache.wicket.IConverterLocator;
+import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis;
+
+public class IsisWicketApplication_Defaults {
+
+    @Rule
+    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    private IsisWicketApplication application;
+
+    @Before
+    public void setUp() throws Exception {
+        application = new IsisWicketApplication();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void usesCustomSubclassOfAuthenticatedWebSession() {
+        final Class<? extends AuthenticatedWebSession> webSessionClass = application.getWebSessionClass();
+        assertThat(webSessionClass.equals(AuthenticatedWebSessionForIsis.class), is(true));
+    }
+
+    @Ignore // 6.0.0 does it differently
+    @Test
+    public void providesCustomRequestCycle() {
+//        final WebRequest mockRequest = context.mock(WebRequest.class);
+//        final Response mockResponse = context.mock(Response.class);
+//        final RequestCycle newRequestCycle = application.newRequestCycle(mockRequest, mockResponse);
+//        assertThat(newRequestCycle, is(WebRequestCycleForIsis.class));
+    }
+
+    @Test
+    public void providesConverterLocatorRegistersIsisSpecificConverters() {
+        final IConverterLocator converterLocator = application.newConverterLocator();
+        assertThat(converterLocator.getConverter(ObjectAdapter.class), is(not(nullValue())));
+        assertThat(converterLocator.getConverter(ObjectAdapterMemento.class), is(not(nullValue())));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java
new file mode 100644
index 0000000..5e754b0
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java
@@ -0,0 +1,97 @@
+/*
+ *  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 static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.WebPage;
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.ui.pages.home.HomePage;
+
+public class IsisWicketApplication_Pages {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY);
+
+    @Mock
+    private PageClassRegistry mockPageClassRegistry;
+    
+    private IsisWicketApplication application;
+
+    @Test
+    public void delegatesToPageClassRegistryToObtainPageTypes() {
+        final PageType pageType = PageType.HOME;
+        final Class<HomePage> expectedPageClass = HomePage.class;
+        
+        application = new IsisWicketApplication() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public PageClassRegistry getPageClassRegistry() {
+                return mockPageClassRegistry;
+            }
+
+        };
+        context.checking(new Expectations() {
+            {
+                one(mockPageClassRegistry).getPageClass(pageType);
+                will(returnValue(expectedPageClass));
+            }
+        });
+        final Class<? extends Page> pageClass = application.getHomePage();
+        assertThat(expectedPageClass.isAssignableFrom(pageClass), is(true));
+    }
+
+    @Test
+    public void delegatesToPageClassRegistryToObtainPageTypes_ForSignIn() {
+
+        final PageType pageType = PageType.SIGN_IN;
+        final Class<WebPage> expectedPageClass = WebPage.class;
+
+        final PageClassRegistry mockPageClassRegistry = context.mock(PageClassRegistry.class);
+        application = new IsisWicketApplication() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public PageClassRegistry getPageClassRegistry() {
+                return mockPageClassRegistry;
+            }
+        };
+        context.checking(new Expectations() {
+            {
+                one(mockPageClassRegistry).getPageClass(pageType);
+                will(returnValue(expectedPageClass));
+            }
+        });
+        final Class<? extends Page> pageClass = application.getSignInPageClass();
+        assertThat(expectedPageClass.isAssignableFrom(pageClass), is(true));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java
new file mode 100644
index 0000000..2dda4ef
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java
@@ -0,0 +1,70 @@
+/*
+ *  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 static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.apache.isis.core.commons.config.IsisConfigurationBuilder;
+import org.apache.isis.core.runtime.system.DeploymentType;
+import org.apache.isis.core.runtime.system.IsisSystem;
+
+public class IsisWicket_providers {
+
+    private IsisWicketModule isisWicketModule;
+    private Injector injector;
+
+    @Before
+    public void setUp() throws Exception {
+        isisWicketModule = new IsisWicketModule();
+        injector = Guice.createInjector(isisWicketModule);
+    }
+
+    @Ignore // REVIEW: DKH
+    @Test
+    public void deploymentType() {
+        final DeploymentType instance = injector.getInstance(DeploymentType.class);
+        assertThat(instance, is(notNullValue()));
+    }
+
+    @Ignore // REVIEW: DKH
+    @Test
+    public void configurationBuilder() {
+        final IsisConfigurationBuilder instance = injector.getInstance(IsisConfigurationBuilder.class);
+        assertThat(instance, is(notNullValue()));
+    }
+
+    @Ignore
+    // need to handle config
+    @Test
+    public void isisSystem() {
+        final IsisSystem instance = injector.getInstance(IsisSystem.class);
+        assertThat(instance, is(notNullValue()));
+    }
+
+}