Package bufferings.ktr.wjr.client

Source Code of bufferings.ktr.wjr.client.WjrView

/*
* Copyright 2010 bufferings[at]gmail.com
*
* 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 bufferings.ktr.wjr.client;

import static bufferings.ktr.wjr.client.ui.widget.JQueryUI.*;
import static bufferings.ktr.wjr.shared.util.Preconditions.*;

import java.util.ArrayList;
import java.util.List;

import bufferings.ktr.wjr.client.ui.WjrButtonPanel;
import bufferings.ktr.wjr.client.ui.WjrDialogPanel;
import bufferings.ktr.wjr.client.ui.WjrPopupPanel;
import bufferings.ktr.wjr.client.ui.WjrResultPanel;
import bufferings.ktr.wjr.client.ui.WjrTracePanel;
import bufferings.ktr.wjr.client.ui.WjrTreePanel;
import bufferings.ktr.wjr.client.ui.widget.WjrTree;
import bufferings.ktr.wjr.client.ui.widget.WjrTreeItem;
import bufferings.ktr.wjr.shared.model.WjrClassItem;
import bufferings.ktr.wjr.shared.model.WjrConfig;
import bufferings.ktr.wjr.shared.model.WjrMethodItem;
import bufferings.ktr.wjr.shared.model.WjrStore;
import bufferings.ktr.wjr.shared.model.WjrStoreItem;
import bufferings.ktr.wjr.shared.model.WjrStoreItem.State;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;

/**
* The view of the Kotori Web JUnit Runner.
*
* This class controls all the view components of KtrWjr.
*
* @author bufferings[at]gmail.com
*/
public class WjrView extends Composite implements WjrDisplay,
    SelectionHandler<WjrTreeItem>, ValueChangeHandler<WjrTreeItem> {

  private static final String LOADING_POPUP_TEXT = "Loading...";

  private static final String RUNNING_POPUP_TEXT = "Running...";

  private static final String CANCELING_POPUP_TEXT = "Canceling...";

  private static WjrViewUiBinder uiBinder = GWT.create(WjrViewUiBinder.class);

  interface WjrViewUiBinder extends UiBinder<Widget, WjrView> {
  }

  /**
   * The view event handler.
   */
  protected WjrDisplayHandler handler;

  /**
   * The container widget of this view.
   */
  protected HasWidgets container;

  /**
   * The result panel which shows the result summary of the tests.
   */
  @UiField
  protected WjrResultPanel resultPanel;

  /**
   * The tree panel which shows the test cases and some icon buttons.
   */
  @UiField
  protected WjrTreePanel treePanel;

  /**
   * The button panel of the run and the cancel button.
   */
  @UiField
  protected WjrButtonPanel buttonPanel;

  /**
   * The trace panel which shows the trace and the log.
   */
  @UiField
  protected WjrTracePanel tracePanel;

  /**
   * The popup panel which is shown while the process is running.
   */
  protected WjrPopupPanel popup;

  /**
   * The dialog panel which shows the error message.
   */
  protected WjrDialogPanel dialog;

  /**
   * The tree items to associate with the store items.
   */
  protected List<WjrTreeItem> treeItems = new ArrayList<WjrTreeItem>();

  /**
   * The store items to associate with the tree items. The store items is read
   * only.
   */
  protected List<WjrStoreItem> storeItems = new ArrayList<WjrStoreItem>();

  /**
   * Whether loading the store or not.
   */
  protected boolean loading = false;

  /**
   * Whether running the tests or not.
   */
  protected boolean running = false;

  /**
   * Whether canceled running the tests or not.
   */
  protected boolean canceled = false;

  /**
   * The configuration.
   */
  protected WjrConfig config = new WjrConfig();

  /**
   * UiFactory method which creates WjrButtonPanel and handles its events.
   *
   * @return The instance of the WjrButtonPanel.
   */
  @UiFactory
  protected WjrButtonPanel createWjrButtonPanel() {
    return new WjrButtonPanel(new WjrButtonPanel.Handler() {

      public void onButtonClicked(ClickEvent evt) {
        if (!running) {
          startRunning();
        } else {
          cancelRunning();
        }
      }
    });
  }

  /**
   * UiFactory method which creates WjrTreePanel and handles its events.
   *
   * @return The instance of the WjrTreePanel.
   */
  @UiFactory
  protected WjrTreePanel createWjrTreePanel() {
    return new WjrTreePanel(new WjrTreePanel.Handler() {
      public void onCheckAllButtonClicked(ClickEvent event) {
        updateRunButtonDisabled();
      }

      public void onClearButtonClicked(ClickEvent event) {
        handler.onClearButtonClick();
      }

      public void onReloadButtonClicked(ClickEvent event) {
        startReloading();
      }

      public void onUncheckAllButtonClicked(ClickEvent event) {
        updateRunButtonDisabled();
      }
    });
  }

  /**
   * {@inheritDoc}
   */
  public void go(WjrDisplayHandler handler, HasWidgets container) {
    checkNotNull(handler, "The handler parameter is null.");
    checkNotNull(container, "The container parameter is null.");
    this.handler = handler;
    this.container = container;

    dialog = new WjrDialogPanel("Kotori Web JUnit Runner");
    popup = new WjrPopupPanel();
  }

  /**
   * {@inheritDoc}
   */
  public void notifyLoadingConfigSucceeded(WjrConfig config) {
    finishLoadingConfig(config);
    startReloading();
  }

  /**
   * {@inheritDoc}
   */
  public void notifyLoadingConfigFailed(WjrConfig config, Throwable caught) {
    dialog.show("Cannot load the tests.", caught);
    finishLoadingConfig(config);
  }

  /**
   * Performs the post-processing of loading configuration.
   *
   * Shows the KtrWjr panels.
   *
   * @param config
   *          The user configuration.
   */
  private void finishLoadingConfig(WjrConfig config) {
    initWidget(uiBinder.createAndBindUi(this));

    applyConfig(config);
    setData(new WjrStore());
    updateRunButtonDisabled();
    updateTreeButtonsDisabled();

    container.add(this);
  }

  /**
   * Sets the configuration.
   *
   * @param newConfig
   *          The configuration
   */
  private void applyConfig(WjrConfig newConfig) {
    config = newConfig;
    tracePanel.setTraceTabVisible(config.isLogHookEnabled());
  }

  /**
   * {@inheritDoc}
   */
  public void notifyLoadingStoreSucceeded() {
    finishReloading();
  }

  /**
   * {@inheritDoc}
   */
  public void notifyLoadingStoreFailed(Throwable caught) {
    dialog.show("Cannot load the tests.", caught);
    finishReloading();
  }

  /**
   * {@inheritDoc}
   */
  public void notifyRunningFinished() {
    if (running) {
      running = false;
      canceled = false;
      buttonPanel.changeToRunButton();
      popup.hide();
      updateRunButtonDisabled();
      updateTreeButtonsDisabled();
    }
  }

  /**
   * {@inheritDoc}
   */
  public void setData(WjrStore store) {
    treeItems.clear();
    storeItems.clear();

    updateTracePanel(null);
    updateResultPanel(store);

    WjrTree tree = treePanel.getTree();
    tree.removeItems();

    List<WjrClassItem> classStoreItems = store.getClassItems();
    for (WjrClassItem classStoreItem : classStoreItems) {
      WjrTreeItem classTreeItem = createTreeItem(classStoreItem);
      storeItems.add(classStoreItem);
      treeItems.add(classTreeItem);

      List<WjrMethodItem> methodStoreItems =
        store.getMethodItems(classStoreItem.getClassName());
      storeItems.addAll(methodStoreItems);
      for (WjrMethodItem wjrMethodItem : methodStoreItems) {
        WjrTreeItem methodTreeItem = createTreeItem(wjrMethodItem);
        treeItems.add(methodTreeItem);
        classTreeItem.addItem(methodTreeItem);
      }

      tree.addItem(classTreeItem);
    }
  }

  /**
   * {@inheritDoc}
   */
  public List<WjrMethodItem> getCheckedMethodItems() {
    List<WjrMethodItem> ret = new ArrayList<WjrMethodItem>();
    for (int i = 0, n = treeItems.size(); i < n; i++) {
      if (treeItems.get(i).isChecked()) {
        WjrStoreItem storeItem = storeItems.get(i);
        if (storeItem instanceof WjrMethodItem) {
          ret.add((WjrMethodItem) storeItem);
        }
      }
    }
    return ret;
  }

  /**
   * {@inheritDoc}
   */
  public void repaintAllTreeItems(WjrStore store) {
    updateResultPanel(store);
    for (int i = 0, n = treeItems.size(); i < n; i++) {
      repaintTreeItem(treeItems.get(i), storeItems.get(i));
    }
  }

  /**
   * {@inheritDoc}
   */
  public void repaintTreeItemAncestors(WjrStore store, WjrMethodItem methodItem) {
    updateResultPanel(store);

    WjrTreeItem treeItem = treeItems.get(storeItems.indexOf(methodItem));
    repaintTreeItem(treeItem, methodItem);

    WjrTreeItem parentTreeItem = treeItem.getParentItem();
    repaintTreeItem(parentTreeItem, storeItems.get(treeItems
      .indexOf(parentTreeItem)));
  }

  /**
   * {@inheritDoc}
   */
  public void onSelection(SelectionEvent<WjrTreeItem> event) {
    WjrTreeItem treeItem = event.getSelectedItem();
    if (!treeItem.isSelected()) {
      treeItem.setSelectedStyle("");
      updateTracePanel(null);
    } else {
      WjrStoreItem storeItem =
        (WjrStoreItem) storeItems.get(treeItems.indexOf(treeItem));
      treeItem.setSelectedStyle(getTreeItemSelectedStyle(storeItem));
      updateTracePanel(storeItem);
    }
  }

  /**
   * {@inheritDoc}
   */
  public void onValueChange(ValueChangeEvent<WjrTreeItem> event) {
    updateRunButtonDisabled();
  }

  /**
   * Starts reloading the test store.
   */
  private void startReloading() {
    if (!loading) {
      loading = true;
      setData(new WjrStore());
      updateRunButtonDisabled();
      updateTreeButtonsDisabled();

      popup.setText(LOADING_POPUP_TEXT);
      popup.show();
      handler.onLoadStore();
    }
  }

  /**
   * Performs the post-processing of reloading.
   */
  private void finishReloading() {
    if (loading) {
      loading = false;
      updateRunButtonDisabled();
      updateTreeButtonsDisabled();
      popup.hide();
    }
  }

  /**
   * Starts running the test methods.
   */
  private void startRunning() {
    if (!running) {
      running = true;
      canceled = false;
      buttonPanel.changeToCancelButton();
      updateTreeButtonsDisabled();
      popup.setText(RUNNING_POPUP_TEXT);
      popup.show();
      handler.onRunButtonClick();
    }
  }

  /**
   * Cancel running the test methods.
   */
  private void cancelRunning() {
    if (running && !canceled) {
      canceled = true;
      updateRunButtonDisabled();
      popup.setText(CANCELING_POPUP_TEXT);
      handler.onCancelButtonClick();
    }
  }

  /**
   * Updates the tree panel buttons' disabled.
   */
  private void updateTreeButtonsDisabled() {
    if (treeItems.size() == 0) {
      treePanel.setCheckAllButtonDisabled(true);
      treePanel.setUncheckAllButtonDisabled(true);
      treePanel.setExpandAllButtonDisabled(true);
      treePanel.setCollapseAllButtonDisabled(true);
      treePanel.setClearButtonDisabled(true);
      if (loading) {
        treePanel.setReloadButtonDisabled(true);
      } else {
        treePanel.setReloadButtonDisabled(false);
      }
    } else {
      treePanel.setCheckAllButtonDisabled(false);
      treePanel.setUncheckAllButtonDisabled(false);
      treePanel.setExpandAllButtonDisabled(false);
      treePanel.setCollapseAllButtonDisabled(false);
      if (running) {
        treePanel.setClearButtonDisabled(true);
        treePanel.setReloadButtonDisabled(true);
      } else {
        treePanel.setClearButtonDisabled(false);
        treePanel.setReloadButtonDisabled(false);
      }
    }
  }

  /**
   * Create the tree item from the test store item.
   *
   * @param storeItem
   *          The test store item.
   * @return The tree item.
   */
  private WjrTreeItem createTreeItem(WjrStoreItem storeItem) {
    WjrTreeItem treeItem = new WjrTreeItem();
    treeItem.addSelectionHandler(this);
    treeItem.addValueChangeHandler(this);
    repaintTreeItem(treeItem, storeItem);
    return treeItem;
  }

  /**
   * Updates the result panel from the test store.
   *
   * @param store
   *          The test store.
   */
  private void updateResultPanel(WjrStore store) {
    int runningsCount = store.getRunningCount() + store.getRetryWaitingCount();
    int runsCount =
      store.getTotalCount() - store.getNotYetCount() - runningsCount;
    resultPanel.updateResults(
      runningsCount,
      runsCount,
      store.getTotalCount(),
      store.getErrorCount(),
      store.getFailureCount());
  }

  /**
   * Updates the trace panel with the selected tree item.
   *
   * @param selectedItem
   *          The selected tree item. If no item is selected, set null.
   */
  private void updateTracePanel(WjrStoreItem selectedItem) {
    tracePanel.setTrace(getTreeItemTrace(selectedItem));
    if (config.isLogHookEnabled()) {
      tracePanel.setLog(getTreeItemLog(selectedItem));
    }
  }

  /**
   * Repaints the tree item by the store item.
   *
   * @param treeItem
   *          The tree item.
   * @param storeItem
   *          The test store item.
   */
  private void repaintTreeItem(WjrTreeItem treeItem, WjrStoreItem storeItem) {
    treeItem.setText(getTreeItemText(storeItem));
    treeItem.setIcon(getTreeItemIcon(storeItem));
    if (treeItem.isSelected()) {
      treeItem.setSelectedStyle(getTreeItemSelectedStyle(storeItem));
      updateTracePanel(storeItem);
    }
  }

  /**
   * Updates the run (or cancel) button disabled.
   */
  private void updateRunButtonDisabled() {
    if (loading) {
      buttonPanel.setButtonDisabled(true);
      return;
    }

    if (running) {
      buttonPanel.setButtonDisabled(canceled);
      return;
    }

    boolean checked = false;
    for (WjrTreeItem treeItem : treeItems) {
      if (treeItem.isChecked()) {
        checked = true;
        break;
      }
    }
    buttonPanel.setButtonDisabled(!checked);
  }

  /**
   * Gets the tree item icon from the test store item.
   *
   * @param storeItem
   *          The test store item.
   * @return The tree item icon css class of JQueryUI.
   */
  private String getTreeItemIcon(WjrStoreItem storeItem) {
    switch (storeItem.getState()) {
    case SUCCESS:
      return UI_ICON_CHECK;
    case FAILURE:
      return UI_ICON_NOTICE;
    case ERROR:
      return UI_ICON_CLOSE;
    case NOT_YET:
      return UI_ICON_MINUS;
    case RUNNING:
      return UI_ICON_ARRORREFRESH_1_W;
    case RETRY_WAITING:
      return UI_ICON_CLOCK;
    default:
      // GWT does not emulate format, so i use the format method of Guice's
      // Preconditions class.
      throw new AssertionError(format("Unknown state. [State=%s]", storeItem
        .getState()
        .name()));
    }
  }

  /**
   * Gets the tree item selected style from the test store item.
   *
   * @param storeItem
   *          The test store item.
   * @return The tree item selected css class name of JQueryUI.
   */
  private String getTreeItemSelectedStyle(WjrStoreItem storeItem) {
    switch (storeItem.getState()) {
    case SUCCESS:
    case NOT_YET:
    case RUNNING:
    case RETRY_WAITING:
      return UI_STATE_HIGHLIGHT;
    case FAILURE:
    case ERROR:
      return UI_STATE_ERROR;
    default:
      // GWT does not emulate format, so i use the format method of Guice's
      // Preconditions class.
      throw new AssertionError(format("Unknown state. [State=%s]", storeItem
        .getState()
        .name()));
    }
  }

  /**
   * Gets the tree item text from the test store item.
   *
   * @param storeItem
   *          The test store item.
   * @return The tree item text.
   */
  private String getTreeItemText(WjrStoreItem storeItem) {
    if (storeItem instanceof WjrClassItem) {
      return getTreeItemTextFromClassItem((WjrClassItem) storeItem);
    } else {
      return getTreeItemTextFromMethodItem((WjrMethodItem) storeItem);
    }
  }

  /**
   * Gets the tree item text from the test class item.
   *
   * @param classItem
   *          The test class item.
   * @return The tree item text.
   */
  private String getTreeItemTextFromClassItem(WjrClassItem classItem) {
    return classItem.getClassName();
  }

  /**
   * Gets the tree item text from the test method item.
   *
   * @param methodItem
   *          The test method item.
   * @return The tree item text.
   */
  private String getTreeItemTextFromMethodItem(WjrMethodItem methodItem) {
    StringBuilder sb = new StringBuilder(methodItem.getMethodName());

    if (methodItem.getState() == State.RETRY_WAITING) {
      sb.append(" (").append(getRetryWaitingString(methodItem)).append(")");
    } else if (methodItem.getState() != State.NOT_YET
      && methodItem.getState() != State.RUNNING) {
      sb.append(" (").append(getTimeString(methodItem)).append(")");
    }

    return sb.toString();
  }

  /**
   * Gets the time string from the test method item.
   *
   * @param methodItem
   *          The test method item.
   * @return The time string.
   */
  private String getTimeString(WjrMethodItem methodItem) {
    StringBuilder sb = new StringBuilder();

    String time = methodItem.getTime();
    sb.append(time.length() > 0 ? time : "-").append("ms");

    if (config.isCpumsEnabled()) {
      String cpuTime = methodItem.getCpuTime();
      sb.append(" ");
      sb.append(cpuTime.length() > 0 ? cpuTime : "-").append("cpu_ms");
    }

    if (config.isApimsEnabled()) {
      String apiTime = methodItem.getApiTime();
      sb.append(" ");
      sb.append(apiTime.length() > 0 ? apiTime : "-").append("api_ms");
    }

    return sb.toString();
  }

  /**
   * Gets the retry waiting string from the test method item.
   *
   * @param methodItem
   *          The test method item.
   * @return The time string.
   */
  private Object getRetryWaitingString(WjrMethodItem methodItem) {
    StringBuilder sb = new StringBuilder();
    sb.append("waiting:");
    sb.append(methodItem.getWaitingSeconds());
    sb.append("s retry count:");
    sb.append(methodItem.getRetryCount());
    sb.append("/");
    sb.append(methodItem.getMaxRetryCount());
    return sb.toString();
  }

  /**
   * Gets the tree item log from the test store item.
   *
   * @param storeItem
   *          The test store item.
   * @return The tree item log.
   */
  private String getTreeItemLog(WjrStoreItem storeItem) {
    if (storeItem == null || storeItem instanceof WjrClassItem) {
      return null;
    } else {
      WjrMethodItem methodItem = (WjrMethodItem) storeItem;
      if (methodItem.getState() == State.NOT_YET
        || methodItem.getState() == State.RUNNING
        || methodItem.getState() == State.RETRY_WAITING) {
        return null;
      } else {
        String log = methodItem.getLog();
        return getTimeString(methodItem) + (log != null ? "\n" + log : "");
      }
    }
  }

  /**
   * Gets the tree item trace from the test store item.
   *
   * @param storeItem
   *          The test store item.
   * @return The tree item trace. If the storeItem is null or the trace is not
   *         set, returns null.
   */
  private String getTreeItemTrace(WjrStoreItem storeItem) {
    if (storeItem == null || storeItem instanceof WjrClassItem) {
      return null;
    } else {
      WjrMethodItem methodItem = (WjrMethodItem) storeItem;
      if (methodItem.getState() == State.NOT_YET
        || methodItem.getState() == State.RUNNING
        || methodItem.getState() == State.RETRY_WAITING) {
        return null;
      } else {
        String trace = methodItem.getTrace();
        return (trace != null ? trace : "");
      }
    }
  }
}
TOP

Related Classes of bufferings.ktr.wjr.client.WjrView

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.