diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTree.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTree.java index b98c61dc889..6832d2bc47e 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTree.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTree.java @@ -16,6 +16,7 @@ package org.drools.workbench.screens.scenariosimulation.model.typedescriptor; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +38,7 @@ public class FactModelTree { public enum Type { INPUT, DECISION, + PREDICTION, UNDEFINED } @@ -117,6 +119,18 @@ public static FactModelTree ofDMN(String factName, String importPrefix, Map simpleProperties, String typeName, Type type) { + return new FactModelTree(factName, "", simpleProperties, Collections.emptyMap(), type, typeName, importPrefix); + } + /** * Static factory method to be used in DMN context, to create a Simple Type FactModelTree. * @param factName @@ -134,6 +148,22 @@ public static FactModelTree ofSimpleDMN(String factName, String importPrefix, St return toReturn; } + /** + * Static factory method to be used in DMN context, to create a Simple Type FactModelTree. + * @param factName + * @param simplePropertyType + * @param typeName + * @param type + * @return + */ + public static FactModelTree ofSimplePMML(String factName, String simplePropertyType, String typeName, Type type) { + Map simpleProperties = new HashMap<>(); + simpleProperties.put(VALUE, new FactModelTree.PropertyTypeName(simplePropertyType)); + FactModelTree toReturn = new FactModelTree(factName, "", simpleProperties, Collections.emptyMap(), type, typeName, ""); + toReturn.setSimple(true); + return toReturn; + } + public FactModelTree() { // CDI } @@ -273,7 +303,7 @@ public FactModelTree cloneFactModelTree() { public String toString() { return "FactModelTree{" + "factName='" + factName + '\'' + - "typeName='" + typeName + '\'' + + ", typeName='" + typeName + '\'' + ", simpleProperties=" + simpleProperties + ", expandableProperties=" + expandableProperties + '}'; diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/service/PMMLTypeService.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/service/PMMLTypeService.java new file mode 100644 index 00000000000..27dc4faf16f --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/main/java/org/drools/workbench/screens/scenariosimulation/service/PMMLTypeService.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.service; + +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTuple; +import org.jboss.errai.bus.server.annotations.Remote; +import org.uberfire.backend.vfs.Path; + +@Remote +public interface PMMLTypeService { + + /** + * Retrieves a FactModelTuple representing the given pmml file + * @param path + * @param pmmlPath + * @param modelName + * @return + * @throws Exception + */ + FactModelTuple retrieveFactModelTuple(Path path, String pmmlPath, String modelName); + +} diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/test/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTreeTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/test/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTreeTest.java index f5962c0c1aa..4bf18694131 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/test/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTreeTest.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-api/src/test/java/org/drools/workbench/screens/scenariosimulation/model/typedescriptor/FactModelTreeTest.java @@ -150,6 +150,21 @@ public void ofDMN() { assertEquals(IMPORT_PREFIX, factModelTree.getImportPrefix()); } + @Test + public void ofPMML() { + FactModelTree factModelTree = FactModelTree.ofPMML(FACT_NAME, IMPORT_PREFIX, Collections.emptyMap(), FACT_TYPE, FactModelTree.Type.INPUT); + assertEquals(FACT_NAME, factModelTree.getFactName()); + assertEquals(FACT_TYPE, factModelTree.getTypeName()); + assertEquals("", factModelTree.getFullPackage()); + assertEquals(FACT_TYPE, factModelTree.getFullTypeName()); + assertEquals(FACT_NAME, factModelTree.getFactName()); + assertEquals(0, factModelTree.getSimpleProperties().size()); + assertEquals(0, factModelTree.getGenericTypesMap().size()); + assertEquals(FactModelTree.Type.INPUT, factModelTree.getType()); + assertFalse(factModelTree.isSimple()); + assertEquals(IMPORT_PREFIX, factModelTree.getImportPrefix()); + } + @Test public void ofSimpleDMN() { FactModelTree factModelTree = FactModelTree.ofSimpleDMN(FACT_NAME, IMPORT_PREFIX, SIMPLE_PROPERTY_TYPE, Collections.emptyMap(), FACT_TYPE, FactModelTree.Type.INPUT); diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/pom.xml b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/pom.xml index 156303fbe5a..8af87f78aea 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/pom.xml +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/pom.xml @@ -133,6 +133,25 @@ kie-dmn-core + + + org.kie + kie-pmml-bom + pom + + + org.kie + kie-pmml-api + + + org.kie + kie-pmml-evaluator-core + + + org.kie + kie-pmml-evaluator-assembler + + org.apache.commons commons-csv @@ -214,6 +233,27 @@ tests test + + org.kie + kie-pmml-bom + pom + ${version.org.kie} + + + org.kie + kie-pmml-api + ${version.org.kie} + + + org.kie + kie-pmml-evaluator-core + ${version.org.kie} + + + org.kie + kie-pmml-evaluator-assembler + ${version.org.kie} + org.drools drools-scenario-simulation-backend diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLScenarioValidation.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLScenarioValidation.java new file mode 100644 index 00000000000..a803dc36e17 --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLScenarioValidation.java @@ -0,0 +1,173 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Stream; + +import org.drools.scenariosimulation.api.model.FactMapping; +import org.drools.scenariosimulation.api.model.Settings; +import org.drools.scenariosimulation.api.model.Simulation; +import org.drools.workbench.screens.scenariosimulation.model.FactMappingValidationError; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieRuntimeFactory; +import org.kie.pmml.api.enums.DATA_TYPE; +import org.kie.pmml.api.exceptions.KiePMMLInternalException; +import org.kie.pmml.api.models.MiningField; +import org.kie.pmml.api.models.OutputField; +import org.kie.pmml.api.models.PMMLModel; +import org.kie.pmml.api.runtime.PMMLRuntime; + +import static org.drools.workbench.screens.scenariosimulation.model.FactMappingValidationError.createFieldChangedError; +import static org.drools.workbench.screens.scenariosimulation.model.FactMappingValidationError.createNodeChangedError; + +public class PMMLScenarioValidation extends AbstractScenarioValidation { + + public static final PMMLScenarioValidation INSTANCE = new PMMLScenarioValidation(); + + /** + * Validate structure of a PMML test scenario. + * Supported checks for each column: + * - empty column skip + * - PMML node removed + * - simple type becomes complex type + * - navigation of data type still valid + * - field type changed + * @param simulation + * @param settings + * @param kieContainer + * @return + */ + @Override + public List validate(Simulation simulation, Settings settings, + KieContainer kieContainer) { + List errors = new ArrayList<>(); + String pmmlModelName = settings.getPmmlModelName(); + PMMLModel pmmlModel = getPMMLModel(kieContainer, pmmlModelName); + + for (FactMapping factMapping : simulation.getScesimModelDescriptor().getFactMappings()) { + if (isToSkip(factMapping)) { + continue; + } + + String nodeName = factMapping.getFactIdentifier().getName(); + + DATA_TYPE fieldType; + try { + fieldType = Stream.of(getMiningFieldDataTypeByName(pmmlModel.getMiningFields(), nodeName), + getOutputFieldDataTypeByName(pmmlModel.getOutputFields(), nodeName)) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst() + .orElseThrow(() -> new KiePMMLInternalException(String.format("Failed to find DataType for " + + "field %s", + nodeName))); + } catch (NullPointerException e) { + errors.add(createNodeChangedError(factMapping, "node not found")); + continue; + } + if (!isPMMLFactMappingValid(factMapping, fieldType)) { + errors.add(defineFieldChangedError(factMapping, fieldType, fieldType)); + } + } + return errors; + } + + private static Optional getMiningFieldDataTypeByName(List miningFields, String fieldName) { + return miningFields.stream().filter(miningField -> fieldName.equals(miningField.getName())) + .findFirst() + .map(MiningField::getDataType); + } + + private static Optional getOutputFieldDataTypeByName(List outputFields, String fieldName) { + return outputFields.stream().filter(outputField -> fieldName.equals(outputField.getName())) + .findFirst() + .map(OutputField::getDataType); + } + + private FactMappingValidationError defineFieldChangedError(FactMapping factMapping, DATA_TYPE factType, + DATA_TYPE fieldType) { +// String typeName = factMapping.getClassName(); +// if (isConstraintAdded(typeName, fieldType)) { +// return FactMappingValidationError.createFieldAddedConstraintError(factMapping); +// } +// if (isConstraintRemoved(typeName, factType, fieldType)) { +// return FactMappingValidationError.createFieldRemovedConstraintError(factMapping); +// } + return createFieldChangedError(factMapping, fieldType.getName()); + } + + private boolean isPMMLFactMappingValid(FactMapping factMapping, DATA_TYPE pmmlType) { + String factMappingType = factMapping.getClassName(); + return Objects.equals(factMappingType, pmmlType.getName()); + } +// +// /** +// * To define if a constraint (allowed values) were added in a DATA_TYPE fieldType given a typeName, the following +// * conditions +// * are requires: +// * - typeName MUST BE a BuiltInType (eg. STRING, NUMERIC ..) +// * - DATA_TYPE fieldType MUST have at least one defined Allowed Values +// * - DATA_TYPE fieldType MUST have a Base Type. It's name MUST be equals to given typeName. +// * @param typeName TypeName present in the scesim file +// * @param fieldType DATA_TYPE of field under analysis +// * @return +// */ +// private boolean isConstraintAdded(String typeName, DATA_TYPE fieldType) { +// boolean isTypeNameBuiltInType = !Objects.equals(UNKNOWN, BuiltInType.determineTypeFromName(typeName)); +// boolean hasFieldTypeAllowedValues = +// fieldType.getAllowedValues() != null && !fieldType.getAllowedValues().isEmpty(); +// boolean hasFieldTypeBaseType = Objects.nonNull(fieldType.getBaseType()); +// if (isTypeNameBuiltInType && hasFieldTypeBaseType && hasFieldTypeAllowedValues) { +// Type baseType = getRootType((BaseDATA_TYPEImpl) fieldType.getBaseType()); +// return Objects.equals(typeName, baseType.getName()); +// } +// return false; +// } +// +// /** +// * To define if a constraint (allowed values) were removed in a DATA_TYPE fieldType given a typeName, the +// * following conditions +// * are requires: +// * - DATA_TYPE fieldType MUST DON'T have Allowed Values defined +// * - DATA_TYPE fieldType MUST DON'T have a Base Type. +// * - typeName MUST BE a DATA_TYPE factType's field. The field's DATA_TYPE MUST BE the same of given fieldType +// * DATA_TYPE +// * @param typeName +// * @param factType Fact DATA_TYPE +// * @param fieldType Field DATA_TYPE +// * @return +// */ +// private boolean isConstraintRemoved(String typeName, DATA_TYPE factType, DATA_TYPE fieldType) { +// boolean hasFieldTypeAllowedValues = +// fieldType.getAllowedValues() != null && !fieldType.getAllowedValues().isEmpty(); +// boolean hasFieldTypeBaseType = Objects.nonNull(fieldType.getBaseType()); +// boolean isTypeNameFactTypeField = factType.getFields().containsKey(typeName); +// if (!hasFieldTypeBaseType && !hasFieldTypeAllowedValues && isTypeNameFactTypeField) { +// DATA_TYPE typeNameDATA_TYPE = factType.getFields().get(typeName); +// return Objects.equals(fieldType.getNamespace(), typeNameDATA_TYPE.getNamespace()); +// } +// return false; +// } + + protected PMMLModel getPMMLModel(KieContainer kieContainer, String pmmlModelName) { + PMMLRuntime pmmlRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(PMMLRuntime.class); + return pmmlRuntime.getPMMLModel(pmmlModelName).orElseThrow(() -> new RuntimeException("Unable to find model " + pmmlModelName)); + } +} \ No newline at end of file diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLTypeServiceImpl.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLTypeServiceImpl.java new file mode 100644 index 00000000000..e34dc64d5fb --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLTypeServiceImpl.java @@ -0,0 +1,119 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server; + +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.TreeSet; + +import javax.enterprise.context.ApplicationScoped; + +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree; +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTuple; +import org.drools.workbench.screens.scenariosimulation.service.PMMLTypeService; +import org.guvnor.common.services.backend.exceptions.ExceptionUtilities; +import org.jboss.errai.bus.server.annotations.Service; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieRuntimeFactory; +import org.kie.pmml.api.enums.DATA_TYPE; +import org.kie.pmml.api.enums.FIELD_USAGE_TYPE; +import org.kie.pmml.api.models.MiningField; +import org.kie.pmml.api.models.OutputField; +import org.kie.pmml.api.models.PMMLModel; +import org.kie.pmml.api.runtime.PMMLRuntime; +import org.uberfire.backend.vfs.Path; + +@Service +@ApplicationScoped +public class PMMLTypeServiceImpl + extends AbstractKieContainerService + implements PMMLTypeService { + + @Override + public FactModelTuple retrieveFactModelTuple(Path path, String pmmlPath, String modelName) { + PMMLModel pmmlModel = getPMMLModel(path, modelName); + SortedMap visibleFacts = new TreeMap<>(); + SortedMap hiddenFacts = new TreeMap<>(); + ErrorHolder errorHolder = new ErrorHolder(); + + for (MiningField miningField : pmmlModel.getMiningFields()) { + final DATA_TYPE dataType = miningField.getDataType(); + final String name = miningField.getName(); + FactModelTree.Type modelTreeType = isTarget(miningField) ? FactModelTree.Type.PREDICTION : FactModelTree.Type.INPUT; + try { + visibleFacts.put(name, createTopLevelFactModelTree(name, dataType, modelTreeType)); + } catch (Exception e) { + throw ExceptionUtilities.handleException(e); + } + } + + for (OutputField outputField : pmmlModel.getOutputFields()) { + DATA_TYPE dataType = outputField.getDataType(); + final String name = outputField.getName(); + try { + visibleFacts.put(name, createTopLevelFactModelTree(name, dataType, FactModelTree.Type.PREDICTION)); + } catch (Exception e) { + throw ExceptionUtilities.handleException(e); + } + } + FactModelTuple factModelTuple = new FactModelTuple(visibleFacts, hiddenFacts); + errorHolder.getMultipleNestedCollection().forEach(factModelTuple::addMultipleNestedCollectionError); + errorHolder.getMultipleNestedObject().forEach(factModelTuple::addMultipleNestedObjectError); + return factModelTuple; + } + + public PMMLModel getPMMLModel(Path path, String modelName) { + PMMLRuntime pmmlRuntime = getPMMLRuntime(path); + return pmmlRuntime.getPMMLModel(modelName).orElseThrow(() -> new RuntimeException("Unable to find model " + modelName + " in path " + path)); + } + + public PMMLRuntime getPMMLRuntime(Path path) { + KieContainer kieContainer = getKieContainer(path); + return KieRuntimeFactory.of(kieContainer.getKieBase()).get(PMMLRuntime.class); + } + + /** + * This method is the entry point for FactModelTree. It is the one to be called from the very + * top level DATA_TYPE + * @param factName + * @param type + * @param fmType + * @return + */ + protected FactModelTree createTopLevelFactModelTree(String factName, DATA_TYPE type, FactModelTree.Type fmType) { + return FactModelTree.ofSimplePMML(factName, type.getMappedClass().getCanonicalName(), type.getMappedClass().getCanonicalName(), fmType); + } + + public static boolean isTarget(final MiningField miningField) { + return (miningField.getUsageType().equals(FIELD_USAGE_TYPE.TARGET) || miningField.getUsageType().equals(FIELD_USAGE_TYPE.PREDICTED)); + } + + static class ErrorHolder { + + Set multipleNestedObject = new TreeSet<>(); + Set multipleNestedCollection = new TreeSet<>(); + + public Set getMultipleNestedObject() { + return multipleNestedObject; + } + + public Set getMultipleNestedCollection() { + return multipleNestedCollection; + } + } +} \ No newline at end of file diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImpl.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImpl.java index c5cc35fa038..0c041b54c23 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImpl.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImpl.java @@ -36,8 +36,8 @@ import org.drools.scenariosimulation.api.model.ScesimModelDescriptor; import org.drools.scenariosimulation.api.model.Settings; import org.drools.scenariosimulation.api.model.Simulation; +import org.drools.scenariosimulation.backend.exceptions.ImpossibleToFindDMNException; import org.drools.scenariosimulation.backend.runner.ScenarioJunitActivator; -import org.drools.scenariosimulation.backend.util.ImpossibleToFindDMNException; import org.drools.scenariosimulation.backend.util.ScenarioSimulationXMLPersistence; import org.drools.workbench.screens.scenariosimulation.backend.server.util.ScenarioSimulationBuilder; import org.drools.workbench.screens.scenariosimulation.model.FactMappingValidationError; diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/AbstractSimulationSettingsCreationStrategy.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/AbstractSimulationSettingsCreationStrategy.java new file mode 100644 index 00000000000..6fb9366505c --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/AbstractSimulationSettingsCreationStrategy.java @@ -0,0 +1,229 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.drools.scenariosimulation.api.model.AbstractScesimData; +import org.drools.scenariosimulation.api.model.ExpressionIdentifier; +import org.drools.scenariosimulation.api.model.FactIdentifier; +import org.drools.scenariosimulation.api.model.FactMapping; +import org.drools.scenariosimulation.api.model.FactMappingType; +import org.drools.scenariosimulation.api.model.ScenarioWithIndex; +import org.drools.scenariosimulation.api.model.ScesimModelDescriptor; +import org.drools.scenariosimulation.api.model.Simulation; +import org.drools.scenariosimulation.api.utils.ScenarioSimulationSharedUtils; +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree; +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTuple; +import org.uberfire.backend.vfs.Path; + +import static org.drools.scenariosimulation.api.model.FactMappingType.EXPECT; +import static org.drools.scenariosimulation.api.model.FactMappingType.GIVEN; +import static org.drools.scenariosimulation.api.utils.ConstantsHolder.VALUE; +import static org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree.Type; + +public abstract class AbstractSimulationSettingsCreationStrategy implements SimulationSettingsCreationStrategy { + + @Override + public Simulation createSimulation(Path context, String filePath) { + final FactModelTuple factModelTuple = getFactModelTuple(context, filePath); + Simulation toReturn = new Simulation(); + ScesimModelDescriptor simulationDescriptor = toReturn.getScesimModelDescriptor(); + simulationDescriptor.addFactMapping(FactIdentifier.INDEX.getName(), FactIdentifier.INDEX, ExpressionIdentifier.INDEX); + simulationDescriptor.addFactMapping(FactIdentifier.DESCRIPTION.getName(), FactIdentifier.DESCRIPTION, ExpressionIdentifier.DESCRIPTION); + ScenarioWithIndex scenarioWithIndex = createScesimDataWithIndex(toReturn, simulationDescriptor, ScenarioWithIndex::new); + + AtomicInteger id = new AtomicInteger(1); + final Collection visibleFactTrees = factModelTuple.getVisibleFacts().values(); + final Map hiddenValues = factModelTuple.getHiddenFacts(); + + visibleFactTrees.stream().sorted((a, b) -> { + Type aType = a.getType(); + Type bType = b.getType(); + int inputFirstOrder = Type.INPUT.equals(aType) ? -1 : 1; + return aType.equals(bType) ? 0 : inputFirstOrder; + }).forEach(factModelTree -> { + FactIdentifier factIdentifier = FactIdentifier.create(factModelTree.getFactName(), factModelTree.getFactName(), factModelTree.getImportPrefix()); + FactMappingExtractor factMappingExtractor = new FactMappingExtractor(factIdentifier, scenarioWithIndex.getIndex(), id, convert(factModelTree.getType()), simulationDescriptor, scenarioWithIndex.getScesimData()); + addFactMapping(factMappingExtractor, factModelTree, new ArrayList<>(), hiddenValues); + }); + + addEmptyColumnsIfNeeded(toReturn, scenarioWithIndex); + + return toReturn; + } + + protected abstract FactModelTuple getFactModelTuple(Path context, String filePath); + + protected abstract FactMappingType convert(Type modelTreeType); + + + /** + * If PMML model is empty, contains only inputs or only outputs this method add one GIVEN and/or EXPECT empty column + * @param simulation + * @param scenarioWithIndex + */ + protected void addEmptyColumnsIfNeeded(Simulation simulation, ScenarioWithIndex scenarioWithIndex) { + boolean hasGiven = false; + boolean hasExpect = false; + ScesimModelDescriptor simulationDescriptor = simulation.getScesimModelDescriptor(); + for (FactMapping factMapping : simulationDescriptor.getFactMappings()) { + FactMappingType factMappingType = factMapping.getExpressionIdentifier().getType(); + if (!hasGiven && GIVEN.equals(factMappingType)) { + hasGiven = true; + } else if (!hasExpect && EXPECT.equals(factMappingType)) { + hasExpect = true; + } + } + if (!hasGiven) { + createEmptyColumn(simulationDescriptor, + scenarioWithIndex, + 1, + GIVEN, + findNewIndexOfGroup(simulationDescriptor, GIVEN)); + } + if (!hasExpect) { + createEmptyColumn(simulationDescriptor, + scenarioWithIndex, + 2, + EXPECT, + findNewIndexOfGroup(simulationDescriptor, EXPECT)); + } + } + + protected int findNewIndexOfGroup(ScesimModelDescriptor simulationDescriptor, FactMappingType factMappingType) { + List factMappings = simulationDescriptor.getFactMappings(); + if (GIVEN.equals(factMappingType)) { + for (int i = 0; i < factMappings.size(); i += 1) { + if (EXPECT.equals(factMappings.get(i).getExpressionIdentifier().getType())) { + return i; + } + } + return factMappings.size(); + } else if (EXPECT.equals(factMappingType)) { + return factMappings.size(); + } else { + throw new IllegalArgumentException("This method can be invoked only with GIVEN or EXPECT as FactMappingType"); + } + } + + protected void addFactMapping(FactMappingExtractor factMappingExtractor, + FactModelTree factModelTree, + List previousSteps, + Map hiddenValues) { + internalAddToScenario(factMappingExtractor, + factModelTree, + previousSteps, + hiddenValues, + new HashSet<>()); + } + + protected void internalAddToScenario(FactMappingExtractor factMappingExtractor, + FactModelTree factModelTree, + List readOnlyPreviousSteps, + Map hiddenValues, + Set alreadyVisited) { + + List previousSteps = new ArrayList<>(readOnlyPreviousSteps); + // if is a simple type it generates a single column + if (factModelTree.isSimple()) { + FactModelTree.PropertyTypeName factType = factModelTree.getSimpleProperties().get(VALUE); + factMappingExtractor.getFactMapping(factModelTree, VALUE, previousSteps, factType.getTypeName()); + } + // otherwise it adds a column for each simple properties direct or nested + else { + factModelTree.getSimpleProperties().entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> { + String factName = entry.getKey(); + String factTypeName = entry.getValue().getTypeName(); + + FactMapping factMapping = factMappingExtractor.getFactMapping(factModelTree, factName, previousSteps, factTypeName); + + if (ScenarioSimulationSharedUtils.isList(factTypeName)) { + factMapping.setGenericTypes(factModelTree.getGenericTypeInfo(factName)); + } + factMapping.addExpressionElement(factName, factTypeName); + }); + + factModelTree.getExpandableProperties().entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(entry -> { + String factType = entry.getValue(); + FactModelTree nestedModelTree = hiddenValues.get(factType); + + if (previousSteps.isEmpty()) { + previousSteps.add(factModelTree.getFactName()); + } + ArrayList currentSteps = new ArrayList<>(previousSteps); + currentSteps.add(entry.getKey()); + + if (!alreadyVisited.contains(nestedModelTree.getFactName())) { + alreadyVisited.add(factModelTree.getFactName()); + internalAddToScenario(factMappingExtractor, nestedModelTree, currentSteps, hiddenValues, alreadyVisited); + } + }); + } + } + + public static class FactMappingExtractor { + + private final FactIdentifier factIdentifier; + private final int row; + private final AtomicInteger id; + private final FactMappingType type; + private final ScesimModelDescriptor simulationDescriptor; + private final AbstractScesimData abstractScesimData; + + protected FactMappingExtractor(FactIdentifier factIdentifier, int row, AtomicInteger id, FactMappingType type, ScesimModelDescriptor simulationDescriptor, AbstractScesimData abstractScesimData) { + this.factIdentifier = factIdentifier; + this.row = row; + this.id = id; + this.type = type; + this.simulationDescriptor = simulationDescriptor; + this.abstractScesimData = abstractScesimData; + } + + public FactMapping getFactMapping(FactModelTree factModelTree, String propertyName, List previousSteps, String factType) { + + String factAlias = !previousSteps.isEmpty() ? previousSteps.get(0) : factModelTree.getFactName(); + + ExpressionIdentifier expressionIdentifier = ExpressionIdentifier.create(row + "|" + id.getAndIncrement(), type); + final FactMapping factMapping = simulationDescriptor.addFactMapping(factAlias, factIdentifier, expressionIdentifier); + + List localPreviousStep = new ArrayList<>(previousSteps); + localPreviousStep.add(propertyName); + String expressionAlias = String.join(".", + localPreviousStep.size() > 1 ? + localPreviousStep.subList(1, localPreviousStep.size()) : + localPreviousStep); + factMapping.setExpressionAlias(expressionAlias); + factMapping.setGenericTypes(factModelTree.getGenericTypeInfo(VALUE)); + + previousSteps.forEach(step -> factMapping.addExpressionElement(step, factType)); + + if (previousSteps.isEmpty()) { + factMapping.addExpressionElement(factModelTree.getFactName(), factType); + } + abstractScesimData.addMappingValue(factIdentifier, expressionIdentifier, null); + + return factMapping; + } + } + +} diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/DMNSimulationSettingsCreationStrategy.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/DMNSimulationSettingsCreationStrategy.java index 7ee38ca6c31..a57a013a9eb 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/DMNSimulationSettingsCreationStrategy.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/DMNSimulationSettingsCreationStrategy.java @@ -15,71 +15,30 @@ */ package org.drools.workbench.screens.scenariosimulation.backend.server.util; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import org.drools.scenariosimulation.api.model.AbstractScesimData; -import org.drools.scenariosimulation.api.model.ExpressionIdentifier; -import org.drools.scenariosimulation.api.model.FactIdentifier; -import org.drools.scenariosimulation.api.model.FactMapping; import org.drools.scenariosimulation.api.model.FactMappingType; import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; -import org.drools.scenariosimulation.api.model.ScenarioWithIndex; -import org.drools.scenariosimulation.api.model.ScesimModelDescriptor; import org.drools.scenariosimulation.api.model.Settings; import org.drools.scenariosimulation.api.model.Simulation; -import org.drools.scenariosimulation.api.utils.ScenarioSimulationSharedUtils; -import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree; import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTuple; import org.drools.workbench.screens.scenariosimulation.service.DMNTypeService; import org.uberfire.backend.vfs.Path; import static org.drools.scenariosimulation.api.model.FactMappingType.EXPECT; import static org.drools.scenariosimulation.api.model.FactMappingType.GIVEN; -import static org.drools.scenariosimulation.api.utils.ConstantsHolder.VALUE; import static org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree.Type; @ApplicationScoped -public class DMNSimulationSettingsCreationStrategy implements SimulationSettingsCreationStrategy { +public class DMNSimulationSettingsCreationStrategy extends AbstractSimulationSettingsCreationStrategy { @Inject protected DMNTypeService dmnTypeService; @Override public Simulation createSimulation(Path context, String dmnFilePath) { - final FactModelTuple factModelTuple = getFactModelTuple(context, dmnFilePath); - Simulation toReturn = new Simulation(); - ScesimModelDescriptor simulationDescriptor = toReturn.getScesimModelDescriptor(); - simulationDescriptor.addFactMapping(FactIdentifier.INDEX.getName(), FactIdentifier.INDEX, ExpressionIdentifier.INDEX); - simulationDescriptor.addFactMapping(FactIdentifier.DESCRIPTION.getName(), FactIdentifier.DESCRIPTION, ExpressionIdentifier.DESCRIPTION); - ScenarioWithIndex scenarioWithIndex = createScesimDataWithIndex(toReturn, simulationDescriptor, ScenarioWithIndex::new); - - AtomicInteger id = new AtomicInteger(1); - final Collection visibleFactTrees = factModelTuple.getVisibleFacts().values(); - final Map hiddenValues = factModelTuple.getHiddenFacts(); - - visibleFactTrees.stream().sorted((a, b) -> { - Type aType = a.getType(); - Type bType = b.getType(); - int inputFirstOrder = Type.INPUT.equals(aType) ? -1 : 1; - return aType.equals(bType) ? 0 : inputFirstOrder; - }).forEach(factModelTree -> { - FactIdentifier factIdentifier = FactIdentifier.create(factModelTree.getFactName(), factModelTree.getFactName(), factModelTree.getImportPrefix()); - FactMappingExtractor factMappingExtractor = new FactMappingExtractor(factIdentifier, scenarioWithIndex.getIndex(), id, convert(factModelTree.getType()), simulationDescriptor, scenarioWithIndex.getScesimData()); - addFactMapping(factMappingExtractor, factModelTree, new ArrayList<>(), hiddenValues); - }); - - addEmptyColumnsIfNeeded(toReturn, scenarioWithIndex); - - return toReturn; + return super.createSimulation(context, dmnFilePath); } @Override @@ -91,161 +50,13 @@ public Settings createSettings(Path context, String dmnFilePath) { return toReturn; } - /** - * If DMN model is empty, contains only inputs or only outputs this method add one GIVEN and/or EXPECT empty column - * @param simulation - * @param scenarioWithIndex - */ - protected void addEmptyColumnsIfNeeded(Simulation simulation, ScenarioWithIndex scenarioWithIndex) { - boolean hasGiven = false; - boolean hasExpect = false; - ScesimModelDescriptor simulationDescriptor = simulation.getScesimModelDescriptor(); - for (FactMapping factMapping : simulationDescriptor.getFactMappings()) { - FactMappingType factMappingType = factMapping.getExpressionIdentifier().getType(); - if (!hasGiven && GIVEN.equals(factMappingType)) { - hasGiven = true; - } else if (!hasExpect && EXPECT.equals(factMappingType)) { - hasExpect = true; - } - } - if (!hasGiven) { - createEmptyColumn(simulationDescriptor, - scenarioWithIndex, - 1, - GIVEN, - findNewIndexOfGroup(simulationDescriptor, GIVEN)); - } - if (!hasExpect) { - createEmptyColumn(simulationDescriptor, - scenarioWithIndex, - 2, - EXPECT, - findNewIndexOfGroup(simulationDescriptor, EXPECT)); - } - } - - protected int findNewIndexOfGroup(ScesimModelDescriptor simulationDescriptor, FactMappingType factMappingType) { - List factMappings = simulationDescriptor.getFactMappings(); - if (GIVEN.equals(factMappingType)) { - for (int i = 0; i < factMappings.size(); i += 1) { - if (EXPECT.equals(factMappings.get(i).getExpressionIdentifier().getType())) { - return i; - } - } - return factMappings.size(); - } else if (EXPECT.equals(factMappingType)) { - return factMappings.size(); - } else { - throw new IllegalArgumentException("This method can be invoked only with GIVEN or EXPECT as FactMappingType"); - } - } - // Indirection for test protected FactModelTuple getFactModelTuple(Path context, String dmnFilePath) { return dmnTypeService.retrieveFactModelTuple(context, dmnFilePath); } - protected void addFactMapping(FactMappingExtractor factMappingExtractor, - FactModelTree factModelTree, - List previousSteps, - Map hiddenValues) { - internalAddToScenario(factMappingExtractor, - factModelTree, - previousSteps, - hiddenValues, - new HashSet<>()); - } - - protected void internalAddToScenario(FactMappingExtractor factMappingExtractor, - FactModelTree factModelTree, - List readOnlyPreviousSteps, - Map hiddenValues, - Set alreadyVisited) { - - List previousSteps = new ArrayList<>(readOnlyPreviousSteps); - // if is a simple type it generates a single column - if (factModelTree.isSimple()) { - FactModelTree.PropertyTypeName factType = factModelTree.getSimpleProperties().get(VALUE); - factMappingExtractor.getFactMapping(factModelTree, VALUE, previousSteps, factType.getTypeName()); - } - // otherwise it adds a column for each simple properties direct or nested - else { - factModelTree.getSimpleProperties().entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> { - String factName = entry.getKey(); - String factTypeName = entry.getValue().getTypeName(); - - FactMapping factMapping = factMappingExtractor.getFactMapping(factModelTree, factName, previousSteps, factTypeName); - - if (ScenarioSimulationSharedUtils.isList(factTypeName)) { - factMapping.setGenericTypes(factModelTree.getGenericTypeInfo(factName)); - } - factMapping.addExpressionElement(factName, factTypeName); - }); - - factModelTree.getExpandableProperties().entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(entry -> { - String factType = entry.getValue(); - FactModelTree nestedModelTree = hiddenValues.get(factType); - - if (previousSteps.isEmpty()) { - previousSteps.add(factModelTree.getFactName()); - } - ArrayList currentSteps = new ArrayList<>(previousSteps); - currentSteps.add(entry.getKey()); - - if (!alreadyVisited.contains(nestedModelTree.getFactName())) { - alreadyVisited.add(factModelTree.getFactName()); - internalAddToScenario(factMappingExtractor, nestedModelTree, currentSteps, hiddenValues, alreadyVisited); - } - }); - } - } - - public static class FactMappingExtractor { - - private final FactIdentifier factIdentifier; - private final int row; - private final AtomicInteger id; - private final FactMappingType type; - private final ScesimModelDescriptor simulationDescriptor; - private final AbstractScesimData abstractScesimData; - - public FactMappingExtractor(FactIdentifier factIdentifier, int row, AtomicInteger id, FactMappingType type, ScesimModelDescriptor simulationDescriptor, AbstractScesimData abstractScesimData) { - this.factIdentifier = factIdentifier; - this.row = row; - this.id = id; - this.type = type; - this.simulationDescriptor = simulationDescriptor; - this.abstractScesimData = abstractScesimData; - } - - public FactMapping getFactMapping(FactModelTree factModelTree, String propertyName, List previousSteps, String factType) { - - String factAlias = !previousSteps.isEmpty() ? previousSteps.get(0) : factModelTree.getFactName(); - - ExpressionIdentifier expressionIdentifier = ExpressionIdentifier.create(row + "|" + id.getAndIncrement(), type); - final FactMapping factMapping = simulationDescriptor.addFactMapping(factAlias, factIdentifier, expressionIdentifier); - - List localPreviousStep = new ArrayList<>(previousSteps); - localPreviousStep.add(propertyName); - String expressionAlias = String.join(".", - localPreviousStep.size() > 1 ? - localPreviousStep.subList(1, localPreviousStep.size()) : - localPreviousStep); - factMapping.setExpressionAlias(expressionAlias); - factMapping.setGenericTypes(factModelTree.getGenericTypeInfo(VALUE)); - - previousSteps.forEach(step -> factMapping.addExpressionElement(step, factType)); - - if (previousSteps.isEmpty()) { - factMapping.addExpressionElement(factModelTree.getFactName(), factType); - } - abstractScesimData.addMappingValue(factIdentifier, expressionIdentifier, null); - - return factMapping; - } - } - - private static FactMappingType convert(Type modelTreeType) { + @Override + protected FactMappingType convert(Type modelTreeType) { switch (modelTreeType) { case INPUT: return GIVEN; diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/PMMLSimulationSettingsCreationStrategy.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/PMMLSimulationSettingsCreationStrategy.java new file mode 100644 index 00000000000..546ddd9aaf6 --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/PMMLSimulationSettingsCreationStrategy.java @@ -0,0 +1,73 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server.util; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.drools.scenariosimulation.api.model.FactMappingType; +import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; +import org.drools.scenariosimulation.api.model.Settings; +import org.drools.scenariosimulation.api.model.Simulation; +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTuple; +import org.drools.workbench.screens.scenariosimulation.service.PMMLTypeService; +import org.uberfire.backend.vfs.Path; + +import static org.drools.scenariosimulation.api.model.FactMappingType.EXPECT; +import static org.drools.scenariosimulation.api.model.FactMappingType.GIVEN; +import static org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree.Type; + +@ApplicationScoped +public class PMMLSimulationSettingsCreationStrategy extends AbstractSimulationSettingsCreationStrategy { + + @Inject + protected PMMLTypeService pmmlTypeService; + + @Override + public Simulation createSimulation(Path context, String filePathModelName) { + return super.createSimulation(context, filePathModelName); + } + + @Override + public Settings createSettings(Path context, String filePathModelName) { + Settings toReturn = new Settings(); + String[] parts = filePathModelName.split("\\|"); + toReturn.setType(ScenarioSimulationModel.Type.PMML); + toReturn.setPmmlFilePath(parts[0]); + toReturn.setPmmlModelName(parts[1]); + return toReturn; + } + + // Indirection for test + @Override + protected FactModelTuple getFactModelTuple(Path context, String filePathModelName) { + String[] parts = filePathModelName.split("\\|"); + return pmmlTypeService.retrieveFactModelTuple(context, parts[0], parts[1]); + } + + @Override + protected FactMappingType convert(Type modelTreeType) { + switch (modelTreeType) { + case INPUT: + return GIVEN; + case PREDICTION: + return EXPECT; + default: + throw new IllegalArgumentException("Impossible to map"); + } + } + +} diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/ScenarioSimulationBuilder.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/ScenarioSimulationBuilder.java index 9c8c5b9f2f3..ccf8ce0dd79 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/ScenarioSimulationBuilder.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/main/java/org/drools/workbench/screens/scenariosimulation/backend/server/util/ScenarioSimulationBuilder.java @@ -35,12 +35,17 @@ public class ScenarioSimulationBuilder { @Inject protected DMNSimulationSettingsCreationStrategy dmnSimulationCreationStrategy; + @Inject + protected PMMLSimulationSettingsCreationStrategy pmmlSimulationCreationStrategy; + public Simulation createSimulation(Path context, ScenarioSimulationModel.Type type, String value) { switch (type) { case RULE: return ruleSimulationCreationStrategy.createSimulation(context, value); case DMN: return dmnSimulationCreationStrategy.createSimulation(context, value); + case PMML: + return pmmlSimulationCreationStrategy.createSimulation(context, value); default: throw new IllegalStateException(ERROR_MESSAGE + type); } @@ -52,6 +57,8 @@ public Background createBackground(Path context, ScenarioSimulationModel.Type ty return ruleSimulationCreationStrategy.createBackground(context, value); case DMN: return dmnSimulationCreationStrategy.createBackground(context, value); + case PMML: + return pmmlSimulationCreationStrategy.createBackground(context, value); default: throw new IllegalStateException(ERROR_MESSAGE + type); } @@ -63,6 +70,8 @@ public Settings createSettings(Path context, ScenarioSimulationModel.Type type, return ruleSimulationCreationStrategy.createSettings(context,value); case DMN: return dmnSimulationCreationStrategy.createSettings( context,value); + case PMML: + return pmmlSimulationCreationStrategy.createSettings(context, value); default: throw new IllegalStateException(ERROR_MESSAGE + type); } diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/AbstractPMMLTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/AbstractPMMLTest.java new file mode 100644 index 00000000000..663c138fc21 --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/AbstractPMMLTest.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server; + +import java.io.File; +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; +import org.drools.scenariosimulation.api.model.Settings; +import org.kie.pmml.api.enums.DATA_TYPE; +import org.kie.pmml.api.enums.FIELD_USAGE_TYPE; +import org.kie.pmml.api.models.MiningField; +import org.kie.pmml.api.models.OutputField; +import org.kie.pmml.api.models.PMMLModel; +import org.kie.pmml.evaluator.assembler.factories.PMMLRuntimeFactoryImpl; +import org.kie.pmml.evaluator.core.service.PMMLRuntimeInternalImpl; + +import static org.junit.Assert.assertNotNull; + +public abstract class AbstractPMMLTest { + + protected static final String STRING_ACTIVE_MINING_FIELD = "STRING_ACTIVE_MINING_FIELD"; + protected static final String DOUBLE_PREDICTED_MINING_FIELD = "DOUBLE_PREDICTED_MINING_FIELD"; + protected static final String STRING_OUTPUT_FIELD = "STRING_OUTPUT_FIELD"; + protected static final String STRING_OUTPUT_FIELD_TARGET = "STRING_OUTPUT_FIELD_TARGET"; + protected static final String DOUBLE_OUTPUT_FIELD = "DOUBLE_OUTPUT_FIELD"; + protected static final String DOUBLE_OUTPUT_FIELD_TARGET = "DOUBLE_OUTPUT_FIELD_TARGET"; + protected static final String PMML_FILE = "CategoricalVariablesRegression.pmml"; + protected static final String MODEL_NAME = "CategoricalVariablesRegression"; + protected PMMLModel pmmlModelLocal; + protected Set miningFields; + protected Set outputFields; + protected Settings settingsLocal; + + protected void init() { + settingsLocal = new Settings(); + settingsLocal.setType(ScenarioSimulationModel.Type.PMML); + miningFields = new HashSet<>(); + MiningField stringActiveMiningField = getMiningField(DATA_TYPE.STRING, FIELD_USAGE_TYPE.ACTIVE, + STRING_ACTIVE_MINING_FIELD); + miningFields.add(stringActiveMiningField); + MiningField doublePredictedMiningField = getMiningField(DATA_TYPE.DOUBLE, FIELD_USAGE_TYPE.PREDICTED, + DOUBLE_PREDICTED_MINING_FIELD); + miningFields.add(doublePredictedMiningField); + + outputFields = new HashSet<>(); + OutputField stringOutputField = getOutputField(DATA_TYPE.STRING, STRING_OUTPUT_FIELD, STRING_OUTPUT_FIELD_TARGET); + outputFields.add(stringOutputField); + OutputField doubleOutputField = getOutputField(DATA_TYPE.DOUBLE, DOUBLE_OUTPUT_FIELD, DOUBLE_OUTPUT_FIELD_TARGET); + outputFields.add(doubleOutputField); + final URL resource = AbstractPMMLTest.class.getResource(PMML_FILE); + assertNotNull(resource); + PMMLRuntimeInternalImpl pmmlRuntime = + (PMMLRuntimeInternalImpl) new PMMLRuntimeFactoryImpl().getPMMLRuntimeFromFile(new File(resource.getFile())); + pmmlModelLocal = pmmlRuntime.getPMMLModel(MODEL_NAME).orElseThrow(() -> new RuntimeException("Unable to find " + + "model " + MODEL_NAME)); + } + + /** + * Returns a single SimpleTypeImpl + * @return + */ + protected DATA_TYPE getSimpleNoCollection() { + return DATA_TYPE.STRING; + } + + protected MiningField getMiningField(DATA_TYPE dataType, FIELD_USAGE_TYPE usageType, String name) { + return new MiningField(name, + usageType, + null, + dataType, + null, + null, + null, + null, + null, + null); + } + + protected OutputField getOutputField(DATA_TYPE dataType, String name, String targetField) { + return new OutputField(name, + null, + dataType, + targetField, + null, + null); + } +} \ No newline at end of file diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLScenarioValidationTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLScenarioValidationTest.java new file mode 100644 index 00000000000..bcfad4b5842 --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLScenarioValidationTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server; + +import java.util.List; + +import org.drools.scenariosimulation.api.model.ExpressionIdentifier; +import org.drools.scenariosimulation.api.model.FactIdentifier; +import org.drools.scenariosimulation.api.model.FactMappingType; +import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; +import org.drools.scenariosimulation.api.model.Settings; +import org.drools.scenariosimulation.api.model.Simulation; +import org.drools.workbench.screens.scenariosimulation.model.FactMappingValidationError; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.kie.api.runtime.KieContainer; +import org.kie.pmml.api.enums.DATA_TYPE; +import org.kie.pmml.api.models.PMMLModel; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.drools.scenariosimulation.api.utils.ConstantsHolder.VALUE; +import static org.mockito.Mockito.spy; + +@RunWith(MockitoJUnitRunner.class) +public class PMMLScenarioValidationTest extends AbstractScenarioValidationTest { + + @Mock + private PMMLModel pmmlModelMock; + + private Settings settingsLocal; + + @Before + public void init() { + settingsLocal = new Settings(); + settingsLocal.setType(ScenarioSimulationModel.Type.PMML); + } + + @Test + public void validate() { + PMMLScenarioValidation validationSpy = spy(new PMMLScenarioValidation() { + @Override + protected PMMLModel getPMMLModel(KieContainer kieContainer, String pmmlModelName) { + return pmmlModelMock; + } + }); + + // Test 0 - skip empty or not GIVEN/EXPECT columns + Simulation test0 = new Simulation(); + test0.getScesimModelDescriptor().addFactMapping( + FactIdentifier.DESCRIPTION, + ExpressionIdentifier.create(VALUE, FactMappingType.OTHER)); + test0.getScesimModelDescriptor().addFactMapping( + FactIdentifier.EMPTY, + ExpressionIdentifier.create(VALUE, FactMappingType.GIVEN)); + + List errorsTest0 = validationSpy.validate(test0, settingsLocal, null); + checkResult(errorsTest0); + + // Test 1 - simple types + for (DATA_TYPE dataType : DATA_TYPE.values()) { + Simulation test1 = new Simulation(); + String identifierName = String.format("my%sType", dataType.getName()); + test1.getScesimModelDescriptor().addFactMapping( + FactIdentifier.create(identifierName, dataType.getName()), + ExpressionIdentifier.create(VALUE, FactMappingType.GIVEN)); + List errorsTest1 = validationSpy.validate(test1, settingsLocal, null); + checkResult(errorsTest1); + } + } + +} \ No newline at end of file diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLTypeServiceImplTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLTypeServiceImplTest.java new file mode 100644 index 00000000000..0baf675a21a --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/PMMLTypeServiceImplTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2018 Red Hat, Inc. and/or its affiliates. + * + * 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.workbench.screens.scenariosimulation.backend.server; + +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTree; +import org.drools.workbench.screens.scenariosimulation.model.typedescriptor.FactModelTuple; +import org.junit.Before; +import org.junit.Test; +import org.kie.pmml.api.enums.DATA_TYPE; +import org.kie.pmml.api.models.MiningField; +import org.kie.pmml.api.models.OutputField; +import org.kie.pmml.api.models.PMMLModel; +import org.uberfire.backend.vfs.Path; + +import static org.drools.scenariosimulation.api.utils.ConstantsHolder.VALUE; +import static org.drools.workbench.screens.scenariosimulation.backend.server.PMMLTypeServiceImpl.isTarget; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +public class PMMLTypeServiceImplTest extends AbstractPMMLTest { + + private PMMLTypeServiceImpl pmmlTypeServiceImpl; + + @Before + public void init() { + super.init(); + pmmlTypeServiceImpl = new PMMLTypeServiceImpl() { + @Override + public PMMLModel getPMMLModel(Path path, String stringPath) { + return pmmlModelLocal; + } + }; + } + + @Test + public void createTopLevelFactModelTree() { + // Single property retrieve + DATA_TYPE simpleString = getSimpleNoCollection(); + FactModelTree retrieved = pmmlTypeServiceImpl.createTopLevelFactModelTree("testPath", simpleString, FactModelTree.Type.INPUT); + assertNotNull(retrieved); + assertEquals("testPath", retrieved.getFactName()); + assertEquals(1, retrieved.getSimpleProperties().size()); + assertTrue(retrieved.getSimpleProperties().containsKey(VALUE)); + assertEquals(simpleString.getMappedClass().getCanonicalName(), retrieved.getSimpleProperties().get(VALUE).getTypeName()); + assertFalse(retrieved.getSimpleProperties().get(VALUE).getBaseTypeName().isPresent()); + assertEquals(simpleString.getMappedClass().getCanonicalName(), retrieved.getSimpleProperties().get(VALUE).getPropertyTypeNameToVisualize()); + assertTrue(retrieved.getExpandableProperties().isEmpty()); + assertTrue(retrieved.getGenericTypesMap().isEmpty()); + } + + @Test + public void retrieveFactModelTuplePmml() { + FactModelTuple factModelTuple = pmmlTypeServiceImpl.retrieveFactModelTuple(mock(Path.class), null, null); + // VisibleFacts should match inputs and predictions on given model + int expectedVisibleFacts = pmmlModelLocal.getMiningFields().size() + pmmlModelLocal.getOutputFields().size(); + assertEquals(expectedVisibleFacts, factModelTuple.getVisibleFacts().size()); + // Verify each miningField has been correctly mapped + pmmlModelLocal.getMiningFields().forEach(miningField -> verifyFactModelTree(factModelTuple, miningField)); + // Verify each outputField has been correctly mapped + pmmlModelLocal.getOutputFields().forEach(outputField -> verifyFactModelTree(factModelTuple, outputField)); + } + + /** + * Verify the FactModelTree generated for a given MiningField + * @param factModelTuple + * @param miningField + */ + private void verifyFactModelTree(FactModelTuple factModelTuple, MiningField miningField ) { + final String name = miningField.getName(); + // Check the FactModelTree has been mapped between visible facts + assertTrue(factModelTuple.getVisibleFacts().containsKey(name)); + final FactModelTree mappedFactModelTree = factModelTuple.getVisibleFacts().get(name); + // Check the FactModelTree is not null + assertNotNull(mappedFactModelTree); + DATA_TYPE originalType = miningField.getDataType(); + verifyDATA_TYPE(mappedFactModelTree, originalType); + FactModelTree.Type expected = isTarget(miningField) ? FactModelTree.Type.PREDICTION : FactModelTree.Type.INPUT; + assertEquals(expected, mappedFactModelTree.getType()); + } + + /** + * Verify the FactModelTree generated for a given OutputField + * @param factModelTuple + * @param outputField + */ + private void verifyFactModelTree(FactModelTuple factModelTuple, OutputField outputField) { + final String name = outputField.getName(); + // Check the FactModelTree has been mapped between visible facts + assertTrue(factModelTuple.getVisibleFacts().containsKey(name)); + final FactModelTree mappedFactModelTree = factModelTuple.getVisibleFacts().get(name); + // Check the FactModelTree is not null + assertNotNull(mappedFactModelTree); + DATA_TYPE originalType = outputField.getDataType(); + verifyDATA_TYPE(mappedFactModelTree, originalType); + assertEquals(FactModelTree.Type.PREDICTION, mappedFactModelTree.getType()); + } + + /** + * Verify the FactModelTree generated for a DATA_TYPE + * @param mappedFactModelTree + * @param originalType + */ + private void verifyDATA_TYPE(FactModelTree mappedFactModelTree, DATA_TYPE originalType) { + assertTrue(mappedFactModelTree.getSimpleProperties().containsKey(VALUE)); + assertEquals(originalType.getMappedClass().getCanonicalName(), mappedFactModelTree.getSimpleProperties().get(VALUE).getTypeName()); + assertEquals(originalType.getMappedClass().getCanonicalName(), mappedFactModelTree.getSimpleProperties().get(VALUE).getPropertyTypeNameToVisualize()); + } +} \ No newline at end of file diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImplTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImplTest.java index 9a7609faf10..3bf5a2277d7 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImplTest.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/java/org/drools/workbench/screens/scenariosimulation/backend/server/ScenarioSimulationServiceImplTest.java @@ -25,8 +25,8 @@ import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; import org.drools.scenariosimulation.api.model.Settings; import org.drools.scenariosimulation.api.model.Simulation; +import org.drools.scenariosimulation.backend.exceptions.ImpossibleToFindDMNException; import org.drools.scenariosimulation.backend.runner.ScenarioJunitActivator; -import org.drools.scenariosimulation.backend.util.ImpossibleToFindDMNException; import org.drools.workbench.screens.scenariosimulation.backend.server.util.ScenarioSimulationBuilder; import org.drools.workbench.screens.scenariosimulation.service.DMNTypeService; import org.guvnor.common.services.backend.config.SafeSessionInfo; diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/resources/org/drools/workbench/screens/scenariosimulation/backend/server/CategoricalVariablesRegression.pmml b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/resources/org/drools/workbench/screens/scenariosimulation/backend/server/CategoricalVariablesRegression.pmml new file mode 100644 index 00000000000..4c4df7e8b41 --- /dev/null +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-backend/src/test/resources/org/drools/workbench/screens/scenariosimulation/backend/server/CategoricalVariablesRegression.pmml @@ -0,0 +1,38 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/main/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderBCImpl.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/main/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderBCImpl.java index e8e75a79841..e2ed108e916 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/main/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderBCImpl.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/main/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderBCImpl.java @@ -58,16 +58,21 @@ public ScenarioSimulationAssetsDropdownProviderBCImpl(Caller> assetListConsumer) { - updateAssets(response -> addAssets(response, assetListConsumer)); + updateAssets("*", response -> addAssets(response, assetListConsumer)); } - protected void updateAssets(RemoteCallback callback) { - ProjectAssetsQuery query = createProjectQuery(); + @Override + public void getItems(String type, Consumer> assetListConsumer) { + updateAssets(type, response -> addAssets(response, assetListConsumer)); + } + + protected void updateAssets(String type, RemoteCallback callback) { + ProjectAssetsQuery query = createProjectQuery(type); assetQueryService.getAssets(query).call(callback, new DefaultErrorCallback()); } - protected ProjectAssetsQuery createProjectQuery() { - List suffixes = Collections.singletonList("dmn"); + protected ProjectAssetsQuery createProjectQuery(String type) { + List suffixes = Collections.singletonList(type); return new ProjectAssetsQuery(libraryPlaces.getActiveWorkspace(), "", 0, diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/test/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/test/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderTest.java index 107cb7db580..73fb2aa459c 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/test/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderTest.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-businesscentral-client/src/test/java/org/drools/workbench/screens/scenariosimulation/businesscentral/client/dropdown/ScenarioSimulationAssetsDropdownProviderTest.java @@ -98,25 +98,25 @@ public void setup() { libraryPlacesMock, assetQueryServiceMock) { @Override - protected ProjectAssetsQuery createProjectQuery() { + protected ProjectAssetsQuery createProjectQuery(String type) { return projectAssetsQuery; } }); - projectAssetsQuery = scenarioSimulationAssetsDropdownProvider.createProjectQuery(); + projectAssetsQuery = scenarioSimulationAssetsDropdownProvider.createProjectQuery("dmn"); } @Test public void getItems() { Consumer> assetListConsumerMock = mock(Consumer.class); - doAnswer(invocation -> null).when(scenarioSimulationAssetsDropdownProvider).updateAssets(isA(RemoteCallback.class)); + doAnswer(invocation -> null).when(scenarioSimulationAssetsDropdownProvider).updateAssets(isA(String.class), isA(RemoteCallback.class)); scenarioSimulationAssetsDropdownProvider.getItems(assetListConsumerMock); - verify(scenarioSimulationAssetsDropdownProvider, times(1)).updateAssets(isA(RemoteCallback.class)); + verify(scenarioSimulationAssetsDropdownProvider, times(1)).updateAssets(isA(String.class), isA(RemoteCallback.class)); } @Test public void updateAssets() { RemoteCallback remoteCallbackMock = mock(RemoteCallback.class); - scenarioSimulationAssetsDropdownProvider.updateAssets(remoteCallbackMock); + scenarioSimulationAssetsDropdownProvider.updateAssets("dmn", remoteCallbackMock); verify(assetQueryServiceMock, times(1)).getAssets(eq(projectAssetsQuery)); verify(invokerMock, times(1)).call(eq(remoteCallbackMock), isA(DefaultErrorCallback.class)); } @@ -128,7 +128,7 @@ public void createProjectQuery() { assetQueryServiceMock) { }); - final ProjectAssetsQuery retrieved = scenarioSimulationAssetsDropdownProvider.createProjectQuery(); + final ProjectAssetsQuery retrieved = scenarioSimulationAssetsDropdownProvider.createProjectQuery("dmn"); assertEquals(1000,retrieved.getAmount()); assertEquals(0, retrieved.getStartIndex()); assertEquals("", retrieved.getFilter()); diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationAssetsDropdownProvider.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationAssetsDropdownProvider.java index f48a280be38..66bee22be6f 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationAssetsDropdownProvider.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationAssetsDropdownProvider.java @@ -15,6 +15,10 @@ */ package org.drools.workbench.screens.scenariosimulation.client.dropdown; +import java.util.List; +import java.util.function.Consumer; + +import org.kie.workbench.common.widgets.client.assets.dropdown.KieAssetsDropdownItem; import org.kie.workbench.common.widgets.client.assets.dropdown.KieAssetsDropdownItemsProvider; /** @@ -22,4 +26,6 @@ */ public interface ScenarioSimulationAssetsDropdownProvider extends KieAssetsDropdownItemsProvider { + void getItems(String type, Consumer> assetListConsumer); + } \ No newline at end of file diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationDropdown.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationDropdown.java index 48a95a62cab..396a310e929 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationDropdown.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/dropdown/ScenarioSimulationDropdown.java @@ -26,7 +26,7 @@ @Named(ScenarioSimulationDropdown.BEAN_NAME) public class ScenarioSimulationDropdown extends AbstractKieAssetsDropdown { - final public static String BEAN_NAME = "ScenarioDropdown"; + public static final String BEAN_NAME = "ScenarioDropdown"; @Inject public ScenarioSimulationDropdown(@Named(ScenarioSimulationDropdownView.BEAN_NAME) ScenarioSimulationDropdownView view, @@ -34,6 +34,15 @@ public ScenarioSimulationDropdown(@Named(ScenarioSimulationDropdownView.BEAN_NAM super(view, dataProvider); } + public void loadAssets(String type) { + clear(); + initializeDropdown(type); + } + + public void initializeDropdown(String type) { + ((ScenarioSimulationAssetsDropdownProvider)dataProvider).getItems(type, getAssetListConsumer()); + } + public IsWidget asWidget() { return ((ScenarioSimulationDropdownView) view).asWidget(); } diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/NewScenarioSimulationHandler.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/NewScenarioSimulationHandler.java index 24f06abd583..9e2e932a404 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/NewScenarioSimulationHandler.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/NewScenarioSimulationHandler.java @@ -131,6 +131,9 @@ public void create(final Package pkg, case DMN: value = uploadWidget.getSelectedPath(); break; + case PMML: + value = uploadWidget.getSelectedPath() + "|" + uploadWidget.getModelName(); + break; case RULE: default: value = null; diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelector.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelector.java index 3536fefa778..08e0d0f5562 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelector.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelector.java @@ -40,25 +40,25 @@ public SourceTypeSelector(TitledAttachmentFileWidget uploadWidget) { @Override public void onValueChange(ValueChangeEvent event) { - final boolean dmnSelected = isDMNSelected(); - uploadWidget.setVisible(dmnSelected); - if (dmnSelected) { - uploadWidget.updateAssetList(); + final boolean dmnOrPmmlSelected = isDMNOrPMMLSelected(); + uploadWidget.setVisible(getSelectedType().name().toLowerCase(), dmnOrPmmlSelected); + if (dmnOrPmmlSelected) { + uploadWidget.updateAssetList(getSelectedType().name().toLowerCase()); } } public boolean validate() { - if (isDMNSelected()) { - return uploadWidget.validate(); + if (isDMNOrPMMLSelected()) { + return uploadWidget.validate(getSelectedType().name().toLowerCase()); } else { return true; } } - public boolean isDMNSelected() { + public boolean isDMNOrPMMLSelected() { return radioButtonList.stream() .filter(CheckBox::getValue) - .anyMatch(radioButton -> radioButton.getText().equalsIgnoreCase(ScenarioSimulationModel.Type.DMN.name())); + .anyMatch(radioButton -> radioButton.getText().equalsIgnoreCase(ScenarioSimulationModel.Type.DMN.name()) || radioButton.getText().equalsIgnoreCase(ScenarioSimulationModel.Type.PMML.name())); } /** @@ -85,6 +85,6 @@ protected void addRadioButtons() { radioButtonList.add(radioButton); add(radioButton); } - uploadWidget.setVisible(isDMNSelected()); + uploadWidget.setVisible(getSelectedType().name().toLowerCase(), isDMNOrPMMLSelected()); } } diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidget.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidget.java index ec8df2c0dd1..6f4c5f7104d 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidget.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidget.java @@ -23,10 +23,12 @@ import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.VerticalPanel; import org.drools.workbench.screens.scenariosimulation.client.dropdown.ScenarioSimulationDropdown; import org.drools.workbench.screens.scenariosimulation.client.resources.i18n.ScenarioSimulationEditorConstants; import org.drools.workbench.screens.scenariosimulation.service.ScenarioSimulationService; import org.gwtbootstrap3.client.ui.FormLabel; +import org.gwtbootstrap3.client.ui.Input; import org.gwtbootstrap3.client.ui.constants.ElementTags; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.constants.Styles; @@ -38,12 +40,16 @@ public class TitledAttachmentFileWidget extends Composite { protected FlowPanel fields = GWT.create(FlowPanel.class); + protected VerticalPanel pmmlFields = GWT.create(VerticalPanel.class); protected Div divElement = GWT.create(Div.class); protected FormLabel titleLabel = GWT.create(FormLabel.class); protected Span errorLabel = GWT.create(Span.class); + protected Span pmmlModelLabel = GWT.create(Span.class); + protected Input pmmlModelText = GWT.create(Input.class); protected ScenarioSimulationDropdown scenarioSimulationDropdown; protected Caller scenarioSimulationService; protected String selectedPath; + protected String selectedType = "dmn"; public TitledAttachmentFileWidget(String title, Caller scenarioSimulationService, ScenarioSimulationDropdown scenarioSimulationDropdown) { @@ -59,37 +65,81 @@ public TitledAttachmentFileWidget(String title, fields.add(divElement); fields.add(this.scenarioSimulationDropdown.asWidget()); fields.add(this.errorLabel); + pmmlModelLabel.setText(ScenarioSimulationEditorConstants.INSTANCE.insertPMMLModelName()); + pmmlFields.add(this.pmmlModelLabel); + pmmlFields.add(this.pmmlModelText); + fields.add(pmmlFields); + pmmlFields.setVisible(false); initWidget(fields); scenarioSimulationDropdown.init(); scenarioSimulationDropdown.registerOnChangeHandler(() -> { final Optional value = scenarioSimulationDropdown.getValue(); selectedPath = value.map(KieAssetsDropdownItem::getValue).orElse(null); - validate(); + validate(selectedType); }); } + public void setVisible(String type, boolean visible) { + selectedType = type; + setVisible(visible); + if (visible) { + switch (selectedType) { + case "dmn": + titleLabel.setText(ScenarioSimulationEditorConstants.INSTANCE.chooseDMN()); + errorLabel.setText(ScenarioSimulationEditorConstants.INSTANCE.chooseValidDMNAsset()); + break; + case "pmml": + titleLabel.setText(ScenarioSimulationEditorConstants.INSTANCE.choosePMML()); + errorLabel.setText(ScenarioSimulationEditorConstants.INSTANCE.chooseValidPMMLAsset()); + break; + default: + errorLabel.setText(""); + } + pmmlFields.setVisible(selectedType.equals("pmml")); + } + setVisible(this.getElement(), visible); + } + public void clearStatus() { - updateAssetList(); + updateAssetList("*"); errorLabel.setText(null); selectedPath = null; + pmmlModelText.setText(null); } - public void updateAssetList() { - scenarioSimulationDropdown.loadAssets(); + public void updateAssetList(String type) { + scenarioSimulationDropdown.loadAssets(type); } public String getSelectedPath() { return selectedPath; } - public boolean validate() { - boolean toReturn = selectedPath != null && !selectedPath.isEmpty(); - if (!toReturn) { - errorLabel.setText(ScenarioSimulationEditorConstants.INSTANCE.chooseValidDMNAsset()); - } else { - errorLabel.setText(null); + public String getModelName() { + return pmmlModelText.getText(); + } + + public boolean validate(String type) { + boolean isPathSelected = selectedPath != null && !selectedPath.isEmpty(); + String toSet = ""; + if (!isPathSelected) { + switch (type) { + case "dmn": + toSet = ScenarioSimulationEditorConstants.INSTANCE.chooseValidDMNAsset(); + break; + case "pmml": + toSet = ScenarioSimulationEditorConstants.INSTANCE.chooseValidPMMLAsset(); + break; + default: + toSet = ""; + } + } + boolean isModelNameSet = !type.equals("pmml") || !pmmlModelText.getText().isEmpty(); + if (!isModelNameSet) { + toSet += " " + ScenarioSimulationEditorConstants.INSTANCE.insertPMMLModelName(); } - return toReturn; + errorLabel.setText(toSet); + return isPathSelected && isModelNameSet; } /** diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.java index 3e6e2653b4c..2b9ebfd3806 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/java/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.java @@ -256,6 +256,12 @@ public interface ScenarioSimulationEditorConstants String chooseValidDMNAsset(); + String choosePMML(); + + String chooseValidPMMLAsset(); + + String insertPMMLModelName(); + String removeCollectionMainTitle(); String removeCollectionMainQuestion(); diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/resources/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.properties b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/resources/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.properties index 77d9fb02954..269d9880787 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/resources/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.properties +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/main/resources/org/drools/workbench/screens/scenariosimulation/client/resources/i18n/ScenarioSimulationEditorConstants.properties @@ -133,6 +133,9 @@ redo=Redo sourceType=Source type chooseDMN=Choose a DMN asset chooseValidDMNAsset=Choose a valid DMN asset from the list +choosePMML=Choose a PMML asset +chooseValidPMMLAsset=Choose a valid PMML asset from the list +insertPMMLModelName=Insert the model name removeCollectionText1=This action will remove all items from the collection and the collection itself. removeCollectionQuestion=Do you want to continue and remove the collection? removeCollectionWarningText=This action cannot be undone. diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelectorTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelectorTest.java index 21721a120eb..dc2c91b5717 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelectorTest.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/SourceTypeSelectorTest.java @@ -18,6 +18,7 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwtmockito.GwtMockitoTestRunner; +import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,44 +52,66 @@ public void setUp() throws Exception { public void onValueChange() { reset(uploadWidgetMock); ValueChangeEvent eventMock = mock(ValueChangeEvent.class); - doReturn(false).when(sourceTypeSelector).isDMNSelected(); + doReturn(false).when(sourceTypeSelector).isDMNOrPMMLSelected(); sourceTypeSelector.onValueChange(eventMock); - verify(uploadWidgetMock, never()).updateAssetList(); - doReturn(true).when(sourceTypeSelector).isDMNSelected(); + verify(uploadWidgetMock, never()).updateAssetList("dmn"); + verify(uploadWidgetMock, never()).updateAssetList("pmml"); + doReturn(true).when(sourceTypeSelector).isDMNOrPMMLSelected(); + doReturn(ScenarioSimulationModel.Type.DMN).when(sourceTypeSelector).getSelectedType(); sourceTypeSelector.onValueChange(eventMock); - verify(uploadWidgetMock, times(1)).updateAssetList(); + verify(uploadWidgetMock, times(1)).updateAssetList("dmn"); + doReturn(ScenarioSimulationModel.Type.PMML).when(sourceTypeSelector).getSelectedType(); + sourceTypeSelector.onValueChange(eventMock); + verify(uploadWidgetMock, times(1)).updateAssetList("pmml"); } @Test public void validateDMO() { - commonValidate(false, false, true); + commonValidate(ScenarioSimulationModel.Type.RULE, false, true); } @Test public void validateInvalidDMN() { - commonValidate(true, false, false); + commonValidate(ScenarioSimulationModel.Type.DMN, false, false); } @Test public void validateValidDMN() { - commonValidate(true, true, true); + commonValidate(ScenarioSimulationModel.Type.DMN, true, true); } @Test - public void addRadioButtons() { - reset(uploadWidgetMock); - sourceTypeSelector.addRadioButtons(); - assertEquals(2, sourceTypeSelector.radioButtonList.size()); - verify(uploadWidgetMock, times(1)).setVisible(false); + public void validateInvalidPMML() { + commonValidate(ScenarioSimulationModel.Type.PMML, false, false); + } + + @Test + public void validateValidPMML() { + commonValidate(ScenarioSimulationModel.Type.PMML, true, true); + } + @Test + public void addRadioButtons() { + for (ScenarioSimulationModel.Type type : ScenarioSimulationModel.Type.values()) { + reset(uploadWidgetMock); + reset(sourceTypeSelector); + boolean dmnOrPMMLSelected = !type.equals(ScenarioSimulationModel.Type.RULE); + doReturn(dmnOrPMMLSelected).when(sourceTypeSelector).isDMNOrPMMLSelected(); + doReturn(type).when(sourceTypeSelector).getSelectedType(); + sourceTypeSelector.addRadioButtons(); + assertEquals(3, sourceTypeSelector.radioButtonList.size()); + verify(uploadWidgetMock, times(1)).setVisible(type.name().toLowerCase(), dmnOrPMMLSelected); + } } - private void commonValidate(boolean isDMNSelected, boolean validate, boolean expected) { - doReturn(isDMNSelected).when(sourceTypeSelector).isDMNSelected(); - doReturn(validate).when(uploadWidgetMock).validate(); + private void commonValidate(ScenarioSimulationModel.Type type, boolean validate, boolean expected) { + boolean isDMNSelected = !type.equals(ScenarioSimulationModel.Type.RULE); + doReturn(isDMNSelected).when(sourceTypeSelector).isDMNOrPMMLSelected(); + doReturn(type).when(sourceTypeSelector).getSelectedType(); + doReturn(validate).when(uploadWidgetMock).validate(type.name().toLowerCase()); boolean retrieved = sourceTypeSelector.validate(); if (isDMNSelected) { - verify(uploadWidgetMock, times(1)).validate(); + verify(uploadWidgetMock, times(1)).validate(type.name().toLowerCase()); } if (expected) { assertTrue(retrieved); diff --git a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidgetTest.java b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidgetTest.java index 44e21eb40dd..6664d02d6d1 100644 --- a/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidgetTest.java +++ b/drools-wb-screens/drools-wb-scenario-simulation-editor/drools-wb-scenario-simulation-editor-client/src/test/java/org/drools/workbench/screens/scenariosimulation/client/handlers/TitledAttachmentFileWidgetTest.java @@ -18,6 +18,7 @@ import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwtmockito.GwtMockitoTestRunner; +import org.drools.scenariosimulation.api.model.ScenarioSimulationModel; import org.drools.workbench.screens.scenariosimulation.client.resources.i18n.ScenarioSimulationEditorConstants; import org.gwtbootstrap3.client.ui.FormLabel; import org.gwtbootstrap3.client.ui.html.Span; @@ -66,15 +67,18 @@ public void clearStatus() { titledAttachmentFileWidget.selectedPath = "SELECTED_PATH"; assertNotNull(titledAttachmentFileWidget.selectedPath); titledAttachmentFileWidget.clearStatus(); - verify(titledAttachmentFileWidget, times(1)).updateAssetList(); + verify(titledAttachmentFileWidget, times(1)).updateAssetList("*"); verify(errorLabelMock, times(1)).setText(eq(null)); assertNull(titledAttachmentFileWidget.selectedPath); } @Test public void updateAssetList() { - titledAttachmentFileWidget.updateAssetList(); - verify(scenarioSimulationDropdownMock, times(1)).loadAssets(); + for (ScenarioSimulationModel.Type type : ScenarioSimulationModel.Type.values()) { + String typeName = type.name().toLowerCase(); + titledAttachmentFileWidget.updateAssetList(typeName); + verify(scenarioSimulationDropdownMock, times(1)).loadAssets(typeName); + } } @Test @@ -94,9 +98,9 @@ public void validatePopulatedPath() { private void commonValidate(String selectedPath, boolean expected) { titledAttachmentFileWidget.selectedPath = selectedPath; - boolean retrieved = titledAttachmentFileWidget.validate(); + boolean retrieved = titledAttachmentFileWidget.validate("dmn"); if (expected) { - verify(errorLabelMock, times(1)).setText(eq(null)); + verify(errorLabelMock, times(1)).setText(""); assertTrue(retrieved); } else { verify(errorLabelMock, times(1)).setText(eq(ScenarioSimulationEditorConstants.INSTANCE.chooseValidDMNAsset())); diff --git a/drools-wb-webapp/pom.xml b/drools-wb-webapp/pom.xml index 038d1fd397c..ca9a0d15859 100644 --- a/drools-wb-webapp/pom.xml +++ b/drools-wb-webapp/pom.xml @@ -114,7 +114,7 @@ org.jboss.errai errai-cdi-jboss - runtime + provided ant @@ -124,10 +124,6 @@ xalan xalan - - net.sourceforge.htmlunit - htmlunit - @@ -147,39 +143,14 @@ org.apache.lucene lucene-core - runtime org.uberfire uberfire-services-backend - - - com.thoughtworks.xstream - xstream - - - org.powermock - powermock-api-mockito2 - - - org.powermock - powermock-module-junit4 - - org.jboss.errai errai-bus - - - io.netty - netty-codec-http - - - io.netty - netty-handler - - org.jboss.errai @@ -342,7 +313,6 @@ org.kie kie-ci - runtime @@ -353,12 +323,6 @@ org.kie.server kie-server-api - - - org.kie - kie-pmml-dependencies - - @@ -635,12 +599,6 @@ kie-wb-common-server-ui-backend - - org.kie.server - kie-server-controller-openshift - runtime - - org.kie.workbench.screens kie-wb-common-server-ui-client @@ -1122,7 +1080,6 @@ org.kie.workbench.forms kie-wb-common-forms-backend-services - @@ -1241,25 +1198,21 @@ org.uberfire uberfire-metadata-commons-io - runtime org.uberfire uberfire-metadata-backend-lucene - runtime org.uberfire uberfire-metadata-backend-elasticsearch - runtime org.uberfire uberfire-metadata-backend-infinispan - runtime @@ -1494,7 +1447,6 @@ junit junit - test com.google.gwt.gwtmockito @@ -1662,7 +1614,7 @@ gwt-maven-plugin ${project.build.directory}/gwt-symbols-deploy - -Xmx8G -Xms1024m -Xss1M -XX:CompileThreshold=7000 -Derrai.jboss.home=${wildfly.home} -Derrai.marshalling.server.classOutput=${project.build.outputDirectory} -Derrai.dynamic_validation.enabled=true -Djava.io.tmpdir=${project.build.directory} + -Xmx16G -Xms1024m -Xss1M -XX:CompileThreshold=7000 -Derrai.jboss.home=${wildfly.home} -Derrai.marshalling.server.classOutput=${project.build.outputDirectory} -Derrai.dynamic_validation.enabled=true -Djava.io.tmpdir=${project.build.directory} org.drools.workbench.DroolsWorkbench INFO false