Skip to content

Commit

Permalink
[KOGITO-5777] Centralize data type resolution (#1579)
Browse files Browse the repository at this point in the history
  • Loading branch information
fjtirado authored Sep 6, 2021
1 parent 13ac92a commit bc3ace3
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@
import org.jbpm.process.core.context.variable.Variable;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.process.core.datatype.DataType;
import org.jbpm.process.core.datatype.impl.type.BooleanDataType;
import org.jbpm.process.core.datatype.impl.type.FloatDataType;
import org.jbpm.process.core.datatype.impl.type.IntegerDataType;
import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
import org.jbpm.process.core.datatype.impl.type.StringDataType;
import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.Node;
Expand Down Expand Up @@ -109,6 +105,7 @@ protected void initValidPeers() {
this.validPeers.add(Association.class);
}

@Override
public Object start(final String uri, final String localName, final Attributes attrs,
final ExtensibleXmlParser parser) throws SAXException {
parser.startElementBuilder(localName, attrs);
Expand All @@ -135,7 +132,7 @@ public Object start(final String uri, final String localName, final Attributes a
newId = n.getId();
}
}
((Node) node).setId(++newId);
node.setId(++newId);
}
} else {
AtomicInteger idGen = (AtomicInteger) parser.getMetaData().get("idGen");
Expand All @@ -146,6 +143,7 @@ public Object start(final String uri, final String localName, final Attributes a

protected abstract Node createNode(Attributes attrs);

@Override
public Object end(final String uri, final String localName,
final ExtensibleXmlParser parser) throws SAXException {
final Element element = parser.endElementBuilder();
Expand Down Expand Up @@ -480,33 +478,13 @@ protected void readMultiInstanceLoopCharacteristics(org.w3c.dom.Node xmlNode, Fo
}

protected DataType getDataType(String itemSubjectRef, Map<String, ItemDefinition> itemDefinitions, ClassLoader cl) {
DataType dataType = new ObjectDataType();
DataType dataType = DataTypeResolver.defaultDataType;
if (itemDefinitions == null) {
return dataType;
}
ItemDefinition itemDefinition = itemDefinitions.get(itemSubjectRef);
if (itemDefinition != null) {
String structureRef = itemDefinition.getStructureRef();

if ("java.lang.Boolean".equals(structureRef) || "Boolean".equals(structureRef)) {
dataType = new BooleanDataType();

} else if ("java.lang.Integer".equals(structureRef) || "Integer".equals(structureRef)) {
dataType = new IntegerDataType();

} else if ("java.lang.Float".equals(structureRef) || "Float".equals(structureRef)) {
dataType = new FloatDataType();

} else if ("java.lang.String".equals(structureRef) || "String".equals(structureRef)) {
dataType = new StringDataType();

} else if ("java.lang.Object".equals(structureRef) || "Object".equals(structureRef)) {
dataType = new ObjectDataType(structureRef);

} else {
dataType = new ObjectDataType(structureRef, cl);
}

dataType = DataTypeResolver.fromType(itemDefinition.getStructureRef(), cl);
}
return dataType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@
import org.jbpm.process.core.context.variable.Variable;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.process.core.datatype.DataType;
import org.jbpm.process.core.datatype.impl.type.BooleanDataType;
import org.jbpm.process.core.datatype.impl.type.FloatDataType;
import org.jbpm.process.core.datatype.impl.type.IntegerDataType;
import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
import org.jbpm.process.core.datatype.impl.type.StringDataType;
import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.workflow.core.Node;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
Expand All @@ -59,6 +55,7 @@ protected void initValidPeers() {
this.validPeers.add(SequenceFlow.class);
}

@Override
@SuppressWarnings("unchecked")
public Object start(final String uri, final String localName,
final Attributes attrs, final ExtensibleXmlParser parser)
Expand All @@ -79,33 +76,12 @@ public Object start(final String uri, final String localName,
variable.setName(id);
variable.setMetaData(id, variable.getName());
// retrieve type from item definition
DataType dataType = new ObjectDataType();
DataType dataType = DataTypeResolver.defaultDataType;
Map<String, ItemDefinition> itemDefinitions = (Map<String, ItemDefinition>) ((ProcessBuildData) parser.getData()).getMetaData("ItemDefinitions");
if (itemDefinitions != null) {
ItemDefinition itemDefinition = itemDefinitions.get(itemSubjectRef);
if (itemDefinition != null) {

String structureRef = itemDefinition.getStructureRef();

if ("java.lang.Boolean".equals(structureRef) || "Boolean".equals(structureRef)) {
dataType = new BooleanDataType();

} else if ("java.lang.Integer".equals(structureRef) || "Integer".equals(structureRef)) {
dataType = new IntegerDataType();

} else if ("java.lang.Float".equals(structureRef) || "Float".equals(structureRef)) {
dataType = new FloatDataType();

} else if ("java.lang.String".equals(structureRef) || "String".equals(structureRef)) {
dataType = new StringDataType();

} else if ("java.lang.Object".equals(structureRef) || "Object".equals(structureRef)) {
// use FQCN of Object
dataType = new ObjectDataType("java.lang.Object");

} else {
dataType = new ObjectDataType(structureRef, parser.getClassLoader());
}
dataType = DataTypeResolver.fromType(itemDefinition.getStructureRef(), parser.getClassLoader());
}
}
variable.setType(dataType);
Expand All @@ -116,12 +92,14 @@ public Object start(final String uri, final String localName,
return new Variable();
}

@Override
public Object end(final String uri, final String localName,
final ExtensibleXmlParser parser) throws SAXException {
parser.endElementBuilder();
return parser.getCurrent();
}

@Override
public Class<?> generateNodeFor() {
return Variable.class;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@
import org.jbpm.process.core.context.variable.Variable;
import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.process.core.datatype.DataType;
import org.jbpm.process.core.datatype.impl.type.BooleanDataType;
import org.jbpm.process.core.datatype.impl.type.FloatDataType;
import org.jbpm.process.core.datatype.impl.type.IntegerDataType;
import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
import org.jbpm.process.core.datatype.impl.type.StringDataType;
import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.process.core.datatype.impl.type.UndefinedDataType;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.NodeContainer;
Expand All @@ -62,13 +58,15 @@ public DefinitionsHandler() {
}
}

@Override
public Object start(final String uri, final String localName,
final Attributes attrs, final ExtensibleXmlParser parser)
throws SAXException {
parser.startElementBuilder(localName, attrs);
return new Definitions();
}

@Override
public Object end(final String uri, final String localName,
final ExtensibleXmlParser parser) throws SAXException {
final Element element = parser.endElementBuilder();
Expand All @@ -89,6 +87,7 @@ public Object end(final String uri, final String localName,
return definitions;
}

@Override
public Class<?> generateNodeFor() {
return Definitions.class;
}
Expand Down Expand Up @@ -168,31 +167,10 @@ private void setVariableDataType(Variable variable, Map<String, ItemDefinition>

String itemSubjectRef = (String) variable.getMetaData("ItemSubjectRef");
if (UndefinedDataType.getInstance().equals(variable.getType()) && itemDefinitions != null && itemSubjectRef != null) {
DataType dataType = new ObjectDataType();
DataType dataType = DataTypeResolver.defaultDataType;
ItemDefinition itemDefinition = itemDefinitions.get(itemSubjectRef);
if (itemDefinition != null) {
String structureRef = itemDefinition.getStructureRef();

if ("java.lang.Boolean".equals(structureRef) || "Boolean".equals(structureRef)) {
dataType = new BooleanDataType();

} else if ("java.lang.Integer".equals(structureRef) || "Integer".equals(structureRef)) {
dataType = new IntegerDataType();

} else if ("java.lang.Float".equals(structureRef) || "Float".equals(structureRef)) {
dataType = new FloatDataType();

} else if ("java.lang.String".equals(structureRef) || "String".equals(structureRef)) {
dataType = new StringDataType();

} else if ("java.lang.Object".equals(structureRef) || "Object".equals(structureRef)) {
// use FQCN of Object
dataType = new ObjectDataType("java.lang.Object");

} else {
dataType = new ObjectDataType(structureRef, cl);
}

dataType = DataTypeResolver.fromType(itemDefinition.getStructureRef(), cl);
}
variable.setType(dataType);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.jbpm.process.core.datatype;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;

import org.jbpm.process.core.datatype.impl.type.BooleanDataType;
import org.jbpm.process.core.datatype.impl.type.EnumDataType;
import org.jbpm.process.core.datatype.impl.type.FloatDataType;
import org.jbpm.process.core.datatype.impl.type.IntegerDataType;
import org.jbpm.process.core.datatype.impl.type.ListDataType;
import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
import org.jbpm.process.core.datatype.impl.type.StringDataType;

public class DataTypeResolver {

public static final DataType defaultDataType = new ObjectDataType("java.lang.Object");

private static final Map<Class<?>, DataType> dataTypes = new HashMap<>();

static {
dataTypes.put(Boolean.class, new BooleanDataType());
dataTypes.put(String.class, new StringDataType());
dataTypes.put(Integer.class, new IntegerDataType());
dataTypes.put(Float.class, new FloatDataType());
dataTypes.put(Collection.class, new ListDataType());
dataTypes.put(Enum.class, new EnumDataType());
}

private DataTypeResolver() {
}

public static DataType fromType(String type, ClassLoader cl) {
return type == null ? defaultDataType : from(type, cl);
}

public static DataType fromObject(Object value) {
return value == null ? defaultDataType : from(value.getClass()).orElse(buildObjectDataType(value.getClass().getCanonicalName()));
}

private static DataType from(String type, ClassLoader cl) {
if (!type.contains(".")) {
type = "java.lang." + type;
}
try {
return from(cl.loadClass(type)).orElse(new ObjectDataType(type, cl));
} catch (ClassNotFoundException ex) {
return new ObjectDataType(type);
}
}

private static Optional<DataType> from(Class<?> type) {
for (Entry<Class<?>, DataType> entry : dataTypes.entrySet()) {
if (entry.getKey().isAssignableFrom(type)) {
return Optional.of(entry.getValue());
}
}
return Optional.empty();
}

private static DataType buildObjectDataType(String type) {
try {
Class.forName(type);
return new ObjectDataType(type);
} catch (ClassNotFoundException ex) {
return defaultDataType;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.jbpm.process.core.datatype;

import java.util.Arrays;

import org.jbpm.process.core.datatype.impl.type.BooleanDataType;
import org.jbpm.process.core.datatype.impl.type.EnumDataType;
import org.jbpm.process.core.datatype.impl.type.FloatDataType;
import org.jbpm.process.core.datatype.impl.type.IntegerDataType;
import org.jbpm.process.core.datatype.impl.type.ListDataType;
import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
import org.jbpm.process.core.datatype.impl.type.StringDataType;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertTrue;

public class DataTypeResolverTest {

private enum Champions {
BETIS,
DEPORTIVO,
REAL_SOCIEDAD,
VALENCIA
}

@Test
public void testDataType() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
assertTrue(DataTypeResolver.fromObject("pepe") instanceof StringDataType);
assertTrue(DataTypeResolver.fromObject(true) instanceof BooleanDataType);
assertTrue(DataTypeResolver.fromObject(4) instanceof IntegerDataType);
assertTrue(DataTypeResolver.fromObject(23.2f) instanceof FloatDataType);
assertTrue(DataTypeResolver.fromObject(Arrays.asList("1", "2", "3")) instanceof ListDataType);
assertTrue(DataTypeResolver.fromObject(new byte[0]) instanceof ObjectDataType);
assertTrue(DataTypeResolver.fromObject(Champions.BETIS) instanceof EnumDataType);
assertTrue(DataTypeResolver.fromType("String", cl) instanceof StringDataType);
assertTrue(DataTypeResolver.fromType("Boolean", cl) instanceof BooleanDataType);
assertTrue(DataTypeResolver.fromType("Integer", cl) instanceof IntegerDataType);
assertTrue(DataTypeResolver.fromType("Float", cl) instanceof FloatDataType);
assertTrue(DataTypeResolver.fromType("java.util.List", cl) instanceof ListDataType);
assertTrue(DataTypeResolver.fromType("Object", cl) instanceof ObjectDataType);

}
}
Loading

0 comments on commit bc3ace3

Please sign in to comment.