Package org.apache.isis.viewer.wicket.viewer

Source Code of org.apache.isis.viewer.wicket.viewer.IsisWicketApplication

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you under the Apache License, Version 2.0 (the
*  "License"); you may not use this file except in compliance
*  with the License.  You may obtain a copy of the License at
*
*        http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*/


package org.apache.isis.viewer.wicket.viewer;

import java.util.ServiceLoader;

import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.config.IsisConfigurationBuilder;
import org.apache.isis.core.commons.config.IsisConfigurationBuilderResourceStreams;
import org.apache.isis.core.commons.resource.ResourceStreamSource;
import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
import org.apache.isis.core.commons.resource.ResourceStreamSourceCurrentClassClassPath;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.webapp.config.ResourceStreamSourceForWebInf;
import org.apache.isis.runtimes.dflt.runtime.runner.IsisModule;
import org.apache.isis.runtimes.dflt.runtime.system.DeploymentType;
import org.apache.isis.runtimes.dflt.runtime.system.IsisSystem;
import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
import org.apache.isis.viewer.wicket.model.nof.AuthenticationSessionAccessor;
import org.apache.isis.viewer.wicket.ui.ComponentFactory;
import org.apache.isis.viewer.wicket.ui.app.cssrenderer.ApplicationCssRenderer;
import org.apache.isis.viewer.wicket.ui.app.imagecache.ImageCache;
import org.apache.isis.viewer.wicket.ui.app.imagecache.ImageCacheAccessor;
import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryList;
import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistryAccessor;
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.PageClassRegistryAccessor;
import org.apache.isis.viewer.wicket.ui.pages.PageType;
import org.apache.isis.viewer.wicket.viewer.imagecache.ImageCacheClassPath;
import org.apache.isis.viewer.wicket.viewer.integration.nof.WicketServer;
import org.apache.isis.viewer.wicket.viewer.integration.nof.WicketServerPrototype;
import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis;
import org.apache.isis.viewer.wicket.viewer.integration.wicket.ConverterForObjectAdapter;
import org.apache.isis.viewer.wicket.viewer.integration.wicket.ConverterForObjectAdapterMemento;
import org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis;
import org.apache.wicket.Application;
import org.apache.wicket.IConverterLocator;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Response;
import org.apache.wicket.authentication.AuthenticatedWebApplication;
import org.apache.wicket.authentication.AuthenticatedWebSession;
import org.apache.wicket.guice.GuiceComponentInjector;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.util.convert.ConverterLocator;

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;

/**
* Main application, subclassing the Wicket {@link Application} and bootstrapping
* Isis.
*
* <p>
* Its main responsibility is to allow the set of {@link ComponentFactory}s used to
* render the domain objects to be registered.  This type of customisation is commonplace.
* At a more fundamental level, also allows the {@link Page} implementation for each
* {@link PageType page type} to be overridden.  This is probably less common, because
* CSS can also be used for this purpose.
*
* <p>
* New {@link ComponentFactory}s can be specified in two ways.  The preferred approach is
* to use the {@link ServiceLoader} mechanism, whereby the {@link ComponentFactory}
* implementation class is specified in a file under <tt>META-INF/services</tt>
* See <tt>views-gmaps2</tt> for an example of this.  Including a jar that uses this mechanism
* on the classpath will automatically make the {@link ComponentFactory} defined within it
* available.
*
* <p>
* Alternatively, {@link ComponentFactory}s can be specified by overridding
* {@link #newComponentFactoryList()}.  This offers more fine-grained control for the ordering,
* but is more fiddly.
*
* <p>
* There are also a number of other pluggable hooks (similar way to other Wicket customizations)
* <ul>
* <li> {@link #newComponentFactoryList() (mentioned above)</li>
* <li> {@link #newComponentFactoryRegistry()} (uses the {@link ComponentFactoryList} provided by
*       {@link #newComponentFactoryList()})</li>
* <li> {@link #newPageClassList()}</li>
* <li> {@link #newPageRegistry()} (uses the {@link PageClassList} provided by {@link #newPageClassList()})</li>
* <li> {@link #newConverterLocator()} (probably should not be changed.)</li>
* <li> {@link #newRequestCycle(Request, Response)} (probably should not be changed.)</li>
* </ul>
*/
public class IsisWicketApplication extends AuthenticatedWebApplication implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, ImageCacheAccessor, ApplicationCssRenderer, AuthenticationSessionAccessor {

    private static final long serialVersionUID = 1L;

    private static final String WICKET_CONFIGURATION_TYPE_DEVELOPMENT = Application.DEVELOPMENT;
   
  /**
   * Convenience locator, downcasts inherited functionality.
   */
  public static IsisWicketApplication get() {
    return (IsisWicketApplication) AuthenticatedWebApplication.get();
  }
 
  /**
   * {@link Inject}ed when {@link #init() initialized}.
   */
  @Inject
  private ComponentFactoryRegistry componentFactoryRegistry;

    /**
     * {@link Inject}ed when {@link #init() initialized}.
     */
  @Inject
  private ImageCacheClassPath imageCache;
 
    /**
     * {@link Inject}ed when {@link #init() initialized}.
     */
    @Inject
  private PageClassRegistry pageClassRegistry;

    /**
     * {@link Inject}ed when {@link #init() initialized}.
     */
    @ApplicationCssUrl
    @Inject
    private String applicationCssUrl;

    /**
     * {@link Inject}ed when {@link #init() initialized}.
     */
    @Inject
    @SuppressWarnings("unused")
    private IsisSystem system;


  ///////////////////////////////////////////////////
  // constructor, init
  ///////////////////////////////////////////////////

  public IsisWicketApplication() {
  }
 
  /**
   * Initializes the application; in particular, bootstrapping the
   * Isis backend, and initializing the {@link ComponentFactoryRegistry}
   * to be used for rendering.
   */
  @Override
  protected void init() {
    super.init();
        getResourceSettings().setParentFolderPlaceholder("$up$");
   
        DeploymentType deploymentType = determineDeploymentType();
       
        IsisConfigurationBuilder isisConfigurationBuilder = createConfigBuilder();
       
        final IsisModule isisModule = new IsisModule(deploymentType, isisConfigurationBuilder);
        final Injector injector = Guice.createInjector(isisModule, newIsisWicketModule());
        injector.injectMembers(this);
   
        initWicketComponentInjection(injector);
  }

  
    private DeploymentType determineDeploymentType() {
        if (getConfigurationType().equalsIgnoreCase(WICKET_CONFIGURATION_TYPE_DEVELOPMENT)) {
            return new WicketServerPrototype();
        } else {
            return new WicketServer();
        }
    }

    private IsisConfigurationBuilder createConfigBuilder() {
        final ResourceStreamSource rssServletContext = new ResourceStreamSourceForWebInf(getServletContext());
        final ResourceStreamSource rssTcl = new ResourceStreamSourceContextLoaderClassPath();
        final ResourceStreamSource rssClasspath = new ResourceStreamSourceCurrentClassClassPath();
        IsisConfigurationBuilder isisConfigurationBuilder = new IsisConfigurationBuilderResourceStreams(rssTcl, rssClasspath, rssServletContext);
        return isisConfigurationBuilder;
    }


    protected void initWicketComponentInjection(final Injector injector) {
        addComponentInstantiationListener(new GuiceComponentInjector(this, injector));
    }

    /**
   * Override if required
   */
  protected Module newIsisWicketModule() {
        return new IsisWicketModule();
    }


  ///////////////////////////////////////////////////
  // 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 WebRequestCycleForIsis custom implementation} of
   * Wicket's own {@link RequestCycle}, hooking in to provide session and
   * transaction management across potentially multiple concurrent requests for
   * the same Wicket session.
   *
   * <p>
   * In general, it shouldn't be necessary to override this method.
   */
  @Override
  public RequestCycle newRequestCycle(Request request, Response response) {
    return new WebRequestCycleForIsis(this, (WebRequest) request, response);
  }

  /**
   * Installs a {@link ConverterLocator} preconfigured with a number of implementations
   * to support Isis specific objects.
   *
   * <p>
   * In general, it shouldn't be necessary to override this method.
   */
  @Override
  protected IConverterLocator newConverterLocator() {
      ConverterLocator converterLocator = new ConverterLocator();
      converterLocator.set(ObjectAdapter.class, new ConverterForObjectAdapter());
      converterLocator.set(ObjectAdapterMemento.class, new ConverterForObjectAdapterMemento());
      return converterLocator;
  }


    ///////////////////////////////////////////////////
    // Application Css
    ///////////////////////////////////////////////////

    protected String getApplicationCssUrl() {
        return applicationCssUrl;
    }
   
    /**
     * Renders the {@link #getApplicationCssUrl() application-supplied CSS}, if any.
     *
     * <p>
     * TODO: doing it this way, as opposed to simply {@link #addRenderHeadListener(IHeaderContributor) registering} an {@link IHeaderContributor}
     * does mean that the header is not first in the list, so can override other page-level CSS.  However, it still comes after
     * any component-level CSS, so is not ideal.
     */
    @Override
    public void renderApplicationCss(HtmlHeaderContainer container) {
        final String cssUrl = getApplicationCssUrl();
        if (cssUrl == null) {
            return;
        }
        final IHeaderResponse headerResponse = container.getHeaderResponse();
        headerResponse.renderCSSReference(cssUrl);
    }


  ///////////////////////////////////////////////////
  // Component Factories
  ///////////////////////////////////////////////////

  /**
   * The {@link ComponentFactoryRegistry} created in {@link #newComponentFactoryRegistry()}.
   */
  @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);
  }

  ///////////////////////////////////////////////////
  // Images
  ///////////////////////////////////////////////////

  @Override
    public ImageCache getImageCache() {
    return imageCache;
  }

  ///////////////////////////////////////////////////
    // Authentication Session
    ///////////////////////////////////////////////////

  @Override
    public AuthenticationSession getAuthenticationSession() {
      return IsisContext.getAuthenticationSession();
  }

}
TOP

Related Classes of org.apache.isis.viewer.wicket.viewer.IsisWicketApplication

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.