Package com.daikit.daikit4gxt.client.controller

Source Code of com.daikit.daikit4gxt.client.controller.BaseMainController

/**
* Copyright (C) 2013 DaiKit.com - daikit4gxt module (admin@daikit.com)
*
*         Project home : http://code.daikit.com/daikit4gxt
*
* Licensed 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 com.daikit.daikit4gxt.client.controller;

import java.util.HashMap;
import java.util.Map;

import com.daikit.commons.shared.bean.BaseUser;
import com.daikit.commons.shared.utils.DkObjectUtils;
import com.daikit.daikit4gxt.client.DkMain;
import com.daikit.daikit4gxt.client.action.BaseAction;
import com.daikit.daikit4gxt.client.action.processor.DkConnectionReturnProcessor;
import com.daikit.daikit4gxt.client.action.processor.DkStandardConnectionReturnProcessor;
import com.daikit.daikit4gxt.client.action.standard.BaseConnectAction;
import com.daikit.daikit4gxt.client.action.standard.BaseDisconnectAction;
import com.daikit.daikit4gxt.client.action.standard.BaseInvalidateUiAction;
import com.daikit.daikit4gxt.client.action.standard.BaseLoadInitializationDataAction;
import com.daikit.daikit4gxt.client.action.standard.BaseOnApplicationLoadedAction;
import com.daikit.daikit4gxt.client.action.standard.BaseOnStandaloneApplicationLoadedAction;
import com.daikit.daikit4gxt.client.action.standard.BaseReloadCurrentScreenAction;
import com.daikit.daikit4gxt.client.action.standard.BaseShowScreenAction;
import com.daikit.daikit4gxt.client.event.DkDisconnectEvent;
import com.daikit.daikit4gxt.client.event.DkDisconnectEvent.DisconnectEventHandler;
import com.daikit.daikit4gxt.client.event.DkDisconnectEvent.HasDisconnectEventHandlers;
import com.daikit.daikit4gxt.client.exception.ApplicationInitializationException;
import com.daikit.daikit4gxt.client.log.BaseLogger;
import com.daikit.daikit4gxt.client.rpc.BaseRpcMiscs;
import com.daikit.daikit4gxt.client.rpc.BaseRpcMiscsAsync;
import com.daikit.daikit4gxt.client.rpc.BaseRpcUser;
import com.daikit.daikit4gxt.client.rpc.BaseRpcUserAsync;
import com.daikit.daikit4gxt.client.screen.Screen;
import com.daikit.daikit4gxt.client.screen.WelcomeScreen;
import com.daikit.daikit4gxt.client.ui.BaseGui;
import com.daikit.daikit4gxt.client.ui.popup.ConnectionPopup;
import com.daikit.daikit4gxt.shared.bean.ConnectionData;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.sencha.gxt.widget.core.client.Component;
import com.sencha.gxt.widget.core.client.form.FormPanel;


/**
* Application controller class that all applications should extend.
*
* @author tcaselli
* @version $Revision$ Last modifier: $Author$ Last commit: $Date$
*/
public abstract class BaseMainController implements HasDisconnectEventHandlers
{

  private final BaseLogger log = BaseLogger.getLog(BaseMainController.class);

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // ATTRIBUTES
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * The Graphic User Interface.
   */
  private final BaseGui gui;
  private Screen currentScreen = null;
  private Screen previousScreen = null;
  private DkConnectionReturnProcessor connectionReturnProcessor = new DkStandardConnectionReturnProcessor();
  private String connectionPopupMessage = null;
  private boolean isInvalidatingUI = false;
  private String screenDisplayId;

  private final Map<String, Screen> createdScreens = new HashMap<String, Screen>();

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // CREATION
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * Only constructor.
   *
   * @param gui
   *           the application graphical user interface extending {@link BaseGui}
   */
  public BaseMainController(final BaseGui gui)
  {
    this.gui = gui;
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // ACTIONS
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * @return whether a chain action is currently running.
   */
  public boolean isChainActionRunning()
  {
    return BaseAction.isChainRunning();
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // CONNECTION
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * @return the connection popup instance
   */
  public ConnectionPopup getConnectionPopupInstance()
  {
    return ConnectionPopup.instance();
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // SCREEN MANAGEMENT
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * Call onBeforeScreenLeft() on the current screen if not null.
   *
   * @param currentAction
   *           the current chain action. To be able to restart it after.
   * @return whether or not the current screen can be changed to the given currentScreen.
   */
  public boolean onBeforeScreenLeft(final BaseAction<?> currentAction)
  {
    return this.currentScreen == null || this.currentScreen.onBeforeScreenLeft(currentAction);
  }

  /**
   * Call onScreenBeforeShow(previousDisplayedScreen) on the current screen. After the call to this function the
   * mainController.currentScreen is set to this and the show screen process (layout and chain actions) is done.
   *
   * @param previousDisplayedScreen
   *           the previous displayed screen
   * @param optionalArgs
   *           optional arguments
   */
  public void onScreenBeforeShow(final Screen previousDisplayedScreen, final Object... optionalArgs)
  {
    if (currentScreen != null)
    {
      currentScreen.baseBeforeScreenShow(previousDisplayedScreen, optionalArgs);
    }
  }

  /**
   * Create a {@link Screen} instance from the given class.<br>
   * This screen must be specified in the {@link #getSpecificScreenInstance(Class)} implementation.
   *
   * @param clazz
   *           the class of the screen to be created
   * @return the created screen instance
   */
  @SuppressWarnings("unchecked")
  public final <S extends Screen> S getScreenInstance(final Class<S> clazz)
  {
    S ret = (S) createdScreens.get(clazz.getName());
    if (ret == null)
    {
      final String className = clazz.getName();
      if (WelcomeScreen.class.getName().equals(className))
      {
        ret = (S) new WelcomeScreen();
        createdScreens.put(className, ret);
      }
      else
      {
        ret = (S) getSpecificScreenInstance(clazz);
        if (ret != null)
        {
          createdScreens.put(className, ret);
        }
        else
        {
          throw new ApplicationInitializationException("The given Screen class : " + className
              + " is not referenced in the Screen Creator.");
        }
      }
      log.debug("[ShowScreenAction Screen {" + className + "} Created]");
    }
    return ret;
  }

  /**
   * Method to be overridden to provide a way to access the default application screen. This screen will be loaded
   * first when the application starts.
   *
   * @return the default {@link Screen} class.
   */
  public abstract Class<? extends Screen> getDefaultScreen();

  /**
   * Method to be used to know if a screen is the currently displayed screen.
   *
   * @param screenClass
   *           the {@link Screen} class to test if it is the currently displayed screen.
   *
   * @return whether the given screen is the current one
   */
  public boolean isCurrentScreen(final Class<? extends Screen> screenClass)
  {
    return DkObjectUtils.equalsWithNull(screenClass, getCurrentScreen() == null ? null : getCurrentScreen().getClass());
  }

  /**
   * Show the screen corresponding to the given class.<br>
   * Given parameters will be sent to the screen via the {@link Screen#initializeScreen(Object...)} and
   * {@link Screen#getReloadScreenAction(boolean, Object...)} methods.
   *
   * @param screen
   *           the {@link Screen} to be shown.
   * @param initializationArgs
   *           parameters to be sent to the screen for initialization and reload.
   */
  public void showScreen(final Class<? extends Screen> screen, final Object... initializationArgs)
  {
    BaseShowScreenAction.get(screen, initializationArgs).execute();
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // REFRESH / RELOAD CURRENT SCREEN
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * Wrapper to {@link #refreshScreen(boolean, Object...)} with force=false and no optional argument
   */
  public void refreshScreen()
  {
    refreshScreen(false);
  }

  /**
   * Refresh current screen by getting the screen reload action and executing it after having called
   * {@link Screen#onBeforeScreenRefresh(BaseAction)}
   *
   * @param force
   *           to force layout refresh
   * @param optionalArgs
   *           to pass optional arguments to {@link Screen#getReloadScreenAction(boolean, Object...)} method.
   */
  public void refreshScreen(final boolean force, final Object... optionalArgs)
  {
    final BaseAction<?> reloadScreenAction = BaseReloadCurrentScreenAction.get(force, optionalArgs);
    if (reloadScreenAction != null)
    {
      if (currentScreen.onBeforeScreenRefresh(reloadScreenAction))
      {
        reloadScreenAction.execute();
      }
    }
    else
    {
      log.error("Don't call Main.controller().refreshScreen() before having shown the screen.");
    }
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // URL METHODS
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * Call URL , for example to download a file.
   *
   * @param url
   *           the url to be called (must be absolute starting with http://)
   */
  public void callUrl(final String url)
  {
    final FormPanel hyperlinkFormPanel = gui.getHyperlinkCallerFormPanel();
    hyperlinkFormPanel.setAction(url);
    log.debug("CALL URL : " + url);
    hyperlinkFormPanel.submit();
  }

  /**
   * Open a new window (or tab depending on the browser) and display the page with the given url.
   *
   * @param url
   *           the url to be called (must be absolute starting with http://)
   */
  public void openUrlInNewWindow(final String url)
  {
    openHyperlinkInNewWindow(url);
  }

  private static native void openHyperlinkInNewWindow(String url)/*-{
                                            window.open(url);
                                            }-*/;

  /**
   * Open a new tab (or window depending on the browser) and display the page with the given url.
   *
   * @param url
   *           the url to be called (must be absolute starting with http://)
   */
  public void openUrlInNewTab(final String url)
  {
    openHyperlinkInNewTab(url);
  }

  private static native void openHyperlinkInNewTab(String url)/*-{
                                          window.open(url, '_blank');
                                          }-*/;

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // METHODS TO BE OVERRIDEN
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * Method intended to create Screen instances according to their Class. This is useful because there is no way to
   * instantiate an Object from its class excepted with a call to "new Class(...)". Class.newInstance() is not
   * compilable with GWT.
   *
   * @param clazz
   *           the Class for the instance to be created.
   * @return a Screen object
   */
  protected abstract <S extends Screen> Screen getSpecificScreenInstance(Class<S> clazz);

  /**
   * Return the action to be executed after Connection success. May be overridden to provide custom action.
   *
   * @param previousLoggedUser
   *           the previous logged user
   * @return the created {@link BaseAction}
   */
  public BaseAction<?> getSpecificAfterConnectAction(final BaseUser previousLoggedUser)
  {
    return BaseLoadInitializationDataAction.get();
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // RPCS
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  protected BaseRpcUserAsync rpcUser;
  protected BaseRpcMiscsAsync rpcMiscs;

  /**
   * Method to be overridden if you want to override {@link BaseRpcUser}
   *
   * @return the asynchronous interface client side implementation.
   */
  public BaseRpcUserAsync baseRpcUser()
  {
    if (rpcUser == null)
    {
      rpcUser = GWT.create(BaseRpcUser.class);
    }
    return rpcUser;
  }

  /**
   * Method to be overridden if you want to override {@link BaseRpcMiscs}
   *
   * @return the asynchronous interface client side implementation.
   */
  public BaseRpcMiscsAsync baseRpcMiscs()
  {
    if (rpcMiscs == null)
    {
      rpcMiscs = GWT.create(BaseRpcMiscs.class);
    }
    return rpcMiscs;
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // METHODS - UI
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * Do invalidate UI without action (GUI+ currentScreen). This method is also called by the
   * {@link BaseInvalidateUiAction}.
   *
   * @param doForceLayout
   *           to force the application layout refresh
   */
  public void invalidateUi(final boolean doForceLayout)
  {
    isInvalidatingUI = true;
    gui.invalidateUi();
    if (currentScreen != null)
    {
      currentScreen.baseInvalidateUi();
    }
    if (doForceLayout)
    {
      gui.getViewport().forceLayout();
    }
    isInvalidatingUI = false;
  }

  /**
   * Method called when user wants to changed full screen status.
   *
   * @param fullScreen
   *           indicating whether the application should now be displayed in full screen.
   */
  public void onFullScreen(final boolean fullScreen)
  {
    DkMain.model().setFullSize(fullScreen);
    gui.onFullScreenChanged();
    if (currentScreen != null)
    {
      currentScreen.baseOnFullScreenChanged();
    }
    invalidateUi(true);
  }

  /**
   * Method called once the application is loaded. Wrapper to {@link #getOnApplicationLoadedAction()}.execute()
   */
  public void onApplicationLoaded()
  {
    getOnApplicationLoadedAction().execute();
  }

  /**
   *
   * @return the {@link BaseAction} to be executed once the application is loaded.
   */
  public BaseAction<?> getOnApplicationLoadedAction()
  {
    return DkMain.config().isStandalone() ? BaseOnStandaloneApplicationLoadedAction.get() : BaseOnApplicationLoadedAction.get();
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // GETTERS / SETTERS
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * @return the graphical user interface extending {@link BaseGui}
   */
  public BaseGui getGui()
  {
    return gui;
  }

  /**
   * @return the current screen extending {@link Screen}
   */
  public Screen getCurrentScreen()
  {
    return currentScreen;
  }

  /**
   * Set the current screen. This method <b>MUST NOT</b> be called directly but only via the action
   * {@link BaseShowScreenAction} or the controller method {@link #showScreen(Class, Object...)}
   *
   * @param currentScreen
   *           the screen instance to be shown.
   */
  public final void setCurrentScreen(final Screen currentScreen)
  {
    this.currentScreen = currentScreen;
  }

  /**
   * @return the previous screen extending {@link Screen}
   */
  public Screen getPreviousScreen()
  {
    return previousScreen;
  }

  /**
   * Sets the previous displayed screen. This method <b>MUST NOT</b> be called directly but only via the action
   * {@link BaseShowScreenAction} or the controller method {@link #showScreen(Class, Object...)}
   *
   * @param previousScreen
   *           the previousScreen to set
   */
  public void setPreviousScreen(final Screen previousScreen)
  {
    this.previousScreen = previousScreen;
  }

  /**
   * @return the connectionPopupMessage
   */
  public String getConnectionPopupMessage()
  {
    return connectionPopupMessage;
  }

  /**
   * @param connectionPopupMessage
   *           the connectionPopupMessage to set
   */
  public void setConnectionPopupMessage(final String connectionPopupMessage)
  {
    this.connectionPopupMessage = connectionPopupMessage;
  }

  /**
   * @return the connectionReturnProcessor
   */
  public DkConnectionReturnProcessor getConnectionReturnProcessor()
  {
    return connectionReturnProcessor;
  }

  /**
   * @param connectionReturnProcessor
   *           the connectionReturnProcessor to set
   */
  public void setConnectionReturnProcessor(final DkConnectionReturnProcessor connectionReturnProcessor)
  {
    this.connectionReturnProcessor = connectionReturnProcessor;
  }

  /**
   * @return the screenDisplayId
   */
  public String getScreenDisplayId()
  {
    return screenDisplayId;
  }

  /**
   * @param screenDisplayId
   *           the screenDisplayId to set
   */
  public void setScreenDisplayId(final String screenDisplayId)
  {
    this.screenDisplayId = screenDisplayId;
  }

  /**
   * @return the isInvalidatingUI
   */
  public boolean isInvalidatingUI()
  {
    return isInvalidatingUI;
  }

  /**
   * @param isInvalidatingUI
   *           the isInvalidatingUI to set
   */
  public void setInvalidatingUI(final boolean isInvalidatingUI)
  {
    this.isInvalidatingUI = isInvalidatingUI;
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // CONNECTION / DISCONNECTION IN CASE OF STANDALONE APPLICATIONS
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * In case of a stand-alone application this method execute the {@link BaseConnectAction} with given parameters
   *
   * @param connectionData
   *           the {@link ConnectionData}
   */
  public void doConnect(final ConnectionData connectionData)
  {
    doConnect(connectionData, null);
  }

  /**
   * In case of a stand-alone application this method execute the {@link BaseConnectAction} with given parameters
   *
   * @param connectionData
   *           the {@link ConnectionData}
   * @param customChainActionIfLoginSucceded
   *           an eventual chain action to execute if connection succeeded (it may be null)
   */
  public void doConnect(final ConnectionData connectionData, final BaseAction<?> customChainActionIfLoginSucceded)
  {
    BaseConnectAction.get(connectionData, customChainActionIfLoginSucceded).execute();
  }

  /**
   * In case of a stand-alone application this method execute the {@link BaseDisconnectAction}
   */
  public void doDisconnect()
  {
    BaseDisconnectAction.get().execute();
  }

  /**
   * Call onBeforeDisconnect() on the current screen if not null.
   *
   * @param currentAction
   *           the current chain action. To be able to restart it after.
   * @return whether or not the user can disconnect now. For example if there are things to be saved before you can
   *         return false in this method and display a pop-up asking to save.
   */
  public boolean onBeforeDisconnect(final BaseAction<?> currentAction)
  {
    return this.currentScreen == null || this.currentScreen.onBeforeDisconnect(currentAction);
  }

  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  // EVENT HANDLING
  // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  /**
   * @see Component#fireEvent(GwtEvent)
   * @param event
   *           the event
   */
  public void fireEvent(final GwtEvent<?> event)
  {
    getGui().getViewport().fireEvent(event);
  }

  @Override
  public HandlerRegistration addDisconnectEventHandler(final DisconnectEventHandler handler)
  {
    return getGui().getViewport().addHandler(handler, DkDisconnectEvent.getType());
  }
}
TOP

Related Classes of com.daikit.daikit4gxt.client.controller.BaseMainController

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.