You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/06/03 08:52:03 UTC
[isis] 01/02: ISIS-1959: Update to Wicket 8
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 9ec61c0c3a9ec47b9488ce8c6ac37ebcc8abb060
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jun 2 14:46:45 2018 +0200
ISIS-1959: Update to Wicket 8
tabs don't work yet
Task-Url: https://issues.apache.org/jira/browse/ISIS-1959
---
core/pom.xml | 14 +-
.../background/BackgroundServiceDefault.java | 4 +
.../wicket/viewer/IsisWicketApplication.java | 1647 ++++++++++----------
.../ActionResultResponseHandlingStrategy.java | 7 +-
.../serviceactions/TertiaryActionsPanel.java | 26 +-
.../ajaxtable/IsisAjaxFallbackHeadersToolbar.java | 29 +-
.../ajaxtable/IsisAjaxFallbackOrderByBorder.java | 13 +-
.../ajaxtable/IsisAjaxNavigationToolbar.java | 6 +-
.../components/tree/IsisToWicketTreeAdapter.java | 5 +-
.../widgets/buttons/ContainedButtonPanel.java | 2 +-
.../select2/providers/EmptyChoiceProvider.java | 11 +-
.../wicket/ui/panels/PromptFormAbstract.java | 31 +-
12 files changed, 910 insertions(+), 885 deletions(-)
diff --git a/core/pom.xml b/core/pom.xml
index 880991d..cfcafa9 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -154,12 +154,17 @@
<jetty.version>9.4.3.v20170317</jetty.version>
- <wicket.version>7.9.0</wicket.version>
- <wicketstuff.version>7.8.1</wicketstuff.version>
+ <wicket.version>8.0.0</wicket.version>
+ <wicketstuff.version>8.0.0</wicketstuff.version>
+ <wicket-source.version>7.0.0</wicket-source.version>
+<!-- [ahuber] update to newer versions just does not work as a drop in replacement
+ <wicket-webjars.version>2.0.7</wicket-webjars.version>
+ <wicket-bootstrap.version>2.0.1</wicket-bootstrap.version>
+-->
<wicket-webjars.version>0.5.4</wicket-webjars.version>
<wicket-bootstrap.version>0.10.16</wicket-bootstrap.version>
- <wicket-source.version>7.0.0</wicket-source.version>
+
<select2.version>4.0.3</select2.version>
@@ -1984,7 +1989,8 @@ ${license.additional-notes}
<dependency>
- <groupId>net.ftlines.wicket-source</groupId>
+ <groupId>net.ftlines.wicket-source</groupId>
+<!-- [ahuber] for version 8.0.0 we might consider<groupId>com.github.jennybrown8.wicket-source</groupId> -->
<artifactId>wicket-source</artifactId>
<version>${wicket-source.version}</version>
<exclusions>
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
index d3010fe..3f11b89 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -193,6 +194,9 @@ public class BackgroundServiceDefault implements BackgroundService2 {
final Command command = commandContext.getCommand();
final BackgroundCommandService2 bcs2 = (BackgroundCommandService2) backgroundCommandService;
+ Objects.requireNonNull(bcs2,
+ ()->String.format("You need to provide a domain-service implementing '%s'!",
+ BackgroundCommandService2.class.getName()));
final List<ObjectAdapter> targetList = Collections.singletonList(domainObjectAdapter);
final CommandDto dto =
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
index b60ee44..94af982 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
@@ -30,6 +30,7 @@ import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.function.Function;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.context._Context;
@@ -85,6 +86,7 @@ import org.apache.wicket.Page;
import org.apache.wicket.RuntimeConfigurationType;
import org.apache.wicket.SharedResources;
import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.AjaxRequestTarget.IListener;
import org.apache.wicket.authentication.IAuthenticationStrategy;
import org.apache.wicket.authentication.strategy.DefaultAuthenticationStrategy;
import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
@@ -98,9 +100,9 @@ import org.apache.wicket.devutils.debugbar.VersionDebugContributor;
import org.apache.wicket.devutils.diskstore.DebugDiskDataStore;
import org.apache.wicket.guice.GuiceComponentInjector;
import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.ResourceAggregator;
import org.apache.wicket.markup.head.filter.JavaScriptFilteredIntoFooterHeaderResponse;
import org.apache.wicket.markup.html.IHeaderContributor;
-import org.apache.wicket.markup.html.IHeaderResponseDecorator;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.cycle.IRequestCycleListener;
import org.apache.wicket.request.cycle.PageRequestHandlerTracker;
@@ -108,15 +110,12 @@ import org.apache.wicket.request.cycle.RequestCycleListenerCollection;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.settings.DebugSettings;
import org.apache.wicket.settings.RequestCycleSettings;
-import org.apache.wicket.util.IContextProvider;
import org.apache.wicket.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.select2.ApplicationSettings;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Resources;
import com.google.inject.Guice;
@@ -156,823 +155,827 @@ import net.ftlines.wicketsource.WicketSource;
* This mechanism allows a number of other aspects to be customized.
*/
public class IsisWicketApplication
- extends AuthenticatedWebApplication
- implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketViewerSettingsAccessor {
-
- private static final long serialVersionUID = 1L;
-
- private static final Logger LOG = LoggerFactory.getLogger(IsisWicketApplication.class);
-
- private static final String STRIP_WICKET_TAGS_KEY = "isis.viewer.wicket.stripWicketTags";
- private static final boolean STRIP_WICKET_TAGS_DEFAULT = true;
- private static final String AJAX_DEBUG_MODE_KEY = "isis.viewer.wicket.ajaxDebugMode";
- private static final boolean AJAX_DEBUG_MODE_DEFAULT = false;
- private static final String WICKET_SOURCE_PLUGIN_KEY = "isis.viewer.wicket.wicketSourcePlugin";
- private static final boolean WICKET_SOURCE_PLUGIN_DEFAULT = false;
-
- private static final String WICKET_REMEMBER_ME_COOKIE_KEY = "isis.viewer.wicket.rememberMe.cookieKey";
- private static final String WICKET_REMEMBER_ME_COOKIE_KEY_DEFAULT = "isisWicketRememberMe";
- private static final String WICKET_REMEMBER_ME_ENCRYPTION_KEY = "isis.viewer.wicket.rememberMe.encryptionKey";
-
- /**
- * A configuration setting which value determines whether debug bar and other stuff influenced by {@link DebugSettings#isDevelopmentUtilitiesEnabled()} is enabled or not.
- *
- * <p>
- * By default, depends on the mode (prototyping = enabled, server = disabled). This property acts as an override.
- * </p>
- */
- public static final String ENABLE_DEVELOPMENT_UTILITIES_KEY = "isis.viewer.wicket.developmentUtilities.enable";
- public static final boolean ENABLE_DEVELOPMENT_UTILITIES_DEFAULT = false;
-
-
-
- private final IsisLoggingConfigurer loggingConfigurer = new IsisLoggingConfigurer();
-
- /**
- * Convenience locator, downcasts inherited functionality.
- */
- public static IsisWicketApplication get() {
- return (IsisWicketApplication) AuthenticatedWebApplication.get();
- }
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @com.google.inject.Inject
- private ComponentFactoryRegistry componentFactoryRegistry;
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @SuppressWarnings("unused")
- @com.google.inject.Inject
- private ImageResourceCache imageCache;
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @SuppressWarnings("unused")
- @com.google.inject.Inject
- private WicketViewerSettings wicketViewerSettings;
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @com.google.inject.Inject
- private PageClassRegistry pageClassRegistry;
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @com.google.inject.Inject
- private IsisSessionFactory isisSessionFactory;
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @com.google.inject.Inject
- private IsisConfiguration configuration;
-
- /**
- * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
- */
- @com.google.inject.Inject
- private DeploymentCategory deploymentCategory;
-
- @com.google.inject.Inject
- private WicketViewerSettings settings;
-
-
- private boolean determiningConfigurationType;
- private DeploymentTypeWicketAbstract deploymentType;
-
-
- // /////////////////////////////////////////////////
- // constructor, init
- // /////////////////////////////////////////////////
-
- public IsisWicketApplication() {
- }
-
-
- /**
- * Although there are warnings about not overriding this method, it doesn't seem possible
- * to call {@link #setResourceSettings(org.apache.wicket.settings.ResourceSettings)} in the
- * {@link #init()} method.
- */
- @Override
- protected void internalInit() {
- // replace with custom implementation of ResourceSettings that changes the order
- // in which search for i18n properties, to search for the application-specific
- // settings before any other.
- setResourceSettings(new IsisResourceSettings(this));
-
- // this doesn't seem to accomplish anything
- // addListenerToStripRemovedComponentsFromAjaxTargetResponse();
-
- super.internalInit();
- }
-
- @Override
- public Application setAjaxRequestTargetProvider(final IContextProvider<AjaxRequestTarget, Page> ajaxRequestTargetProvider) {
- final Application application = super.setAjaxRequestTargetProvider(new IContextProvider<AjaxRequestTarget, Page>(){
- @Override
- public AjaxRequestTarget get(final Page context) {
- return decorate(ajaxRequestTargetProvider.get(context));
- }
-
- AjaxRequestTarget decorate(final AjaxRequestTarget ajaxRequestTarget) {
- ajaxRequestTarget.registerRespondListener(
- new TargetRespondListenerToResetQueryResultCache());
- return ajaxRequestTarget;
- }
- } );
- return application;
- }
-
- // idea here is to avoid XmlPartialPageUpdate spitting out warnings, eg:
- //
- // 13:08:36,642 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxLink [Component id = copyLink]]' with markupid: 'copyLink94c' not rendered because it was already removed from page
- // 13:08:36,642 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[SimpleClipboardModalWindow [Component id = simpleClipboardModalWindow]]' with markupid: 'simpleClipboardModalWindow94e' not rendered because it was already removed from page
- // 13:08:36,643 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxFallbackLink [Component id = link]]' with markupid: 'link951' not rendered because it was already removed from page
- // 13:08:36,643 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxFallbackLink [Component id = link]]' with markupid: 'link952' not rendered because it was already removed from page
- // 13:08:36,655 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxLink [Component id = clearBookmarkLink]]' with markupid: 'clearBookmarkLink953' not rendered because it was already removed from page
- //
- // however, doesn't seem to work (even though the provided map is mutable).
- // must be some other sort of side-effect which causes the enqueued component(s) to be removed from page between
- // this listener firing and XmlPartialPageUpdate actually attempting to render the change components
- //
- private boolean addListenerToStripRemovedComponentsFromAjaxTargetResponse() {
- return getAjaxRequestTargetListeners().add(new AjaxRequestTarget.AbstractListener(){
-
- @Override
- public void onBeforeRespond(Map<String, Component> map, AjaxRequestTarget target)
- {
-
- List<String> idsToRemove = Lists.newArrayList();
- final Set<Map.Entry<String, Component>> entries = map.entrySet();
- for (Map.Entry<String, Component> entry : entries) {
- final Component component = entry.getValue();
- final Page page = component.findParent(Page.class);
- if(page == null) {
- idsToRemove.add(entry.getKey());
- }
- }
- for (String id : idsToRemove) {
- map.remove(id);
- }
-
- }
- });
- }
-
- /**
- * Initializes the application; in particular, bootstrapping the Isis
- * backend, and initializing the {@link ComponentFactoryRegistry} to be used
- * for rendering.
- */
- @Override
- protected void init() {
- List<Future<Object>> futures = null;
- try {
- super.init();
-
- _Context.setDefaultClassLoader(this.getClass().getClassLoader(), true);
-
- futures = startBackgroundInitializationThreads();
-
- String isisConfigDir = getServletContext().getInitParameter("isis.config.dir");
-
- configureLogging(isisConfigDir);
-
- getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.REDIRECT_TO_RENDER);
-
- getResourceSettings().setParentFolderPlaceholder("$up$");
-
- final IsisConfigurationBuilder isisConfigurationBuilder = obtainConfigBuilder();
- isisConfigurationBuilder.addDefaultConfigurationResourcesAndPrimers();
-
- _Resource.putContextPathIfPresent(getServletContext().getContextPath());
-
- final IsisConfigurationDefault configuration = isisConfigurationBuilder.getConfiguration();
-
- DeploymentTypeWicketAbstract deploymentType =
- determineDeploymentType(configuration.getString("isis.deploymentType"));
-
- RequestCycleListenerCollection requestCycleListeners = getRequestCycleListeners();
- IRequestCycleListener requestCycleListenerForIsis = newWebRequestCycleForIsis();
- requestCycleListeners.add(requestCycleListenerForIsis);
- requestCycleListeners.add(new PageRequestHandlerTracker());
-
- //
- // create IsisSessionFactory
- //
- final DeploymentCategory deploymentCategory = deploymentType.getDeploymentCategory();
- final IsisInjectModule isisModule = newIsisModule(deploymentCategory, configuration);
- final Injector injector = Guice.createInjector(isisModule, newIsisWicketModule());
- initWicketComponentInjection(injector);
-
- injector.injectMembers(this); // populates this.isisSessionFactory
-
- getServletContext().setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, this.isisSessionFactory);
-
-
- if (requestCycleListenerForIsis instanceof WebRequestCycleForIsis) {
- WebRequestCycleForIsis webRequestCycleForIsis = (WebRequestCycleForIsis) requestCycleListenerForIsis;
- webRequestCycleForIsis.setPageClassRegistry(pageClassRegistry);
- }
-
- this.getMarkupSettings().setStripWicketTags(determineStripWicketTags(configuration));
-
- configureSecurity(configuration);
-
- getDebugSettings().setAjaxDebugModeEnabled(determineAjaxDebugModeEnabled(configuration));
-
- // must be done after injected componentFactoryRegistry into the app itself
- buildCssBundle();
-
- filterJavascriptContributions();
-
- configureWicketSourcePluginIfNecessary();
-
- // TODO ISIS-987 Either make the API better (no direct access to the map) or use DB records
- int maxEntries = 1000;
- setMetaData(AccountConfirmationMap.KEY, new AccountConfirmationMap(maxEntries, Duration.days(1)));
-
- mountPages();
-
- @SuppressWarnings("unused")
- SharedResources sharedResources = getSharedResources();
-
- final MetaModelInvalidException mmie = IsisContext.getMetaModelInvalidExceptionIfAny();
- if(mmie != null) {
- log(mmie.getValidationErrors());
- }
-
- if(getDeploymentCategory().isPrototyping()) {
- DebugDiskDataStore.register(this);
- LOG.info("DebugDiskDataStore registered; access via ~/wicket/internal/debug/diskDataStore");
- LOG.info("DebugDiskDataStore: eg, http://localhost:8080/wicket/wicket/internal/debug/diskDataStore");
- }
-
- if(!getDebugSettings().isDevelopmentUtilitiesEnabled()) {
- boolean enableDevUtils = configuration
- .getBoolean(ENABLE_DEVELOPMENT_UTILITIES_KEY, ENABLE_DEVELOPMENT_UTILITIES_DEFAULT);
- if(enableDevUtils) {
- getDebugSettings().setDevelopmentUtilitiesEnabled(true);
-
- // copied from DebugBarInitializer
- // this is hacky, but need to do this because IInitializer#init() called before
- // the Application's #init() is called.
- // an alternative, better, design might be to move Isis' own initialization into an
- // implementation of IInitializer?
- DebugBar.registerContributor(VersionDebugContributor.DEBUG_BAR_CONTRIB, this);
- DebugBar.registerContributor(InspectorDebugPanel.DEBUG_BAR_CONTRIB, this);
- DebugBar.registerContributor(SessionSizeDebugPanel.DEBUG_BAR_CONTRIB, this);
- DebugBar.registerContributor(PageSizeDebugPanel.DEBUG_BAR_CONTRIB, this);
- }
- }
-
- LOG.info("storeSettings.inmemoryCacheSize : {}", getStoreSettings().getInmemoryCacheSize());
- LOG.info("storeSettings.asynchronousQueueCapacity: {}", getStoreSettings().getAsynchronousQueueCapacity());
- LOG.info("storeSettings.maxSizePerSession : {}", getStoreSettings().getMaxSizePerSession());
- LOG.info("storeSettings.fileStoreFolder : {}", getStoreSettings().getFileStoreFolder());
-
- } catch(RuntimeException ex) {
- // because Wicket's handling in its WicketFilter (that calls this method) does not log the exception.
- LOG.error("Failed to initialize", ex);
- throw ex;
- } finally {
- ThreadPoolSupport.join(futures);
- }
- }
-
- protected List<Future<Object>> startBackgroundInitializationThreads() {
- return ThreadPoolSupport.getInstance().invokeAll(_Lists.<Callable<Object>>of(
-
- Executors.callable(this::configureWebJars),
- Executors.callable(this::configureWicketBootstrap),
- Executors.callable(this::configureWicketSelect2),
- Executors.callable(ChangesDtoUtils::init),
- Executors.callable(InteractionDtoUtils::init),
- Executors.callable(CommandDtoUtils::init)
- ));
- }
-
- /**
- * protected visibility to allow ad-hoc overriding of some other authentication strategy.
- */
- protected void configureSecurity(final IsisConfiguration configuration) {
- getSecuritySettings().setAuthenticationStrategy(newAuthenticationStrategy(configuration));
- }
-
- /**
- * protected visibility to allow ad-hoc overriding of some other authentication strategy.
- */
- protected IAuthenticationStrategy newAuthenticationStrategy(final IsisConfiguration configuration) {
- final String cookieKey = configuration.getString(WICKET_REMEMBER_ME_COOKIE_KEY,
- WICKET_REMEMBER_ME_COOKIE_KEY_DEFAULT);
- final String encryptionKey = configuration.getString(WICKET_REMEMBER_ME_ENCRYPTION_KEY, defaultEncryptionKeyIfNotConfigured());
- return new DefaultAuthenticationStrategy(cookieKey, encryptionKey);
- }
-
- /**
- * As called by {@link #newAuthenticationStrategy(IsisConfiguration)}; if an encryption key for the 'rememberMe'
- * cookie hasn't been configured, then use a different encryption key for the 'rememberMe' cookie each time the
- * app is restarted.
- */
- protected String defaultEncryptionKeyIfNotConfigured() {
- return getDeploymentCategory().isProduction()
- ? UUID.randomUUID().toString()
- : "PrototypingEncryptionKey";
- }
-
- private void log(final Set<String> validationErrors) {
- log("");
- logBanner();
- log("");
- for (String validationError : validationErrors) {
- logError(validationError);
- }
- log("");
- log("Please inspect the above messages and correct your domain model.");
- log("");
- logBanner();
- log("");
- }
-
- private void configureWicketSelect2() {
- ApplicationSettings select2Settings = ApplicationSettings.get();
- select2Settings.setCssReference(new Select2BootstrapCssReference());
- select2Settings.setJavaScriptReference(new Select2JsReference());
- }
-
- protected void configureWicketSourcePluginIfNecessary() {
- if(isWicketSourcePluginEnabled(this.configuration)) {
- configureWicketSourcePlugin();
- }
- }
-
- protected void configureWicketSourcePlugin() {
- if(!deploymentCategory.isProduction()) {
- WicketSource.configure(this);
- }
- }
-
- /**
- * For convenience of subclasses.
- */
- protected static String readLines(final Class<?> contextClass, final String resourceName, final String fallback) {
- try {
- List<String> readLines = Resources.readLines(Resources.getResource(contextClass, resourceName), Charset.defaultCharset());
- final String aboutText = Joiner.on("\n").join(readLines);
- return aboutText;
- } catch (IOException e) {
- return fallback;
- }
- }
-
-
- // //////////////////////////////////////
-
- /**
- * Install 2 default collector instances: (FileAssetPathCollector(WEBJARS_PATH_PREFIX), JarAssetPathCollector),
- * and a webjars resource finder.
- *
- * <p>
- * Factored out for easy (informal) pluggability.
- * </p>
- */
- protected void configureWebJars() {
- IWebjarsSettings settings = new WebjarsSettings();
- WicketWebjars.install(this, settings);
- }
-
- protected void configureWicketBootstrap() {
- final IBootstrapSettings settings = new BootstrapSettings();
- settings.setDeferJavascript(false);
- Bootstrap.install(this, settings);
-
- getHeaderContributorListeners().add(new IHeaderContributor() {
- @Override
- public void renderHead(IHeaderResponse response) {
- BootstrapBaseBehavior bootstrapBaseBehavior = new BootstrapBaseBehavior();
- bootstrapBaseBehavior.renderHead(settings, response);
- }
- });
- }
-
- // //////////////////////////////////////
-
- /**
- * Factored out for easy (informal) pluggability.
- */
- protected void configureLogging(String isisConfigDir) {
- final String loggingPropertiesDir;
- if(isisConfigDir != null) {
- loggingPropertiesDir = isisConfigDir;
- } else {
- loggingPropertiesDir = getServletContext().getRealPath("/WEB-INF");
- }
-
- loggingConfigurer.configureLogging(loggingPropertiesDir, new String[0]);
- }
-
- // //////////////////////////////////////
-
- /**
- * Factored out for easy (informal) pluggability.
- */
- protected IRequestCycleListener newWebRequestCycleForIsis() {
- return new WebRequestCycleForIsis();
- }
-
- // //////////////////////////////////////
-
- /**
- * Made protected visibility for easy (informal) pluggability.
- */
- protected void determineDeploymentTypeIfRequired() {
- if(deploymentType != null) {
- return;
- }
-
- determiningConfigurationType = true;
- try {
- final IsisConfigurationBuilder isisConfigurationBuilder = obtainConfigBuilder();
-
- final IsisConfiguration configuration = isisConfigurationBuilder.peekConfiguration();
- String deploymentTypeFromConfig = configuration.getString("isis.deploymentType");
- deploymentType = determineDeploymentType(deploymentTypeFromConfig);
- } finally {
- determiningConfigurationType = false;
- }
- }
-
- /**
- * Made protected visibility for easy (informal) pluggability.
- */
- protected DeploymentTypeWicketAbstract determineDeploymentType(String deploymentTypeFromConfig) {
- final DeploymentTypeWicketAbstract prototype = new WicketServerPrototype();
- final DeploymentTypeWicketAbstract deployment = new WicketServer();
-
- if(deploymentTypeFromConfig != null) {
- final DeploymentType deploymentType = DeploymentType.lookup(deploymentTypeFromConfig);
- return !deploymentType.getDeploymentCategory().isProduction()
- ? prototype
- : deployment;
- } else {
- return usesDevelopmentConfig()
- ? prototype
- : deployment;
- }
- }
-
-
- // //////////////////////////////////////
-
- private IsisConfigurationBuilder isisConfigurationBuilder;
-
- protected IsisConfigurationBuilder obtainConfigBuilder() {
- return isisConfigurationBuilder != null
- ? isisConfigurationBuilder
- : (isisConfigurationBuilder = IsisWebAppBootstrapper.obtainConfigBuilderFrom(getServletContext()));
- }
-
- // //////////////////////////////////////
-
- /**
- * Override if required
- */
- protected Module newIsisWicketModule() {
- return new IsisWicketModule();
- }
-
- // //////////////////////////////////////
-
- /**
- * Made protected visibility for easy (informal) pluggability.
- */
- protected void buildCssBundle() {
- // get the css for all components built by component factories
- final Set<CssResourceReference> references = cssResourceReferencesForAllComponents();
-
- // some additional special cases.
- addSpecialCasesToCssBundle(references);
-
- // create the bundle
- getResourceBundles().addCssBundle(
- IsisWicketApplication.class, "isis-wicket-viewer-bundle.css",
- references.toArray(new CssResourceReference[]{}));
- }
-
- /**
- * Additional special cases to be included in the main CSS bundle.
- *
- * <p>
- * These are typically either superclasses or components that don't have their own ComponentFactory, or
- * for {@link ComponentFactory}s (such as <tt>StringPanelFactory</tt>) that don't quite follow the usual pattern
- * (because they create different types of panels).
- *
- * <p>
- * Note that it doesn't really matter if we miss one or two; their CSS will simply be served up individually.
- */
- protected void addSpecialCasesToCssBundle(final Set<CssResourceReference> references) {
-
- // abstract classes
-
- // ... though it turns out we cannot add this particular one to the bundle, because
- // it has CSS image links intended to be resolved relative to LinksSelectorPanelAbstract.class.
- // Adding them into the bundle would mean these CSS links are resolved relative to IsisWicketApplication.class
- // instead.
- // references.add(PanelUtil.cssResourceReferenceFor(LinksSelectorPanelAbstract.class));
-
- // components without factories
- references.add(PanelUtil.cssResourceReferenceFor(AdditionalLinksPanel.class));
-
- // non-conforming component factories
- references.add(PanelUtil.cssResourceReferenceFor(MultiLineStringPanel.class));
- }
-
- protected final static Function<ComponentFactory, Iterable<CssResourceReference>> getCssResourceReferences =
- new Function<ComponentFactory, Iterable<CssResourceReference>>(){
- @Override
- public Iterable<CssResourceReference> apply(final ComponentFactory input) {
- final CssResourceReference cssResourceReference = input.getCssResourceReference();
- return cssResourceReference != null?
- Collections.singletonList(cssResourceReference):
- Collections.<CssResourceReference>emptyList();
- }
- };
-
-
- protected Set<CssResourceReference> cssResourceReferencesForAllComponents() {
- // TODO mgrigorov: ISIS-537 temporary disabled to not mess up with Bootstrap styles
-// Collection<ComponentFactory> componentFactories = getComponentFactoryRegistry().listComponentFactories();
- return Sets.newLinkedHashSet(
-// Iterables.concat(
-// Iterables.transform(
-// componentFactories,
-// getCssResourceReferences))
- );
- }
-
- // //////////////////////////////////////
-
- /**
- * filters Javascript header contributions so rendered to bottom of page.
- *
- * <p>
- * Factored out for easy (informal) pluggability.
- * </p>
- */
- protected void filterJavascriptContributions() {
- setHeaderResponseDecorator(new IHeaderResponseDecorator()
- {
- @Override
- public IHeaderResponse decorate(IHeaderResponse response)
- {
- // use this header resource decorator to load all JavaScript resources in the page
- // footer (after </body>)
- return new JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS");
- }
- });
- }
-
- // //////////////////////////////////////
-
- /**
- * Map entity and action to provide prettier URLs.
- *
- * <p>
- * Factored out for easy (informal) pluggability.
- * </p>
- */
- protected void mountPages() {
-
- mountPage("/signin", PageType.SIGN_IN);
- mountPage("/signup", PageType.SIGN_UP);
- mountPage("/signup/verify", PageType.SIGN_UP_VERIFY);
- mountPage("/password/reset", PageType.PASSWORD_RESET);
-
- mountPage("/entity/#{objectOid}", PageType.ENTITY);
-
- // nb: action mount cannot contain {actionArgs}, because the default
- // parameters encoder doesn't seem to be able to handle multiple args
- mountPage("/action/${objectOid}/${actionOwningSpec}/${actionId}/${actionType}", PageType.ACTION_PROMPT);
-
- mountPage("/logout", WicketLogoutPage.class);
- }
-
- protected void mountPage(final String mountPath, final PageType pageType) {
- final Class<? extends Page> pageClass = this.pageClassRegistry.getPageClass(pageType);
- mount(new MountedMapper(mountPath, pageClass));
- }
-
-
- // //////////////////////////////////////
-
- private void logError(String validationError) {
- log(validationError);
- }
-
- private static void logBanner() {
- String msg = "################################################ ISIS METAMODEL VALIDATION ERRORS ################################################################";
- log(msg);
- }
-
- private static void log(String msg) {
- System.err.println(msg);
- LOG.error(msg);
- }
-
- // //////////////////////////////////////
-
- /**
- * Whether Wicket tags should be stripped from the markup, as specified by configuration settings..
- *
- * <p>
- * If the <tt>isis.viewer.wicket.stripWicketTags</tt> is set, then this is used, otherwise the default is to strip
- * the tags because they may break some CSS rules.
- */
- private boolean determineStripWicketTags(IsisConfiguration configuration) {
- final boolean strip = configuration.getBoolean(STRIP_WICKET_TAGS_KEY, STRIP_WICKET_TAGS_DEFAULT);
- return strip;
- }
-
- // //////////////////////////////////////
-
- /**
- * Whether the Ajax debug should be shown, as specified by configuration settings.
- *
- * <p>
- * If the <tt>isis.viewer.wicket.ajaxDebugMode</tt> is set, then this is used, otherwise the default is to disable.
- */
- private boolean determineAjaxDebugModeEnabled(IsisConfiguration configuration) {
- final boolean debugModeEnabled = configuration.getBoolean(AJAX_DEBUG_MODE_KEY, AJAX_DEBUG_MODE_DEFAULT);
- return debugModeEnabled;
- }
-
- /**
- * Whether the Wicket source plugin should be enabled, as specified by configuration settings.
- *
- * <p>
- * If the <tt>isis.viewer.wicket.wicketSourcePlugin</tt> is set, then this is used, otherwise the default is to disable.
- */
- private boolean isWicketSourcePluginEnabled(IsisConfiguration configuration) {
- final boolean pluginEnabled = configuration.getBoolean(WICKET_SOURCE_PLUGIN_KEY, WICKET_SOURCE_PLUGIN_DEFAULT);
- return pluginEnabled;
- }
-
- // //////////////////////////////////////
-
- @Override
- protected void onDestroy() {
- try {
- if (isisSessionFactory != null) {
- isisSessionFactory.destroyServicesAndShutdown();
- }
- getServletContext().setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, null);
- super.onDestroy();
- IsisContext.clear();
- } catch(final RuntimeException ex) {
- // symmetry with #init()
- LOG.error("Failed to destroy", ex);
- throw ex;
- }
- }
-
- // //////////////////////////////////////
-
- @Override
- public RuntimeConfigurationType getConfigurationType() {
- if(determiningConfigurationType) {
- // avoiding an infinite loop; have already passed through here once before
- // this time around, just delegate to web-inf
- return super.getConfigurationType();
- }
- determineDeploymentTypeIfRequired();
- return deploymentType.getConfigurationType();
- }
-
- protected IsisInjectModule newIsisModule(
- final DeploymentCategory deploymentCategory,
- final IsisConfigurationDefault isisConfiguration) {
- return new IsisInjectModule(deploymentCategory, isisConfiguration);
- }
-
- // //////////////////////////////////////
-
-
- protected void initWicketComponentInjection(final Injector injector) {
- getComponentInstantiationListeners().add(new GuiceComponentInjector(this, injector, false));
- }
-
- // /////////////////////////////////////////////////
- // Wicket Hooks
- // /////////////////////////////////////////////////
-
- /**
- * Installs a {@link AuthenticatedWebSessionForIsis custom implementation}
- * of Wicket's own {@link AuthenticatedWebSession}, effectively associating
- * the Wicket session with the Isis's equivalent session object.
- *
- * <p>
- * In general, it shouldn't be necessary to override this method.
- */
- @Override
- protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
- return AuthenticatedWebSessionForIsis.class;
- }
-
- /**
- * Installs a {@link ConverterLocator} preconfigured with a number of
- * implementations to support Isis specific objects.
- */
- @Override
- protected IConverterLocator newConverterLocator() {
- final ConverterLocator converterLocator = new ConverterLocator();
- converterLocator.set(ObjectAdapter.class, new ConverterForObjectAdapter());
- converterLocator.set(ObjectAdapterMemento.class, new ConverterForObjectAdapterMemento());
- return converterLocator;
- }
-
- // /////////////////////////////////////////////////
- // Component Factories
- // /////////////////////////////////////////////////
-
- @Override
- public final ComponentFactoryRegistry getComponentFactoryRegistry() {
- return componentFactoryRegistry;
- }
-
- // /////////////////////////////////////////////////
- // Page Registry
- // /////////////////////////////////////////////////
-
- /**
- * Access to other page types.
- *
- * <p>
- * Non-final only for testing purposes; should not typically be overridden.
- */
- @Override
- public PageClassRegistry getPageClassRegistry() {
- return pageClassRegistry;
- }
-
- /**
- * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
- */
- @Override
- public Class<? extends Page> getHomePage() {
- return getPageClassRegistry().getPageClass(PageType.HOME);
- }
-
- /**
- * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
- */
- @SuppressWarnings("unchecked")
- @Override
- public Class<? extends WebPage> getSignInPageClass() {
- return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.SIGN_IN);
- }
-
- /**
- * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
- */
- @SuppressWarnings("unchecked")
- public Class<? extends WebPage> getSignUpPageClass() {
- return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.SIGN_UP);
- }
-
- /**
- * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
- */
- @SuppressWarnings("unchecked")
- public Class<? extends WebPage> getSignUpVerifyPageClass() {
- return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.SIGN_UP_VERIFY);
- }
-
- /**
- * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
- */
- @SuppressWarnings("unchecked")
- public Class<? extends WebPage> getForgotPasswordPageClass() {
- return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.PASSWORD_RESET);
- }
-
- public AuthenticationSession getAuthenticationSession() {
- return isisSessionFactory.getCurrentSession().getAuthenticationSession();
- }
-
- public DeploymentCategory getDeploymentCategory() {
- return deploymentCategory;
- }
-
- @Override
- public WicketViewerSettings getSettings() {
- return settings;
- }
+extends AuthenticatedWebApplication
+implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketViewerSettingsAccessor {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(IsisWicketApplication.class);
+
+ private static final String STRIP_WICKET_TAGS_KEY = "isis.viewer.wicket.stripWicketTags";
+ private static final boolean STRIP_WICKET_TAGS_DEFAULT = true;
+ private static final String AJAX_DEBUG_MODE_KEY = "isis.viewer.wicket.ajaxDebugMode";
+ private static final boolean AJAX_DEBUG_MODE_DEFAULT = false;
+ private static final String WICKET_SOURCE_PLUGIN_KEY = "isis.viewer.wicket.wicketSourcePlugin";
+ private static final boolean WICKET_SOURCE_PLUGIN_DEFAULT = false;
+
+ private static final String WICKET_REMEMBER_ME_COOKIE_KEY = "isis.viewer.wicket.rememberMe.cookieKey";
+ private static final String WICKET_REMEMBER_ME_COOKIE_KEY_DEFAULT = "isisWicketRememberMe";
+ private static final String WICKET_REMEMBER_ME_ENCRYPTION_KEY = "isis.viewer.wicket.rememberMe.encryptionKey";
+
+ /**
+ * A configuration setting which value determines whether debug bar and other stuff influenced by {@link DebugSettings#isDevelopmentUtilitiesEnabled()} is enabled or not.
+ *
+ * <p>
+ * By default, depends on the mode (prototyping = enabled, server = disabled). This property acts as an override.
+ * </p>
+ */
+ public static final String ENABLE_DEVELOPMENT_UTILITIES_KEY = "isis.viewer.wicket.developmentUtilities.enable";
+ public static final boolean ENABLE_DEVELOPMENT_UTILITIES_DEFAULT = false;
+
+
+
+ private final IsisLoggingConfigurer loggingConfigurer = new IsisLoggingConfigurer();
+
+ /**
+ * Convenience locator, downcasts inherited functionality.
+ */
+ public static IsisWicketApplication get() {
+ return (IsisWicketApplication) AuthenticatedWebApplication.get();
+ }
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @com.google.inject.Inject
+ private ComponentFactoryRegistry componentFactoryRegistry;
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @SuppressWarnings("unused")
+ @com.google.inject.Inject
+ private ImageResourceCache imageCache;
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @SuppressWarnings("unused")
+ @com.google.inject.Inject
+ private WicketViewerSettings wicketViewerSettings;
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @com.google.inject.Inject
+ private PageClassRegistry pageClassRegistry;
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @com.google.inject.Inject
+ private IsisSessionFactory isisSessionFactory;
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @com.google.inject.Inject
+ private IsisConfiguration configuration;
+
+ /**
+ * {@link com.google.inject.Inject Inject}ed when {@link #init() initialized}.
+ */
+ @com.google.inject.Inject
+ private DeploymentCategory deploymentCategory;
+
+ @com.google.inject.Inject
+ private WicketViewerSettings settings;
+
+
+ private boolean determiningConfigurationType;
+ private DeploymentTypeWicketAbstract deploymentType;
+
+
+ // /////////////////////////////////////////////////
+ // constructor, init
+ // /////////////////////////////////////////////////
+
+ public IsisWicketApplication() {
+ }
+
+
+ /**
+ * Although there are warnings about not overriding this method, it doesn't seem possible
+ * to call {@link #setResourceSettings(org.apache.wicket.settings.ResourceSettings)} in the
+ * {@link #init()} method.
+ */
+ @Override
+ protected void internalInit() {
+ // replace with custom implementation of ResourceSettings that changes the order
+ // in which search for i18n properties, to search for the application-specific
+ // settings before any other.
+ setResourceSettings(new IsisResourceSettings(this));
+
+ // this doesn't seem to accomplish anything
+ // addListenerToStripRemovedComponentsFromAjaxTargetResponse();
+
+ super.internalInit();
+
+ }
+
+ private static AjaxRequestTarget decorate(final AjaxRequestTarget ajaxRequestTarget) {
+ ajaxRequestTarget.registerRespondListener( new TargetRespondListenerToResetQueryResultCache() );
+ return ajaxRequestTarget;
+ }
+
+
+ @Override
+ public Application setAjaxRequestTargetProvider(Function<Page, AjaxRequestTarget> ajaxRequestTargetProvider) {
+ final Application application = super.setAjaxRequestTargetProvider(
+ (Page context) -> decorate(ajaxRequestTargetProvider.apply(context)) );
+ return application;
+ }
+
+ // idea here is to avoid XmlPartialPageUpdate spitting out warnings, eg:
+ //
+ // 13:08:36,642 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxLink [Component id = copyLink]]' with markupid: 'copyLink94c' not rendered because it was already removed from page
+ // 13:08:36,642 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[SimpleClipboardModalWindow [Component id = simpleClipboardModalWindow]]' with markupid: 'simpleClipboardModalWindow94e' not rendered because it was already removed from page
+ // 13:08:36,643 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxFallbackLink [Component id = link]]' with markupid: 'link951' not rendered because it was already removed from page
+ // 13:08:36,643 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxFallbackLink [Component id = link]]' with markupid: 'link952' not rendered because it was already removed from page
+ // 13:08:36,655 [XmlPartialPageUpdate qtp1988859660-18 WARN ] Component '[AjaxLink [Component id = clearBookmarkLink]]' with markupid: 'clearBookmarkLink953' not rendered because it was already removed from page
+ //
+ // however, doesn't seem to work (even though the provided map is mutable).
+ // must be some other sort of side-effect which causes the enqueued component(s) to be removed from page between
+ // this listener firing and XmlPartialPageUpdate actually attempting to render the change components
+ //
+ private boolean addListenerToStripRemovedComponentsFromAjaxTargetResponse() {
+ return getAjaxRequestTargetListeners().add(new IListener(){
+
+ @Override
+ public void onBeforeRespond(Map<String, Component> map, AjaxRequestTarget target) {
+
+ System.out.println("=====================================");
+ System.out.println("=== on before respond");
+ System.out.println("map="+map);
+ System.out.println("=====================================");
+ System.out.println("=== removals");
+ map.entrySet().removeIf(entry->{
+ final Component component = entry.getValue();
+ final Page page = component.findParent(Page.class);
+ if(page==null) {
+ System.out.println("id: "+entry.getKey()+": page="+page);
+ }
+ return page==null;
+ });
+
+ System.out.println("=====================================");
+
+ }
+ });
+ }
+
+ /**
+ * Initializes the application; in particular, bootstrapping the Isis
+ * backend, and initializing the {@link ComponentFactoryRegistry} to be used
+ * for rendering.
+ */
+ @Override
+ protected void init() {
+ List<Future<Object>> futures = null;
+ try {
+ super.init();
+
+ _Context.setDefaultClassLoader(this.getClass().getClassLoader(), true);
+
+ futures = startBackgroundInitializationThreads();
+
+ String isisConfigDir = getServletContext().getInitParameter("isis.config.dir");
+
+ configureLogging(isisConfigDir);
+
+ getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.REDIRECT_TO_RENDER);
+
+ getResourceSettings().setParentFolderPlaceholder("$up$");
+
+ final IsisConfigurationBuilder isisConfigurationBuilder = obtainConfigBuilder();
+ isisConfigurationBuilder.addDefaultConfigurationResourcesAndPrimers();
+
+ _Resource.putContextPathIfPresent(getServletContext().getContextPath());
+
+ final IsisConfigurationDefault configuration = isisConfigurationBuilder.getConfiguration();
+
+ DeploymentTypeWicketAbstract deploymentType =
+ determineDeploymentType(configuration.getString("isis.deploymentType"));
+
+ RequestCycleListenerCollection requestCycleListeners = getRequestCycleListeners();
+ IRequestCycleListener requestCycleListenerForIsis = newWebRequestCycleForIsis();
+ requestCycleListeners.add(requestCycleListenerForIsis);
+ requestCycleListeners.add(new PageRequestHandlerTracker());
+
+ //
+ // create IsisSessionFactory
+ //
+ final DeploymentCategory deploymentCategory = deploymentType.getDeploymentCategory();
+ final IsisInjectModule isisModule = newIsisModule(deploymentCategory, configuration);
+ final Injector injector = Guice.createInjector(isisModule, newIsisWicketModule());
+ initWicketComponentInjection(injector);
+
+ injector.injectMembers(this); // populates this.isisSessionFactory
+
+ getServletContext().setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, this.isisSessionFactory);
+
+
+ if (requestCycleListenerForIsis instanceof WebRequestCycleForIsis) {
+ WebRequestCycleForIsis webRequestCycleForIsis = (WebRequestCycleForIsis) requestCycleListenerForIsis;
+ webRequestCycleForIsis.setPageClassRegistry(pageClassRegistry);
+ }
+
+ this.getMarkupSettings().setStripWicketTags(determineStripWicketTags(configuration));
+
+ configureSecurity(configuration);
+
+ getDebugSettings().setAjaxDebugModeEnabled(determineAjaxDebugModeEnabled(configuration));
+
+ // must be done after injected componentFactoryRegistry into the app itself
+ buildCssBundle();
+
+ filterJavascriptContributions();
+
+ configureWicketSourcePluginIfNecessary();
+
+ // TODO ISIS-987 Either make the API better (no direct access to the map) or use DB records
+ int maxEntries = 1000;
+ setMetaData(AccountConfirmationMap.KEY, new AccountConfirmationMap(maxEntries, Duration.days(1)));
+
+ mountPages();
+
+ @SuppressWarnings("unused")
+ SharedResources sharedResources = getSharedResources();
+
+ final MetaModelInvalidException mmie = IsisContext.getMetaModelInvalidExceptionIfAny();
+ if(mmie != null) {
+ log(mmie.getValidationErrors());
+ }
+
+ if(getDeploymentCategory().isPrototyping()) {
+ DebugDiskDataStore.register(this);
+ LOG.info("DebugDiskDataStore registered; access via ~/wicket/internal/debug/diskDataStore");
+ LOG.info("DebugDiskDataStore: eg, http://localhost:8080/wicket/wicket/internal/debug/diskDataStore");
+ }
+
+ if(!getDebugSettings().isDevelopmentUtilitiesEnabled()) {
+ boolean enableDevUtils = configuration
+ .getBoolean(ENABLE_DEVELOPMENT_UTILITIES_KEY, ENABLE_DEVELOPMENT_UTILITIES_DEFAULT);
+ if(enableDevUtils) {
+ getDebugSettings().setDevelopmentUtilitiesEnabled(true);
+
+ // copied from DebugBarInitializer
+ // this is hacky, but need to do this because IInitializer#init() called before
+ // the Application's #init() is called.
+ // an alternative, better, design might be to move Isis' own initialization into an
+ // implementation of IInitializer?
+ DebugBar.registerContributor(VersionDebugContributor.DEBUG_BAR_CONTRIB, this);
+ DebugBar.registerContributor(InspectorDebugPanel.DEBUG_BAR_CONTRIB, this);
+ DebugBar.registerContributor(SessionSizeDebugPanel.DEBUG_BAR_CONTRIB, this);
+ DebugBar.registerContributor(PageSizeDebugPanel.DEBUG_BAR_CONTRIB, this);
+ }
+ }
+
+ LOG.info("storeSettings.inmemoryCacheSize : {}", getStoreSettings().getInmemoryCacheSize());
+ LOG.info("storeSettings.asynchronousQueueCapacity: {}", getStoreSettings().getAsynchronousQueueCapacity());
+ LOG.info("storeSettings.maxSizePerSession : {}", getStoreSettings().getMaxSizePerSession());
+ LOG.info("storeSettings.fileStoreFolder : {}", getStoreSettings().getFileStoreFolder());
+
+ } catch(RuntimeException ex) {
+ // because Wicket's handling in its WicketFilter (that calls this method) does not log the exception.
+ LOG.error("Failed to initialize", ex);
+ throw ex;
+ } finally {
+ ThreadPoolSupport.join(futures);
+ }
+ }
+
+ protected List<Future<Object>> startBackgroundInitializationThreads() {
+ return ThreadPoolSupport.getInstance().invokeAll(_Lists.<Callable<Object>>of(
+
+ Executors.callable(this::configureWebJars),
+ Executors.callable(this::configureWicketBootstrap),
+ Executors.callable(this::configureWicketSelect2),
+ Executors.callable(ChangesDtoUtils::init),
+ Executors.callable(InteractionDtoUtils::init),
+ Executors.callable(CommandDtoUtils::init)
+ ));
+ }
+
+ /**
+ * protected visibility to allow ad-hoc overriding of some other authentication strategy.
+ */
+ protected void configureSecurity(final IsisConfiguration configuration) {
+ getSecuritySettings().setAuthenticationStrategy(newAuthenticationStrategy(configuration));
+ }
+
+ /**
+ * protected visibility to allow ad-hoc overriding of some other authentication strategy.
+ */
+ protected IAuthenticationStrategy newAuthenticationStrategy(final IsisConfiguration configuration) {
+ final String cookieKey = configuration.getString(WICKET_REMEMBER_ME_COOKIE_KEY,
+ WICKET_REMEMBER_ME_COOKIE_KEY_DEFAULT);
+ final String encryptionKey = configuration.getString(WICKET_REMEMBER_ME_ENCRYPTION_KEY, defaultEncryptionKeyIfNotConfigured());
+ return new DefaultAuthenticationStrategy(cookieKey, encryptionKey);
+ }
+
+ /**
+ * As called by {@link #newAuthenticationStrategy(IsisConfiguration)}; if an encryption key for the 'rememberMe'
+ * cookie hasn't been configured, then use a different encryption key for the 'rememberMe' cookie each time the
+ * app is restarted.
+ */
+ protected String defaultEncryptionKeyIfNotConfigured() {
+ return getDeploymentCategory().isProduction()
+ ? UUID.randomUUID().toString()
+ : "PrototypingEncryptionKey";
+ }
+
+ private void log(final Set<String> validationErrors) {
+ log("");
+ logBanner();
+ log("");
+ for (String validationError : validationErrors) {
+ logError(validationError);
+ }
+ log("");
+ log("Please inspect the above messages and correct your domain model.");
+ log("");
+ logBanner();
+ log("");
+ }
+
+ private void configureWicketSelect2() {
+ ApplicationSettings select2Settings = ApplicationSettings.get();
+ select2Settings.setCssReference(new Select2BootstrapCssReference());
+ select2Settings.setJavaScriptReference(new Select2JsReference());
+ }
+
+ protected void configureWicketSourcePluginIfNecessary() {
+ if(isWicketSourcePluginEnabled(this.configuration)) {
+ configureWicketSourcePlugin();
+ }
+ }
+
+ protected void configureWicketSourcePlugin() {
+ if(!deploymentCategory.isProduction()) {
+ WicketSource.configure(this);
+ }
+ }
+
+ /**
+ * For convenience of subclasses.
+ */
+ protected static String readLines(final Class<?> contextClass, final String resourceName, final String fallback) {
+ try {
+ List<String> readLines = Resources.readLines(Resources.getResource(contextClass, resourceName), Charset.defaultCharset());
+ final String aboutText = Joiner.on("\n").join(readLines);
+ return aboutText;
+ } catch (IOException e) {
+ return fallback;
+ }
+ }
+
+
+ // //////////////////////////////////////
+
+ /**
+ * Install 2 default collector instances: (FileAssetPathCollector(WEBJARS_PATH_PREFIX), JarAssetPathCollector),
+ * and a webjars resource finder.
+ *
+ * <p>
+ * Factored out for easy (informal) pluggability.
+ * </p>
+ */
+ protected void configureWebJars() {
+ IWebjarsSettings settings = new WebjarsSettings();
+ WicketWebjars.install(this, settings);
+ }
+
+ protected void configureWicketBootstrap() {
+ final IBootstrapSettings settings = new BootstrapSettings();
+ settings.setDeferJavascript(false);
+ Bootstrap.install(this, settings);
+
+ getHeaderContributorListeners().add(new IHeaderContributor() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void renderHead(IHeaderResponse response) {
+ BootstrapBaseBehavior bootstrapBaseBehavior = new BootstrapBaseBehavior();
+ bootstrapBaseBehavior.renderHead(settings, response);
+ }
+ });
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Factored out for easy (informal) pluggability.
+ */
+ protected void configureLogging(String isisConfigDir) {
+ final String loggingPropertiesDir;
+ if(isisConfigDir != null) {
+ loggingPropertiesDir = isisConfigDir;
+ } else {
+ loggingPropertiesDir = getServletContext().getRealPath("/WEB-INF");
+ }
+
+ loggingConfigurer.configureLogging(loggingPropertiesDir, new String[0]);
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Factored out for easy (informal) pluggability.
+ */
+ protected IRequestCycleListener newWebRequestCycleForIsis() {
+ return new WebRequestCycleForIsis();
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Made protected visibility for easy (informal) pluggability.
+ */
+ protected void determineDeploymentTypeIfRequired() {
+ if(deploymentType != null) {
+ return;
+ }
+
+ determiningConfigurationType = true;
+ try {
+ final IsisConfigurationBuilder isisConfigurationBuilder = obtainConfigBuilder();
+
+ final IsisConfiguration configuration = isisConfigurationBuilder.peekConfiguration();
+ String deploymentTypeFromConfig = configuration.getString("isis.deploymentType");
+ deploymentType = determineDeploymentType(deploymentTypeFromConfig);
+ } finally {
+ determiningConfigurationType = false;
+ }
+ }
+
+ /**
+ * Made protected visibility for easy (informal) pluggability.
+ */
+ protected DeploymentTypeWicketAbstract determineDeploymentType(String deploymentTypeFromConfig) {
+ final DeploymentTypeWicketAbstract prototype = new WicketServerPrototype();
+ final DeploymentTypeWicketAbstract deployment = new WicketServer();
+
+ if(deploymentTypeFromConfig != null) {
+ final DeploymentType deploymentType = DeploymentType.lookup(deploymentTypeFromConfig);
+ return !deploymentType.getDeploymentCategory().isProduction()
+ ? prototype
+ : deployment;
+ } else {
+ return usesDevelopmentConfig()
+ ? prototype
+ : deployment;
+ }
+ }
+
+
+ // //////////////////////////////////////
+
+ private IsisConfigurationBuilder isisConfigurationBuilder;
+
+ protected IsisConfigurationBuilder obtainConfigBuilder() {
+ return isisConfigurationBuilder != null
+ ? isisConfigurationBuilder
+ : (isisConfigurationBuilder = IsisWebAppBootstrapper.obtainConfigBuilderFrom(getServletContext()));
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Override if required
+ */
+ protected Module newIsisWicketModule() {
+ return new IsisWicketModule();
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Made protected visibility for easy (informal) pluggability.
+ */
+ protected void buildCssBundle() {
+ // get the css for all components built by component factories
+ final Set<CssResourceReference> references = cssResourceReferencesForAllComponents();
+
+ // some additional special cases.
+ addSpecialCasesToCssBundle(references);
+
+ // create the bundle
+ getResourceBundles().addCssBundle(
+ IsisWicketApplication.class, "isis-wicket-viewer-bundle.css",
+ references.toArray(new CssResourceReference[]{}));
+ }
+
+ /**
+ * Additional special cases to be included in the main CSS bundle.
+ *
+ * <p>
+ * These are typically either superclasses or components that don't have their own ComponentFactory, or
+ * for {@link ComponentFactory}s (such as <tt>StringPanelFactory</tt>) that don't quite follow the usual pattern
+ * (because they create different types of panels).
+ *
+ * <p>
+ * Note that it doesn't really matter if we miss one or two; their CSS will simply be served up individually.
+ */
+ protected void addSpecialCasesToCssBundle(final Set<CssResourceReference> references) {
+
+ // abstract classes
+
+ // ... though it turns out we cannot add this particular one to the bundle, because
+ // it has CSS image links intended to be resolved relative to LinksSelectorPanelAbstract.class.
+ // Adding them into the bundle would mean these CSS links are resolved relative to IsisWicketApplication.class
+ // instead.
+ // references.add(PanelUtil.cssResourceReferenceFor(LinksSelectorPanelAbstract.class));
+
+ // components without factories
+ references.add(PanelUtil.cssResourceReferenceFor(AdditionalLinksPanel.class));
+
+ // non-conforming component factories
+ references.add(PanelUtil.cssResourceReferenceFor(MultiLineStringPanel.class));
+ }
+
+ protected final static Function<ComponentFactory, Iterable<CssResourceReference>> getCssResourceReferences =
+ (ComponentFactory input) -> {
+ final CssResourceReference cssResourceReference = input.getCssResourceReference();
+ return cssResourceReference != null?
+ Collections.singletonList(cssResourceReference):
+ Collections.<CssResourceReference>emptyList();
+ };
+
+
+ protected Set<CssResourceReference> cssResourceReferencesForAllComponents() {
+ // TODO mgrigorov: ISIS-537 temporary disabled to not mess up with Bootstrap styles
+ // Collection<ComponentFactory> componentFactories = getComponentFactoryRegistry().listComponentFactories();
+ return Sets.newLinkedHashSet(
+ // Iterables.concat(
+ // Iterables.transform(
+ // componentFactories,
+ // getCssResourceReferences))
+ );
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * filters Javascript header contributions so rendered to bottom of page.
+ *
+ * <p>
+ * Factored out for easy (informal) pluggability.
+ * </p>
+ */
+ protected void filterJavascriptContributions() {
+
+ setHeaderResponseDecorator(response -> {
+ return new ResourceAggregator(new JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
+ });
+
+ //[ahuber] no longer supported since wicket 8
+// setHeaderResponseDecorator(new IHeaderResponseDecorator()
+// {
+// @Override
+// public IHeaderResponse decorate(IHeaderResponse response)
+// {
+// // use this header resource decorator to load all JavaScript resources in the page
+// // footer (after </body>)
+// return new JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS");
+// }
+// });
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Map entity and action to provide prettier URLs.
+ *
+ * <p>
+ * Factored out for easy (informal) pluggability.
+ * </p>
+ */
+ protected void mountPages() {
+
+ mountPage("/signin", PageType.SIGN_IN);
+ mountPage("/signup", PageType.SIGN_UP);
+ mountPage("/signup/verify", PageType.SIGN_UP_VERIFY);
+ mountPage("/password/reset", PageType.PASSWORD_RESET);
+
+ mountPage("/entity/#{objectOid}", PageType.ENTITY);
+
+ // nb: action mount cannot contain {actionArgs}, because the default
+ // parameters encoder doesn't seem to be able to handle multiple args
+ mountPage("/action/${objectOid}/${actionOwningSpec}/${actionId}/${actionType}", PageType.ACTION_PROMPT);
+
+ mountPage("/logout", WicketLogoutPage.class);
+ }
+
+ protected void mountPage(final String mountPath, final PageType pageType) {
+ final Class<? extends Page> pageClass = this.pageClassRegistry.getPageClass(pageType);
+ mount(new MountedMapper(mountPath, pageClass));
+ }
+
+
+ // //////////////////////////////////////
+
+ private void logError(String validationError) {
+ log(validationError);
+ }
+
+ private static void logBanner() {
+ String msg = "################################################ ISIS METAMODEL VALIDATION ERRORS ################################################################";
+ log(msg);
+ }
+
+ private static void log(String msg) {
+ System.err.println(msg);
+ LOG.error(msg);
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Whether Wicket tags should be stripped from the markup, as specified by configuration settings..
+ *
+ * <p>
+ * If the <tt>isis.viewer.wicket.stripWicketTags</tt> is set, then this is used, otherwise the default is to strip
+ * the tags because they may break some CSS rules.
+ */
+ private boolean determineStripWicketTags(IsisConfiguration configuration) {
+ final boolean strip = configuration.getBoolean(STRIP_WICKET_TAGS_KEY, STRIP_WICKET_TAGS_DEFAULT);
+ return strip;
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * Whether the Ajax debug should be shown, as specified by configuration settings.
+ *
+ * <p>
+ * If the <tt>isis.viewer.wicket.ajaxDebugMode</tt> is set, then this is used, otherwise the default is to disable.
+ */
+ private boolean determineAjaxDebugModeEnabled(IsisConfiguration configuration) {
+ final boolean debugModeEnabled = configuration.getBoolean(AJAX_DEBUG_MODE_KEY, AJAX_DEBUG_MODE_DEFAULT);
+ return debugModeEnabled;
+ }
+
+ /**
+ * Whether the Wicket source plugin should be enabled, as specified by configuration settings.
+ *
+ * <p>
+ * If the <tt>isis.viewer.wicket.wicketSourcePlugin</tt> is set, then this is used, otherwise the default is to disable.
+ */
+ private boolean isWicketSourcePluginEnabled(IsisConfiguration configuration) {
+ final boolean pluginEnabled = configuration.getBoolean(WICKET_SOURCE_PLUGIN_KEY, WICKET_SOURCE_PLUGIN_DEFAULT);
+ return pluginEnabled;
+ }
+
+ // //////////////////////////////////////
+
+ @Override
+ protected void onDestroy() {
+ try {
+ if (isisSessionFactory != null) {
+ isisSessionFactory.destroyServicesAndShutdown();
+ }
+ getServletContext().setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, null);
+ super.onDestroy();
+ IsisContext.clear();
+ } catch(final RuntimeException ex) {
+ // symmetry with #init()
+ LOG.error("Failed to destroy", ex);
+ throw ex;
+ }
+ }
+
+ // //////////////////////////////////////
+
+ @Override
+ public RuntimeConfigurationType getConfigurationType() {
+ if(determiningConfigurationType) {
+ // avoiding an infinite loop; have already passed through here once before
+ // this time around, just delegate to web-inf
+ return super.getConfigurationType();
+ }
+ determineDeploymentTypeIfRequired();
+ return deploymentType.getConfigurationType();
+ }
+
+ protected IsisInjectModule newIsisModule(
+ final DeploymentCategory deploymentCategory,
+ final IsisConfigurationDefault isisConfiguration) {
+ return new IsisInjectModule(deploymentCategory, isisConfiguration);
+ }
+
+ // //////////////////////////////////////
+
+
+ protected void initWicketComponentInjection(final Injector injector) {
+ getComponentInstantiationListeners().add(new GuiceComponentInjector(this, injector, false));
+ }
+
+ // /////////////////////////////////////////////////
+ // Wicket Hooks
+ // /////////////////////////////////////////////////
+
+ /**
+ * Installs a {@link AuthenticatedWebSessionForIsis custom implementation}
+ * of Wicket's own {@link AuthenticatedWebSession}, effectively associating
+ * the Wicket session with the Isis's equivalent session object.
+ *
+ * <p>
+ * In general, it shouldn't be necessary to override this method.
+ */
+ @Override
+ protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
+ return AuthenticatedWebSessionForIsis.class;
+ }
+
+ /**
+ * Installs a {@link ConverterLocator} preconfigured with a number of
+ * implementations to support Isis specific objects.
+ */
+ @Override
+ protected IConverterLocator newConverterLocator() {
+ final ConverterLocator converterLocator = new ConverterLocator();
+ converterLocator.set(ObjectAdapter.class, new ConverterForObjectAdapter());
+ converterLocator.set(ObjectAdapterMemento.class, new ConverterForObjectAdapterMemento());
+ return converterLocator;
+ }
+
+ // /////////////////////////////////////////////////
+ // Component Factories
+ // /////////////////////////////////////////////////
+
+ @Override
+ public final ComponentFactoryRegistry getComponentFactoryRegistry() {
+ return componentFactoryRegistry;
+ }
+
+ // /////////////////////////////////////////////////
+ // Page Registry
+ // /////////////////////////////////////////////////
+
+ /**
+ * Access to other page types.
+ *
+ * <p>
+ * Non-final only for testing purposes; should not typically be overridden.
+ */
+ @Override
+ public PageClassRegistry getPageClassRegistry() {
+ return pageClassRegistry;
+ }
+
+ /**
+ * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+ */
+ @Override
+ public Class<? extends Page> getHomePage() {
+ return getPageClassRegistry().getPageClass(PageType.HOME);
+ }
+
+ /**
+ * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Class<? extends WebPage> getSignInPageClass() {
+ return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.SIGN_IN);
+ }
+
+ /**
+ * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+ */
+ @SuppressWarnings("unchecked")
+ public Class<? extends WebPage> getSignUpPageClass() {
+ return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.SIGN_UP);
+ }
+
+ /**
+ * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+ */
+ @SuppressWarnings("unchecked")
+ public Class<? extends WebPage> getSignUpVerifyPageClass() {
+ return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.SIGN_UP_VERIFY);
+ }
+
+ /**
+ * Delegates to the {@link #getPageClassRegistry() PageClassRegistry}.
+ */
+ @SuppressWarnings("unchecked")
+ public Class<? extends WebPage> getForgotPasswordPageClass() {
+ return (Class<? extends WebPage>) getPageClassRegistry().getPageClass(PageType.PASSWORD_RESET);
+ }
+
+ public AuthenticationSession getAuthenticationSession() {
+ return isisSessionFactory.getCurrentSession().getAuthenticationSession();
+ }
+
+ public DeploymentCategory getDeploymentCategory() {
+ return deploymentCategory;
+ }
+
+ @Override
+ public WicketViewerSettings getSettings() {
+ return settings;
+ }
}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java
index c3f91ce..34e9ed0 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java
@@ -64,7 +64,7 @@ public enum ActionResultResponseHandlingStrategy {
final ActionResultResponse resultResponse,
final IsisSessionFactory isisSessionFactory) {
final RequestCycle requestCycle = RequestCycle.get();
- AjaxRequestTarget target = requestCycle.find(AjaxRequestTarget.class);
+ AjaxRequestTarget target = requestCycle.find(AjaxRequestTarget.class).orElse(null);
if (target == null) {
// non-Ajax request => just stream the Lob to the browser
@@ -134,8 +134,9 @@ public enum ActionResultResponseHandlingStrategy {
* an Ajax request.
*/
private static class StreamAfterAjaxResponseBehavior extends AbstractAjaxBehavior {
-
- private final String fileName;
+ private static final long serialVersionUID = 1L;
+
+ private final String fileName;
private final IResourceStream resourceStream;
private final Duration cacheDuration;
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryActionsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryActionsPanel.java
index 88d2090..17b5e5b 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryActionsPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryActionsPanel.java
@@ -20,8 +20,8 @@ package org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions;
import java.util.List;
-import com.google.common.collect.Lists;
-
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.Page;
import org.apache.wicket.markup.head.CssHeaderItem;
@@ -33,8 +33,7 @@ import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.request.resource.CssResourceReference;
-import org.apache.isis.viewer.wicket.model.models.PageType;
-import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import com.google.common.collect.Lists;
/**
* A panel responsible to render the application actions as menu in a navigation bar.
@@ -46,12 +45,16 @@ import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
*/
public class TertiaryActionsPanel extends Panel {
- public TertiaryActionsPanel(String id, List<CssMenuItem> menuItems) {
+ private static final long serialVersionUID = 1L;
+
+ public TertiaryActionsPanel(String id, List<CssMenuItem> menuItems) {
super(id);
addLogoutLink(this);
final List<CssMenuItem> subMenuItems = flatten(menuItems);
final ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems", subMenuItems) {
- @Override
+ private static final long serialVersionUID = 1L;
+
+ @Override
protected void populateItem(ListItem<CssMenuItem> listItem) {
CssMenuItem subMenuItem = listItem.getModelObject();
if (subMenuItem.hasSubMenuItems()) {
@@ -63,7 +66,9 @@ public class TertiaryActionsPanel extends Panel {
};
WebComponent divider = new WebComponent("divider") {
- @Override
+ private static final long serialVersionUID = 1L;
+
+ @Override
protected void onConfigure() {
super.onConfigure();
@@ -84,13 +89,16 @@ public class TertiaryActionsPanel extends Panel {
}
private void addLogoutLink(MarkupContainer themeDiv) {
- Link logoutLink = new Link("logoutLink") {
+ Link<Void> logoutLink = new Link<Void>("logoutLink") {
+
+ private static final long serialVersionUID = 1L;
- @Override
+ @Override
public void onClick() {
getSession().invalidate();
setResponsePage(getSignInPage());
}
+
};
themeDiv.add(logoutLink);
}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java
index 425a6da..6892cff 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java
@@ -16,15 +16,14 @@
*/
package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable;
-import org.apache.wicket.ajax.attributes.IAjaxCallListener;
+import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackHeadersToolbar;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
-
/**
* Adapted from Wicket's own {@link AjaxFallbackHeadersToolbar}.
*/
@@ -38,7 +37,7 @@ public class IsisAjaxFallbackHeadersToolbar<S> extends IsisAjaxHeadersToolbar<S>
final IsisAjaxFallbackDataTable<?, S> table,
final CollectionContentsSortableDataProvider stateLocator)
{
- super(table, (ISortStateLocator<S>)stateLocator);
+ super(table, _Casts.uncheckedCast(stateLocator));
this.table = table;
table.setOutputMarkupId(true);
this.stateLocator = stateLocator;
@@ -55,18 +54,18 @@ public class IsisAjaxFallbackHeadersToolbar<S> extends IsisAjaxHeadersToolbar<S>
protected WebMarkupContainer newSortableHeader(final String borderId, final S property,
final ISortStateLocator<S> locator)
{
- return new IsisAjaxFallbackOrderByBorder<S>(borderId, table, property, locator, getAjaxCallListener());
+ return new IsisAjaxFallbackOrderByBorder<S>(borderId, table, property, locator/*, getAjaxCallListener()*/);
}
- /**
- * Returns a decorator that will be used to decorate ajax links used in sortable headers
- *
- * @return decorator or null for none
- */
- protected IAjaxCallListener getAjaxCallListener()
- {
- return null;
- }
+// /**
+// * Returns a decorator that will be used to decorate ajax links used in sortable headers
+// *
+// * @return decorator or null for none
+// */
+// protected IAjaxCallListener getAjaxCallListener()
+// {
+// return null;
+// }
// //////////////////////////////////////
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackOrderByBorder.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackOrderByBorder.java
index 92f1b7a..f0fdfac 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackOrderByBorder.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackOrderByBorder.java
@@ -16,15 +16,13 @@
*/
package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.attributes.IAjaxCallListener;
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.sort.AjaxFallbackOrderByBorder;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortState;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
-
public class IsisAjaxFallbackOrderByBorder<T> extends AjaxFallbackOrderByBorder<T> {
private static final long serialVersionUID = 1L;
@@ -34,8 +32,13 @@ public class IsisAjaxFallbackOrderByBorder<T> extends AjaxFallbackOrderByBorder<
private final ISortStateLocator<T> stateLocator;
- public IsisAjaxFallbackOrderByBorder(String id, IsisAjaxFallbackDataTable<?, ?> dataTable, T sortProperty, ISortStateLocator<T> stateLocator, IAjaxCallListener ajaxCallListener) {
- super(id, sortProperty, stateLocator, ajaxCallListener);
+ public IsisAjaxFallbackOrderByBorder(
+ String id,
+ IsisAjaxFallbackDataTable<?, ?> dataTable,
+ T sortProperty,
+ ISortStateLocator<T> stateLocator
+ /* removed in wicket 8, IAjaxCallListener ajaxCallListener*/) {
+ super(id, sortProperty, stateLocator/* removed in wicket 8, ajaxCallListener*/);
this.dataTable = dataTable;
this.stateLocator = stateLocator;
this.sortProperty = sortProperty;
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxNavigationToolbar.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxNavigationToolbar.java
index 189b48b..e837cf3 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxNavigationToolbar.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxNavigationToolbar.java
@@ -45,9 +45,11 @@ public class IsisAjaxNavigationToolbar extends AjaxNavigationToolbar {
private void addShowAllButton(final DataTable<?, ?> table) {
table.setOutputMarkupId(true);
- ((MarkupContainer)get("span")).add(new AjaxLink(ID_SHOW_ALL) {
+ ((MarkupContainer)get("span")).add(new AjaxLink<Void>(ID_SHOW_ALL) {
- @Override
+ private static final long serialVersionUID = 1L;
+
+ @Override
public void onClick(AjaxRequestTarget target) {
showAllItemsOn(table);
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java
index 46cf5d2..c615cbd 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java
@@ -36,7 +36,6 @@ import org.apache.wicket.extensions.markup.html.repeater.tree.ITreeProvider;
import org.apache.wicket.extensions.markup.html.repeater.tree.NestedTree;
import org.apache.wicket.extensions.markup.html.repeater.tree.Node;
import org.apache.wicket.extensions.markup.html.repeater.tree.theme.WindowsTheme;
-import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
@@ -102,7 +101,7 @@ class IsisToWicketTreeAdapter {
private static final long serialVersionUID = 1L;
@Override
- public void onClick(AjaxRequestTarget target) {
+ public void onClick(Optional<AjaxRequestTarget> target) {
toggleExpandCollapse.run();
}
@@ -416,7 +415,7 @@ class IsisToWicketTreeAdapter {
/**
* Wicket's model for collapse/expand state
*/
- private static class TreeExpansionModel extends AbstractReadOnlyModel<Set<TreeModel>> {
+ private static class TreeExpansionModel implements IModel<Set<TreeModel>> {
private static final long serialVersionUID = 648152234030889164L;
public static TreeExpansionModel of(Set<TreePath> expandedTreePaths) {
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
index 5319a87..f3f7a9f 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
@@ -55,7 +55,7 @@ public class ContainedButtonPanel extends PanelAbstract<Model<String>> {
private static final long serialVersionUID = 1L;
@Override
- protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ protected void onSubmit(final AjaxRequestTarget target) {
setDefaultFormProcessing(false);
ContainedButtonPanel.this.onSubmit();
if (target != null) {
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/EmptyChoiceProvider.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/EmptyChoiceProvider.java
index aaf752d..93d83d2 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/EmptyChoiceProvider.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/EmptyChoiceProvider.java
@@ -18,16 +18,15 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers;
import java.util.Collection;
-import org.apache.wicket.ajax.json.JSONException;
-import org.apache.wicket.ajax.json.JSONStringer;
import org.wicketstuff.select2.ChoiceProvider;
import org.wicketstuff.select2.Response;
import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
public class EmptyChoiceProvider extends ChoiceProvider<ObjectAdapterMemento> {
-
- public static final EmptyChoiceProvider INSTANCE = new EmptyChoiceProvider();
+ private static final long serialVersionUID = 1L;
+
+ public static final EmptyChoiceProvider INSTANCE = new EmptyChoiceProvider();
@Override
public String getDisplayValue(ObjectAdapterMemento object) {
@@ -44,10 +43,6 @@ public class EmptyChoiceProvider extends ChoiceProvider<ObjectAdapterMemento> {
}
@Override
- public void toJson(ObjectAdapterMemento choice, JSONStringer writer) throws JSONException {
- }
-
- @Override
public Collection<ObjectAdapterMemento> toChoices(Collection<String> ids) {
return null;
}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
index ee31549..bd9629e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
@@ -63,7 +63,9 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
extends FormAbstract<ObjectAdapter>
implements ScalarModelSubscriber2 {
- private static final String ID_OK_BUTTON = "okButton";
+ private static final long serialVersionUID = 1L;
+
+ private static final String ID_OK_BUTTON = "okButton";
public static final String ID_CANCEL_BUTTON = "cancelButton";
private static final String ID_FEEDBACK = "feedback";
@@ -117,8 +119,8 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
private static final long serialVersionUID = 1L;
@Override
- public void onSubmit(AjaxRequestTarget target, Form<?> form) {
- onOkSubmittedOf(target, form, this);
+ public void onSubmit(AjaxRequestTarget target) {
+ onOkSubmittedOf(target, getForm(), this);
}
@Override
@@ -129,16 +131,16 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
}
@Override
- protected void onError(AjaxRequestTarget target, Form<?> form) {
- target.add(form);
+ protected void onError(AjaxRequestTarget target) {
+ target.add(getForm());
}
}
: new AjaxButton(ID_OK_BUTTON, new ResourceModel("okLabel")) {
private static final long serialVersionUID = 1L;
@Override
- public void onSubmit(AjaxRequestTarget target, Form<?> form) {
- onOkSubmittedOf(target, form, this);
+ public void onSubmit(AjaxRequestTarget target) {
+ onOkSubmittedOf(target, getForm(), this);
}
@Override
@@ -149,8 +151,8 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
}
@Override
- protected void onError(AjaxRequestTarget target, Form<?> form) {
- target.add(form);
+ protected void onError(AjaxRequestTarget target) {
+ target.add(getForm());
}
};
okButton.add(new JGrowlBehaviour());
@@ -164,7 +166,7 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
private static final long serialVersionUID = 1L;
@Override
- public void onSubmit(final AjaxRequestTarget target, Form<?> form) {
+ public void onSubmit(final AjaxRequestTarget target) {
closePromptIfAny(target);
onCancelSubmitted(target);
@@ -175,7 +177,9 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
if (formExecutorContext.getPromptStyle().isInlineOrInlineAsIfEdit()) {
cancelButton.add(new FireOnEscapeKey() {
- @Override
+ private static final long serialVersionUID = 1L;
+
+ @Override
protected void respond(final AjaxRequestTarget target) {
onCancelSubmitted(target);
}
@@ -335,8 +339,9 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
}
static abstract class FireOnEscapeKey extends AbstractDefaultAjaxBehavior {
-
- private static final String PRE_JS =
+ private static final long serialVersionUID = 1L;
+
+ private static final String PRE_JS =
"" + "$(document).ready( function() { \n"
+ " $(document).bind('keyup', function(evt) { \n"
+ " if (evt.keyCode == 27) { \n";
--
To stop receiving notification emails like this one, please contact
ahuber@apache.org.