/*
* Copyright 2010 JBoss Inc
*
* 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 org.drools.guvnor.client.qa.testscenarios;
import java.util.List;
import org.drools.guvnor.client.common.DirtyableFlexTable;
import org.drools.guvnor.client.common.GenericCallback;
import org.drools.guvnor.client.common.SmallLabel;
import org.drools.guvnor.client.messages.Constants;
import org.drools.guvnor.client.packages.SuggestionCompletionCache;
import org.drools.guvnor.client.qa.VerifyRulesFiredWidget;
import org.drools.guvnor.client.resources.Images;
import org.drools.guvnor.client.rpc.MetaData;
import org.drools.guvnor.client.rpc.RepositoryServiceFactory;
import org.drools.guvnor.client.rpc.RuleAsset;
import org.drools.guvnor.client.ruleeditor.EditorWidget;
import org.drools.guvnor.client.ruleeditor.RuleViewer;
import org.drools.ide.common.client.modeldriven.SuggestionCompletionEngine;
import org.drools.ide.common.client.modeldriven.testing.CallFixtureMap;
import org.drools.ide.common.client.modeldriven.testing.ExecutionTrace;
import org.drools.ide.common.client.modeldriven.testing.Fixture;
import org.drools.ide.common.client.modeldriven.testing.FixtureList;
import org.drools.ide.common.client.modeldriven.testing.FixturesMap;
import org.drools.ide.common.client.modeldriven.testing.Scenario;
import org.drools.ide.common.client.modeldriven.testing.VerifyFact;
import org.drools.ide.common.client.modeldriven.testing.VerifyRuleFired;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class ScenarioWidget extends Composite
implements
EditorWidget {
private Constants constants = GWT.create( Constants.class );
private static Images images = GWT.create( Images.class );
private String[] availableRules;
protected final SuggestionCompletionEngine suggestionCompletionEngine;
private ChangeHandler ruleSelectionCL;
private final RuleAsset asset;
private final VerticalPanel layout;
private boolean showResults;
private HandlerRegistration availableRulesHandlerRegistration;
public ScenarioWidget(RuleAsset asset,
RuleViewer viewer) {
this( asset );
}
public ScenarioWidget(RuleAsset asset) {
this.asset = asset;
this.layout = new VerticalPanel();
this.setShowResults( false );
this.suggestionCompletionEngine = SuggestionCompletionCache
.getInstance().getEngineFromCache( asset.metaData.packageName );
if ( getScenario().fixtures.size() == 0 ) {
getScenario().fixtures.add( new ExecutionTrace() );
}
if ( !asset.isreadonly ) {
layout.add( new TestRunnerWidget( this,
asset.metaData.packageName ) );
}
renderEditor();
initWidget( layout );
setStyleName( "scenario-Viewer" );
layout.setWidth( "100%" );
}
private void createWidgetForEditorLayout(DirtyableFlexTable editorLayout,
int layoutRow,
int layoutColumn,
Widget widget) {
editorLayout.setWidget( layoutRow,
layoutColumn,
widget );
}
void renderEditor() {
if ( this.layout.getWidgetCount() == 2 ) {
this.layout.remove( 1 );
}
DirtyableFlexTable editorLayout = createDirtyableFlexTable();
this.layout.add( editorLayout );
ScenarioHelper scenarioHelper = new ScenarioHelper();
List<Fixture> fixtures = getScenario().fixtures;
List<ExecutionTrace> listExecutionTrace = scenarioHelper
.getExecutionTraceFor( fixtures );
int layoutRow = 1;
int executionTraceLine = 0;
ExecutionTrace previousExecutionTrace = null;
for ( final Fixture fixture : fixtures ) {
if ( fixture instanceof ExecutionTrace ) {
ExecutionTrace currentExecutionTrace = (ExecutionTrace) fixture;
createWidgetForEditorLayout( editorLayout,
layoutRow,
0,
createExpectPanel( currentExecutionTrace ) );
executionTraceLine++;
if ( executionTraceLine >= listExecutionTrace.size() ) {
executionTraceLine = listExecutionTrace.size() - 1;
}
createWidgetForEditorLayout( editorLayout,
layoutRow,
1,
createExecutionWidget( currentExecutionTrace ) );
editorLayout.setHorizontalAlignmentForFlexCellFormatter(
layoutRow,
2,
HasHorizontalAlignment.ALIGN_LEFT );
previousExecutionTrace = currentExecutionTrace;
} else if ( fixture instanceof FixturesMap ) {
createWidgetForEditorLayout(
editorLayout,
layoutRow,
0,
createGivenLabelButton( listExecutionTrace,
executionTraceLine,
previousExecutionTrace ) );
layoutRow++;
createWidgetForEditorLayout(
editorLayout,
layoutRow,
1,
createGivenPanel( listExecutionTrace,
executionTraceLine,
(FixturesMap) fixture ) );
} else if ( fixture instanceof CallFixtureMap ) {
createWidgetForEditorLayout(
editorLayout,
layoutRow,
0,
createCallMethodLabelButton( listExecutionTrace,
executionTraceLine,
previousExecutionTrace ) );
layoutRow++;
createWidgetForEditorLayout(
editorLayout,
layoutRow,
1,
createCallMethodOnGivenPanel( listExecutionTrace,
executionTraceLine,
(CallFixtureMap) fixture ) );
} else {
FixtureList fixturesList = (FixtureList) fixture;
Fixture first = fixturesList.get( 0 );
if ( first instanceof VerifyFact ) {
createWidgetForEditorLayout(
editorLayout,
layoutRow,
1,
createVerifyFactsPanel( listExecutionTrace,
executionTraceLine,
fixturesList ) );
} else if ( first instanceof VerifyRuleFired ) {
createWidgetForEditorLayout( editorLayout,
layoutRow,
1,
createVerifyRulesFiredWidget( fixturesList ) );
}
}
layoutRow++;
}
// add more execution sections.
createWidgetForEditorLayout( editorLayout,
layoutRow,
0,
createAddExecuteButton() );
layoutRow++;
createWidgetForEditorLayout( editorLayout,
layoutRow,
0,
createSmallLabel() );
// config section
createWidgetForEditorLayout( editorLayout,
layoutRow,
1,
createConfigWidget() );
layoutRow++;
// global section
HorizontalPanel horizontalPanel = createHorizontalPanel();
createWidgetForEditorLayout( editorLayout,
layoutRow,
0,
horizontalPanel );
createWidgetForEditorLayout( editorLayout,
layoutRow,
1,
createGlobalPanel( scenarioHelper,
previousExecutionTrace ) );
}
private GlobalPanel createGlobalPanel(ScenarioHelper scenarioHelper,
ExecutionTrace previousExecutionTrace) {
return new GlobalPanel(
scenarioHelper.lumpyMapGlobals( getScenario().globals ),
getScenario(),
previousExecutionTrace,
this );
}
private HorizontalPanel createHorizontalPanel() {
HorizontalPanel h = new HorizontalPanel();
h.add( new GlobalButton( getScenario(),
this ) );
h.add( new SmallLabel( constants.globals() ) );
return h;
}
private SmallLabel createSmallLabel() {
return new SmallLabel( constants.configuration() );
}
private ConfigWidget createConfigWidget() {
return new ConfigWidget( getScenario(),
asset.metaData.packageName,
this );
}
private AddExecuteButton createAddExecuteButton() {
return new AddExecuteButton( getScenario(),
this );
}
private VerifyRulesFiredWidget createVerifyRulesFiredWidget(
FixtureList fixturesList) {
return new VerifyRulesFiredWidget( fixturesList,
getScenario(),
isShowResults() );
}
private VerifyFactsPanel createVerifyFactsPanel(
List<ExecutionTrace> listExecutionTrace,
int executionTraceLine,
FixtureList fixturesList) {
return new VerifyFactsPanel( fixturesList,
listExecutionTrace.get( executionTraceLine ),
getScenario(),
this,
isShowResults() );
}
private CallMethodLabelButton createCallMethodLabelButton(
List<ExecutionTrace> listExecutionTrace,
int executionTraceLine,
ExecutionTrace previousExecutionTrace) {
return new CallMethodLabelButton( previousExecutionTrace,
getScenario(),
listExecutionTrace.get( executionTraceLine ),
this );
}
private GivenLabelButton createGivenLabelButton(
List<ExecutionTrace> listExecutionTrace,
int executionTraceLine,
ExecutionTrace previousExecutionTrace) {
return new GivenLabelButton( previousExecutionTrace,
getScenario(),
listExecutionTrace.get( executionTraceLine ),
this );
}
private ExecutionWidget createExecutionWidget(
ExecutionTrace currentExecutionTrace) {
return new ExecutionWidget( currentExecutionTrace,
isShowResults() );
}
private ExpectPanel createExpectPanel(ExecutionTrace currentExecutionTrace) {
return new ExpectPanel( asset.metaData.packageName,
currentExecutionTrace,
getScenario(),
this );
}
private DirtyableFlexTable createDirtyableFlexTable() {
DirtyableFlexTable editorLayout = new DirtyableFlexTable();
editorLayout.clear();
editorLayout.setWidth( "100%" );
editorLayout.setStyleName( "model-builder-Background" );
return editorLayout;
}
private Widget createGivenPanel(List<ExecutionTrace> listExecutionTrace,
int executionTraceLine,
FixturesMap given) {
if ( given.size() > 0 ) {
return new GivenPanel( listExecutionTrace,
executionTraceLine,
given,
getScenario(),
this );
} else {
return new HTML( "<i><small>"
+ constants.AddInputDataAndExpectationsHere()
+ "</small></i>" );
}
}
private Widget createCallMethodOnGivenPanel(
List<ExecutionTrace> listExecutionTrace,
int executionTraceLine,
CallFixtureMap given) {
if ( given.size() > 0 ) {
return new CallMethodOnGivenPanel( listExecutionTrace,
executionTraceLine,
given,
getScenario(),
this );
} else {
return new HTML( "<i><small>"
+ constants.AddInputDataAndExpectationsHere()
+ "</small></i>" );
}
}
public Widget getRuleSelectionWidget(final String packageName,
final RuleSelectionEvent selected) {
final HorizontalPanel horizontalPanel = new HorizontalPanel();
final TextBox ruleNameTextBox = new TextBox();
ruleNameTextBox.setTitle( constants.EnterRuleNameScenario() );
horizontalPanel.add( ruleNameTextBox );
if ( !(availableRules == null) ) {
final ListBox availableRulesBox = new ListBox();
availableRulesBox.addItem( constants.pleaseChoose1() );
for ( int i = 0; i < availableRules.length; i++ ) {
availableRulesBox.addItem( availableRules[i] );
}
availableRulesBox.setSelectedIndex( 0 );
if ( availableRulesHandlerRegistration != null ) {
availableRulesHandlerRegistration.removeHandler();
}
ruleSelectionCL = new ChangeHandler() {
public void onChange(ChangeEvent event) {
ruleNameTextBox.setText( availableRulesBox
.getItemText( availableRulesBox.getSelectedIndex() ) );
}
};
availableRulesHandlerRegistration = availableRulesBox
.addChangeHandler( ruleSelectionCL );
horizontalPanel.add( availableRulesBox );
} else {
final Button showList = new Button( constants.showListButton() );
horizontalPanel.add( showList );
showList.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent event) {
horizontalPanel.remove( showList );
final Image busy = new Image( images.searching() );
final Label loading = new SmallLabel( constants
.loadingList1() );
horizontalPanel.add( busy );
horizontalPanel.add( loading );
Scheduler scheduler = Scheduler.get();
scheduler.scheduleDeferred( new Command() {
public void execute() {
RepositoryServiceFactory.getService()
.listRulesInPackage( packageName,
new GenericCallback<String[]>() {
public void onSuccess(
String[] list) {
availableRules = (list);
final ListBox availableRulesBox = new ListBox();
availableRulesBox.addItem( constants
.pleaseChoose1() );
for ( int i = 0; i < list.length; i++ ) {
availableRulesBox
.addItem( list[i] );
}
ruleSelectionCL = new ChangeHandler() {
public void onChange(
ChangeEvent event) {
ruleNameTextBox
.setText( availableRulesBox
.getItemText( availableRulesBox
.getSelectedIndex() ) );
}
};
availableRulesHandlerRegistration = availableRulesBox
.addChangeHandler( ruleSelectionCL );
availableRulesBox
.setSelectedIndex( 0 );
horizontalPanel
.add( availableRulesBox );
horizontalPanel
.remove( busy );
horizontalPanel
.remove( loading );
}
} );
}
} );
}
} );
}
Button ok = new Button( constants.OK() );
ok.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent event) {
selected.ruleSelected( ruleNameTextBox.getText() );
}
} );
horizontalPanel.add( ok );
return horizontalPanel;
}
/**
* Use some CSS trickery to get a percent bar.
*/
public static Widget getBar(String colour,
int width,
float percent) {
int pixels = (int) (width * (percent / 100));
String html = "<div class=\"smallish-progress-wrapper\" style=\"width: "
+ width
+ "px\">"
+ "<div class=\"smallish-progress-bar\" style=\"width: "
+ pixels
+ "px; background-color: "
+ colour
+ ";\"></div>"
+ "<div class=\"smallish-progress-text\" style=\"width: "
+ width + "px\">" + (int) percent + "%</div></div>"; // NON-NLS
return new HTML( html );
}
public static Widget getBar(String colour,
int width,
int numerator,
int denominator) {
int percent = 0;
if ( denominator != 0 ) {
percent = (int) ((((float) denominator - (float) numerator) / (float) denominator) * 100);
}
return getBar( colour,
width,
percent );
}
void setShowResults(boolean showResults) {
this.showResults = showResults;
}
boolean isShowResults() {
return showResults;
}
public MetaData getMetaData() {
return asset.metaData;
}
public void setScenario(Scenario scenario) {
asset.content = scenario;
}
public Scenario getScenario() {
return (Scenario) asset.content;
}
}