/**
* 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.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.drools.ide.common.client.modeldriven.testing.ActivateRuleFlowGroup;
import org.drools.ide.common.client.modeldriven.testing.CallFixtureMap;
import org.drools.ide.common.client.modeldriven.testing.CallMethod;
import org.drools.ide.common.client.modeldriven.testing.ExecutionTrace;
import org.drools.ide.common.client.modeldriven.testing.FactData;
import org.drools.ide.common.client.modeldriven.testing.FieldData;
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.RetractFact;
import org.drools.ide.common.client.modeldriven.testing.VerifyFact;
import org.drools.ide.common.client.modeldriven.testing.VerifyRuleFired;
/**
* Some utility methods as the display logic is a bit hairy.
*/
public class ScenarioHelper {
static final String RETRACT_KEY = "retract";
static final String ACTIVATE_RULE_FLOW_GROUP = "activate_rule_flow_group";
/**
* Called lumpy map - as this takes a flat list of fixtures, and groups
* things together. It will return a list - of which each element will
* either be a list - or a map. If its a map - then its a map of FactData to
* the fact type. If its a list, then it will be expectations or
* retractions.
*
* Man, this will be so much nicer with generics.
*
* @return List<List<VeryifyRuleFired or VerifyFact or RetractFact> OR
* Map<String, List<FactData>> OR ExecutionTrace>
*/
public List<Fixture> lumpyMap(List<Fixture> fixtures) {
List<Fixture> output = new ArrayList<Fixture>();
FixturesMap dataInput = new FixturesMap();
CallFixtureMap callOnDataInput = new CallFixtureMap();
FixtureList verifyFact = new FixtureList();
FixtureList verifyRule = new FixtureList();
FixtureList retractFacts = new FixtureList();
for ( Iterator<Fixture> iterator = fixtures.iterator(); iterator
.hasNext(); ) {
Fixture fixture = iterator.next();
if ( fixture instanceof FactData ) {
accumulateData( dataInput,
fixture );
} else if ( fixture instanceof CallMethod ) {
accumulateCallMethode( callOnDataInput,
fixture );
} else if ( fixture instanceof ActivateRuleFlowGroup ) {
accumulateData( dataInput,
fixture );
} else if ( fixture instanceof RetractFact ) {
retractFacts.add( (RetractFact) fixture );
} else if ( fixture instanceof VerifyRuleFired ) {
verifyRule.add( (VerifyRuleFired) fixture );
} else if ( fixture instanceof VerifyFact ) {
verifyFact.add( (VerifyFact) fixture );
} else if ( fixture instanceof ExecutionTrace ) {
gatherFixtures( output,
dataInput,
callOnDataInput,
verifyFact,
verifyRule,
retractFacts,
false );
output.add( fixture );
verifyRule = new FixtureList();
verifyFact = new FixtureList();
retractFacts = new FixtureList();
callOnDataInput = new CallFixtureMap();
dataInput = new FixturesMap();
}
}
gatherFixtures( output,
dataInput,
callOnDataInput,
verifyFact,
verifyRule,
retractFacts,
true );
return output;
}
private void gatherFixtures(List<Fixture> output,
FixturesMap dataInput,
CallFixtureMap callOnDataInput,
FixtureList verifyFact,
FixtureList verifyRule,
FixtureList retractFacts,
boolean end) {
if ( verifyRule.size() > 0 ) output.add( verifyRule );
if ( verifyFact.size() > 0 ) output.add( verifyFact );
if ( retractFacts.size() > 0 ) dataInput.put( RETRACT_KEY,
retractFacts );
if ( dataInput.size() > 0 || !end ) output.add( dataInput ); // want to have a place holder for the GUI
if ( callOnDataInput.size() > 0 || !end ) output.add( callOnDataInput );
}
/**
* Group the globals together by fact type.
*/
public Map<String, FixtureList> lumpyMapGlobals(List<FactData> globals) {
Map<String, FixtureList> map = new HashMap<String, FixtureList>();
for ( FactData factData : globals ) {
accumulateData( map,
factData );
}
return map;
}
public List<ExecutionTrace> getExecutionTraceFor(List<Fixture> fixtures) {
List<Fixture> processedFixtures = lumpyMap( fixtures );
List<ExecutionTrace> listExecutionTrace = new ArrayList<ExecutionTrace>();
for ( int i = 0; i < processedFixtures.size(); i++ ) {
final Object fixture = processedFixtures.get( i );
if ( fixture instanceof ExecutionTrace ) {
listExecutionTrace.add( (ExecutionTrace) fixture );
}
}
return listExecutionTrace;
}
private void accumulateData(Map<String, FixtureList> dataInput,
Fixture f) {
if ( f instanceof FactData ) {
FactData fd = (FactData) f;
if ( !dataInput.containsKey( fd.type ) ) {
dataInput.put( fd.type,
new FixtureList() );
}
((FixtureList) dataInput.get( fd.type )).add( fd );
} else if ( f instanceof ActivateRuleFlowGroup ) {
if ( !dataInput.containsKey( ScenarioHelper.ACTIVATE_RULE_FLOW_GROUP ) ) {
dataInput.put( ScenarioHelper.ACTIVATE_RULE_FLOW_GROUP,
new FixtureList() );
}
((FixtureList) dataInput
.get( ScenarioHelper.ACTIVATE_RULE_FLOW_GROUP )).add( f );
}
}
private void accumulateCallMethode(Map<String, FixtureList> dataInput,
Fixture f) {
if ( f instanceof CallMethod ) {
CallMethod fd = (CallMethod) f;
if ( !dataInput.containsKey( fd.variable ) ) {
dataInput.put( fd.variable,
new FixtureList() );
}
((FixtureList) dataInput.get( fd.variable )).add( fd );
}
}
static void removeFields(List<Fixture> factDatas,
String field) {
for ( Fixture fixture : factDatas ) {
if ( fixture instanceof FactData ) {
FactData factData = (FactData) fixture;
for ( Iterator<FieldData> fieldDataIterator = factData.fieldData
.iterator(); fieldDataIterator.hasNext(); ) {
FieldData fieldData = fieldDataIterator.next();
if ( fieldData.name.equals( field ) ) {
fieldDataIterator.remove();
}
}
}
}
}
}