All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.tapirtest.execution.gui.application.views.MainViewModel Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/**
 * MIT License
 * 
 * Copyright (c) 2018 b+m Informatik AG
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package io.tapirtest.execution.gui.application.views;

import com.google.common.collect.Iterables;
import de.bmiag.tapir.bootstrap.TapirBootstrapper;
import de.bmiag.tapir.execution.TapirExecutor;
import de.bmiag.tapir.execution.model.ExecutionPlan;
import de.bmiag.tapir.execution.model.Identifiable;
import de.bmiag.tapir.execution.model.TestClass;
import de.bmiag.tapir.execution.model.TestStep;
import de.bmiag.tapir.execution.model.TestSuite;
import de.saxsys.mvvmfx.ViewModel;
import de.saxsys.mvvmfx.utils.commands.Action;
import de.saxsys.mvvmfx.utils.commands.DelegateCommand;
import io.tapirtest.execution.gui.application.components.AbstractCheckBoxTreeItem;
import io.tapirtest.execution.gui.application.components.ExecutionPlanTreeItem;
import io.tapirtest.execution.gui.application.components.TestStepTreeItem;
import io.tapirtest.execution.gui.application.data.ExecutionStatus;
import io.tapirtest.execution.gui.application.data.Property;
import io.tapirtest.execution.gui.application.filter.GUIStepExecutionInvocationHandler;
import io.tapirtest.execution.gui.application.listener.GUIExecutionListener;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.scene.control.Alert;
import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.control.TreeItem;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Pure;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * The view model of the main page.
 * 
 * @author Nils Christian Ehmke
 * 
 * @since 1.0.0
 */
@Accessors
@SuppressWarnings("all")
public class MainViewModel implements ViewModel {
  private final static Logger logger = LogManager.getLogger(MainViewModel.class);
  
  private final DelegateCommand reinitializeExecutionPlanCommand = this.createCommand(((Runnable) () -> {
    this.performReinitializeExecutionPlan();
  }));
  
  private final DelegateCommand selectAllCommand = this.createCommand(((Runnable) () -> {
    this.performSelectAll();
  }));
  
  private final DelegateCommand deselectAllCommand = this.createCommand(((Runnable) () -> {
    this.performDeselectAll();
  }));
  
  private final DelegateCommand startTestsCommand = this.createCommand(((Runnable) () -> {
    this.performStartTests();
  }));
  
  private final DelegateCommand addPropertyCommand = this.createCommand(((Runnable) () -> {
    this.performAddProperty();
  }));
  
  private final DelegateCommand deletePropertyCommand = this.createCommand(((Runnable) () -> {
    this.performDeleteProperty();
  }));
  
  private final SimpleObjectProperty refreshTableObservable = new SimpleObjectProperty();
  
  private final SimpleObjectProperty> executionPlanRoot = new SimpleObjectProperty>();
  
  private final SimpleListProperty propertiesContent = new SimpleListProperty(FXCollections.observableArrayList());
  
  private final SimpleObjectProperty selectedProperty = new SimpleObjectProperty();
  
  private final SimpleBooleanProperty readOnlyMode = new SimpleBooleanProperty();
  
  private Class testClass;
  
  private ConfigurableApplicationContext tapirContext;
  
  private TapirExecutor tapirExecutor;
  
  /**
   * This method is executed once everything else of the application is initialized.
   */
  public void start(final Application.Parameters parameters) {
    try {
      final List rawParameters = parameters.getRaw();
      int _size = rawParameters.size();
      boolean _lessThan = (_size < 1);
      if (_lessThan) {
        throw new IllegalArgumentException("The tapir extensions launcher requires the test class or test suite as first parameter");
      }
      final String firstParameter = rawParameters.get(0);
      try {
        this.testClass = Class.forName(firstParameter);
      } catch (final Throwable _t) {
        if (_t instanceof ClassNotFoundException) {
          StringConcatenation _builder = new StringConcatenation();
          _builder.append("The class \'");
          _builder.append(firstParameter);
          _builder.append("\' can not be found");
          throw new IllegalArgumentException(_builder.toString());
        } else {
          throw Exceptions.sneakyThrow(_t);
        }
      }
      this.performReinitializeExecutionPlan();
    } catch (final Throwable _t_1) {
      if (_t_1 instanceof Exception) {
        final Exception ex_1 = (Exception)_t_1;
        this.handleException(ex_1);
      } else {
        throw Exceptions.sneakyThrow(_t_1);
      }
    }
  }
  
  /**
   * This method is performed when the user wants to reinitialize the execution plan.
   */
  private void performReinitializeExecutionPlan() {
    final Function1 _function = (Property it) -> {
      String _key = it.getKey();
      return Boolean.valueOf((_key != null));
    };
    final Consumer _function_1 = (Property it) -> {
      System.setProperty(it.getKey(), it.getValue());
    };
    IterableExtensions.filter(this.propertiesContent.getValue(), _function).forEach(_function_1);
    this.restartTapirContext();
    final ExecutionPlan executionPlan = this.tapirExecutor.getExecutionPlan();
    final ExecutionPlanTreeItem executionPlanItem = new ExecutionPlanTreeItem(executionPlan);
    this.executionPlanRoot.set(executionPlanItem);
    this.selectAllNodes(executionPlanItem);
    this.expandNodes(executionPlanItem);
  }
  
  private TapirExecutor restartTapirContext() {
    TapirExecutor _xblockexpression = null;
    {
      if ((this.tapirContext != null)) {
        this.tapirContext.close();
      }
      this.tapirContext = TapirBootstrapper.bootstrap(this.testClass);
      final TapirExecutor.TapirExecutorFactory tapirExecutorFactory = this.tapirContext.getBean(TapirExecutor.TapirExecutorFactory.class);
      _xblockexpression = this.tapirExecutor = tapirExecutorFactory.getExecutorForClass(this.testClass);
    }
    return _xblockexpression;
  }
  
  private void expandNodes(final TreeItem treeItem) {
    treeItem.setExpanded(true);
    final Identifiable value = treeItem.getValue();
    if (((value instanceof ExecutionPlan) || (value instanceof TestSuite))) {
      final Consumer> _function = (TreeItem it) -> {
        this.expandNodes(it);
      };
      treeItem.getChildren().forEach(_function);
    } else {
      if ((value instanceof TestClass)) {
        treeItem.setExpanded(false);
      }
    }
  }
  
  /**
   * This method is performed when the user wants to select all items.
   */
  private void performSelectAll() {
    this.selectAllNodes(this.executionPlanRoot.get());
  }
  
  private void selectAllNodes(final TreeItem treeItem) {
    ((CheckBoxTreeItem) treeItem).setSelected(true);
    final Consumer> _function = (TreeItem it) -> {
      this.selectAllNodes(it);
    };
    treeItem.getChildren().forEach(_function);
  }
  
  /**
   * This method is performed when the user wants to deselect all items.
   */
  private void performDeselectAll() {
    this.deselectAllNodes(this.executionPlanRoot.get());
  }
  
  private void deselectAllNodes(final TreeItem treeItem) {
    ((CheckBoxTreeItem) treeItem).setSelected(false);
    final Consumer> _function = (TreeItem it) -> {
      this.deselectAllNodes(it);
    };
    treeItem.getChildren().forEach(_function);
  }
  
  /**
   * This method is performed when the user wants to start the tests.
   */
  private void performStartTests() {
    final Runnable _function = () -> {
      try {
        this.readOnlyMode.set(true);
        this.resetExecutionState(this.executionPlanRoot.get());
        final List selectedSteps = this.getSelectedSteps(this.executionPlanRoot.get());
        final Runnable _function_1 = () -> {
          Object _object = new Object();
          this.refreshTableObservable.setValue(_object);
        };
        Platform.runLater(_function_1);
        final GUIStepExecutionInvocationHandler stepExecutionInvocationHandler = this.tapirContext.getBean(GUIStepExecutionInvocationHandler.class);
        stepExecutionInvocationHandler.setSelectedTestSteps(selectedSteps);
        final GUIExecutionListener executionListener = this.tapirContext.getBean(GUIExecutionListener.class);
        executionListener.setExecutionPlanRoot(this.executionPlanRoot.get());
        executionListener.setRefreshTableObservable(this.refreshTableObservable);
        this.tapirExecutor.execute();
      } catch (final Throwable _t) {
        if (_t instanceof Exception) {
          final Exception ex = (Exception)_t;
          this.handleException(ex);
        } else {
          throw Exceptions.sneakyThrow(_t);
        }
      } finally {
        this.readOnlyMode.set(false);
      }
    };
    new Thread(_function).start();
  }
  
  private void resetExecutionState(final TreeItem treeItem) {
    ((AbstractCheckBoxTreeItem) treeItem).setExecutionStatus(ExecutionStatus.NONE);
    final Consumer> _function = (TreeItem it) -> {
      this.resetExecutionState(it);
    };
    treeItem.getChildren().forEach(_function);
  }
  
  private List getSelectedSteps(final TreeItem treeItem) {
    List _xifexpression = null;
    if ((treeItem instanceof TestStepTreeItem)) {
      List _xifexpression_1 = null;
      boolean _isSelected = ((CheckBoxTreeItem) treeItem).isSelected();
      if (_isSelected) {
        Identifiable _value = ((TestStepTreeItem)treeItem).getValue();
        _xifexpression_1 = Collections.unmodifiableList(CollectionLiterals.newArrayList(((TestStep) _value)));
      } else {
        _xifexpression_1 = Collections.unmodifiableList(CollectionLiterals.newArrayList());
      }
      _xifexpression = _xifexpression_1;
    } else {
      final Function1, List> _function = (TreeItem it) -> {
        return this.getSelectedSteps(it);
      };
      _xifexpression = IterableExtensions.toList(Iterables.concat(ListExtensions., List>map(treeItem.getChildren(), _function)));
    }
    return _xifexpression;
  }
  
  /**
   * This method is performed when the user wants to add a property entry.
   */
  private boolean performAddProperty() {
    Property _property = new Property();
    return this.propertiesContent.add(_property);
  }
  
  /**
   * This method is performed when the user wants to delete a property entry.
   */
  private boolean performDeleteProperty() {
    boolean _xblockexpression = false;
    {
      final Property selectedProperty = this.selectedProperty.get();
      boolean _xifexpression = false;
      if ((selectedProperty != null)) {
        _xifexpression = this.propertiesContent.remove(selectedProperty);
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }
  
  private DelegateCommand createCommand(final Runnable aAction) {
    final Supplier _function = () -> {
      return new Action() {
        @Override
        protected void action() throws Exception {
          try {
            aAction.run();
          } catch (final Throwable _t) {
            if (_t instanceof Exception) {
              final Exception ex = (Exception)_t;
              MainViewModel.this.handleException(ex);
            } else {
              throw Exceptions.sneakyThrow(_t);
            }
          }
        }
      };
    };
    return new DelegateCommand(_function);
  }
  
  private void handleException(final Exception exception) {
    final Runnable _function = () -> {
      MainViewModel.logger.error("An exception occurred", exception);
      final Alert alert = new Alert(Alert.AlertType.ERROR);
      alert.setTitle("Error");
      alert.setHeaderText(exception.getLocalizedMessage());
      alert.showAndWait();
    };
    final Runnable runnable = _function;
    Platform.runLater(runnable);
  }
  
  @Pure
  public DelegateCommand getReinitializeExecutionPlanCommand() {
    return this.reinitializeExecutionPlanCommand;
  }
  
  @Pure
  public DelegateCommand getSelectAllCommand() {
    return this.selectAllCommand;
  }
  
  @Pure
  public DelegateCommand getDeselectAllCommand() {
    return this.deselectAllCommand;
  }
  
  @Pure
  public DelegateCommand getStartTestsCommand() {
    return this.startTestsCommand;
  }
  
  @Pure
  public DelegateCommand getAddPropertyCommand() {
    return this.addPropertyCommand;
  }
  
  @Pure
  public DelegateCommand getDeletePropertyCommand() {
    return this.deletePropertyCommand;
  }
  
  @Pure
  public SimpleObjectProperty getRefreshTableObservable() {
    return this.refreshTableObservable;
  }
  
  @Pure
  public SimpleObjectProperty> getExecutionPlanRoot() {
    return this.executionPlanRoot;
  }
  
  @Pure
  public SimpleListProperty getPropertiesContent() {
    return this.propertiesContent;
  }
  
  @Pure
  public SimpleObjectProperty getSelectedProperty() {
    return this.selectedProperty;
  }
  
  @Pure
  public SimpleBooleanProperty getReadOnlyMode() {
    return this.readOnlyMode;
  }
  
  @Pure
  public Class getTestClass() {
    return this.testClass;
  }
  
  public void setTestClass(final Class testClass) {
    this.testClass = testClass;
  }
  
  @Pure
  public ConfigurableApplicationContext getTapirContext() {
    return this.tapirContext;
  }
  
  public void setTapirContext(final ConfigurableApplicationContext tapirContext) {
    this.tapirContext = tapirContext;
  }
  
  @Pure
  public TapirExecutor getTapirExecutor() {
    return this.tapirExecutor;
  }
  
  public void setTapirExecutor(final TapirExecutor tapirExecutor) {
    this.tapirExecutor = tapirExecutor;
  }
}